31#include "cr2res_utils.h"
32#include "cr2res_idp.h"
33#include "cr2res_nodding.h"
34#include "cr2res_calib.h"
35#include "cr2res_pfits.h"
36#include "cr2res_dfs.h"
37#include "cr2res_bpm.h"
38#include "cr2res_trace.h"
39#include "cr2res_extract.h"
42#include "cr2res_photom.h"
48#define RECIPE_STRING "cr2res_obs_nodding"
54int cpl_plugin_get_info(cpl_pluginlist * list);
60static int cr2res_obs_nodding_astrometry_compare(
61 const cpl_frame * frame1,
62 const cpl_frame * frame2) ;
63static cpl_frameset * cr2res_obs_nodding_find_RAW(
64 const cpl_frameset * in,
66static int cr2res_obs_nodding_check_inputs_validity(
67 const cpl_frameset * rawframes) ;
68static int cr2res_obs_nodding_reduce(
69 const cpl_frameset * rawframes,
70 const cpl_frame * trace_wave_frame,
71 const cpl_frame * detlin_frame,
72 const cpl_frame * master_dark_frame,
73 const cpl_frame * master_flat_frame,
74 const cpl_frame * bpm_frame,
75 const cpl_frame * blaze_frame,
77 int subtract_nolight_rows,
78 int subtract_interorder_column,
81 int extract_oversample,
83 int extract_swath_width,
85 double extract_smooth_slit,
86 double extract_smooth_spec,
93 hdrl_image ** combineda,
94 cpl_table ** extracta,
95 cpl_table ** slitfunca,
98 hdrl_image ** combinedb,
99 cpl_table ** extractb,
100 cpl_table ** slitfuncb,
101 hdrl_image ** modelb,
103 cpl_table ** extractc,
104 cpl_propertylist ** ext_plist) ;
106static int cr2res_obs_nodding_create(cpl_plugin *);
107static int cr2res_obs_nodding_exec(cpl_plugin *);
108static int cr2res_obs_nodding_destroy(cpl_plugin *);
109static int cr2res_obs_nodding(cpl_frameset *,
const cpl_parameterlist *);
115static char cr2res_obs_nodding_description[] =
"\
116Nodding Observation \n\
117 This recipe handles nodding observations. It expects an even number \n\
118 of rawframes in input, and as many A positions as B positions \n\
119 If the input are standard stars, it computes a post processing step \n\
120 to determine the throughput. \n\
121 If the input are spectro astrometric data, it will apply the nodding \n\
122 on each of the sub-groups \n\
125 raw.fits " CR2RES_CAL_NODDING_OTHER_RAW
" [2 to 2n] \n\
126 or " CR2RES_CAL_NODDING_JITTER_RAW
" [2 to 2n] \n\
127 or " CR2RES_OBS_NODDING_OTHER_RAW
" [2 to 2n] \n\
128 or " CR2RES_OBS_NODDING_JITTER_RAW
" [2 to 2n] \n\
129 or " CR2RES_OBS_ASTROMETRY_OTHER_RAW
" [2 to 2n] \n\
130 or " CR2RES_OBS_ASTROMETRY_JITTER_RAW
" [2 to 2n] \n\
131 trace.fits " CR2RES_CAL_FLAT_TW_PROCATG
" [1] \n\
132 or " CR2RES_CAL_FLAT_TW_MERGED_PROCATG
" \n\
133 or " CR2RES_UTIL_TRACE_TW_PROCATG
" \n\
134 or " CR2RES_UTIL_WAVE_TW_PROCATG
" \n\
135 or " CR2RES_CAL_WAVE_TW_PROCATG
" \n\
136 or " CR2RES_UTIL_SLIT_CURV_TW_PROCATG
" \n\
137 detlin.fits " CR2RES_CAL_DETLIN_COEFFS_PROCATG
" [0 to 1] \n\
138 bpm.fits " CR2RES_CAL_DARK_BPM_PROCATG
" [0 to 1] \n\
139 or " CR2RES_CAL_FLAT_BPM_PROCATG
" \n\
140 or " CR2RES_CAL_DETLIN_BPM_PROCATG
" \n\
141 or " CR2RES_UTIL_BPM_MERGE_PROCATG
" \n\
142 or " CR2RES_UTIL_BPM_SPLIT_PROCATG
" \n\
143 master_dark.fits " CR2RES_CAL_DARK_MASTER_PROCATG
" [0 to 1] \n\
144 master_flat.fits " CR2RES_CAL_FLAT_MASTER_PROCATG
" [0 to 1] \n\
145 photo_flux.fits " CR2RES_PHOTO_FLUX_PROCATG
" [0 to 1] \n\
146 blaze.fits " CR2RES_CAL_FLAT_EXTRACT_1D_PROCATG
" [0 to 1] \n\
149 cr2res_obs_nodding_extractedA.fits "
150 CR2RES_OBS_NODDING_EXTRACTA_PROCATG
"\n\
151 cr2res_obs_nodding_extractedB.fits "
152 CR2RES_OBS_NODDING_EXTRACTB_PROCATG
"\n\
153 cr2res_obs_nodding_combinedA.fits "
154 CR2RES_OBS_NODDING_COMBINEDA_PROCATG
"\n\
155 cr2res_obs_nodding_combinedB.fits "
156 CR2RES_OBS_NODDING_COMBINEDB_PROCATG
"\n\
157 cr2res_obs_nodding_trace_wave_A.fits "
158 CR2RES_OBS_NODDING_TWA_PROCATG
"\n\
159 cr2res_obs_nodding_trace_wave_B.fits "
160 CR2RES_OBS_NODDING_TWB_PROCATG
"\n\
161 cr2res_obs_nodding_modelA.fits "
162 CR2RES_OBS_NODDING_SLITMODELA_PROCATG
"\n\
163 cr2res_obs_nodding_modelB.fits "
164 CR2RES_OBS_NODDING_SLITMODELB_PROCATG
"\n\
165 cr2res_obs_nodding_slitfuncA.fits "
166 CR2RES_OBS_NODDING_SLITFUNCA_PROCATG
"\n\
167 cr2res_obs_nodding_slitfuncB.fits "
168 CR2RES_OBS_NODDING_SLITFUNCB_PROCATG
"\n\
169 cr2res_obs_nodding_throughput.fits "
170 CR2RES_OBS_NODDING_THROUGHPUT_PROCATG
"\n\
173 loop on detectors d: \n\
174 call cr2res_obs_nodding_reduce() \n\
175 -> combined[a|b](d) \n\
176 -> extract[a|b|c](d) \n\
177 -> slitfunc[a|b](d) \n\
180 Save combineda and combinedb \n\
181 Save extracta, extractb, extractc \n\
182 Save slitfunca and slitfuncb \n\
183 Save modela and modelb \n\
186 cr2res_obs_nodding_reduce() \n\
187 Load the input raw frames in an image list \n\
188 Apply the calibrations to the image list \n\
189 Split the list in listA and listB image lists \n\
190 Compute diffA=listA-listB and diffB=listB-listA \n\
191 Collapse diffA and diffB \n\
193 Load the input trace wave \n\
194 Compute the slit fractions for A and B by using the nodthrow \n\
195 and the assumption that A and B are at equal distances \n\
196 from the slit center. \n\
197 Compute 2 new trace_wave files with these 2 computed slit fractions\n\
198 Extract the spectra for A and for B \n\
199 -> extracted[a|b] \n\
200 -> slit_func[a|b] \n\
201 -> model_master[a|b] \n\
202 -> trace_wave[a|b] \n\
203 Compute QC parameters \n\
204 If STD star, compute the throughput \n\
207 Library functions used \n\
208 cr2res_io_find_TRACE_WAVE() \n\
209 cr2res_io_find_BPM() \n\
210 cr2res_obs_nodding_reduce() \n\
211 cr2res_nodding_read_positions() \n\
212 cr2res_io_read_dits() \n\
213 cr2res_io_load_image_list_from_set() \n\
214 cr2res_calib_imagelist() \n\
215 cr2res_combine_nodding_split() \n\
216 cr2res_io_load_TRACE_WAVE() \n\
217 cr2res_pfits_get_nodthrow() \n\
218 cr2res_trace_new_slit_fraction() \n\
219 cr2res_extract_traces() \n\
220 cr2res_qc_obs_nodding_signal() \n\
221 cr2res_qc_obs_nodding_transmission() \n\
222 cr2res_qc_obs_slit_psf() \n\
223 cr2res_photom_engine() \n\
224 cr2res_io_save_COMBINED() \n\
225 cr2res_io_save_EXTRACT_1D() \n\
226 cr2res_io_save_SLIT_FUNC() \n\
227 cr2res_io_save_SLIT_MODEL() \n\
228 cr2res_io_save_THROUGHPUT() \n\
247int cpl_plugin_get_info(cpl_pluginlist * list)
249 cpl_recipe * recipe = cpl_calloc(1,
sizeof *recipe );
250 cpl_plugin * plugin = &recipe->interface;
252 if (cpl_plugin_init(plugin,
254 CR2RES_BINARY_VERSION,
255 CPL_PLUGIN_TYPE_RECIPE,
257 "Nodding Observation recipe",
258 cr2res_obs_nodding_description,
259 CR2RES_PIPELINE_AUTHORS,
262 cr2res_obs_nodding_create,
263 cr2res_obs_nodding_exec,
264 cr2res_obs_nodding_destroy)) {
265 cpl_msg_error(cpl_func,
"Plugin initialization failed");
266 (void)cpl_error_set_where(cpl_func);
270 if (cpl_pluginlist_append(list, plugin)) {
271 cpl_msg_error(cpl_func,
"Error adding plugin to list");
272 (void)cpl_error_set_where(cpl_func);
288static int cr2res_obs_nodding_create(cpl_plugin * plugin)
290 cpl_recipe * recipe ;
294 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
295 recipe = (cpl_recipe *)plugin;
300 recipe->parameters = cpl_parameterlist_new();
303 p = cpl_parameter_new_value(
304 "cr2res.cr2res_obs_nodding.subtract_nolight_rows",
306 "Subtract median row from baffled region at detector bottom",
307 "cr2res.cr2res_obs_nodding", FALSE);
308 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"subtract_nolight_rows");
309 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
310 cpl_parameterlist_append(recipe->parameters, p);
312 p = cpl_parameter_new_value(
313 "cr2res.cr2res_obs_nodding.subtract_interorder_column",
315 "Subtract column-by-column fit to the pixel values between orders",
316 "cr2res.cr2res_obs_nodding", TRUE);
317 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
318 "subtract_interorder_column");
319 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
320 cpl_parameterlist_append(recipe->parameters, p);
322 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_nodding.cosmics",
323 CPL_TYPE_BOOL,
"Find and mark cosmic rays hits as bad",
324 "cr2res.cr2res_obs_nodding", FALSE);
325 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"cosmics");
326 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
327 cpl_parameterlist_append(recipe->parameters, p);
329 p = cpl_parameter_new_enum(
"cr2res.cr2res_obs_nodding.error_method",
330 CPL_TYPE_STRING,
"The 1d extraction error calculation method",
331 "cr2res.cr2res_obs_nodding",
332 "Horne", 2,
"Poisson",
"Horne");
333 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"error_method");
334 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
335 cpl_parameterlist_append(recipe->parameters, p);
337 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_nodding.nodding_invert",
338 CPL_TYPE_BOOL,
"Flag to use when A is above B",
339 "cr2res.cr2res_obs_nodding", FALSE);
340 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nodding_invert");
341 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
342 cpl_parameterlist_append(recipe->parameters, p);
344 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_nodding.extract_oversample",
345 CPL_TYPE_INT,
"factor by which to oversample the extraction",
346 "cr2res.cr2res_obs_nodding", 7);
347 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extract_oversample");
348 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
349 cpl_parameterlist_append(recipe->parameters, p);
351 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_nodding.extract_pclip",
352 CPL_TYPE_DOUBLE,
"percentage of high and low pixels to clip on first iteration",
353 "cr2res.cr2res_obs_nodding", 0.1);
354 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extract_pclip");
355 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
356 cpl_parameterlist_append(recipe->parameters, p);
358 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_nodding.extract_swath_width",
359 CPL_TYPE_INT,
"The swath width",
"cr2res.cr2res_obs_nodding", 800);
360 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extract_swath_width");
361 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
362 cpl_parameterlist_append(recipe->parameters, p);
364 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_nodding.extract_height",
365 CPL_TYPE_INT,
"Extraction height",
"cr2res.cr2res_obs_nodding", -1);
366 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extract_height");
367 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
368 cpl_parameterlist_append(recipe->parameters, p);
370 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_nodding.extract_smooth_slit",
371 CPL_TYPE_DOUBLE,
"Smoothing along the slit",
372 "cr2res.cr2res_obs_nodding", 1.0);
373 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extract_smooth_slit");
374 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
375 cpl_parameterlist_append(recipe->parameters, p);
377 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_nodding.extract_smooth_spec",
378 CPL_TYPE_DOUBLE,
"Smoothing along spectrum",
379 "cr2res.cr2res_obs_nodding", 8e-8);
380 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extract_smooth_spec");
381 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
382 cpl_parameterlist_append(recipe->parameters, p);
384 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_nodding.detector",
385 CPL_TYPE_INT,
"Only reduce the specified detector",
386 "cr2res.cr2res_obs_nodding", 0);
387 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"detector");
388 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
389 cpl_parameterlist_append(recipe->parameters, p);
391 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_nodding.create_idp",
392 CPL_TYPE_BOOL,
"Flag to produce IDP files",
393 "cr2res.cr2res_obs_nodding", FALSE);
394 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"idp");
395 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
396 cpl_parameterlist_append(recipe->parameters, p);
398 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_nodding.display_detector",
399 CPL_TYPE_INT,
"Apply the display for the specified detector",
400 "cr2res.cr2res_obs_nodding", 0);
401 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"display_detector");
402 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
403 cpl_parameterlist_append(recipe->parameters, p);
405 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_nodding.display_order",
406 CPL_TYPE_INT,
"Apply the display for the specified order",
407 "cr2res.cr2res_obs_nodding", 1000);
408 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"display_order");
409 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
410 cpl_parameterlist_append(recipe->parameters, p);
412 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_nodding.display_trace",
413 CPL_TYPE_INT,
"Apply the display for the specified trace",
414 "cr2res.cr2res_obs_nodding", 0);
415 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"display_trace");
416 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
417 cpl_parameterlist_append(recipe->parameters, p);
429static int cr2res_obs_nodding_exec(cpl_plugin * plugin)
434 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
435 recipe = (cpl_recipe *)plugin;
438 return cr2res_obs_nodding(recipe->frames, recipe->parameters);
448static int cr2res_obs_nodding_destroy(cpl_plugin * plugin)
453 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
454 recipe = (cpl_recipe *)plugin;
457 cpl_parameterlist_delete(recipe->parameters);
469static int cr2res_obs_nodding(
470 cpl_frameset * frameset,
471 const cpl_parameterlist * parlist)
473 const cpl_parameter * param ;
474 int extract_oversample, extract_swath_width,
475 extract_height, reduce_det,
476 disp_order_idx, disp_trace, disp_det,
477 nodding_invert, create_idp, subtract_nolight_rows,
478 subtract_interorder_column, cosmics,
480 double extract_smooth_slit, extract_smooth_spec,
483 double ra, dec, mjd_obs, mjd_cen, geolon, geolat, geoelev,
485 cpl_frameset * rawframes ;
486 cpl_frameset * raw_flat_frames ;
487 const cpl_frame * trace_wave_frame ;
488 const cpl_frame * detlin_frame ;
489 const cpl_frame * master_dark_frame ;
490 const cpl_frame * photo_flux_frame ;
491 const cpl_frame * blaze_frame ;
492 const cpl_frame * master_flat_frame ;
493 const cpl_frame * bpm_frame ;
495 cpl_size nlabels, l ;
496 char * product_name_addon ;
497 hdrl_image * combineda[CR2RES_NB_DETECTORS] ;
498 cpl_table * extracta[CR2RES_NB_DETECTORS] ;
499 cpl_table * slitfunca[CR2RES_NB_DETECTORS] ;
500 hdrl_image * modela[CR2RES_NB_DETECTORS] ;
501 cpl_table * twa[CR2RES_NB_DETECTORS] ;
502 hdrl_image * combinedb[CR2RES_NB_DETECTORS] ;
503 cpl_table * extractb[CR2RES_NB_DETECTORS] ;
504 cpl_table * slitfuncb[CR2RES_NB_DETECTORS] ;
505 hdrl_image * modelb[CR2RES_NB_DETECTORS] ;
506 cpl_table * twb[CR2RES_NB_DETECTORS] ;
507 cpl_table * extractc[CR2RES_NB_DETECTORS] ;
508 cpl_table * throughput[CR2RES_NB_DETECTORS] ;
509 cpl_propertylist * qc_main ;
510 cpl_propertylist * ext_plist[CR2RES_NB_DETECTORS] ;
511 cpl_propertylist * ext_plist_photom[CR2RES_NB_DETECTORS] ;
514 cpl_table * eop_table ;
522 param = cpl_parameterlist_find_const(parlist,
523 "cr2res.cr2res_obs_nodding.subtract_nolight_rows");
524 subtract_nolight_rows = cpl_parameter_get_bool(param);
525 param = cpl_parameterlist_find_const(parlist,
526 "cr2res.cr2res_obs_nodding.subtract_interorder_column");
527 subtract_interorder_column = cpl_parameter_get_bool(param);
528 param = cpl_parameterlist_find_const(parlist,
529 "cr2res.cr2res_obs_nodding.nodding_invert");
530 nodding_invert = cpl_parameter_get_bool(param);
531 param = cpl_parameterlist_find_const(parlist,
532 "cr2res.cr2res_obs_nodding.extract_oversample");
533 extract_oversample = cpl_parameter_get_int(param);
534 param = cpl_parameterlist_find_const(parlist,
535 "cr2res.cr2res_obs_nodding.extract_pclip");
536 extract_pclip = cpl_parameter_get_double(param);
537 param = cpl_parameterlist_find_const(parlist,
538 "cr2res.cr2res_obs_nodding.extract_swath_width");
539 extract_swath_width = cpl_parameter_get_int(param);
540 param = cpl_parameterlist_find_const(parlist,
541 "cr2res.cr2res_obs_nodding.extract_height");
542 extract_height = cpl_parameter_get_int(param);
543 param = cpl_parameterlist_find_const(parlist,
544 "cr2res.cr2res_obs_nodding.extract_smooth_slit");
545 extract_smooth_slit = cpl_parameter_get_double(param);
546 param = cpl_parameterlist_find_const(parlist,
547 "cr2res.cr2res_obs_nodding.extract_smooth_spec");
548 extract_smooth_spec = cpl_parameter_get_double(param);
549 param = cpl_parameterlist_find_const(parlist,
550 "cr2res.cr2res_obs_nodding.detector");
551 reduce_det = cpl_parameter_get_int(param);
552 param = cpl_parameterlist_find_const(parlist,
553 "cr2res.cr2res_obs_nodding.create_idp");
554 create_idp = cpl_parameter_get_bool(param);
555 param = cpl_parameterlist_find_const(parlist,
556 "cr2res.cr2res_obs_nodding.display_detector");
557 disp_det = cpl_parameter_get_int(param);
558 param = cpl_parameterlist_find_const(parlist,
559 "cr2res.cr2res_obs_nodding.display_order");
560 disp_order_idx = cpl_parameter_get_int(param);
561 param = cpl_parameterlist_find_const(parlist,
562 "cr2res.cr2res_obs_nodding.display_trace");
563 disp_trace = cpl_parameter_get_int(param);
564 param = cpl_parameterlist_find_const(parlist,
565 "cr2res.cr2res_obs_nodding.cosmics");
566 cosmics = cpl_parameter_get_bool(param);
567 param = cpl_parameterlist_find_const(parlist,
568 "cr2res.cr2res_obs_nodding.error_method");
569 if(strcmp(cpl_parameter_get_string(param),
"Horne") == 0)
570 error_method = CR2RES_EXTRACT_ERROR_HORNE;
572 error_method = CR2RES_EXTRACT_ERROR_POISSON;
575 int extract_niter = 30;
576 double extract_kappa = 10;
580 cpl_msg_error(__func__,
"Cannot identify RAW and CALIB frames") ;
581 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
587 if (trace_wave_frame == NULL) {
588 cpl_msg_error(__func__,
"Could not find TRACE_WAVE frame") ;
591 detlin_frame = cpl_frameset_find_const(frameset,
592 CR2RES_CAL_DETLIN_COEFFS_PROCATG);
593 master_dark_frame = cpl_frameset_find_const(frameset,
594 CR2RES_CAL_DARK_MASTER_PROCATG) ;
595 if (master_dark_frame != NULL) {
596 cpl_msg_warning(__func__,
597 "Providing a MASTER DARK is not recommended for this recipe") ;
599 blaze_frame = cpl_frameset_find_const(frameset,
600 CR2RES_CAL_FLAT_EXTRACT_1D_PROCATG) ;
601 photo_flux_frame = cpl_frameset_find_const(frameset,
602 CR2RES_PHOTO_FLUX_PROCATG) ;
603 master_flat_frame = cpl_frameset_find_const(frameset,
604 CR2RES_CAL_FLAT_MASTER_PROCATG) ;
608 rawframes = cr2res_obs_nodding_find_RAW(frameset, &type) ;
609 if (rawframes == NULL) {
610 cpl_msg_error(__func__,
"Could not find RAW frames") ;
618 if ((labels = cpl_frameset_labelise(rawframes,
619 cr2res_obs_nodding_astrometry_compare, &nlabels)) == NULL) {
620 cpl_msg_error(__func__,
"Cannot label input frames") ;
621 cpl_frameset_delete(rawframes) ;
622 if (raw_flat_frames != NULL) cpl_frameset_delete(raw_flat_frames) ;
623 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
628 if (type != 3 && nlabels != 1) {
629 cpl_msg_error(__func__,
"Expect only one DROT POSANG value - abort") ;
630 cpl_frameset_delete(rawframes) ;
631 if (raw_flat_frames != NULL) cpl_frameset_delete(raw_flat_frames) ;
633 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
638 for (l = 0; l < (int)nlabels; l++) {
640 cpl_frameset *raw_one_angle;
641 cpl_propertylist *plist;
643 raw_one_angle = cpl_frameset_extract(rawframes, labels, (cpl_size)l) ;
646 plist = cpl_propertylist_load(cpl_frame_get_filename(
647 cpl_frameset_get_position(raw_one_angle, 0)), 0) ;
649 cpl_propertylist_delete(plist) ;
651 cpl_msg_info(__func__,
"Process Angle %g", drot_posang) ;
652 cpl_msg_indent_more() ;
655 for (det_nr = 1; det_nr <= CR2RES_NB_DETECTORS; det_nr++) {
657 combineda[det_nr - 1] = NULL;
658 extracta[det_nr - 1] = NULL;
659 slitfunca[det_nr - 1] = NULL;
660 modela[det_nr - 1] = NULL;
661 twa[det_nr - 1] = NULL;
662 combinedb[det_nr - 1] = NULL;
663 extractb[det_nr - 1] = NULL;
664 slitfuncb[det_nr - 1] = NULL;
665 modelb[det_nr - 1] = NULL;
666 twb[det_nr - 1] = NULL;
667 extractc[det_nr - 1] = NULL;
668 ext_plist[det_nr - 1] = NULL;
669 ext_plist_photom[det_nr - 1] = NULL;
670 throughput[det_nr - 1] = NULL;
673 if (reduce_det != 0 && det_nr != reduce_det)
676 cpl_msg_info(__func__,
"Process Detector %d", det_nr);
677 cpl_msg_indent_more();
680 if (cr2res_obs_nodding_reduce(
681 raw_one_angle, trace_wave_frame,
682 detlin_frame, master_dark_frame, master_flat_frame,
683 bpm_frame, blaze_frame, nodding_invert,
684 subtract_nolight_rows, subtract_interorder_column, cosmics,
686 extract_oversample, extract_pclip, extract_swath_width, extract_height,
687 extract_smooth_slit, extract_smooth_spec, extract_niter,
688 extract_kappa, det_nr, disp_det, disp_order_idx, disp_trace,
689 &(combineda[det_nr - 1]), &(extracta[det_nr - 1]),
690 &(slitfunca[det_nr - 1]), &(modela[det_nr - 1]),
691 &(twa[det_nr - 1]), &(combinedb[det_nr - 1]),
692 &(extractb[det_nr - 1]), &(slitfuncb[det_nr - 1]),
693 &(modelb[det_nr - 1]), &(twb[det_nr - 1]),
694 &(extractc[det_nr - 1]), &(ext_plist[det_nr - 1])) == -1) {
695 cpl_msg_warning(__func__,
"Failed to reduce detector %d",
699 else if (type == 2) {
702 "Sensitivity / Conversion / Throughput computation");
703 cpl_msg_indent_more();
707 gain = CR2RES_GAIN_CHIP1;
709 gain = CR2RES_GAIN_CHIP2;
711 gain = CR2RES_GAIN_CHIP3;
714 plist = cpl_propertylist_load(
715 cpl_frame_get_filename(
716 cpl_frameset_get_position_const(raw_one_angle, 0)),
723 cpl_propertylist_delete(plist);
724 if (cpl_error_get_code()) {
725 cpl_msg_indent_less();
727 cpl_msg_warning(__func__,
"Missing Header Informations");
732 extracta[det_nr - 1],
733 cpl_frame_get_filename(photo_flux_frame),
734 cur_setting, ra, dec, gain, dit, disp_det == det_nr,
735 disp_order_idx, disp_trace,
736 &(throughput[det_nr - 1]),
737 &(ext_plist_photom[det_nr - 1])) == -1) {
738 cpl_msg_warning(__func__,
739 "Failed to reduce detector %d", det_nr);
743 cpl_free(cur_setting);
744 cpl_msg_indent_less();
746 cpl_msg_indent_less();
750 if (nlabels == 1) product_name_addon = cpl_sprintf(
".fits") ;
751 else product_name_addon = cpl_sprintf(
"_%g.fits",
755 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
756 if (ext_plist_photom[det_nr-1] != NULL &&
757 ext_plist[det_nr-1] != NULL) {
758 cpl_propertylist_append(ext_plist[det_nr-1],
759 ext_plist_photom[det_nr-1]) ;
764 qc_main = cpl_propertylist_new();
765 cpl_propertylist_append_double(qc_main,
766 CR2RES_HEADER_DRS_TMID,
771 if (eop_table != NULL) {
772 plist=cpl_propertylist_load(cpl_frame_get_filename(
773 cpl_frameset_get_position_const(raw_one_angle, 0)), 0) ;
775 ra = cpl_propertylist_get_double(plist,
"RA") ;
776 dec = cpl_propertylist_get_double(plist,
"DEC") ;
777 mjd_obs = cpl_propertylist_get_double(plist,
"MJD-OBS") ;
778 geolon = cpl_propertylist_get_double(plist,
"ESO TEL GEOLON") ;
779 geolat = cpl_propertylist_get_double(plist,
"ESO TEL GEOLAT") ;
780 geoelev = cpl_propertylist_get_double(plist,
"ESO TEL GEOELEV") ;
782 cpl_propertylist_delete(plist) ;
785 if (!cpl_error_get_code()) {
788 (mjd_cen-mjd_obs)*24*3600, geolon, geolat, geoelev,
789 0.0, 0.0, 0.0, 0.0, &barycorr);
791 cpl_msg_info(__func__,
"Barycentric correction: %g m/s",
794 cpl_msg_info(__func__,
"Cannot derive Barycentric correction");
797 cpl_table_delete(eop_table) ;
802 if(error_method == CR2RES_EXTRACT_ERROR_HORNE){
803 cpl_propertylist_append_string(qc_main, CR2RES_HEADER_DRS_ERRMETHOD,
807 cpl_propertylist_append_string(qc_main, CR2RES_HEADER_DRS_ERRMETHOD,
811 cpl_propertylist_append_int(qc_main,
812 CR2RES_HEADER_QC_NUMSAT,
817 if (trace_wave_frame != NULL)
818 cpl_frameset_insert(raw_one_angle,
819 cpl_frame_duplicate(trace_wave_frame)) ;
820 if (detlin_frame != NULL)
821 cpl_frameset_insert(raw_one_angle,
822 cpl_frame_duplicate(detlin_frame)) ;
823 if (master_dark_frame != NULL)
824 cpl_frameset_insert(raw_one_angle,
825 cpl_frame_duplicate(master_dark_frame)) ;
826 if (master_flat_frame!= NULL)
827 cpl_frameset_insert(raw_one_angle,
828 cpl_frame_duplicate(master_flat_frame)) ;
829 if (bpm_frame!= NULL)
830 cpl_frameset_insert(raw_one_angle,
831 cpl_frame_duplicate(bpm_frame)) ;
832 if (blaze_frame!= NULL)
833 cpl_frameset_insert(raw_one_angle,
834 cpl_frame_duplicate(blaze_frame)) ;
835 if (photo_flux_frame!= NULL)
836 cpl_frameset_insert(raw_one_angle,
837 cpl_frame_duplicate(photo_flux_frame)) ;
839 out_file = cpl_sprintf(
"%s_combinedA%s", RECIPE_STRING,
840 product_name_addon) ;
842 combineda, qc_main, ext_plist,
843 CR2RES_OBS_NODDING_COMBINEDA_PROCATG, RECIPE_STRING) ;
846 char *qc_perdet_keywords[] = { CR2RES_HEADER_QC_SIGNAL,
847 CR2RES_HEADER_QC_STANDARD_FLUX,
848 CR2RES_HEADER_QC_SLITFWHM_MED };
850 char *qc_pertrace_keywords[] = { CR2RES_HEADER_QC_SNR_BASE,
851 CR2RES_HEADER_QC_SLITFWHM_ORDER_BASE };
853 int qc_perdet_size =
sizeof(qc_perdet_keywords) /
sizeof(
char *);
854 int qc_pertrace_size =
sizeof(qc_pertrace_keywords) /
sizeof(
char *);
856 int qc_sizes_ext[] = {CR2RES_NB_DETECTORS};
857 cpl_propertylist** qc_plists_ext[] = {ext_plist} ;
858 char * qc_res_avg, * qc_res_rmsd, * qc_ref;
862 for (qc_i=0; qc_i<qc_perdet_size ; qc_i++) {
864 qc_res_avg = cpl_sprintf(
"%s %s",
865 qc_perdet_keywords[qc_i],
"AVG");
866 qc_res_rmsd = cpl_sprintf(
"%s %s",
867 qc_perdet_keywords[qc_i],
"RMS");
869 cr2res_qc_calculate_mean_and_rmsd(qc_plists_ext, 1, qc_sizes_ext,
870 qc_perdet_keywords[qc_i], qc_main,
871 qc_res_avg, qc_res_rmsd);
873 cpl_free(qc_res_avg);
874 cpl_free(qc_res_rmsd);
878 int min_order = INT_MAX;
879 int max_order = INT_MIN;
880 int current_min, current_max;
882 for (qc_i = 0; qc_i < CR2RES_NB_DETECTORS; qc_i++) {
883 if (twa[qc_i] == NULL) {
887 cpl_table_get_column_min(twa[qc_i],
"Order");
888 if (cpl_error_get_code() != CPL_ERROR_NONE) {
891 if (current_min < min_order) {
892 min_order = current_min;
896 cpl_table_get_column_max(twa[qc_i],
"Order");
897 if (cpl_error_get_code() != CPL_ERROR_NONE) {
900 if (current_max > max_order) {
901 max_order = current_max;
905 for (qc_i = 0; qc_i < qc_pertrace_size; qc_i++) {
906 for (
int order_id = min_order; order_id <= max_order; order_id++) {
908 qc_ref = cpl_sprintf(
"%s%d", qc_pertrace_keywords[qc_i],
911 cpl_sprintf(
"%s%d %s", qc_pertrace_keywords[qc_i],
914 cpl_sprintf(
"%s%d %s", qc_pertrace_keywords[qc_i],
917 cr2res_qc_calculate_mean_and_rmsd(qc_plists_ext, 1, qc_sizes_ext,
918 qc_ref, qc_main, qc_res_avg,
922 cpl_free(qc_res_avg);
923 cpl_free(qc_res_rmsd);
927 out_file = cpl_sprintf(
"%s_extractedA%s", RECIPE_STRING,
928 product_name_addon) ;
930 extracta, qc_main, ext_plist,
931 CR2RES_OBS_NODDING_EXTRACTA_PROCATG, RECIPE_STRING);
934 extracta, qc_main, ext_plist,
935 CR2RES_OBS_NODDING_EXTRACTA_IDP_PROCATG,
964 out_file = cpl_sprintf(
"%s_slitfuncA%s", RECIPE_STRING,
965 product_name_addon) ;
967 slitfunca, qc_main, ext_plist,
968 CR2RES_OBS_NODDING_SLITFUNCA_PROCATG, RECIPE_STRING) ;
971 out_file = cpl_sprintf(
"%s_modelA%s", RECIPE_STRING,
972 product_name_addon) ;
974 modela, qc_main, ext_plist,
975 CR2RES_OBS_NODDING_SLITMODELA_PROCATG, RECIPE_STRING) ;
978 out_file = cpl_sprintf(
"%s_trace_wave_A%s", RECIPE_STRING,
979 product_name_addon) ;
981 twa, qc_main, ext_plist, CR2RES_OBS_NODDING_TWA_PROCATG,
985 out_file = cpl_sprintf(
"%s_combinedB%s", RECIPE_STRING,
986 product_name_addon) ;
988 combinedb, qc_main, ext_plist,
989 CR2RES_OBS_NODDING_COMBINEDB_PROCATG, RECIPE_STRING) ;
992 out_file = cpl_sprintf(
"%s_extractedB%s", RECIPE_STRING,
993 product_name_addon) ;
995 extractb, qc_main, ext_plist,
996 CR2RES_OBS_NODDING_EXTRACTB_PROCATG, RECIPE_STRING);
999 extractb, qc_main, ext_plist,
1000 CR2RES_OBS_NODDING_EXTRACTB_IDP_PROCATG,
1005 out_file = cpl_sprintf(
"%s_slitfuncB%s", RECIPE_STRING,
1006 product_name_addon) ;
1008 slitfuncb, qc_main, ext_plist,
1009 CR2RES_OBS_NODDING_SLITFUNCB_PROCATG, RECIPE_STRING) ;
1012 out_file = cpl_sprintf(
"%s_modelB%s", RECIPE_STRING,
1013 product_name_addon) ;
1015 modelb, qc_main, ext_plist,
1016 CR2RES_OBS_NODDING_SLITMODELB_PROCATG, RECIPE_STRING) ;
1019 out_file = cpl_sprintf(
"%s_trace_wave_B%s", RECIPE_STRING,
1020 product_name_addon) ;
1022 twb, qc_main, ext_plist, CR2RES_OBS_NODDING_TWB_PROCATG,
1026 out_file = cpl_sprintf(
"%s_extracted_combined%s", RECIPE_STRING,
1027 product_name_addon) ;
1029 extractc, qc_main, ext_plist,
1030 CR2RES_OBS_NODDING_EXTRACTC_PROCATG, RECIPE_STRING);
1033 extractc, qc_main, ext_plist,
1034 CR2RES_OBS_NODDING_EXTRACTC_IDP_PROCATG,
1041 qc_res_avg = cpl_sprintf(
"%s %s", CR2RES_HEADER_QC_THROUGHPUT,
"AVG");
1042 qc_res_rmsd = cpl_sprintf(
"%s %s", CR2RES_HEADER_QC_THROUGHPUT,
"RMS");
1044 cr2res_qc_calculate_mean_and_rmsd(qc_plists_ext, 1, qc_sizes_ext,
1045 CR2RES_HEADER_QC_THROUGHPUT, qc_main,
1046 qc_res_avg, qc_res_rmsd);
1048 cpl_free(qc_res_avg);
1049 cpl_free(qc_res_rmsd);
1051 out_file = cpl_sprintf(
"%s_throughput%s", RECIPE_STRING,
1052 product_name_addon) ;
1054 parlist, throughput, qc_main, ext_plist,
1055 CR2RES_OBS_NODDING_THROUGHPUT_PROCATG, RECIPE_STRING) ;
1058 cpl_free(product_name_addon) ;
1061 cpl_propertylist_delete(qc_main) ;
1062 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
1063 if (combineda[det_nr-1] != NULL)
1065 if (extracta[det_nr-1] != NULL)
1066 cpl_table_delete(extracta[det_nr-1]) ;
1067 if (slitfunca[det_nr-1] != NULL)
1068 cpl_table_delete(slitfunca[det_nr-1]) ;
1069 if (modela[det_nr-1] != NULL)
1071 if (twa[det_nr-1] != NULL)
1072 cpl_table_delete(twa[det_nr-1]) ;
1073 if (combinedb[det_nr-1] != NULL)
1075 if (extractb[det_nr-1] != NULL)
1076 cpl_table_delete(extractb[det_nr-1]) ;
1077 if (slitfuncb[det_nr-1] != NULL)
1078 cpl_table_delete(slitfuncb[det_nr-1]) ;
1079 if (modelb[det_nr-1] != NULL)
1081 if (twb[det_nr-1] != NULL)
1082 cpl_table_delete(twb[det_nr-1]) ;
1083 if (extractc[det_nr-1] != NULL)
1084 cpl_table_delete(extractc[det_nr-1]) ;
1085 if (throughput[det_nr-1] != NULL)
1086 cpl_table_delete(throughput[det_nr-1]) ;
1087 if (ext_plist[det_nr-1] != NULL)
1088 cpl_propertylist_delete(ext_plist[det_nr-1]) ;
1089 if (ext_plist_photom[det_nr-1] != NULL)
1090 cpl_propertylist_delete(ext_plist_photom[det_nr-1]) ;
1092 cpl_frameset_delete(raw_one_angle) ;
1093 cpl_msg_indent_less() ;
1096 cpl_frameset_delete(rawframes) ;
1097 if (raw_flat_frames != NULL) cpl_frameset_delete(raw_flat_frames) ;
1099 return (
int)cpl_error_get_code();
1142static int cr2res_obs_nodding_reduce(
1143 const cpl_frameset * rawframes,
1144 const cpl_frame * trace_wave_frame,
1145 const cpl_frame * detlin_frame,
1146 const cpl_frame * master_dark_frame,
1147 const cpl_frame * master_flat_frame,
1148 const cpl_frame * bpm_frame,
1149 const cpl_frame * blaze_frame,
1151 int subtract_nolight_rows,
1152 int subtract_interorder_column,
1155 int extract_oversample,
1156 double extract_pclip,
1157 int extract_swath_width,
1159 double extract_smooth_slit,
1160 double extract_smooth_spec,
1162 double extract_kappa,
1167 hdrl_image ** combineda,
1168 cpl_table ** extracta,
1169 cpl_table ** slitfunca,
1170 hdrl_image ** modela,
1172 hdrl_image ** combinedb,
1173 cpl_table ** extractb,
1174 cpl_table ** slitfuncb,
1175 hdrl_image ** modelb,
1177 cpl_table ** extractc,
1178 cpl_propertylist ** ext_plist)
1180 hdrl_imagelist * in ;
1181 hdrl_imagelist * in_calib ;
1182 hdrl_imagelist * in_a ;
1183 hdrl_imagelist * in_b ;
1184 hdrl_imagelist * diff_a ;
1185 hdrl_imagelist * diff_b ;
1186 hdrl_image * collapsed_a ;
1187 hdrl_image * collapsed_b ;
1188 cpl_image * contrib_a ;
1189 cpl_image * contrib_b ;
1190 cr2res_nodding_pos * nod_positions ;
1192 cpl_vector * ndits=NULL ;
1193 cpl_vector * ndsamples ;
1194 cpl_table * trace_wave ;
1196 cpl_table * trace_wave_a ;
1197 cpl_table * trace_wave_b ;
1198 cpl_table * blaze_table ;
1199 cpl_array * slit_frac_a ;
1200 cpl_array * slit_frac_b ;
1201 cpl_table * extracted_a ;
1202 cpl_table * extracted_b ;
1203 cpl_table * extracted_combined ;
1204 cpl_table * slit_func_a ;
1205 cpl_table * slit_func_b ;
1206 hdrl_image * model_master_a ;
1207 hdrl_image * model_master_b ;
1208 cpl_propertylist * plist ;
1209 cpl_size nframes, i ;
1211 const char * first_fname ;
1212 double slit_length, extr_width_frac, slit_frac_a_bot,
1213 slit_frac_a_mid, slit_frac_a_top, slit_frac_b_bot,
1214 slit_frac_b_mid, slit_frac_b_top, nod_throw,
1215 gain, error_factor ;
1216 double qc_signal_a, qc_signal_b, qc_fwhm_a,
1217 qc_fwhm_b, qc_standard_flux_a,
1218 qc_standard_flux_b, qc_fwhm_med, blaze_norm ;
1219 cpl_array * fwhm_a_array ;
1220 cpl_array * fwhm_b_array ;
1221 char * cur_setting ;
1222 int * order_idx_values ;
1223 int * order_idx_values_der ;
1225 double * qc_der_snrs ;
1226 int nb_order_idx_values,
1227 nb_order_idx_values_der,
1228 order_zp, order_idx, order_idxp ;
1231 if (combineda == NULL || combinedb == NULL ||
1232 twa == NULL || twb == NULL ||
1233 slitfunca == NULL || slitfuncb == NULL ||
1234 modela == NULL || modelb == NULL ||
1235 extracta == NULL || extractb == NULL || extractc == NULL ||
1236 ext_plist == NULL || rawframes == NULL || trace_wave_frame == NULL)
1240 if (reduce_det == 1) gain = CR2RES_GAIN_CHIP1 ;
1241 else if (reduce_det == 2) gain = CR2RES_GAIN_CHIP2 ;
1242 else if (reduce_det == 3) gain = CR2RES_GAIN_CHIP3 ;
1244 cpl_msg_error(__func__,
"Failed to get the Gain value") ;
1249 if (cr2res_obs_nodding_check_inputs_validity(rawframes) != 1) {
1250 cpl_msg_error(__func__,
"Invalid Inputs") ;
1255 nframes = cpl_frameset_get_size(rawframes) ;
1256 first_fname = cpl_frame_get_filename(
1257 cpl_frameset_get_position_const(rawframes, 0)) ;
1260 if ((plist = cpl_propertylist_load(cpl_frame_get_filename(trace_wave_frame),
1262 cpl_msg_error(__func__,
"Cannot read the ORDER_ZP from the input TW") ;
1265 order_zp = cr2res_pfits_get_order_zp(plist) ;
1266 cpl_propertylist_delete(plist) ;
1267 if (cpl_error_get_code()) {
1268 cpl_msg_error(__func__,
"Missing ORDER_ZP in the header - Skip") ;
1275 cpl_msg_info(__func__,
"Get the Nodding positions") ;
1276 cpl_msg_indent_more() ;
1278 for (i=0 ; i<nframes ; i++) {
1279 cpl_msg_info(__func__,
"Frame %s - Nodding %c",
1280 cpl_frame_get_filename(
1281 cpl_frameset_get_position_const(rawframes, i)),
1284 cpl_msg_indent_less() ;
1290 if (cpl_msg_get_level() == CPL_MSG_DEBUG && dits != NULL)
1291 cpl_vector_dump(dits, stdout) ;
1295 if (cpl_msg_get_level() == CPL_MSG_DEBUG && ndits != NULL)
1296 cpl_vector_dump(ndits, stdout) ;
1299 cpl_msg_info(__func__,
"Load the image list") ;
1301 reduce_det)) == NULL) {
1302 cpl_msg_error(__func__,
"Cannot load images") ;
1303 cpl_free(nod_positions) ;
1304 if (dits != NULL) cpl_vector_delete(dits) ;
1308 cpl_msg_error(__func__,
"Inconsistent number of loaded images") ;
1309 cpl_free(nod_positions) ;
1310 if (dits != NULL) cpl_vector_delete(dits) ;
1316 cpl_msg_info(__func__,
"Apply the Calibrations") ;
1317 cpl_msg_indent_more() ;
1320 subtract_nolight_rows, subtract_interorder_column, cosmics,
1321 master_flat_frame, master_dark_frame, bpm_frame, detlin_frame, dits,
1323 cpl_vector_delete(ndsamples) ;
1324 if (in_calib == NULL) {
1325 cpl_msg_error(__func__,
"Failed to apply the calibrations") ;
1326 cpl_msg_indent_less() ;
1327 cpl_free(nod_positions) ;
1328 if (dits != NULL) cpl_vector_delete(dits) ;
1329 if (ndits != NULL) cpl_vector_delete(ndits) ;
1334 cpl_msg_indent_less() ;
1338 hdrl_image * mflat = NULL ;
1339 cpl_image * flat_relerr2 = NULL ;
1340 if (master_flat_frame != NULL) {
1342 cpl_frame_get_filename(master_flat_frame), reduce_det) ;
1343 if (mflat == NULL) {
1344 cpl_msg_error(__func__,
"Cannot load the master flat") ;
1345 cpl_free(nod_positions) ;
1346 if (dits != NULL) cpl_vector_delete(dits) ;
1347 cpl_vector_delete(ndits) ;
1354 flat_relerr2, -1.0) ;
1356 if (master_dark_frame != NULL && dits != NULL &&
1358 reduce_det, mflat, dits, -1.0)) {
1359 cpl_msg_error(__func__,
"Cannot remove the master dark errors") ;
1360 cpl_free(nod_positions) ;
1361 cpl_vector_delete(dits) ;
1362 cpl_vector_delete(ndits) ;
1365 if (flat_relerr2 != NULL) cpl_image_delete(flat_relerr2) ;
1369 if (dits != NULL) cpl_vector_delete(dits) ;
1372 cpl_msg_info(__func__,
"Split the images in A and B lists") ;
1373 cpl_msg_indent_more() ;
1376 cpl_msg_error(__func__,
"Failed to split the nodding positions") ;
1377 cpl_msg_indent_less() ;
1378 cpl_free(nod_positions) ;
1380 cpl_vector_delete(ndits) ;
1385 if (error_method == CR2RES_EXTRACT_ERROR_HORNE) {
1386 error_factor = -1.0;
1389 error_factor = gain * cpl_vector_get(ndits, 0) *
1393 for (i=0; i<cpl_vector_get_size(ndits); i++){
1394 if (cpl_vector_get(ndits,i) != cpl_vector_get(ndits, 0))
1395 cpl_msg_warning(__func__,
"Raw frames have different NDIT! "
1396 "Error spectrum will likely be scaled incorrectly.");
1398 cpl_vector_delete(ndits) ;
1399 cpl_free(nod_positions) ;
1401 cpl_msg_indent_less() ;
1406 cpl_msg_error(__func__,
"Inconsistent A / B number of images") ;
1413 cpl_msg_info(__func__,
"Compute difference image lists A-B and B-A") ;
1422 cpl_msg_info(__func__,
"Collapse image lists A-B and B-A") ;
1423 cpl_msg_indent_more() ;
1426 cpl_msg_error(__func__,
"Failed to Collapse A-B") ;
1429 cpl_msg_indent_less() ;
1432 cpl_image_delete(contrib_a) ;
1436 cpl_msg_error(__func__,
"Failed to Collapse B-A") ;
1439 cpl_msg_indent_less() ;
1442 cpl_image_delete(contrib_b) ;
1444 cpl_msg_indent_less() ;
1447 if (flat_relerr2 != NULL) {
1450 cpl_image_delete(flat_relerr2) ;
1454 cpl_msg_info(__func__,
"Load the TRACE WAVE") ;
1456 trace_wave_frame), reduce_det)) == NULL) {
1457 cpl_msg_error(__func__,
"Failed to Load the traces file") ;
1464 cpl_msg_warning(__func__,
"TRACE ADJUST NOT YET IMPLEMENTED") ;
1479 cpl_msg_info(__func__,
"Compute the slit fractions for A and B positions");
1480 cpl_msg_indent_more() ;
1489 if ((plist = cpl_propertylist_load(first_fname, 0)) == NULL) {
1490 cpl_msg_error(__func__,
"Cannot read the NODTHROW in the input files") ;
1491 cpl_msg_indent_less() ;
1494 cpl_table_delete(trace_wave) ;
1498 cpl_propertylist_delete(plist) ;
1499 if (nod_throw < slit_length / 2.0) {
1500 extr_width_frac = nod_throw/slit_length ;
1501 if (nodding_invert == 1) {
1502 slit_frac_a_bot = 0.5 ;
1503 slit_frac_a_mid = slit_frac_a_bot + extr_width_frac/2.0 ;
1504 slit_frac_a_top = slit_frac_a_bot + extr_width_frac ;
1505 slit_frac_b_top = 0.5 ;
1506 slit_frac_b_mid = slit_frac_b_top - extr_width_frac/2.0 ;
1507 slit_frac_b_bot = slit_frac_b_top - extr_width_frac ;
1509 slit_frac_a_top = 0.5 ;
1510 slit_frac_a_mid = slit_frac_a_top - extr_width_frac/2.0 ;
1511 slit_frac_a_bot = slit_frac_a_top - extr_width_frac ;
1512 slit_frac_b_bot = 0.5 ;
1513 slit_frac_b_mid = slit_frac_b_bot + extr_width_frac/2.0 ;
1514 slit_frac_b_top = slit_frac_b_bot + extr_width_frac ;
1516 }
else if (nod_throw <= slit_length) {
1517 extr_width_frac = (slit_length - nod_throw)/slit_length ;
1518 if (nodding_invert == 1) {
1519 slit_frac_a_top = 1.0 ;
1520 slit_frac_a_mid = slit_frac_a_top - extr_width_frac/2.0 ;
1521 slit_frac_a_bot = slit_frac_a_top - extr_width_frac ;
1522 slit_frac_b_bot = 0.0 ;
1523 slit_frac_b_mid = slit_frac_b_bot + extr_width_frac/2.0 ;
1524 slit_frac_b_top = slit_frac_b_bot + extr_width_frac ;
1526 slit_frac_a_bot = 0.0 ;
1527 slit_frac_a_mid = slit_frac_a_bot + extr_width_frac/2.0 ;
1528 slit_frac_a_top = slit_frac_a_bot + extr_width_frac ;
1529 slit_frac_b_top = 1.0 ;
1530 slit_frac_b_mid = slit_frac_b_top - extr_width_frac/2.0 ;
1531 slit_frac_b_bot = slit_frac_b_top - extr_width_frac ;
1534 cpl_msg_error(__func__,
"NODTHROW > slit length (%g>%g)- abort",
1535 nod_throw, slit_length) ;
1536 cpl_msg_indent_less() ;
1539 cpl_table_delete(trace_wave) ;
1542 cpl_msg_info(__func__,
"Nod Throw : %g arcsecs", nod_throw) ;
1543 cpl_msg_info(__func__,
"Nodding A extraction: Slit fraction %g - %g",
1544 slit_frac_a_bot, slit_frac_a_top) ;
1545 cpl_msg_info(__func__,
"Nodding B extraction: Slit fraction %g - %g",
1546 slit_frac_b_bot, slit_frac_b_top) ;
1548 slit_frac_a = cpl_array_new(3, CPL_TYPE_DOUBLE) ;
1549 cpl_array_set(slit_frac_a, 0, slit_frac_a_bot) ;
1550 cpl_array_set(slit_frac_a, 1, slit_frac_a_mid) ;
1551 cpl_array_set(slit_frac_a, 2, slit_frac_a_top) ;
1553 slit_frac_b = cpl_array_new(3, CPL_TYPE_DOUBLE) ;
1554 cpl_array_set(slit_frac_b, 0, slit_frac_b_bot) ;
1555 cpl_array_set(slit_frac_b, 1, slit_frac_b_mid) ;
1556 cpl_array_set(slit_frac_b, 2, slit_frac_b_top) ;
1557 cpl_msg_indent_less() ;
1560 cpl_msg_info(__func__,
"Recompute the traces for the A slit fraction") ;
1562 slit_frac_a)) == NULL) {
1563 cpl_msg_error(__func__,
1564 "Failed to compute the traces for extraction of A") ;
1567 cpl_table_delete(trace_wave) ;
1568 cpl_array_delete(slit_frac_a) ;
1569 cpl_array_delete(slit_frac_b) ;
1572 cpl_array_delete(slit_frac_a) ;
1574 cpl_msg_info(__func__,
"Recompute the traces for the B slit fraction") ;
1576 slit_frac_b)) == NULL) {
1577 cpl_msg_error(__func__,
1578 "Failed to compute the traces for extraction of B") ;
1581 cpl_table_delete(trace_wave) ;
1582 cpl_table_delete(trace_wave_a) ;
1583 cpl_array_delete(slit_frac_b) ;
1586 cpl_array_delete(slit_frac_b) ;
1589 blaze_table = NULL ;
1591 if (blaze_frame != NULL) {
1592 cpl_msg_info(__func__,
"Load the BLAZE") ;
1594 blaze_frame), reduce_det)) == NULL) {
1595 cpl_msg_error(__func__,
"Failed to Load the Blaze file") ;
1598 cpl_table_delete(trace_wave) ;
1599 cpl_table_delete(trace_wave_a) ;
1600 cpl_table_delete(trace_wave_b) ;
1603 cpl_propertylist * blaze_plist ;
1604 blaze_plist = cpl_propertylist_load_regexp(cpl_frame_get_filename(
1605 blaze_frame),0,CR2RES_HEADER_QC_BLAZE_NORM,0);
1606 if(cpl_propertylist_get_size(blaze_plist)>0){
1607 blaze_norm = cpl_propertylist_get_double(blaze_plist, CR2RES_HEADER_QC_BLAZE_NORM);
1611 cpl_msg_warning(__func__,
"QC BLAZE NORM value not found, reverting to per trace normalization") ;
1613 if(blaze_plist!=NULL){
1614 cpl_propertylist_delete(blaze_plist);
1619 cpl_msg_info(__func__,
"A position Spectra Extraction") ;
1620 cpl_msg_indent_more() ;
1622 -1, CR2RES_EXTR_OPT_CURV, extract_height, extract_swath_width,
1623 extract_oversample, extract_pclip, extract_smooth_slit, extract_smooth_spec,
1624 extract_niter, extract_kappa, error_factor,
1625 disp_det==reduce_det, disp_order_idx, disp_trace,
1626 &extracted_a, &slit_func_a, &model_master_a) == -1) {
1627 cpl_msg_error(__func__,
"Failed to extract A");
1628 cpl_msg_indent_less() ;
1631 cpl_table_delete(trace_wave_a) ;
1632 cpl_table_delete(trace_wave_b) ;
1633 cpl_table_delete(trace_wave) ;
1636 cpl_msg_indent_less() ;
1638 cpl_msg_info(__func__,
"B position Spectra Extraction") ;
1639 cpl_msg_indent_more() ;
1641 -1, CR2RES_EXTR_OPT_CURV, extract_height, extract_swath_width,
1642 extract_oversample, extract_pclip, extract_smooth_slit, extract_smooth_spec,
1643 extract_niter, extract_kappa, error_factor,
1644 disp_det==reduce_det, disp_order_idx, disp_trace,
1645 &extracted_b, &slit_func_b, &model_master_b) == -1) {
1646 cpl_msg_error(__func__,
"Failed to extract B");
1647 cpl_msg_indent_less() ;
1648 cpl_table_delete(extracted_a) ;
1649 cpl_table_delete(slit_func_a) ;
1653 cpl_table_delete(trace_wave_a) ;
1654 cpl_table_delete(trace_wave_b) ;
1655 cpl_table_delete(trace_wave) ;
1658 cpl_msg_indent_less() ;
1660 if (blaze_table != NULL) cpl_table_delete(blaze_table) ;
1663 cpl_msg_info(__func__,
"A and B spectra combination") ;
1664 cpl_msg_indent_more() ;
1666 cpl_msg_indent_less() ;
1669 plist = cpl_propertylist_load(first_fname, 0) ;
1672 cpl_propertylist_delete(plist) ;
1675 plist = cpl_propertylist_load(first_fname,
1679 cpl_msg_info(__func__,
"QC parameters computation") ;
1682 cpl_propertylist_append_double(plist, CR2RES_HEADER_QC_SIGNAL,
1683 (qc_signal_a+qc_signal_b)/2.0) ;
1686 qc_standard_flux_a =
1688 qc_standard_flux_b =
1690 cpl_propertylist_append_double(plist, CR2RES_HEADER_QC_STANDARD_FLUX,
1691 (qc_standard_flux_a+qc_standard_flux_b)/2.0) ;
1692 cpl_free(cur_setting) ;
1695 qc_snrs =
cr2res_qc_snr(trace_wave_a, extracted_a, &order_idx_values,
1696 &nb_order_idx_values) ;
1697 qc_der_snrs =
cr2res_qc_der_snr(trace_wave_a, extracted_a, &order_idx_values_der,
1698 &nb_order_idx_values_der) ;
1699 for (i=0 ; i<nb_order_idx_values ; i++) {
1700 order_idx = order_idx_values[i] ;
1702 key_name = cpl_sprintf(CR2RES_HEADER_QC_SNR, order_idxp) ;
1703 cpl_propertylist_append_double(plist, key_name, qc_snrs[i]) ;
1704 cpl_free(key_name) ;
1705 key_name = cpl_sprintf(CR2RES_HEADER_QC_DER_SNR, order_idxp) ;
1706 cpl_propertylist_append_double(plist, key_name, qc_der_snrs[i]) ;
1707 cpl_free(key_name) ;
1709 cpl_free(order_idx_values) ;
1710 cpl_free(order_idx_values_der) ;
1712 cpl_free(qc_der_snrs) ;
1716 &nb_order_idx_values);
1719 fwhm_a_array = cpl_array_new(nb_order_idx_values, CPL_TYPE_DOUBLE);
1720 fwhm_b_array = cpl_array_new(nb_order_idx_values, CPL_TYPE_DOUBLE);
1721 for (i=0 ; i<nb_order_idx_values ; i++) {
1722 order_idx = order_idx_values[i] ;
1725 extract_oversample);
1727 extract_oversample);
1729 key_name = cpl_sprintf(CR2RES_HEADER_QC_SLITFWHM_ORDER, order_idxp) ;
1730 cpl_propertylist_append_double(plist, key_name,
1731 (qc_fwhm_a+qc_fwhm_b)/2.0) ;
1732 cpl_free(key_name) ;
1733 cpl_array_set(fwhm_a_array, i, qc_fwhm_a) ;
1734 cpl_array_set(fwhm_b_array, i, qc_fwhm_b) ;
1736 qc_fwhm_a = cpl_array_get_median(fwhm_a_array);
1737 qc_fwhm_b = cpl_array_get_median(fwhm_b_array);
1738 qc_fwhm_med = (qc_fwhm_a+qc_fwhm_b)/2.0 ;
1739 cpl_propertylist_append_double(plist, CR2RES_HEADER_QC_SLITFWHM_MED,
1741 if (qc_fwhm_med < 3.5) {
1742 cpl_msg_warning(__func__,
"Median FWHM of the PSF along the slit "
1743 "is %gpix, i.e. below the slit width. This means the slit "
1744 "is likely not evenly filled with light "
1745 "in the spectral direction. This can result in a "
1746 "wavelength offset between A and B nodding positions, and with "
1747 "respect to calibrations."
1750 cpl_array_delete(fwhm_a_array) ;
1751 cpl_array_delete(fwhm_b_array) ;
1756 for (i = 0; i < nb_order_idx_values; i++) {
1758 order_idx = order_idx_values[i] ;
1762 key_name = cpl_sprintf(CR2RES_HEADER_QC_REAL_ORDER, order_idxp) ;
1763 cpl_propertylist_append_int(plist, key_name, order_real) ;
1764 cpl_free(key_name) ;
1767 cpl_table_delete(trace_wave) ;
1768 cpl_free(order_idx_values) ;
1771 *combineda = collapsed_a ;
1772 *extracta = extracted_a ;
1773 *slitfunca = slit_func_a ;
1774 *modela = model_master_a ;
1775 *twa = trace_wave_a ;
1777 *combinedb = collapsed_b ;
1778 *extractb = extracted_b ;
1779 *slitfuncb = slit_func_b ;
1780 *modelb = model_master_b ;
1781 *twb = trace_wave_b ;
1783 *extractc = extracted_combined ;
1784 *ext_plist = plist ;
1796static int cr2res_obs_nodding_check_inputs_validity(
1797 const cpl_frameset * rawframes)
1799 cpl_propertylist * plist ;
1800 cr2res_nodding_pos * nod_positions ;
1801 cpl_size nframes, i ;
1806 if (rawframes == NULL)
return -1 ;
1809 nframes = cpl_frameset_get_size(rawframes) ;
1811 cpl_msg_error(__func__,
"Require an even number of raw frames") ;
1818 if (nod_positions == NULL)
return -1 ;
1819 for (i=0 ; i<nframes ; i++) {
1820 if (nod_positions[i] == CR2RES_NODDING_A) nb_a++ ;
1821 if (nod_positions[i] == CR2RES_NODDING_B) nb_b++ ;
1823 cpl_free(nod_positions) ;
1825 if (nb_a == 0 || nb_b == 0 || nb_a != nb_b) {
1826 cpl_msg_error(__func__,
"Require as many A and B positions") ;
1831 if ((plist = cpl_propertylist_load(cpl_frame_get_filename(
1832 cpl_frameset_get_position_const(rawframes, 0)),
1837 cpl_propertylist_delete(plist) ;
1838 for (i = 1; i < nframes; i++) {
1839 double nodthrow_cur;
1840 if ((plist = cpl_propertylist_load(cpl_frame_get_filename(
1841 cpl_frameset_get_position_const(rawframes, i)),
1846 cpl_propertylist_delete(plist) ;
1848 if (fabs(nodthrow_cur-nodthrow) > 1e-3) {
1849 cpl_msg_error(__func__,
1850 "Require constant NOD THROW in the raw frames") ;
1874static cpl_frameset * cr2res_obs_nodding_find_RAW(
1875 const cpl_frameset * in,
1878 cpl_frameset * out ;
1881 if (in == NULL)
return NULL ;
1888 if (type != NULL) *type = 1 ;
1895 if (type != NULL) *type = 2 ;
1900 CR2RES_OBS_ASTROMETRY_JITTER_RAW) ;
1903 if (type != NULL) *type = 3 ;
1908 if (type != NULL) *type = 0 ;
1921static int cr2res_obs_nodding_astrometry_compare(
1922 const cpl_frame * frame1,
1923 const cpl_frame * frame2)
1926 cpl_propertylist * plist1 ;
1927 cpl_propertylist * plist2 ;
1928 double dval1, dval2 ;
1931 if (frame1==NULL || frame2==NULL)
return -1 ;
1934 if ((plist1=cpl_propertylist_load(cpl_frame_get_filename(frame1),0))==NULL){
1935 cpl_msg_error(__func__,
"getting header from reference frame");
1938 if ((plist2=cpl_propertylist_load(cpl_frame_get_filename(frame2),0))==NULL){
1939 cpl_msg_error(__func__,
"getting header from reference frame");
1940 cpl_propertylist_delete(plist1) ;
1945 if (cpl_error_get_code()) {
1946 cpl_propertylist_delete(plist1) ;
1947 cpl_propertylist_delete(plist2) ;
1956 if (cpl_error_get_code()) {
1957 cpl_msg_error(__func__,
"Cannot get the angle");
1958 cpl_propertylist_delete(plist1) ;
1959 cpl_propertylist_delete(plist2) ;
1962 if (fabs(dval1-dval2) > 1e-3) comparison = 0 ;
1964 cpl_propertylist_delete(plist1) ;
1965 cpl_propertylist_delete(plist2) ;
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.
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.
cpl_table * cr2res_io_load_EXTRACT_1D(const char *filename, int detector)
Load a table from a EXTRACT_1D.
const cpl_frame * cr2res_io_find_BPM(const cpl_frameset *in)
Get the first CR2RES_BPM_DRSTYPE frame from a frameset.
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.
const cpl_frame * cr2res_io_find_TRACE_WAVE(const cpl_frameset *in)
Get the first CR2RES_TW_DRSTYPE frame from a frameset.
cpl_vector * cr2res_io_read_ndsamples(const cpl_frameset *in)
Get the NDSAMPLES from a frame set.
int cr2res_io_convert_order_idx_to_idxp(int order_idx)
Convert the order_idx to the order_idxp.
int cr2res_io_save_TRACE_WAVE(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 TRACE_WAVE.
cpl_vector * cr2res_io_read_dits(const cpl_frameset *in)
Get the DITS from a frame set.
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.
hdrl_imagelist * cr2res_io_load_image_list_from_set(const cpl_frameset *in, int detector)
Load an hdrl image list from an images frameset.
cpl_table * cr2res_io_get_eop_table()
Get the eop_table.
int cr2res_io_save_THROUGHPUT(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 THROUGHPUT table.
int cr2res_io_get_ext_idx(const char *filename, int detector, int data)
Get the wished extension number for a detector.
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.
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.
cpl_table * cr2res_io_load_TRACE_WAVE(const char *filename, int detector)
Load a table from a TRACE_WAVE.
cpl_vector * cr2res_io_read_ndits(const cpl_frameset *in)
Get the NDITs from a frame set.
hdrl_image * cr2res_io_load_MASTER_FLAT(const char *filename, int detector)
Load an hdrl image from a MASTER_FLAT.
const char * cr2res_pfits_get_wlen_id(const cpl_propertylist *plist)
find out the Setting
double cr2res_pfits_get_dit(const cpl_propertylist *plist)
find out the DIT value
double cr2res_pfits_get_dec(const cpl_propertylist *plist)
find out the DEC
double cr2res_pfits_get_drot_posang(const cpl_propertylist *plist)
find out the DROT POSANG value
double cr2res_pfits_get_nodthrow(const cpl_propertylist *plist)
find out the NODTHROW value
double cr2res_pfits_get_ra(const cpl_propertylist *plist)
find out the RA
int cr2res_photom_engine(const cpl_table *extr, const char *std_star_file, const char *setting, double ra, double dec, double gain, double exptime, int display, int display_order, int display_trace, cpl_table **throughput, cpl_propertylist **ext_plist)
Compute the conversion/throughput/sensitivity high level.
int cr2res_qc_numsat(const cpl_frameset *frameset)
Calculate the number of saturated pixels.
double * cr2res_qc_der_snr(const cpl_table *tw, const cpl_table *extracted, int **out_order_idx_values, int *out_nb_order_idx_values)
Computes the DER SNR of several spectra.
double cr2res_qc_obs_nodding_signal(const cpl_table *extracted)
Computes the integrated flux over part of the spectrum.
double cr2res_qc_obs_nodding_standard_flux(const cpl_table *extracted, char *setting)
Computes the standard flux over part of the spectrum.
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.
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.
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_format_setting(char *setting_id)
Format the setting.
int cr2res_order_idx_to_real(int order_idx, int order_zp)
Convert the order_idx into order_real.
char cr2res_nodding_position_char(cr2res_nodding_pos pos)
Get the nodding position character for display.
int cr2res_combine_nodding_split(const hdrl_imagelist *in, const cr2res_nodding_pos *positions, hdrl_imagelist **pos_a, hdrl_imagelist **pos_b)
Split A/B positions in 2 image lists.
double cr2res_utils_get_center_mjd(const cpl_frameset *frameset)
Calculate the middle of the exposures in the frameset.
cr2res_nodding_pos * cr2res_nodding_read_positions(const cpl_frameset *in)
Get the nodding positions from a frame set.
cpl_table * cr2res_combine_extracted(const cpl_table *extracta, const cpl_table *extractb)
Combine two extracted spectra by resampling one to the other's WL.
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
cpl_error_code hdrl_imagelist_collapse_mean(const hdrl_imagelist *himlist, hdrl_image **out, cpl_image **contrib)
Mean collapsing of image list.
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.
cpl_error_code hdrl_imagelist_sub_imagelist(hdrl_imagelist *himlist1, const hdrl_imagelist *himlist2)
Subtract two image lists, the first one is replaced by the result.
hdrl_imagelist * hdrl_imagelist_duplicate(const hdrl_imagelist *himlist)
Duplicate an image list.
hdrl_image * hdrl_imagelist_get(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of images.