IIINSTRUMENT Pipeline Reference Manual  0.1.13
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 
63 static 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 */
75 cpl_recipe_define( rrrecipe,
76  IIINSTRUMENT_BINARY_VERSION,
77  "Firstname Lastname",
78  "usd-help@eso.org",
79  "2018",
80  "An example recipe.",
81  rrrecipe_description);
82 
83 /*----------------------------------------------------------------------------*/
87 /*----------------------------------------------------------------------------*/
88 
91 /*----------------------------------------------------------------------------*/
95 /*----------------------------------------------------------------------------*/
96 
97 /*----------------------------------------------------------------------------*/
107 /*----------------------------------------------------------------------------*/
108 static 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 /*----------------------------------------------------------------------------*/
240 static 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 }
iiinstrument_pfits_get_dit
double iiinstrument_pfits_get_dit(const cpl_propertylist *plist)
find out the DIT value
Definition: iiinstrument_pfits.c:68
iiinstrument_check_and_set_groups
cpl_error_code iiinstrument_check_and_set_groups(cpl_frameset *frameset)
check the entries in the recipe and classify the frameset with the tags
Definition: iiinstrument_utils.c:70