CR2RE Pipeline Reference Manual 1.7.0
cr2res_obs_staring.c
1/*
2 * This file is part of the CR2RES Pipeline
3 * Copyright (C) 2002,2003 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 02111-1307 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24/*-----------------------------------------------------------------------------
25 Includes
26 -----------------------------------------------------------------------------*/
27
28#include <string.h>
29#include <cpl.h>
30
31#include "cr2res_utils.h"
32#include "cr2res_idp.h"
33#include "cr2res_calib.h"
34#include "cr2res_pfits.h"
35#include "cr2res_dfs.h"
36#include "cr2res_bpm.h"
37#include "cr2res_trace.h"
38#include "cr2res_extract.h"
39#include "cr2res_io.h"
40#include "cr2res_qc.h"
41
42/*-----------------------------------------------------------------------------
43 Define
44 -----------------------------------------------------------------------------*/
45
46#define RECIPE_STRING "cr2res_obs_staring"
47
48/*-----------------------------------------------------------------------------
49 Plugin registration
50 -----------------------------------------------------------------------------*/
51
52int cpl_plugin_get_info(cpl_pluginlist * list);
53
54/*-----------------------------------------------------------------------------
55 Private function prototypes
56 -----------------------------------------------------------------------------*/
57
58static cpl_frameset * cr2res_obs_staring_find_RAW(
59 const cpl_frameset * in) ;
60static int cr2res_obs_staring_check_inputs_validity(
61 const cpl_frameset * rawframes) ;
62static int cr2res_obs_staring_reduce(
63 const cpl_frameset * rawframes,
64 const cpl_frame * trace_wave_frame,
65 const cpl_frame * detlin_frame,
66 const cpl_frame * master_dark_frame,
67 const cpl_frame * master_flat_frame,
68 const cpl_frame * bpm_frame,
69 const cpl_frame * blaze_frame,
70 const cpl_array * slit_frac,
71 int subtract_nolight_rows,
72 int subtract_interorder_column,
73 int cosmics,
74 int error_method,
75 int extract_oversample,
76 double extract_pclip,
77 int extract_swath_width,
78 int extract_height,
79 double extract_smooth_slit,
80 double extract_smooth_spec,
81 int reduce_det,
82 hdrl_image ** combined,
83 cpl_table ** extract,
84 cpl_table ** slitfunc,
85 hdrl_image ** model,
86 cpl_propertylist ** ext_plist) ;
87static int cr2res_obs_staring_create(cpl_plugin *);
88static int cr2res_obs_staring_exec(cpl_plugin *);
89static int cr2res_obs_staring_destroy(cpl_plugin *);
90static int cr2res_obs_staring(cpl_frameset *, const cpl_parameterlist *);
91
92/*-----------------------------------------------------------------------------
93 Static variables
94 -----------------------------------------------------------------------------*/
95
96static char cr2res_obs_staring_description[] = "\
97Staring Observation \n\
98 This recipe handles staring observations. \n\
99 \n\
100 Inputs \n\
101 raw.fits " CR2RES_OBS_STARING_OTHER_RAW" [1 to n] \n\
102 or " CR2RES_OBS_STARING_JITTER_RAW" [1 to n] \n\
103 or " CR2RES_OBS_STARING_WAVE_SKY_RAW" [1 to n] \n\
104 trace.fits " CR2RES_CAL_FLAT_TW_PROCATG " [1] \n\
105 or " CR2RES_CAL_FLAT_TW_MERGED_PROCATG " \n\
106 or " CR2RES_UTIL_TRACE_TW_PROCATG " \n\
107 or " CR2RES_UTIL_WAVE_TW_PROCATG " \n\
108 or " CR2RES_CAL_WAVE_TW_PROCATG " \n\
109 or " CR2RES_UTIL_SLIT_CURV_TW_PROCATG " \n\
110 detlin.fits " CR2RES_CAL_DETLIN_COEFFS_PROCATG " [0 to 1] \n\
111 bpm.fits " CR2RES_CAL_DARK_BPM_PROCATG " [0 to 1] \n\
112 or " CR2RES_CAL_FLAT_BPM_PROCATG " \n\
113 or " CR2RES_CAL_DETLIN_BPM_PROCATG " \n\
114 or " CR2RES_UTIL_BPM_MERGE_PROCATG " \n\
115 or " CR2RES_UTIL_BPM_SPLIT_PROCATG " \n\
116 master_dark.fits " CR2RES_CAL_DARK_MASTER_PROCATG " [0 to 1] \n\
117 master_flat.fits " CR2RES_CAL_FLAT_MASTER_PROCATG " [0 to 1] \n\
118 blaze.fits " CR2RES_CAL_FLAT_EXTRACT_1D_PROCATG " [0 to 1] \n\
119 \n\
120 Outputs \n\
121 cr2res_obs_staring_slitfunc.fits "
122 CR2RES_OBS_STARING_SLITFUNC_PROCATG "\n\
123 cr2res_obs_staring_model.fits "
124 CR2RES_OBS_STARING_SLITMODEL_PROCATG "\n\
125 cr2res_obs_staring_extracted.fits "
126 CR2RES_OBS_STARING_EXTRACT_PROCATG "\n\
127 \n\
128 Algorithm \n\
129 loop on detectors d: \n\
130 call cr2res_obs_staring_reduce() \n\
131 -> combined(d) \n\
132 -> extract(d) \n\
133 -> slitfunc(d) \n\
134 -> model(d) \n\
135 Save extract \n\
136 Save slitfunc \n\
137 Save model \n\
138 \n\
139 cr2res_obs_staring_reduce() \n\
140 Load the input raw frames in an image list \n\
141 Apply the calibrations to the image list \n\
142 Remove the master dark and flat errors from each image \n\
143 Collapse the image list \n\
144 Add the master dark and flat errors to the collapsed image \n\
145 Load the input trace wave \n\
146 Recompute a new trace wave with the specified slit fraction \n\
147 (--slit_frac) if needed \n\
148 Extract the spectra from the collapsed image \n\
149 -> combined \n\
150 -> extracted \n\
151 -> slit_func \n\
152 -> model_master \n\
153 Compute QC parameters \n\
154 \n\
155 Library functions used \n\
156 cr2res_io_find_TRACE_WAVE() \n\
157 cr2res_io_find_BPM() \n\
158 cr2res_obs_staring_reduce() \n\
159 cr2res_io_read_dits() \n\
160 cr2res_io_load_image_list_from_set() \n\
161 cr2res_calib_imagelist() \n\
162 cr2res_io_load_TRACE_WAVE() \n\
163 cr2res_extract_traces() \n\
164 cr2res_io_save_COMBINED() \n\
165 cr2res_io_save_EXTRACT_1D() \n\
166 cr2res_io_save_SLIT_FUNC() \n\
167";
168
169/*-----------------------------------------------------------------------------
170 Function code
171 -----------------------------------------------------------------------------*/
172
173/*----------------------------------------------------------------------------*/
183/*----------------------------------------------------------------------------*/
184int cpl_plugin_get_info(cpl_pluginlist * list)
185{
186 cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
187 cpl_plugin * plugin = &recipe->interface;
188
189 if (cpl_plugin_init(plugin,
190 CPL_PLUGIN_API,
191 CR2RES_BINARY_VERSION,
192 CPL_PLUGIN_TYPE_RECIPE,
193 RECIPE_STRING,
194 "Staring Observation recipe",
195 cr2res_obs_staring_description,
196 CR2RES_PIPELINE_AUTHORS,
197 PACKAGE_BUGREPORT,
199 cr2res_obs_staring_create,
200 cr2res_obs_staring_exec,
201 cr2res_obs_staring_destroy)) {
202 cpl_msg_error(cpl_func, "Plugin initialization failed");
203 (void)cpl_error_set_where(cpl_func);
204 return 1;
205 }
206
207 if (cpl_pluginlist_append(list, plugin)) {
208 cpl_msg_error(cpl_func, "Error adding plugin to list");
209 (void)cpl_error_set_where(cpl_func);
210 return 1;
211 }
212
213 return 0;
214}
215
216/*----------------------------------------------------------------------------*/
224/*----------------------------------------------------------------------------*/
225static int cr2res_obs_staring_create(cpl_plugin * plugin)
226{
227 cpl_recipe * recipe ;
228 cpl_parameter * p ;
229
230 /* Check that the plugin is part of a valid recipe */
231 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
232 recipe = (cpl_recipe *)plugin;
233 else
234 return -1;
235
236 /* Create the parameters list in the cpl_recipe object */
237 recipe->parameters = cpl_parameterlist_new();
238
239 /* Fill the parameters list */
240
241 p = cpl_parameter_new_value(
242 "cr2res.cr2res_obs_staring.subtract_nolight_rows",
243 CPL_TYPE_BOOL,
244 "Subtract median row from baffled region at detector bottom",
245 "cr2res.cr2res_obs_staring", FALSE);
246 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "subtract_nolight_rows");
247 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
248 cpl_parameterlist_append(recipe->parameters, p);
249
250 p = cpl_parameter_new_value(
251 "cr2res.cr2res_obs_staring.subtract_interorder_column",
252 CPL_TYPE_BOOL,
253 "Subtract column-by-column fit to the pixel values between"
254 " spectral orders",
255 "cr2res.cr2res_obs_staring", TRUE);
256 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
257 "subtract_interorder_column");
258 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
259 cpl_parameterlist_append(recipe->parameters, p);
260
261 p = cpl_parameter_new_value("cr2res.cr2res_obs_staring.cosmics",
262 CPL_TYPE_BOOL, "Find and mark cosmic rays hits as bad",
263 "cr2res.cr2res_obs_staring", FALSE);
264 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "cosmics");
265 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
266 cpl_parameterlist_append(recipe->parameters, p);
267
268 p = cpl_parameter_new_enum("cr2res.cr2res_obs_staring.error_method",
269 CPL_TYPE_STRING, "The 1d extraction error calculation method",
270 "cr2res.cr2res_obs_staring",
271 "Horne", 2, "Poisson", "Horne");
272 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "error_method");
273 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
274 cpl_parameterlist_append(recipe->parameters, p);
275
276 p = cpl_parameter_new_value("cr2res.cr2res_obs_staring.slit_frac",
277 CPL_TYPE_STRING, "Wished slit fraction",
278 "cr2res.cr2res_obs_staring", "-1.0, -1.0");
279 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slit_frac");
280 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
281 cpl_parameterlist_append(recipe->parameters, p);
282
283 p = cpl_parameter_new_value("cr2res.cr2res_obs_staring.extract_oversample",
284 CPL_TYPE_INT, "factor by which to oversample the extraction",
285 "cr2res.cr2res_obs_staring", 5);
286 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "extract_oversample");
287 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
288 cpl_parameterlist_append(recipe->parameters, p);
289
290 p = cpl_parameter_new_value("cr2res.cr2res_obs_staring.extract_pclip",
291 CPL_TYPE_DOUBLE, "percentage of high and low pixels to clip on first iteration",
292 "cr2res.cr2res_obs_staring", 0.1);
293 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "extract_pclip");
294 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
295 cpl_parameterlist_append(recipe->parameters, p);
296
297 p = cpl_parameter_new_value("cr2res.cr2res_obs_staring.extract_swath_width",
298 CPL_TYPE_INT, "The swath width", "cr2res.cr2res_obs_staring", 800);
299 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "extract_swath_width");
300 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
301 cpl_parameterlist_append(recipe->parameters, p);
302
303 p = cpl_parameter_new_value("cr2res.cr2res_obs_staring.extract_height",
304 CPL_TYPE_INT, "Extraction height",
305 "cr2res.cr2res_obs_staring", -1);
306 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "extract_height");
307 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
308 cpl_parameterlist_append(recipe->parameters, p);
309
310 p = cpl_parameter_new_value("cr2res.cr2res_obs_staring.extract_smooth_slit",
311 CPL_TYPE_DOUBLE,
312 "Smoothing along the slit (1 for high S/N, 5 for low)",
313 "cr2res.cr2res_obs_staring", 2.0);
314 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "extract_smooth_slit");
315 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
316 cpl_parameterlist_append(recipe->parameters, p);
317
318 p = cpl_parameter_new_value("cr2res.cr2res_obs_staring.extract_smooth_spec",
319 CPL_TYPE_DOUBLE, "Smoothing along the spectrum",
320 "cr2res.cr2res_obs_staring", 0.0);
321 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "extract_smooth_spec");
322 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
323 cpl_parameterlist_append(recipe->parameters, p);
324
325 p = cpl_parameter_new_value("cr2res.cr2res_obs_staring.detector",
326 CPL_TYPE_INT, "Only reduce the specified detector",
327 "cr2res.cr2res_obs_staring", 0);
328 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "detector");
329 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
330 cpl_parameterlist_append(recipe->parameters, p);
331
332 p = cpl_parameter_new_value("cr2res.cr2res_obs_staring.create_idp",
333 CPL_TYPE_BOOL, "Flag to produce IDP files",
334 "cr2res.cr2res_obs_staring", FALSE);
335 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "idp");
336 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
337 cpl_parameterlist_append(recipe->parameters, p);
338
339 p = cpl_parameter_new_value("cr2res.cr2res_obs_staring.display_order",
340 CPL_TYPE_INT, "Apply the display for the specified order",
341 "cr2res.cr2res_obs_staring", 0);
342 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "display_order");
343 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
344 cpl_parameterlist_append(recipe->parameters, p);
345
346 p = cpl_parameter_new_value("cr2res.cr2res_obs_staring.display_trace",
347 CPL_TYPE_INT, "Apply the display for the specified trace",
348 "cr2res.cr2res_obs_staring", 0);
349 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "display_trace");
350 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
351 cpl_parameterlist_append(recipe->parameters, p);
352
353 return 0;
354}
355
356/*----------------------------------------------------------------------------*/
362/*----------------------------------------------------------------------------*/
363static int cr2res_obs_staring_exec(cpl_plugin * plugin)
364{
365 cpl_recipe *recipe;
366
367 /* Get the recipe out of the plugin */
368 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
369 recipe = (cpl_recipe *)plugin;
370 else return -1;
371
372 return cr2res_obs_staring(recipe->frames, recipe->parameters);
373}
374
375/*----------------------------------------------------------------------------*/
381/*----------------------------------------------------------------------------*/
382static int cr2res_obs_staring_destroy(cpl_plugin * plugin)
383{
384 cpl_recipe *recipe;
385
386 /* Get the recipe out of the plugin */
387 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
388 recipe = (cpl_recipe *)plugin;
389 else return -1 ;
390
391 cpl_parameterlist_delete(recipe->parameters);
392 return 0 ;
393}
394
395/*----------------------------------------------------------------------------*/
402/*----------------------------------------------------------------------------*/
403static int cr2res_obs_staring(
404 cpl_frameset * frameset,
405 const cpl_parameterlist * parlist)
406{
407 const cpl_parameter * param ;
408 int subtract_nolight_rows, subtract_interorder_column,
409 extract_oversample, create_idp, cosmics,
410 error_method,
411 extract_swath_width, extract_height, reduce_det;
412 double extract_smooth_slit, extract_smooth_spec,
413 extract_pclip, slit_low, slit_up ;
414 double barycorr;
415 cpl_array * slit_frac ;
416 cpl_frameset * rawframes ;
417 const cpl_frame * trace_wave_frame ;
418 const cpl_frame * detlin_frame ;
419 const cpl_frame * master_dark_frame ;
420 const cpl_frame * master_flat_frame ;
421 const cpl_frame * bpm_frame ;
422 const cpl_frame * blaze_frame ;
423 const char * sval ;
424 hdrl_image * combined[CR2RES_NB_DETECTORS] ;
425 cpl_table * extract[CR2RES_NB_DETECTORS] ;
426 cpl_table * slitfunc[CR2RES_NB_DETECTORS] ;
427 hdrl_image * model[CR2RES_NB_DETECTORS] ;
428 cpl_propertylist * qc_main ;
429 cpl_propertylist * ext_plist[CR2RES_NB_DETECTORS] ;
430 char * out_file;
431 cpl_table * eop_table ;
432 int det_nr;
433
434 /* RETRIEVE INPUT PARAMETERS */
435 param = cpl_parameterlist_find_const(parlist,
436 "cr2res.cr2res_obs_staring.subtract_nolight_rows");
437 subtract_nolight_rows = cpl_parameter_get_bool(param);
438 param = cpl_parameterlist_find_const(parlist,
439 "cr2res.cr2res_obs_staring.subtract_interorder_column");
440 subtract_interorder_column = cpl_parameter_get_bool(param);
441 param = cpl_parameterlist_find_const(parlist,
442 "cr2res.cr2res_obs_staring.cosmics");
443 cosmics = cpl_parameter_get_bool(param);
444 param = cpl_parameterlist_find_const(parlist,
445 "cr2res.cr2res_obs_staring.error_method");
446 if (strcmp(cpl_parameter_get_string(param), "Horne") == 0)
447 error_method = CR2RES_EXTRACT_ERROR_HORNE;
448 else
449 error_method = CR2RES_EXTRACT_ERROR_POISSON;
450 param = cpl_parameterlist_find_const(parlist,
451 "cr2res.cr2res_obs_staring.extract_oversample");
452 extract_oversample = cpl_parameter_get_int(param);
453 param = cpl_parameterlist_find_const(parlist,
454 "cr2res.cr2res_obs_staring.extract_pclip");
455 extract_pclip = cpl_parameter_get_double(param);
456 param = cpl_parameterlist_find_const(parlist,
457 "cr2res.cr2res_obs_staring.extract_swath_width");
458 extract_swath_width = cpl_parameter_get_int(param);
459 param = cpl_parameterlist_find_const(parlist,
460 "cr2res.cr2res_obs_staring.extract_height");
461 extract_height = cpl_parameter_get_int(param);
462 param = cpl_parameterlist_find_const(parlist,
463 "cr2res.cr2res_obs_staring.extract_smooth_slit");
464 extract_smooth_slit = cpl_parameter_get_double(param);
465 param = cpl_parameterlist_find_const(parlist,
466 "cr2res.cr2res_obs_staring.extract_smooth_spec");
467 extract_smooth_spec = cpl_parameter_get_double(param);
468 param = cpl_parameterlist_find_const(parlist,
469 "cr2res.cr2res_obs_staring.detector");
470 reduce_det = cpl_parameter_get_int(param);
471 param = cpl_parameterlist_find_const(parlist,
472 "cr2res.cr2res_obs_staring.create_idp");
473 create_idp = cpl_parameter_get_bool(param);
474 /*param = cpl_parameterlist_find_const(parlist,
475 "cr2res.cr2res_obs_staring.display_order");
476 disp_order = cpl_parameter_get_int(param);
477 param = cpl_parameterlist_find_const(parlist,
478 "cr2res.cr2res_obs_staring.display_trace");
479 disp_trace = cpl_parameter_get_int(param);*/
480 param = cpl_parameterlist_find_const(parlist,
481 "cr2res.cr2res_obs_staring.slit_frac");
482 sval = cpl_parameter_get_string(param) ;
483 if (sscanf(sval, "%lg,%lg", &slit_low, &slit_up) != 2) {
484 cpl_msg_error(__func__, "Invalid Slit Fraction specified");
485 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
486 return -1 ;
487 }
488
489 /* Check Parameters */
490 if (slit_low >= 0.0 && slit_up >= 0.0 && slit_low <= 1.0 && slit_up <= 1.0
491 && slit_up > slit_low) {
492 slit_frac = cpl_array_new(3, CPL_TYPE_DOUBLE) ;
493 cpl_array_set(slit_frac, 0, slit_low) ;
494 cpl_array_set(slit_frac, 1, (slit_low+slit_up)/2.0) ;
495 cpl_array_set(slit_frac, 2, slit_up) ;
496 } else {
497 slit_frac = NULL ;
498 }
499
500 /* Identify the RAW and CALIB frames in the input frameset */
501 if (cr2res_dfs_set_groups(frameset)) {
502 if (slit_frac != NULL) cpl_array_delete(slit_frac) ;
503 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
504 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
505 return -1 ;
506 }
507
508 /* Get Calibration frames */
509 trace_wave_frame = cr2res_io_find_TRACE_WAVE(frameset) ;
510 if (trace_wave_frame == NULL) {
511 if (slit_frac != NULL) cpl_array_delete(slit_frac) ;
512 cpl_msg_error(__func__, "Could not find TRACE_WAVE frame") ;
513 return -1 ;
514 }
515 detlin_frame = cpl_frameset_find_const(frameset,
516 CR2RES_CAL_DETLIN_COEFFS_PROCATG);
517 master_dark_frame = cpl_frameset_find_const(frameset,
518 CR2RES_CAL_DARK_MASTER_PROCATG) ;
519 master_flat_frame = cpl_frameset_find_const(frameset,
520 CR2RES_CAL_FLAT_MASTER_PROCATG) ;
521 bpm_frame = cr2res_io_find_BPM(frameset) ;
522 blaze_frame = cpl_frameset_find_const(frameset,
523 CR2RES_CAL_FLAT_EXTRACT_1D_PROCATG) ;
524
525 /* Get the RAW Frames */
526 rawframes = cr2res_obs_staring_find_RAW(frameset) ;
527 if (rawframes == NULL) {
528 if (slit_frac != NULL) cpl_array_delete(slit_frac) ;
529 cpl_msg_error(__func__, "Could not find RAW frames") ;
530 return -1 ;
531 }
532
533 /* Loop on the detectors */
534 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
535 /* Initialise */
536 combined[det_nr-1] = NULL ;
537 extract[det_nr-1] = NULL ;
538 slitfunc[det_nr-1] = NULL ;
539 model[det_nr-1] = NULL ;
540 ext_plist[det_nr-1] = NULL ;
541
542 /* Compute only one detector */
543 if (reduce_det != 0 && det_nr != reduce_det) continue ;
544
545 cpl_msg_info(__func__, "Process Detector %d", det_nr) ;
546 cpl_msg_indent_more() ;
547
548 /* Call the reduction function */
549 if (cr2res_obs_staring_reduce(rawframes,
550 trace_wave_frame, detlin_frame, master_dark_frame,
551 master_flat_frame, bpm_frame, blaze_frame, slit_frac,
552 subtract_nolight_rows, subtract_interorder_column,
553 cosmics, error_method, extract_oversample, extract_pclip,
554 extract_swath_width, extract_height, extract_smooth_slit,
555 extract_smooth_spec, det_nr,
556 &(combined[det_nr-1]),
557 &(extract[det_nr-1]),
558 &(slitfunc[det_nr-1]),
559 &(model[det_nr-1]),
560 &(ext_plist[det_nr-1])) == -1) {
561 cpl_msg_warning(__func__, "Failed to reduce detector %d", det_nr);
562 cpl_error_reset() ;
563 cpl_msg_indent_less() ;
564 }
565 cpl_msg_indent_less() ;
566 }
567 if (slit_frac != NULL) cpl_array_delete(slit_frac) ;
568
569 /* Save Products */
570
571 /* Add ESO.DRS.TMID in the Main Header */
572 qc_main = cpl_propertylist_new();
573 cpl_propertylist_append_double(qc_main,
574 CR2RES_HEADER_DRS_TMID,
575 cr2res_utils_get_center_mjd(rawframes)) ;
576
577 /* Add barycentric correction */
578 eop_table = cr2res_io_get_eop_table() ;
579 if (eop_table != NULL) {
580 double ra, dec, mjd_obs, geolon, geolat, geoelev;
581 cpl_propertylist *plist;
582 plist=cpl_propertylist_load(cpl_frame_get_filename(
583 cpl_frameset_get_position_const(rawframes, 0)), 0) ;
584
585 ra = cpl_propertylist_get_double(plist, "RA") ;
586 dec = cpl_propertylist_get_double(plist, "DEC") ;
587 mjd_obs = cpl_propertylist_get_double(plist, "MJD-OBS") ;
588 geolon = cpl_propertylist_get_double(plist, "ESO TEL GEOLON") ;
589 geolat = cpl_propertylist_get_double(plist, "ESO TEL GEOLAT") ;
590 geoelev = cpl_propertylist_get_double(plist, "ESO TEL GEOELEV") ;
591
592 cpl_propertylist_delete(plist) ;
593
594 barycorr = 0.0 ;
595 if (!cpl_error_get_code()) {
596 double mjd_cen;
597 mjd_cen = cr2res_utils_get_center_mjd(rawframes) ;
598 hdrl_barycorr_compute(ra, dec, eop_table, mjd_obs,
599 (mjd_cen-mjd_obs)*24*3600, geolon, geolat, geoelev,
600 0.0, 0.0, 0.0, 0.0, &barycorr);
601
602 cpl_msg_info(__func__, "Barycentric correction: %g m/s",
603 barycorr);
604 }
605 else {
606 cpl_msg_info(__func__, "Cannot derive Barycentric correction");
607 cpl_error_reset() ;
608 }
609 cpl_table_delete(eop_table) ;
610 cpl_propertylist_append_double(qc_main, CR2RES_HEADER_DRS_BARYCORR,
611 barycorr);
612 }
613
614 if (error_method == CR2RES_EXTRACT_ERROR_HORNE) {
615 cpl_propertylist_append_string(qc_main, CR2RES_HEADER_DRS_ERRMETHOD,
616 "Horne") ;
617 } else {
618 cpl_propertylist_append_string(qc_main, CR2RES_HEADER_DRS_ERRMETHOD,
619 "Poisson") ;
620 }
621
622 /* Add QC NUMSAT */
623 cpl_propertylist_append_int(qc_main,
624 CR2RES_HEADER_QC_NUMSAT,
625 cr2res_qc_numsat(rawframes)) ;
626
627 /* Save only the used RAW - fill raw_one_angle with CALIBS */
628 if (trace_wave_frame != NULL)
629 cpl_frameset_insert(rawframes,
630 cpl_frame_duplicate(trace_wave_frame)) ;
631 if (detlin_frame != NULL)
632 cpl_frameset_insert(rawframes,
633 cpl_frame_duplicate(detlin_frame)) ;
634 if (master_dark_frame != NULL)
635 cpl_frameset_insert(rawframes,
636 cpl_frame_duplicate(master_dark_frame)) ;
637 if (master_flat_frame!= NULL)
638 cpl_frameset_insert(rawframes,
639 cpl_frame_duplicate(master_flat_frame)) ;
640 if (bpm_frame!= NULL)
641 cpl_frameset_insert(rawframes,
642 cpl_frame_duplicate(bpm_frame)) ;
643 if (blaze_frame!= NULL)
644 cpl_frameset_insert(rawframes,
645 cpl_frame_duplicate(blaze_frame)) ;
646
647 out_file = cpl_sprintf("%s_combined.fits", RECIPE_STRING) ;
648 cr2res_io_save_COMBINED(out_file, frameset, rawframes, parlist,
649 combined, qc_main, ext_plist,
650 CR2RES_OBS_STARING_COMBINED_PROCATG, RECIPE_STRING) ;
651 cpl_free(out_file);
652
653 out_file = cpl_sprintf("%s_slitfunc.fits", RECIPE_STRING) ;
654 cr2res_io_save_SLIT_FUNC(out_file, frameset, rawframes, parlist,
655 slitfunc, qc_main, ext_plist, CR2RES_OBS_STARING_SLITFUNC_PROCATG,
656 RECIPE_STRING) ;
657 cpl_free(out_file);
658
659 out_file = cpl_sprintf("%s_model.fits", RECIPE_STRING) ;
660 cr2res_io_save_SLIT_MODEL(out_file, frameset, rawframes, parlist,
661 model, qc_main, ext_plist, CR2RES_OBS_STARING_SLITMODEL_PROCATG,
662 RECIPE_STRING) ;
663 cpl_free(out_file);
664
665 out_file = cpl_sprintf("%s_extracted.fits", RECIPE_STRING) ;
666 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist, extract,
667 qc_main, ext_plist, CR2RES_OBS_STARING_EXTRACT_PROCATG,
668 RECIPE_STRING);
669 if (create_idp) {
670 cr2res_idp_save(out_file, frameset, rawframes, parlist,
671 extract, qc_main, ext_plist,
672 CR2RES_OBS_STARING_IDP_PROCATG,
673 RECIPE_STRING) ;
674 }
675 cpl_free(out_file);
676 cpl_frameset_delete(rawframes) ;
677
678 /* Free */
679 cpl_propertylist_delete(qc_main) ;
680 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
681 if (combined[det_nr-1] != NULL)
682 hdrl_image_delete(combined[det_nr-1]) ;
683 if (extract[det_nr-1] != NULL)
684 cpl_table_delete(extract[det_nr-1]) ;
685 if (slitfunc[det_nr-1] != NULL)
686 cpl_table_delete(slitfunc[det_nr-1]) ;
687 if (model[det_nr-1] != NULL)
688 hdrl_image_delete(model[det_nr-1]) ;
689 if (ext_plist[det_nr-1] != NULL)
690 cpl_propertylist_delete(ext_plist[det_nr-1]) ;
691 }
692
693 return (int)cpl_error_get_code();
694}
695
696/*----------------------------------------------------------------------------*/
722/*----------------------------------------------------------------------------*/
723static int cr2res_obs_staring_reduce(
724 const cpl_frameset * rawframes,
725 const cpl_frame * trace_wave_frame,
726 const cpl_frame * detlin_frame,
727 const cpl_frame * master_dark_frame,
728 const cpl_frame * master_flat_frame,
729 const cpl_frame * bpm_frame,
730 const cpl_frame * blaze_frame,
731 const cpl_array * slit_frac,
732 int subtract_nolight_rows,
733 int subtract_interorder_column,
734 int cosmics,
735 int error_method,
736 int extract_oversample,
737 double extract_pclip,
738 int extract_swath_width,
739 int extract_height,
740 double extract_smooth_slit,
741 double extract_smooth_spec,
742 int reduce_det,
743 hdrl_image ** combined,
744 cpl_table ** extract,
745 cpl_table ** slitfunc,
746 hdrl_image ** model,
747 cpl_propertylist ** ext_plist)
748{
749 hdrl_imagelist * in ;
750 hdrl_imagelist * in_calib ;
751 cpl_vector * dits ;
752 cpl_vector * ndits ;
753 cpl_vector * ndsamples ;
754 cpl_table * blaze_table ;
755 cpl_table * trace_wave ;
756 cpl_table * trace_wave_new ;
757 hdrl_image * collapsed ;
758 hdrl_image * mflat ;
759 cpl_image * flat_relerr2 ;
760 cpl_image * contrib ;
761 cpl_propertylist * plist ;
762 cpl_size i ;
763 hdrl_image * model_master ;
764 cpl_table * slit_func ;
765 cpl_table * extracted ;
766 int * order_idx_values ;
767 double * qc_snrs ;
768 cpl_array * fwhm_array ;
769 char * key_name ;
770 const char * first_fname ;
771 double qc_signal, qc_fwhm, gain, error_factor, blaze_norm ;
772 int order_zp, nb_order_idx_values,
773 order_idx, order_idxp ;
774
775 /* Check Inputs */
776 if (combined == NULL || extract == NULL || ext_plist == NULL ||
777 rawframes == NULL || trace_wave_frame == NULL) return -1 ;
778
779 /* Get the Gain */
780 if (reduce_det == 1) gain = CR2RES_GAIN_CHIP1 ;
781 else if (reduce_det == 2) gain = CR2RES_GAIN_CHIP2 ;
782 else if (reduce_det == 3) gain = CR2RES_GAIN_CHIP3 ;
783 else {
784 cpl_msg_error(__func__, "Failed to get the Gain value") ;
785 return -1 ;
786 }
787
788 /* Check raw frames consistency */
789 if (cr2res_obs_staring_check_inputs_validity(rawframes) != 1) {
790 cpl_msg_error(__func__, "Invalid Inputs") ;
791 return -1 ;
792 }
793
794 /* Initialise */
795 first_fname = cpl_frame_get_filename(
796 cpl_frameset_get_position_const(rawframes, 0)) ;
797
798 /* Get the order zeropoint */
799 if ((plist = cpl_propertylist_load(cpl_frame_get_filename(trace_wave_frame),
800 0)) == NULL) {
801 cpl_msg_error(__func__, "Cannot read the ORDER_ZP from the input TW") ;
802 return -1 ;
803 }
804 order_zp = cr2res_pfits_get_order_zp(plist) ;
805 cpl_propertylist_delete(plist) ;
806 if (cpl_error_get_code()) {
807 cpl_msg_error(__func__, "Missing ORDER_ZP in the header - Skip") ;
808 cpl_error_reset() ;
809 /* Negative Zerop to log the fact that it is missing */
810 order_zp = -100 ;
811 }
812
813 /* Load the DITs if necessary */
814 if (master_dark_frame != NULL) dits = cr2res_io_read_dits(rawframes) ;
815 else dits = NULL ;
816 if (cpl_msg_get_level() == CPL_MSG_DEBUG && dits != NULL)
817 cpl_vector_dump(dits, stdout) ;
818
819 /* Load NDITs */
820 ndits = cr2res_io_read_ndits(rawframes) ;
821
822 /* Load image list */
823 if ((in = cr2res_io_load_image_list_from_set(rawframes,
824 reduce_det)) == NULL) {
825 cpl_msg_error(__func__, "Cannot load images") ;
826 if (dits != NULL) cpl_vector_delete(dits) ;
827 return -1 ;
828 }
829 if (hdrl_imagelist_get_size(in) != cpl_frameset_get_size(rawframes)) {
830 cpl_msg_error(__func__, "Inconsistent number of loaded images") ;
831 if (dits != NULL) cpl_vector_delete(dits) ;
833 return -1 ;
834 }
835
836 /* Set the error factor. */
837 if (error_method == CR2RES_EXTRACT_ERROR_HORNE) {
838 error_factor = -1.0 ;
839 } else {
840 error_factor = gain * cpl_vector_get(ndits, 0) *
841 cpl_frameset_get_size(rawframes) ;
842 }
843
844 for (i=0; i<cpl_vector_get_size(ndits); i++){
845 if (cpl_vector_get(ndits,i) != cpl_vector_get(ndits, 0))
846 cpl_msg_warning(__func__, "Raw frames have different NDIT! "
847 "Error spectrum will likely be scaled incorrectly.");
848 }
849
850 /* Calibrate the images */
851 ndsamples = cr2res_io_read_ndsamples(rawframes) ;
852 in_calib = cr2res_calib_imagelist(in, reduce_det, 0,
853 subtract_nolight_rows, subtract_interorder_column, cosmics,
854 master_flat_frame, master_dark_frame, bpm_frame, detlin_frame,
855 dits, ndits, ndsamples) ;
856 cpl_vector_delete(ndsamples) ;
857 if (in_calib == NULL) {
858 cpl_msg_error(__func__, "Failed to apply the calibrations") ;
859 if (dits != NULL) cpl_vector_delete(dits) ;
860 if (ndits != NULL) cpl_vector_delete(ndits) ;
862 return -1 ;
863 }
865 if (ndits != NULL) cpl_vector_delete(ndits) ;
866
867 /* Master dark and flat errors are the same in all frames: remove them */
868 /* before the collapse and add them back once to the collapsed image */
869 mflat = NULL ;
870 flat_relerr2 = NULL ;
871 if (master_flat_frame != NULL) {
872 if ((mflat = cr2res_io_load_MASTER_FLAT(
873 cpl_frame_get_filename(master_flat_frame),
874 reduce_det)) == NULL) {
875 cpl_msg_error(__func__, "Cannot load the master flat") ;
876 if (dits != NULL) cpl_vector_delete(dits) ;
877 hdrl_imagelist_delete(in_calib) ;
878 return -1 ;
879 }
880 flat_relerr2 = cr2res_calib_flat_relerr2(mflat) ;
881 for (i=0 ; i<hdrl_imagelist_get_size(in_calib) ; i++)
883 flat_relerr2, -1.0) ;
884 }
885 if (dits != NULL && cr2res_calib_dark_var(in_calib, master_dark_frame,
886 reduce_det, mflat, dits, -1.0)) {
887 cpl_msg_error(__func__, "Cannot remove the master dark errors") ;
888 cpl_vector_delete(dits) ;
889 hdrl_imagelist_delete(in_calib) ;
890 if (mflat != NULL) hdrl_image_delete(mflat) ;
891 if (flat_relerr2 != NULL) cpl_image_delete(flat_relerr2) ;
892 return -1 ;
893 }
894
895 /* Collapse the image list */
896 cpl_msg_info(__func__, "Collapse") ;
897 cpl_msg_indent_more() ;
898 if (hdrl_imagelist_collapse_mean(in_calib, &collapsed, &contrib) !=
899 CPL_ERROR_NONE) {
900 cpl_msg_error(__func__, "Failed to Collapse") ;
901 hdrl_imagelist_delete(in_calib) ;
902 if (dits != NULL) cpl_vector_delete(dits) ;
903 if (mflat != NULL) hdrl_image_delete(mflat) ;
904 if (flat_relerr2 != NULL) cpl_image_delete(flat_relerr2) ;
905 cpl_msg_indent_less() ;
906 return -1 ;
907 }
908 cpl_image_delete(contrib) ;
909 hdrl_imagelist_delete(in_calib) ;
910 cpl_msg_indent_less() ;
911
912 if (flat_relerr2 != NULL) {
913 cr2res_calib_flat_var(collapsed, flat_relerr2, 1.0) ;
914 cpl_image_delete(flat_relerr2) ;
915 }
916 if (dits != NULL) {
917 hdrl_imagelist * one = hdrl_imagelist_new() ;
918 cpl_vector * mean_dit = cpl_vector_new(1) ;
919 int status ;
920 cpl_vector_set(mean_dit, 0, cpl_vector_get_mean(dits)) ;
921 hdrl_imagelist_set(one, collapsed, 0) ;
922 status = cr2res_calib_dark_var(one, master_dark_frame, reduce_det,
923 mflat, mean_dit, 1.0) ;
924 hdrl_imagelist_unset(one, 0) ;
926 cpl_vector_delete(mean_dit) ;
927 cpl_vector_delete(dits) ;
928 if (status) {
929 cpl_msg_error(__func__, "Cannot add the master dark errors") ;
930 hdrl_image_delete(collapsed) ;
931 if (mflat != NULL) hdrl_image_delete(mflat) ;
932 return -1 ;
933 }
934 }
935 if (mflat != NULL) hdrl_image_delete(mflat) ;
936
937 /* Load the trace wave */
938 cpl_msg_info(__func__, "Load the TRACE WAVE") ;
939 if ((trace_wave = cr2res_io_load_TRACE_WAVE(cpl_frame_get_filename(
940 trace_wave_frame), reduce_det)) == NULL) {
941 cpl_msg_error(__func__, "Failed to Load the traces file") ;
942 hdrl_image_delete(collapsed) ;
943 return -1 ;
944 }
945
946 /* Extract at the specified slit fraction */
947 if (slit_frac != NULL) {
948 if ((trace_wave_new = cr2res_trace_new_slit_fraction(
949 trace_wave, slit_frac)) == NULL) {
950 cpl_msg_warning(__func__,
951 "Failed to compute the traces for user specified slit fraction") ;
952 cpl_error_reset() ;
953 } else {
954 cpl_table_delete(trace_wave) ;
955 trace_wave = trace_wave_new ;
956 trace_wave_new = NULL ;
957 }
958 }
959
960 /* Load Blaze */
961 blaze_table = NULL ;
962 blaze_norm = 0;
963 if (blaze_frame != NULL) {
964 cpl_msg_info(__func__, "Load the BLAZE") ;
965 if ((blaze_table = cr2res_io_load_EXTRACT_1D(cpl_frame_get_filename(
966 blaze_frame), reduce_det)) == NULL) {
967 cpl_msg_error(__func__, "Failed to Load the Blaze file") ;
968 hdrl_image_delete(collapsed) ;
969 cpl_table_delete(trace_wave) ;
970 return -1 ;
971 }
972 cpl_propertylist * blaze_plist ;
973 blaze_plist = cpl_propertylist_load_regexp(cpl_frame_get_filename(
974 blaze_frame),0,CR2RES_HEADER_QC_BLAZE_NORM,0);
975 if(cpl_propertylist_get_size(blaze_plist)>0){
976 blaze_norm = cpl_propertylist_get_double(blaze_plist, CR2RES_HEADER_QC_BLAZE_NORM);
977 }
978 else {
979 blaze_norm = -1;
980 cpl_msg_warning(__func__, "QC BLAZE NORM value not found, reverting to per trace normalization") ;
981 }
982 if(blaze_plist!=NULL){
983 cpl_propertylist_delete(blaze_plist);
984 }
985 }
986
987 /* TODO, make parameters */
988 int extract_niter = 10;
989 double extract_kappa = 10;
990
991 /* Execute the extraction */
992 cpl_msg_info(__func__, "Spectra Extraction") ;
993 if (cr2res_extract_traces(collapsed, trace_wave, NULL, blaze_table, blaze_norm, -1, -1,
994 CR2RES_EXTR_OPT_CURV, extract_height, extract_swath_width,
995 extract_oversample, extract_pclip, extract_smooth_slit, extract_smooth_spec,
996 extract_niter, extract_kappa, error_factor,
997 0, 0, 0, &extracted, &slit_func, &model_master) == -1) {
998 cpl_msg_error(__func__, "Failed to extract");
999 hdrl_image_delete(collapsed) ;
1000 cpl_table_delete(trace_wave) ;
1001 return -1 ;
1002 }
1003 if (blaze_table != NULL) cpl_table_delete(blaze_table) ;
1004
1005 /* Store the extension header for product saving */
1006 plist = cpl_propertylist_load(first_fname,
1007 cr2res_io_get_ext_idx(first_fname, reduce_det, 1)) ;
1008
1009 /* QC - Signal and FWHM */
1010 qc_signal = cr2res_qc_obs_nodding_signal(extracted) ;
1011 cpl_propertylist_append_double(plist, CR2RES_HEADER_QC_SIGNAL, qc_signal) ;
1012
1013 /* QC - SNR */
1014 qc_snrs = cr2res_qc_snr(trace_wave, extracted, &order_idx_values,
1015 &nb_order_idx_values) ;
1016 for (i=0 ; i<nb_order_idx_values ; i++) {
1017 order_idx = order_idx_values[i] ;
1018 order_idxp = cr2res_io_convert_order_idx_to_idxp(order_idx) ;
1019 key_name = cpl_sprintf(CR2RES_HEADER_QC_SNR, order_idxp) ;
1020 cpl_propertylist_append_double(plist, key_name, qc_snrs[i]) ;
1021 cpl_free(key_name) ;
1022 }
1023 cpl_free(order_idx_values) ;
1024 cpl_free(qc_snrs) ;
1025
1026 /* Get the order numbers from the TW rows */
1027 order_idx_values = cr2res_trace_get_order_idx_values(trace_wave,
1028 &nb_order_idx_values);
1029
1030 /* QC - SLIT FWHM */
1031 fwhm_array = cpl_array_new(nb_order_idx_values, CPL_TYPE_DOUBLE);
1032 for (i=0 ; i<nb_order_idx_values ; i++) {
1033 order_idx = order_idx_values[i] ;
1034 order_idxp = cr2res_io_convert_order_idx_to_idxp(order_idx) ;
1035 qc_fwhm = cr2res_qc_obs_slit_psf(slit_func, order_idxp,
1036 extract_oversample);
1037
1038 key_name = cpl_sprintf(CR2RES_HEADER_QC_SLITFWHM_ORDER, order_idxp) ;
1039 cpl_propertylist_append_double(plist, key_name, qc_fwhm) ;
1040 cpl_free(key_name) ;
1041 cpl_array_set(fwhm_array, i, qc_fwhm) ;
1042 }
1043 cpl_free(order_idx_values) ;
1044 qc_fwhm = cpl_array_get_median(fwhm_array);
1045 cpl_propertylist_append_double(plist, CR2RES_HEADER_QC_SLITFWHM_MED,
1046 qc_fwhm) ;
1047 if (qc_fwhm < 3.5) {
1048 cpl_msg_warning(__func__, "Median FWHM of the PSF along the slit "
1049 "is %gpix, i.e. below the slit width. This means the slit "
1050 "is likely not evenly filled with light "
1051 "in the spectral direction. This can result in a "
1052 "wavelength offset between different positions along the slit,"
1053 " and with respect to calibrations."
1054 , qc_fwhm);
1055 }
1056
1057 cpl_array_delete(fwhm_array) ;
1058
1059 /* QC - Real Orders */
1060 if (order_zp > 0) {
1061 /* Get the order numbers from the TW rows */
1062 order_idx_values = cr2res_trace_get_order_idx_values(trace_wave,
1063 &nb_order_idx_values);
1064
1065 /* Compute the Real Order numbers and store them in QCs */
1066 for (i = 0; i < nb_order_idx_values; i++) {
1067 int order_real;
1068 order_idx = order_idx_values[i] ;
1069 order_idxp = cr2res_io_convert_order_idx_to_idxp(order_idx) ;
1070 order_real = cr2res_order_idx_to_real(order_idx, order_zp) ;
1071 key_name = cpl_sprintf(CR2RES_HEADER_QC_REAL_ORDER, order_idxp) ;
1072 cpl_propertylist_append_int(plist, key_name, order_real) ;
1073 cpl_free(key_name) ;
1074 }
1075 cpl_free(order_idx_values) ;
1076 }
1077 cpl_table_delete(trace_wave) ;
1078
1079 /* Return */
1080 *combined = collapsed ;
1081 *extract = extracted ;
1082 *slitfunc = slit_func ;
1083 *model = model_master ;
1084 *ext_plist = plist ;
1085
1086 return 0 ;
1087}
1088
1089/*----------------------------------------------------------------------------*/
1095/*----------------------------------------------------------------------------*/
1096static int cr2res_obs_staring_check_inputs_validity(
1097 const cpl_frameset * rawframes)
1098{
1099 /* Check Inputs */
1100 if (rawframes == NULL) return -1 ;
1101 return 1 ;
1102}
1103
1104/*----------------------------------------------------------------------------*/
1113/*----------------------------------------------------------------------------*/
1114static cpl_frameset * cr2res_obs_staring_find_RAW(
1115 const cpl_frameset * in)
1116{
1117 cpl_frameset * out ;
1118
1119 /* Check entries */
1120 if (in == NULL) return NULL ;
1121
1122 out = cr2res_extract_frameset(in, CR2RES_OBS_STARING_OTHER_RAW) ;
1123 if (out == NULL) {
1124 out = cr2res_extract_frameset(in, CR2RES_OBS_STARING_JITTER_RAW) ;
1125 }
1126 if (out == NULL) {
1127 out = cr2res_extract_frameset(in, CR2RES_OBS_STARING_WAVE_SKY_RAW) ;
1128 }
1129 return out ;
1130}
1131
cpl_image * cr2res_calib_flat_relerr2(const hdrl_image *mflat)
Squared relative error of a master flat, (sigma_F/F)^2.
hdrl_imagelist * cr2res_calib_imagelist(const hdrl_imagelist *in, int chip, int clean_bad, int subtract_nolight_rows, int subtract_interorder_column, int cosmics_corr, const cpl_frame *flat, const cpl_frame *dark, const cpl_frame *bpm, const cpl_frame *detlin, const cpl_vector *dits, const cpl_vector *ndits, const cpl_vector *ndsamples)
The images calibration routine for a given chip on a list.
int cr2res_calib_dark_var(hdrl_imagelist *list, const cpl_frame *master_dark_frame, int chip, const hdrl_image *mflat, const cpl_vector *dits, double sign)
Add or remove the master dark variance of cr2res_calib_image()
void cr2res_calib_flat_var(hdrl_image *ima, const cpl_image *relerr2, double sign)
Add or remove the flat-field variance term of an image.
cpl_error_code cr2res_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition cr2res_dfs.c:53
int cr2res_extract_traces(const hdrl_image *img, const cpl_table *traces, const cpl_table *slit_func_in, const cpl_table *blaze_table_in, float blaze_norm, int reduce_order, int reduce_trace, cr2res_extr_method extr_method, int extr_height, int swath_width, int oversample, double pclip, double smooth_slit, double smooth_spec, int niter, double kappa, double error_factor, int display, int disp_order_idx, int disp_trace, cpl_table **extracted, cpl_table **slit_func, hdrl_image **model_master)
Extracts all the passed traces at once.
int cr2res_idp_save(const char *filename, cpl_frameset *allframes, cpl_frameset *rawframes, const cpl_parameterlist *parlist, cpl_table **tables, cpl_propertylist *main_qc_plist, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save an IDP file.
Definition cr2res_idp.c:98
cpl_table * cr2res_io_load_EXTRACT_1D(const char *filename, int detector)
Load a table from a EXTRACT_1D.
Definition cr2res_io.c:1326
const cpl_frame * cr2res_io_find_BPM(const cpl_frameset *in)
Get the first CR2RES_BPM_DRSTYPE frame from a frameset.
Definition cr2res_io.c:369
int cr2res_io_save_SLIT_MODEL(const char *filename, cpl_frameset *allframes, cpl_frameset *inframes, const cpl_parameterlist *parlist, hdrl_image **data, const cpl_propertylist *qc_list, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save a SLIT_MODEL.
Definition cr2res_io.c:1853
const cpl_frame * cr2res_io_find_TRACE_WAVE(const cpl_frameset *in)
Get the first CR2RES_TW_DRSTYPE frame from a frameset.
Definition cr2res_io.c:231
cpl_vector * cr2res_io_read_ndsamples(const cpl_frameset *in)
Get the NDSAMPLES from a frame set.
Definition cr2res_io.c:492
int cr2res_io_convert_order_idx_to_idxp(int order_idx)
Convert the order_idx to the order_idxp.
Definition cr2res_io.c:613
cpl_vector * cr2res_io_read_dits(const cpl_frameset *in)
Get the DITS from a frame set.
Definition cr2res_io.c:432
int cr2res_io_save_EXTRACT_1D(const char *filename, cpl_frameset *allframes, cpl_frameset *inframes, const cpl_parameterlist *parlist, cpl_table **tables, const cpl_propertylist *qc_list, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save a 1D extracted spectrum.
Definition cr2res_io.c:1762
hdrl_imagelist * cr2res_io_load_image_list_from_set(const cpl_frameset *in, int detector)
Load an hdrl image list from an images frameset.
Definition cr2res_io.c:838
cpl_table * cr2res_io_get_eop_table()
Get the eop_table.
Definition cr2res_io.c:120
int cr2res_io_get_ext_idx(const char *filename, int detector, int data)
Get the wished extension number for a detector.
Definition cr2res_io.c:674
int cr2res_io_save_SLIT_FUNC(const char *filename, cpl_frameset *allframes, cpl_frameset *inframes, const cpl_parameterlist *parlist, cpl_table **slit_func, const cpl_propertylist *qc_list, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save a SLIT_FUNC.
Definition cr2res_io.c:1822
int cr2res_io_save_COMBINED(const char *filename, cpl_frameset *allframes, cpl_frameset *inframes, const cpl_parameterlist *parlist, hdrl_image **data, const cpl_propertylist *qc_list, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save a COMBINED.
Definition cr2res_io.c:1884
cpl_table * cr2res_io_load_TRACE_WAVE(const char *filename, int detector)
Load a table from a TRACE_WAVE.
Definition cr2res_io.c:1139
cpl_vector * cr2res_io_read_ndits(const cpl_frameset *in)
Get the NDITs from a frame set.
Definition cr2res_io.c:462
hdrl_image * cr2res_io_load_MASTER_FLAT(const char *filename, int detector)
Load an hdrl image from a MASTER_FLAT.
Definition cr2res_io.c:1096
int cr2res_qc_numsat(const cpl_frameset *frameset)
Calculate the number of saturated pixels.
Definition cr2res_qc.c:1299
double cr2res_qc_obs_nodding_signal(const cpl_table *extracted)
Computes the integrated flux over part of the spectrum.
Definition cr2res_qc.c:845
double * cr2res_qc_snr(const cpl_table *tw, const cpl_table *extracted, int **out_order_idx_values, int *out_nb_order_idx_values)
Computes the SNR of several spectra.
Definition cr2res_qc.c:1010
double cr2res_qc_obs_slit_psf(const cpl_table *slitfu, int order_idxp, int oversample)
Computes the FWHM of the PSF along the slit for a given order.
Definition cr2res_qc.c:1210
cpl_table * cr2res_trace_new_slit_fraction(const cpl_table *traces, const cpl_array *new_slit_fraction)
Recompute the traces at a newly specified slit fraction.
int * cr2res_trace_get_order_idx_values(const cpl_table *trace, int *nb_order_idx_values)
Count and return the different order_idx values from a TW table.
int cr2res_order_idx_to_real(int order_idx, int order_zp)
Convert the order_idx into order_real.
double cr2res_utils_get_center_mjd(const cpl_frameset *frameset)
Calculate the middle of the exposures in the frameset.
cpl_frameset * cr2res_extract_frameset(const cpl_frameset *in, const char *tag)
Extract the frames with the given tag from a frameset.
const char * cr2res_get_license(void)
Get the pipeline copyright and license.
cpl_error_code hdrl_barycorr_compute(double ra, double dec, const cpl_table *eop_table, double mjdobs, double time_to_mid_exposure, double longitude, double latitude, double elevation, double pressure, double temperature, double humidity, double wavelength, double *barycorr)
Derives the barycentric correction using the erfa function eraApco13(). The latter For a terrestrial ...
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
Definition hdrl_image.c:379
cpl_error_code hdrl_imagelist_collapse_mean(const hdrl_imagelist *himlist, hdrl_image **out, cpl_image **contrib)
Mean collapsing of image list.
hdrl_image * hdrl_imagelist_unset(hdrl_imagelist *himlist, cpl_size pos)
Remove an image from an imagelist.
cpl_error_code hdrl_imagelist_set(hdrl_imagelist *himlist, hdrl_image *himg, cpl_size pos)
Insert an image into an imagelist.
void hdrl_imagelist_delete(hdrl_imagelist *himlist)
Free all memory used by a hdrl_imagelist object including the images.
cpl_size hdrl_imagelist_get_size(const hdrl_imagelist *himlist)
Get the number of images in the imagelist.
hdrl_imagelist * hdrl_imagelist_new(void)
Create an empty imagelist.
hdrl_image * hdrl_imagelist_get(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of images.