IIINSTRUMENT Pipeline Reference Manual 0.1.15
rrrecipe.c
1/*
2 * This file is part of the IIINSTRUMENT Pipeline
3 * Copyright (C) 2002-2019 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24/*----------------------------------------------------------------------------*/
28/*----------------------------------------------------------------------------*/
29
30#include "iiinstrument_utils.h"
31#include "iiinstrument_pfits.h"
32#include "iiinstrument_dfs.h"
33
34#include <cpl.h>
35
36/*----------------------------------------------------------------------------*/
40/*----------------------------------------------------------------------------*/
41
42#define RECIPE_NAME "rrrecipe"
43#define CONTEXT "iiinstrument."RECIPE_NAME
44
45/*----------------------------------------------------------------------------*/
49/*----------------------------------------------------------------------------*/
50
51/*----------------------------------------------------------------------------*/
55/*----------------------------------------------------------------------------*/
56
57/*----------------------------------------------------------------------------*/
61/*----------------------------------------------------------------------------*/
62
63static const char rrrecipe_description[] =
64 "This example text is used to describe the recipe.\n"
65 "The description should include the required FITS-files and\n"
66 "their associated tags, e.g.\n"
67 "IIINSTRUMENT-RRRECIPE-raw-file.fits " RRRECIPE_RAW "\n"
68 "and any optional files, e.g.\n"
69 "IIINSTRUMENT-RRRECIPE-flat-file.fits " IIINSTRUMENT_CALIB_FLAT "\n"
70 "\n"
71 "Additionally, it should describe functionality of the expected output."
72 "\n";
73
74/* Standard CPL recipe definition */
75cpl_recipe_define( rrrecipe,
76 IIINSTRUMENT_BINARY_VERSION,
77 "Firstname Lastname",
78 PACKAGE_BUGREPORT,
79 "2021",
80 "An example recipe.",
81 rrrecipe_description);
82
83/*----------------------------------------------------------------------------*/
87/*----------------------------------------------------------------------------*/
88
91/*----------------------------------------------------------------------------*/
95/*----------------------------------------------------------------------------*/
96
97/*----------------------------------------------------------------------------*/
107/*----------------------------------------------------------------------------*/
108static int rrrecipe(
109 cpl_frameset * frameset,
110 const cpl_parameterlist * parlist)
111{
112 const cpl_parameter *param;
113 const char *str_option;
114 int bool_option;
115 const cpl_frame *rawframe;
116 const cpl_frame *flat;
117 double qc_param;
118 cpl_propertylist *plist;
119 cpl_propertylist *applist;
120 cpl_image *image;
121
122
123 if (iiinstrument_check_and_set_groups(frameset) != CPL_ERROR_NONE) {
124 return cpl_error_get_code();
125 }
126
127 /* Use the errorstate to detect an error in a function that does not
128 return an error code. */
129 cpl_errorstate prestate = cpl_errorstate_get();
130
131
132 /* HOW TO RETRIEVE INPUT PARAMETERS */
133
134 /* --stropt */
135 param = cpl_parameterlist_find_const(parlist, CONTEXT".str_option");
136 str_option = cpl_parameter_get_string(param);
137
138 /* --boolopt */
139 param = cpl_parameterlist_find_const(parlist, CONTEXT".bool_option");
140 bool_option = cpl_parameter_get_bool(param);
141
142 if (!cpl_errorstate_is_equal(prestate)) {
143 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
144 "Could not retrieve the input parameters");
145 }
146
147
148 /* HOW TO ACCESS INPUT DATA */
149
150 /* - A required file */
151 rawframe = cpl_frameset_find_const(frameset, RRRECIPE_RAW);
152 if (rawframe == NULL) {
153 /* cpl_frameset_find_const() does not set an error code, when a frame
154 is not found, so we will set one here. */
155 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
156 "SOF does not have any file tagged with %s", RRRECIPE_RAW);
157 }
158
159 /* - A recommended file */
160 flat = cpl_frameset_find(frameset, IIINSTRUMENT_CALIB_FLAT);
161 if (flat == NULL) {
162 cpl_msg_warning(cpl_func, "SOF does not have any file tagged with %s",
163 IIINSTRUMENT_CALIB_FLAT);
164 }
165
166
167 /* HOW TO GET THE VALUE OF A FITS KEYWORD */
168 /* - Load only DETector related keys */
169 plist = cpl_propertylist_load_regexp(cpl_frame_get_filename(rawframe),
170 0, "ESO DET ", 0);
171 if (plist == NULL) {
172 /* In this case an error message is added to the error propagation */
173 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
174 "Could not read the FITS header");
175 }
176
177 if (bool_option == CPL_FALSE) {
178 cpl_msg_info(cpl_func, "Bool option unset: String: %s", str_option);
179 }
180
181 qc_param = iiinstrument_pfits_get_dit(plist);
182 cpl_propertylist_delete(plist);
183
184
185 /* Check for a change in the CPL error state */
186 /* - if it did change then propagate the error and return */
187 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
188
189
190 /* NOW PERFORMING THE DATA REDUCTION */
191
192 /* Let's just load an image for the example */
193 image = cpl_image_load(cpl_frame_get_filename(rawframe), CPL_TYPE_FLOAT, 0,
194 0);
195 if (image == NULL) {
196 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
197 "Could not load the image");
198 }
199
200 applist = cpl_propertylist_new();
201
202 /* Add the product category */
203 cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG,
204 RRRECIPE_OUT_PROCATG);
205
206 /* Add a QC parameter */
207 cpl_propertylist_append_double(applist, "ESO QC QCPARAM", qc_param);
208
209
210 /* HOW TO SAVE A DFS-COMPLIANT PRODUCT TO DISK */
211 if (cpl_dfs_save_image(frameset, NULL, parlist, frameset, NULL, image,
212 CPL_BPP_IEEE_FLOAT, RECIPE_NAME, applist,
213 NULL, PACKAGE "/" PACKAGE_VERSION,
214 "rrrecipe.fits")) {
215 /* Propagate the error */
216 (void)cpl_error_set_where(cpl_func);
217 }
218
219
220 /* Cleanup */
221 cpl_image_delete(image);
222 cpl_propertylist_delete(applist);
223
224
225 return cpl_error_get_code();
226}
227
230/*----------------------------------------------------------------------------*/
239/*----------------------------------------------------------------------------*/
240static cpl_error_code rrrecipe_fill_parameterlist(
241 cpl_parameterlist *self)
242{
243 /* Add the different default parameters to the recipe */
244 cpl_errorstate prestate = cpl_errorstate_get();
245
246 /* Fill the parameters list */
247 cpl_parameter *par;
248
249 /* --stropt */
250 par = cpl_parameter_new_value(CONTEXT".str_option",
251 CPL_TYPE_STRING, "the string option",
252 CONTEXT, "NONE");
253 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "stropt");
254 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
255 cpl_parameterlist_append(self, par);
256
257 /* --fileopt */
258 par = cpl_parameter_new_value(CONTEXT".file_option",
259 CPL_TYPE_STRING, "the file option",
260 CONTEXT, "NONE");
261 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "fileopt");
262 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
263 cpl_parameterlist_append(self, par);
264
265 /* --boolopt */
266 par = cpl_parameter_new_value(CONTEXT".bool_option",
267 CPL_TYPE_BOOL, "a flag",
268 CONTEXT, TRUE);
269 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "boolopt");
270 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
271 cpl_parameterlist_append(self, par);
272
273 /* --intopt */
274 par = cpl_parameter_new_value(CONTEXT".int_option",
275 CPL_TYPE_INT, "an integer",
276 CONTEXT, 3);
277 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "intopt");
278 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
279 cpl_parameterlist_append(self, par);
280
281 /* --floatopt */
282 par = cpl_parameter_new_value(CONTEXT".float_option", CPL_TYPE_DOUBLE,
283 "A float",
284 CONTEXT, 0.5);
285 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "floatopt");
286 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
287 cpl_parameterlist_append(self, par);
288
289 /* --rangeopt */
290 par = cpl_parameter_new_range(CONTEXT".range_option", CPL_TYPE_INT,
291 "This is a value range of type int",
292 CONTEXT, 3, 0, 10);
293 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "rangeopt");
294 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
295 cpl_parameterlist_append(self, par);
296
297 /* --enumopt */
298 par = cpl_parameter_new_enum(CONTEXT".enum_option", CPL_TYPE_STRING,
299 "This is an enumeration of type string",
300 CONTEXT, "first", 3, "first", "second", "third");
301 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "enumopt");
302 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
303 cpl_parameterlist_append(self, par);
304
305 /* --floatrangeopt */
306 par = cpl_parameter_new_range(CONTEXT".float_range_option", CPL_TYPE_DOUBLE,
307 "This is a value range of type float."
308 " Valid ragne is [-5.5, 5.5]",
309 CONTEXT, 3.5, -5.5, 5.5);
310 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "floatrangeopt");
311 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
312 cpl_parameterlist_append(self, par);
313
314
315 /* Check possible errors */
316 if (!cpl_errorstate_is_equal(prestate)) {
317 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
318 "rrrecipe_fill_parameterlist failed!");
319 }
320
321 return CPL_ERROR_NONE;
322}
double iiinstrument_pfits_get_dit(const cpl_propertylist *plist)
find out the DIT value
cpl_error_code iiinstrument_check_and_set_groups(cpl_frameset *frameset)
check the entries in the recipe and classify the frameset with the tags