CR2RE Pipeline Reference Manual 1.6.2
cr2res_obs_pol.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_pol.h"
34#include "cr2res_nodding.h"
35#include "cr2res_calib.h"
36#include "cr2res_pfits.h"
37#include "cr2res_dfs.h"
38#include "cr2res_bpm.h"
39#include "cr2res_trace.h"
40#include "cr2res_extract.h"
41#include "cr2res_io.h"
42#include "cr2res_qc.h"
43
44/*-----------------------------------------------------------------------------
45 Define
46 -----------------------------------------------------------------------------*/
47
48#define RECIPE_STRING "cr2res_obs_pol"
49
50/*-----------------------------------------------------------------------------
51 Plugin registration
52 -----------------------------------------------------------------------------*/
53
54int cpl_plugin_get_info(cpl_pluginlist * list);
55
56/*-----------------------------------------------------------------------------
57 Private function prototypes
58 -----------------------------------------------------------------------------*/
59
60static int * cr2res_obs_pol_get_order_numbers(
61 const cpl_table ** extracted,
62 int next,
63 int * norders) ;
64static int cr2res_obs_pol_check_inputs_validity(
65 const cpl_frameset * rawframes,
66 cpl_size * ngroups) ;
67static int cr2res_obs_pol_reduce(
68 const cpl_frameset * rawframes,
69 const cpl_frame * trace_wave_frame,
70 const cpl_frame * detlin_frame,
71 const cpl_frame * master_dark_frame,
72 const cpl_frame * master_flat_frame,
73 const cpl_frame * bpm_frame,
74 const cpl_frame * blaze_frame,
75 int subtract_nolight_rows,
76 int subtract_interorder_column,
77 int cosmics,
78 int extract_oversample,
79 int extract_swath_width,
80 int extract_height,
81 double extract_smooth_slit,
82 double extract_smooth_spec,
83 int save_group,
84 int reduce_det,
85 hdrl_image ** in_calib_1_a,
86 hdrl_image ** in_calib_2_a,
87 hdrl_image ** in_calib_3_a,
88 hdrl_image ** in_calib_4_a,
89 cpl_table ** trace_wave_1u_a,
90 cpl_table ** trace_wave_1d_a,
91 cpl_table ** trace_wave_2u_a,
92 cpl_table ** trace_wave_2d_a,
93 cpl_table ** trace_wave_3u_a,
94 cpl_table ** trace_wave_3d_a,
95 cpl_table ** trace_wave_4u_a,
96 cpl_table ** trace_wave_4d_a,
97 cpl_table ** extract1D_1u_a,
98 cpl_table ** extract1D_1d_a,
99 cpl_table ** extract1D_2u_a,
100 cpl_table ** extract1D_2d_a,
101 cpl_table ** extract1D_3u_a,
102 cpl_table ** extract1D_3d_a,
103 cpl_table ** extract1D_4u_a,
104 cpl_table ** extract1D_4d_a,
105 cpl_table ** pol_speca,
106 hdrl_image ** in_calib_1_b,
107 hdrl_image ** in_calib_2_b,
108 hdrl_image ** in_calib_3_b,
109 hdrl_image ** in_calib_4_b,
110 cpl_table ** trace_wave_1u_b,
111 cpl_table ** trace_wave_1d_b,
112 cpl_table ** trace_wave_2u_b,
113 cpl_table ** trace_wave_2d_b,
114 cpl_table ** trace_wave_3u_b,
115 cpl_table ** trace_wave_3d_b,
116 cpl_table ** trace_wave_4u_b,
117 cpl_table ** trace_wave_4d_b,
118 cpl_table ** extract1D_1u_b,
119 cpl_table ** extract1D_1d_b,
120 cpl_table ** extract1D_2u_b,
121 cpl_table ** extract1D_2d_b,
122 cpl_table ** extract1D_3u_b,
123 cpl_table ** extract1D_3d_b,
124 cpl_table ** extract1D_4u_b,
125 cpl_table ** extract1D_4d_b,
126 cpl_table ** pol_specb,
127 cpl_propertylist ** ext_plista,
128 cpl_propertylist ** ext_plistb) ;
129static int cr2res_obs_pol_reduce_one(
130 const cpl_frameset * rawframes,
131 const cpl_frameset * raw_background_frames,
132 const cpl_frame * trace_wave_frame,
133 const cpl_frame * detlin_frame,
134 const cpl_frame * master_dark_frame,
135 const cpl_frame * master_flat_frame,
136 const cpl_frame * bpm_frame,
137 const cpl_frame * blaze_frame,
138 int subtract_nolight_rows,
139 int subtract_interorder_column,
140 int cosmics,
141 int extract_oversample,
142 int extract_swath_width,
143 int extract_height,
144 double extract_smooth_slit,
145 double extract_smooth_spec,
146 int save_group,
147 int reduce_det,
148 hdrl_image *** in_calib,
149 cpl_table *** tw,
150 cpl_table *** extract1D,
151 cpl_table ** pol_spec,
152 cpl_propertylist ** ext_plist) ;
153static int cr2res_obs_pol_create(cpl_plugin *);
154static int cr2res_obs_pol_exec(cpl_plugin *);
155static int cr2res_obs_pol_destroy(cpl_plugin *);
156static int cr2res_obs_pol(cpl_frameset *, const cpl_parameterlist *);
157
158/*-----------------------------------------------------------------------------
159 Static variables
160 -----------------------------------------------------------------------------*/
161
162static char cr2res_obs_pol_description[] = "\
163Polarimetry Observation \n\
164 The input raw frames are separated in A and B nodding positions. A \n\
165 and B frames are reduced separately. The frames are grouped by blocks \n\
166 of 4 frames. Each block generates 8 extractions. For each order \n\
167 found, 8 spectra are passed to the demodulation functions. \n\
168 The results are stored in polarimetry tables (1 per group of 4 \n\
169 frames). The polarimetry tables are then merged together if there are \n\
170 several group of 4 frames available. \n\
171 \n\
172 Inputs \n\
173 raw.fits " CR2RES_OBS_POLARIMETRY_OTHER_RAW " [4 to 4n] \n\
174 trace.fits " CR2RES_CAL_FLAT_TW_PROCATG " [1] \n\
175 or " CR2RES_CAL_FLAT_TW_MERGED_PROCATG " \n\
176 or " CR2RES_UTIL_TRACE_TW_PROCATG " \n\
177 or " CR2RES_UTIL_WAVE_TW_PROCATG " \n\
178 or " CR2RES_CAL_WAVE_TW_PROCATG " \n\
179 or " CR2RES_UTIL_SLIT_CURV_TW_PROCATG " \n\
180 detlin.fits " CR2RES_CAL_DETLIN_COEFFS_PROCATG " [0 to 1] \n\
181 bpm.fits " CR2RES_CAL_DARK_BPM_PROCATG " [0 to 1] \n\
182 or " CR2RES_CAL_FLAT_BPM_PROCATG " \n\
183 or " CR2RES_CAL_DETLIN_BPM_PROCATG " \n\
184 or " CR2RES_UTIL_BPM_MERGE_PROCATG " \n\
185 or " CR2RES_UTIL_BPM_SPLIT_PROCATG " \n\
186 master_dark.fits " CR2RES_CAL_DARK_MASTER_PROCATG " [0 to 1] \n\
187 master_flat.fits " CR2RES_CAL_FLAT_MASTER_PROCATG " [0 to 1] \n\
188 blaze.fits " CR2RES_CAL_FLAT_EXTRACT_1D_PROCATG " [0 to 1] \n\
189 \n\
190 Outputs \n\
191 cr2res_obs_pol_specA.fits " CR2RES_OBS_POL_SPECA_PROCATG " \n\
192 cr2res_obs_pol_specB.fits " CR2RES_OBS_POL_SPECB_PROCATG " \n\
193 \n\
194 Algorithm \n\
195 loop on detectors d: \n\
196 cr2res_obs_pol_reduce() \n\
197 -> pol_speca(d) \n\
198 -> pol_specb(d) \n\
199 Save pol_speca \n\
200 Save pol_specb \n\
201 \n\
202 cr2res_obs_pol_reduce(): \n\
203 Read the nodding positions of the raw frames \n\
204 Split the rawframes in A and B positions \n\
205 Call cr2res_obs_pol_reduce_one() successively on A and B \n\
206 -> pol_speca \n\
207 -> pol_specb \n\
208 \n\
209 cr2res_obs_pol_reduce_one(): \n\
210 Read the DITs \n\
211 Read the decker positions \n\
212 Load the image list \n\
213 Apply the calibrations to the image list \n\
214 Load the trace_wave \n\
215 For each group of 4 images g: \n\
216 Compute 8 extracted tables (2 per image): \n\
217 1u, 1d, 2u, 2d, 3u, 3d, 4u, 4d \n\
218 where u/d are for up and down \n\
219 1->4 is derived with cr2res_pol_sort_frames() \n\
220 The decker info is used to derive the 8 slit fractions\n\
221 Count norders the number of different orders in those 8 tables \n\
222 [Note : 1 extracted table has 1 spectrum per order] \n\
223 loop on orders o: \n\
224 Get the 8 spectra/wl/error for this order from \n\
225 1u, 1d, 2u, 2d, 3u, 3d, 4u, 4d \n\
226 Call the cr2res_pol_demod_stokes() \n\
227 -> demod_stokes(o, g) \n\
228 Call cr2res_pol_demod_null() \n\
229 -> demod_null(o, g) \n\
230 Call cr2res_pol_demod_intens() \n\
231 -> demod_intens(o, g) \n\
232 Create pol_spec(g) from demod_stokes(g), \n\
233 demod_null(g), \n\
234 demod_intens(g) \n\
235 Merge pol_spec(g) into pol_spec \n\
236 \n\
237 Library functions used \n\
238 cr2res_io_find_TRACE_WAVE() \n\
239 cr2res_io_find_BPM() \n\
240 cr2res_obs_pol_reduce() \n\
241 cr2res_nodding_read_positions() \n\
242 cr2res_combine_nodding_split_frames() \n\
243 cr2res_obs_pol_reduce_one() \n\
244 cr2res_io_read_dits() \n\
245 cr2res_io_read_decker_positions() \n\
246 cr2res_io_load_image_list_from_set() \n\
247 cr2res_calib_imagelist() \n\
248 cr2res_io_load_TRACE_WAVE() \n\
249 cr2res_pol_sort_frames() \n\
250 cr2res_trace_slit_fraction_create() \n\
251 cr2res_trace_new_slit_fraction() \n\
252 cr2res_extract_traces() \n\
253 cr2res_obs_pol_get_order_numbers() \n\
254 cr2res_pol_demod_stokes() \n\
255 cr2res_pol_demod_null() \n\
256 cr2res_pol_demod_intens() \n\
257 cr2res_pol_POL_SPEC_create() \n\
258 cr2res_pol_spec_pol_merge() \n\
259 cr2res_io_save_POL_SPEC() \n\
260";
261
262/*-----------------------------------------------------------------------------
263 Function code
264 -----------------------------------------------------------------------------*/
265
266/*----------------------------------------------------------------------------*/
276/*----------------------------------------------------------------------------*/
277int cpl_plugin_get_info(cpl_pluginlist * list)
278{
279 cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
280 cpl_plugin * plugin = &recipe->interface;
281
282 if (cpl_plugin_init(plugin,
283 CPL_PLUGIN_API,
284 CR2RES_BINARY_VERSION,
285 CPL_PLUGIN_TYPE_RECIPE,
286 RECIPE_STRING,
287 "Polarimetry Observation recipe",
288 cr2res_obs_pol_description,
289 CR2RES_PIPELINE_AUTHORS,
290 PACKAGE_BUGREPORT,
292 cr2res_obs_pol_create,
293 cr2res_obs_pol_exec,
294 cr2res_obs_pol_destroy)) {
295 cpl_msg_error(cpl_func, "Plugin initialization failed");
296 (void)cpl_error_set_where(cpl_func);
297 return 1;
298 }
299
300 if (cpl_pluginlist_append(list, plugin)) {
301 cpl_msg_error(cpl_func, "Error adding plugin to list");
302 (void)cpl_error_set_where(cpl_func);
303 return 1;
304 }
305
306 return 0;
307}
308
309/*----------------------------------------------------------------------------*/
317/*----------------------------------------------------------------------------*/
318static int cr2res_obs_pol_create(cpl_plugin * plugin)
319{
320 cpl_recipe * recipe ;
321 cpl_parameter * p ;
322
323 /* Check that the plugin is part of a valid recipe */
324 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
325 recipe = (cpl_recipe *)plugin;
326 else
327 return -1;
328
329 /* Create the parameters list in the cpl_recipe object */
330 recipe->parameters = cpl_parameterlist_new();
331
332 /* Fill the parameters list */
333 p = cpl_parameter_new_value("cr2res.cr2res_obs_pol.subtract_nolight_rows",
334 CPL_TYPE_BOOL,
335 "Subtract median row from baffled region at detector bottom",
336 "cr2res.cr2res_obs_pol", FALSE);
337 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "subtract_nolight_rows");
338 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
339 cpl_parameterlist_append(recipe->parameters, p);
340
341 p = cpl_parameter_new_value(
342 "cr2res.cr2res_obs_pol.subtract_interorder_column", CPL_TYPE_BOOL,
343 "Subtract column-by-column fit to the pixel values between orders",
344 "cr2res.cr2res_obs_pol", TRUE);
345 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
346 "subtract_interorder_column");
347 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
348 cpl_parameterlist_append(recipe->parameters, p);
349
350 p = cpl_parameter_new_value("cr2res.cr2res_obs_pol.cosmics",
351 CPL_TYPE_BOOL, "Find and mark cosmic rays hits as bad",
352 "cr2res.cr2res_obs_pol", FALSE);
353 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "cosmics");
354 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
355 cpl_parameterlist_append(recipe->parameters, p);
356
357 p = cpl_parameter_new_value("cr2res.cr2res_obs_pol.extract_oversample",
358 CPL_TYPE_INT, "factor by which to oversample the extraction",
359 "cr2res.cr2res_obs_pol", 5);
360 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "extract_oversample");
361 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
362 cpl_parameterlist_append(recipe->parameters, p);
363
364 p = cpl_parameter_new_value("cr2res.cr2res_obs_pol.extract_swath_width",
365 CPL_TYPE_INT, "The swath width", "cr2res.cr2res_obs_pol", 800);
366 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "extract_swath_width");
367 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
368 cpl_parameterlist_append(recipe->parameters, p);
369
370 p = cpl_parameter_new_value("cr2res.cr2res_obs_pol.extract_height",
371 CPL_TYPE_INT, "Extraction height", "cr2res.cr2res_obs_pol", -1);
372 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "extract_height");
373 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
374 cpl_parameterlist_append(recipe->parameters, p);
375
376 p = cpl_parameter_new_value("cr2res.cr2res_obs_pol.extract_smooth_spec",
377 CPL_TYPE_DOUBLE, "Smoothing along the spectrum",
378 "cr2res.cr2res_obs_pol", 0.0);
379 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "extract_smooth_spec");
380 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
381 cpl_parameterlist_append(recipe->parameters, p);
382
383 p = cpl_parameter_new_value("cr2res.cr2res_obs_pol.extract_smooth_slit",
384 CPL_TYPE_DOUBLE, "Smoothing along the slit",
385 "cr2res.cr2res_obs_pol", 2.0);
386 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "extract_smooth_slit");
387 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
388 cpl_parameterlist_append(recipe->parameters, p);
389
390 p = cpl_parameter_new_value("cr2res.cr2res_obs_pol.detector", CPL_TYPE_INT,
391 "Only reduce the specified detector", "cr2res.cr2res_obs_pol", 0);
392 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "detector");
393 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
394 cpl_parameterlist_append(recipe->parameters, p);
395
396 p = cpl_parameter_new_value("cr2res.cr2res_obs_nodding.create_idp",
397 CPL_TYPE_BOOL, "Flag to produce IDP files",
398 "cr2res.cr2res_obs_nodding", FALSE);
399 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "idp");
400 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
401 cpl_parameterlist_append(recipe->parameters, p);
402
403 p = cpl_parameter_new_value("cr2res.cr2res_obs_pol.save_group",
404 CPL_TYPE_INT,
405 "Save extra files for the specified group number (0: no save)",
406 "cr2res.cr2res_obs_pol", 0);
407 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "save_group");
408 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
409 cpl_parameterlist_append(recipe->parameters, p);
410
411 return 0;
412}
413
414/*----------------------------------------------------------------------------*/
420/*----------------------------------------------------------------------------*/
421static int cr2res_obs_pol_exec(cpl_plugin * plugin)
422{
423 cpl_recipe *recipe;
424
425 /* Get the recipe out of the plugin */
426 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
427 recipe = (cpl_recipe *)plugin;
428 else return -1;
429
430 return cr2res_obs_pol(recipe->frames, recipe->parameters);
431}
432
433/*----------------------------------------------------------------------------*/
439/*----------------------------------------------------------------------------*/
440static int cr2res_obs_pol_destroy(cpl_plugin * plugin)
441{
442 cpl_recipe *recipe;
443
444 /* Get the recipe out of the plugin */
445 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
446 recipe = (cpl_recipe *)plugin;
447 else return -1 ;
448
449 cpl_parameterlist_delete(recipe->parameters);
450 return 0 ;
451}
452
453/*----------------------------------------------------------------------------*/
460/*----------------------------------------------------------------------------*/
461static int cr2res_obs_pol(
462 cpl_frameset * frameset,
463 const cpl_parameterlist * parlist)
464{
465 const cpl_parameter * param ;
466 int extract_oversample, extract_swath_width, cosmics,
467 extract_height, reduce_det, create_idp,
468 subtract_nolight_rows,
469 subtract_interorder_column, save_group ;
470 double extract_smooth_slit, extract_smooth_spec ;
471 double barycorr;
472 cpl_frameset * rawframes ;
473 cpl_frameset * raw_flat_frames ;
474 const cpl_frame * trace_wave_frame ;
475 const cpl_frame * detlin_frame ;
476 const cpl_frame * master_dark_frame ;
477 const cpl_frame * master_flat_frame ;
478 const cpl_frame * bpm_frame ;
479 const cpl_frame * blaze_frame ;
480 cpl_propertylist * qc_main ;
481 hdrl_image * in_calib_1_a[CR2RES_NB_DETECTORS] ;
482 hdrl_image * in_calib_2_a[CR2RES_NB_DETECTORS] ;
483 hdrl_image * in_calib_3_a[CR2RES_NB_DETECTORS] ;
484 hdrl_image * in_calib_4_a[CR2RES_NB_DETECTORS] ;
485 hdrl_image * in_calib_1_b[CR2RES_NB_DETECTORS] ;
486 hdrl_image * in_calib_2_b[CR2RES_NB_DETECTORS] ;
487 hdrl_image * in_calib_3_b[CR2RES_NB_DETECTORS] ;
488 hdrl_image * in_calib_4_b[CR2RES_NB_DETECTORS] ;
489 cpl_table * tw_1u_a[CR2RES_NB_DETECTORS] ;
490 cpl_table * tw_1d_a[CR2RES_NB_DETECTORS] ;
491 cpl_table * tw_2u_a[CR2RES_NB_DETECTORS] ;
492 cpl_table * tw_2d_a[CR2RES_NB_DETECTORS] ;
493 cpl_table * tw_3u_a[CR2RES_NB_DETECTORS] ;
494 cpl_table * tw_3d_a[CR2RES_NB_DETECTORS] ;
495 cpl_table * tw_4u_a[CR2RES_NB_DETECTORS] ;
496 cpl_table * tw_4d_a[CR2RES_NB_DETECTORS] ;
497 cpl_table * tw_1u_b[CR2RES_NB_DETECTORS] ;
498 cpl_table * tw_1d_b[CR2RES_NB_DETECTORS] ;
499 cpl_table * tw_2u_b[CR2RES_NB_DETECTORS] ;
500 cpl_table * tw_2d_b[CR2RES_NB_DETECTORS] ;
501 cpl_table * tw_3u_b[CR2RES_NB_DETECTORS] ;
502 cpl_table * tw_3d_b[CR2RES_NB_DETECTORS] ;
503 cpl_table * tw_4u_b[CR2RES_NB_DETECTORS] ;
504 cpl_table * tw_4d_b[CR2RES_NB_DETECTORS] ;
505 cpl_table * extract1D_1u_a[CR2RES_NB_DETECTORS] ;
506 cpl_table * extract1D_1d_a[CR2RES_NB_DETECTORS] ;
507 cpl_table * extract1D_2u_a[CR2RES_NB_DETECTORS] ;
508 cpl_table * extract1D_2d_a[CR2RES_NB_DETECTORS] ;
509 cpl_table * extract1D_3u_a[CR2RES_NB_DETECTORS] ;
510 cpl_table * extract1D_3d_a[CR2RES_NB_DETECTORS] ;
511 cpl_table * extract1D_4u_a[CR2RES_NB_DETECTORS] ;
512 cpl_table * extract1D_4d_a[CR2RES_NB_DETECTORS] ;
513 cpl_table * extract1D_1u_b[CR2RES_NB_DETECTORS] ;
514 cpl_table * extract1D_1d_b[CR2RES_NB_DETECTORS] ;
515 cpl_table * extract1D_2u_b[CR2RES_NB_DETECTORS] ;
516 cpl_table * extract1D_2d_b[CR2RES_NB_DETECTORS] ;
517 cpl_table * extract1D_3u_b[CR2RES_NB_DETECTORS] ;
518 cpl_table * extract1D_3d_b[CR2RES_NB_DETECTORS] ;
519 cpl_table * extract1D_4u_b[CR2RES_NB_DETECTORS] ;
520 cpl_table * extract1D_4d_b[CR2RES_NB_DETECTORS] ;
521 cpl_table * pol_speca[CR2RES_NB_DETECTORS] ;
522 cpl_table * pol_specb[CR2RES_NB_DETECTORS] ;
523 cpl_propertylist * ext_plista[CR2RES_NB_DETECTORS] ;
524 cpl_propertylist * ext_plistb[CR2RES_NB_DETECTORS] ;
525 char * out_file;
526 cpl_table * eop_table ;
527 int det_nr, save_products ;
528
529 /* Initialise */
530
531 /* RETRIEVE INPUT PARAMETERS */
532 param = cpl_parameterlist_find_const(parlist,
533 "cr2res.cr2res_obs_pol.subtract_nolight_rows");
534 subtract_nolight_rows = cpl_parameter_get_bool(param);
535 param = cpl_parameterlist_find_const(parlist,
536 "cr2res.cr2res_obs_pol.subtract_interorder_column");
537 subtract_interorder_column = cpl_parameter_get_bool(param);
538 param = cpl_parameterlist_find_const(parlist,
539 "cr2res.cr2res_obs_pol.cosmics");
540 cosmics = cpl_parameter_get_bool(param);
541 param = cpl_parameterlist_find_const(parlist,
542 "cr2res.cr2res_obs_pol.extract_oversample");
543 extract_oversample = cpl_parameter_get_int(param);
544 param = cpl_parameterlist_find_const(parlist,
545 "cr2res.cr2res_obs_pol.extract_swath_width");
546 extract_swath_width = cpl_parameter_get_int(param);
547 param = cpl_parameterlist_find_const(parlist,
548 "cr2res.cr2res_obs_pol.extract_height");
549 extract_height = cpl_parameter_get_int(param);
550 param = cpl_parameterlist_find_const(parlist,
551 "cr2res.cr2res_obs_pol.extract_smooth_slit");
552 extract_smooth_slit = cpl_parameter_get_double(param);
553 param = cpl_parameterlist_find_const(parlist,
554 "cr2res.cr2res_obs_pol.extract_smooth_spec");
555 extract_smooth_spec = cpl_parameter_get_double(param);
556 param = cpl_parameterlist_find_const(parlist,
557 "cr2res.cr2res_obs_pol.detector");
558 reduce_det = cpl_parameter_get_int(param);
559 param = cpl_parameterlist_find_const(parlist,
560 "cr2res.cr2res_obs_nodding.create_idp");
561 create_idp = cpl_parameter_get_bool(param);
562 param = cpl_parameterlist_find_const(parlist,
563 "cr2res.cr2res_obs_pol.save_group");
564 save_group = cpl_parameter_get_int(param);
565
566 /* Identify the RAW and CALIB frames in the input frameset */
567 if (cr2res_dfs_set_groups(frameset)) {
568 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
569 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
570 return -1 ;
571 }
572
573 /* Get Calibration frames */
574 trace_wave_frame = cr2res_io_find_TRACE_WAVE(frameset) ;
575 if (trace_wave_frame == NULL) {
576 cpl_msg_error(__func__, "Could not find TRACE_WAVE frame") ;
577 return -1 ;
578 }
579 detlin_frame = cpl_frameset_find_const(frameset,
580 CR2RES_CAL_DETLIN_COEFFS_PROCATG);
581 master_dark_frame = cpl_frameset_find_const(frameset,
582 CR2RES_CAL_DARK_MASTER_PROCATG) ;
583 master_flat_frame = cpl_frameset_find_const(frameset,
584 CR2RES_CAL_FLAT_MASTER_PROCATG) ;
585 bpm_frame = cr2res_io_find_BPM(frameset) ;
586 blaze_frame = cpl_frameset_find_const(frameset,
587 CR2RES_CAL_FLAT_EXTRACT_1D_PROCATG) ;
588
589 /* Get the RAW Frames */
590 rawframes = cr2res_extract_frameset(frameset,
591 CR2RES_OBS_POLARIMETRY_OTHER_RAW) ;
592 if (rawframes == NULL) {
593 cpl_msg_error(__func__, "Could not find RAW frames") ;
594 return -1 ;
595 }
596
597 /* Get the RAW flat frames */
598 raw_flat_frames = cr2res_extract_frameset(frameset, CR2RES_FLAT_RAW) ;
599
600 /* Loop on the detectors */
601 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
602 /* Initialise */
603 in_calib_1_a[det_nr-1] = NULL ;
604 in_calib_2_a[det_nr-1] = NULL ;
605 in_calib_3_a[det_nr-1] = NULL ;
606 in_calib_4_a[det_nr-1] = NULL ;
607 in_calib_1_b[det_nr-1] = NULL ;
608 in_calib_2_b[det_nr-1] = NULL ;
609 in_calib_3_b[det_nr-1] = NULL ;
610 in_calib_4_b[det_nr-1] = NULL ;
611 tw_1u_a[det_nr-1] = NULL ;
612 tw_1d_a[det_nr-1] = NULL ;
613 tw_2u_a[det_nr-1] = NULL ;
614 tw_2d_a[det_nr-1] = NULL ;
615 tw_3u_a[det_nr-1] = NULL ;
616 tw_3d_a[det_nr-1] = NULL ;
617 tw_4u_a[det_nr-1] = NULL ;
618 tw_4d_a[det_nr-1] = NULL ;
619 tw_1u_b[det_nr-1] = NULL ;
620 tw_1d_b[det_nr-1] = NULL ;
621 tw_2u_b[det_nr-1] = NULL ;
622 tw_2d_b[det_nr-1] = NULL ;
623 tw_3u_b[det_nr-1] = NULL ;
624 tw_3d_b[det_nr-1] = NULL ;
625 tw_4u_b[det_nr-1] = NULL ;
626 tw_4d_b[det_nr-1] = NULL ;
627 extract1D_1u_a[det_nr-1] = NULL ;
628 extract1D_1d_a[det_nr-1] = NULL ;
629 extract1D_2u_a[det_nr-1] = NULL ;
630 extract1D_2d_a[det_nr-1] = NULL ;
631 extract1D_3u_a[det_nr-1] = NULL ;
632 extract1D_3d_a[det_nr-1] = NULL ;
633 extract1D_4u_a[det_nr-1] = NULL ;
634 extract1D_4d_a[det_nr-1] = NULL ;
635 extract1D_1u_b[det_nr-1] = NULL ;
636 extract1D_1d_b[det_nr-1] = NULL ;
637 extract1D_2u_b[det_nr-1] = NULL ;
638 extract1D_2d_b[det_nr-1] = NULL ;
639 extract1D_3u_b[det_nr-1] = NULL ;
640 extract1D_3d_b[det_nr-1] = NULL ;
641 extract1D_4u_b[det_nr-1] = NULL ;
642 extract1D_4d_b[det_nr-1] = NULL ;
643 pol_speca[det_nr-1] = NULL ;
644 pol_specb[det_nr-1] = NULL ;
645 ext_plista[det_nr-1] = NULL ;
646 ext_plistb[det_nr-1] = NULL ;
647
648 /* Compute only one detector */
649 if (reduce_det != 0 && det_nr != reduce_det) continue ;
650
651 cpl_msg_info(__func__, "Process Detector %d", det_nr) ;
652 cpl_msg_indent_more() ;
653
654 /* Call the reduction function */
655 if (cr2res_obs_pol_reduce(rawframes,
656 trace_wave_frame, detlin_frame, master_dark_frame,
657 master_flat_frame, bpm_frame, blaze_frame,
658 subtract_nolight_rows, subtract_interorder_column,
659 cosmics, extract_oversample, extract_swath_width,
660 extract_height, extract_smooth_slit,
661 extract_smooth_spec, save_group, det_nr,
662 &(in_calib_1_a[det_nr-1]),
663 &(in_calib_2_a[det_nr-1]),
664 &(in_calib_3_a[det_nr-1]),
665 &(in_calib_4_a[det_nr-1]),
666 &(tw_1u_a[det_nr-1]),
667 &(tw_1d_a[det_nr-1]),
668 &(tw_2u_a[det_nr-1]),
669 &(tw_2d_a[det_nr-1]),
670 &(tw_3u_a[det_nr-1]),
671 &(tw_3d_a[det_nr-1]),
672 &(tw_4u_a[det_nr-1]),
673 &(tw_4d_a[det_nr-1]),
674 &(extract1D_1u_a[det_nr-1]),
675 &(extract1D_1d_a[det_nr-1]),
676 &(extract1D_2u_a[det_nr-1]),
677 &(extract1D_2d_a[det_nr-1]),
678 &(extract1D_3u_a[det_nr-1]),
679 &(extract1D_3d_a[det_nr-1]),
680 &(extract1D_4u_a[det_nr-1]),
681 &(extract1D_4d_a[det_nr-1]),
682 &(pol_speca[det_nr-1]),
683 &(in_calib_1_b[det_nr-1]),
684 &(in_calib_2_b[det_nr-1]),
685 &(in_calib_3_b[det_nr-1]),
686 &(in_calib_4_b[det_nr-1]),
687 &(tw_1u_b[det_nr-1]),
688 &(tw_1d_b[det_nr-1]),
689 &(tw_2u_b[det_nr-1]),
690 &(tw_2d_b[det_nr-1]),
691 &(tw_3u_b[det_nr-1]),
692 &(tw_3d_b[det_nr-1]),
693 &(tw_4u_b[det_nr-1]),
694 &(tw_4d_b[det_nr-1]),
695 &(extract1D_1u_b[det_nr-1]),
696 &(extract1D_1d_b[det_nr-1]),
697 &(extract1D_2u_b[det_nr-1]),
698 &(extract1D_2d_b[det_nr-1]),
699 &(extract1D_3u_b[det_nr-1]),
700 &(extract1D_3d_b[det_nr-1]),
701 &(extract1D_4u_b[det_nr-1]),
702 &(extract1D_4d_b[det_nr-1]),
703 &(pol_specb[det_nr-1]),
704 &(ext_plista[det_nr-1]),
705 &(ext_plistb[det_nr-1])) == -1) {
706 cpl_msg_warning(__func__, "Failed to reduce detector %d",
707 det_nr);
708 cpl_error_reset() ;
709 }
710 cpl_msg_indent_less() ;
711 }
712
713 /* Add ESO.DRS.TMID in the Main Header */
714 qc_main = cpl_propertylist_new();
715 cpl_propertylist_append_double(qc_main,
716 CR2RES_HEADER_DRS_TMID,
717 cr2res_utils_get_center_mjd(rawframes)) ;
718
719 /* Add barycentric correction */
720 eop_table = cr2res_io_get_eop_table() ;
721 if (eop_table != NULL) {
722 double ra, dec, mjd_obs, geolon, geolat, geoelev;
723 cpl_propertylist * plist ;
724 plist=cpl_propertylist_load(cpl_frame_get_filename(
725 cpl_frameset_get_position_const(rawframes, 0)), 0) ;
726
727 ra = cpl_propertylist_get_double(plist, "RA") ;
728 dec = cpl_propertylist_get_double(plist, "DEC") ;
729 mjd_obs = cpl_propertylist_get_double(plist, "MJD-OBS") ;
730 geolon = cpl_propertylist_get_double(plist, "ESO TEL GEOLON") ;
731 geolat = cpl_propertylist_get_double(plist, "ESO TEL GEOLAT") ;
732 geoelev = cpl_propertylist_get_double(plist, "ESO TEL GEOELEV") ;
733
734 cpl_propertylist_delete(plist) ;
735
736 barycorr = 0.0 ;
737 if (!cpl_error_get_code()) {
738 double mjd_cen;
739 mjd_cen = cr2res_utils_get_center_mjd(rawframes) ;
740 hdrl_barycorr_compute(ra, dec, eop_table, mjd_obs,
741 (mjd_cen-mjd_obs)*24*3600, geolon, geolat, geoelev,
742 0.0, 0.0, 0.0, 0.0, &barycorr);
743
744 cpl_msg_info(__func__, "Barycentric correction: %g m/s",
745 barycorr);
746 } else {
747 cpl_msg_info(__func__, "Cannot derive Barycentric correction");
748 cpl_error_reset() ;
749 }
750 cpl_table_delete(eop_table) ;
751 cpl_propertylist_append_double(qc_main, CR2RES_HEADER_DRS_BARYCORR,
752 barycorr);
753 }
754
755 /* Add QC NUMSAT */
756 cpl_propertylist_append_int(qc_main,
757 CR2RES_HEADER_QC_NUMSAT,
758 cr2res_qc_numsat(rawframes)) ;
759
760 /* Save Extra Products if at least one is returned */
761 save_products = 0 ;
762 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
763 if (in_calib_1_a[det_nr-1] != NULL) save_products = 1 ;
764 }
765
766 /* Save only the used RAW - fill rawframes with CALIBS */
767 if (trace_wave_frame != NULL)
768 cpl_frameset_insert(rawframes,
769 cpl_frame_duplicate(trace_wave_frame)) ;
770 if (detlin_frame != NULL)
771 cpl_frameset_insert(rawframes,
772 cpl_frame_duplicate(detlin_frame)) ;
773 if (master_dark_frame != NULL)
774 cpl_frameset_insert(rawframes,
775 cpl_frame_duplicate(master_dark_frame)) ;
776 if (master_flat_frame!= NULL)
777 cpl_frameset_insert(rawframes,
778 cpl_frame_duplicate(master_flat_frame)) ;
779 if (bpm_frame!= NULL)
780 cpl_frameset_insert(rawframes,
781 cpl_frame_duplicate(bpm_frame)) ;
782 if (blaze_frame!= NULL)
783 cpl_frameset_insert(rawframes,
784 cpl_frame_duplicate(blaze_frame)) ;
785
786 if (save_products == 1) {
787 /* Calibrated images a */
788 out_file = cpl_sprintf("%s_in_calibA_1.fits", RECIPE_STRING) ;
789 cr2res_io_save_CALIBRATED(out_file, frameset, rawframes, parlist,
790 in_calib_1_a, NULL, ext_plista,
791 CR2RES_OBS_POL_CALIB_A_PROCATG, RECIPE_STRING);
792 cpl_free(out_file);
793 out_file = cpl_sprintf("%s_in_calibA_2.fits", RECIPE_STRING) ;
794 cr2res_io_save_CALIBRATED(out_file, frameset, rawframes, parlist,
795 in_calib_2_a, NULL, ext_plista,
796 CR2RES_OBS_POL_CALIB_A_PROCATG, RECIPE_STRING);
797 cpl_free(out_file);
798 out_file = cpl_sprintf("%s_in_calibA_3.fits", RECIPE_STRING) ;
799 cr2res_io_save_CALIBRATED(out_file, frameset, rawframes, parlist,
800 in_calib_3_a, NULL, ext_plista,
801 CR2RES_OBS_POL_CALIB_A_PROCATG, RECIPE_STRING);
802 cpl_free(out_file);
803 out_file = cpl_sprintf("%s_in_calibA_4.fits", RECIPE_STRING) ;
804 cr2res_io_save_CALIBRATED(out_file, frameset, rawframes, parlist,
805 in_calib_4_a, NULL, ext_plista,
806 CR2RES_OBS_POL_CALIB_A_PROCATG, RECIPE_STRING);
807 cpl_free(out_file);
808
809 /* TW Nodding a */
810 out_file = cpl_sprintf("%s_twA_1u.fits", RECIPE_STRING) ;
811 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
812 tw_1u_a, NULL, ext_plista, CR2RES_OBS_POL_TWA_PROCATG,
813 RECIPE_STRING);
814 cpl_free(out_file);
815 out_file = cpl_sprintf("%s_twA_1d.fits", RECIPE_STRING) ;
816 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
817 tw_1d_a, NULL, ext_plista, CR2RES_OBS_POL_TWA_PROCATG,
818 RECIPE_STRING);
819 cpl_free(out_file);
820 out_file = cpl_sprintf("%s_twA_2u.fits", RECIPE_STRING) ;
821 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
822 tw_2u_a, NULL, ext_plista, CR2RES_OBS_POL_TWA_PROCATG,
823 RECIPE_STRING);
824 cpl_free(out_file);
825 out_file = cpl_sprintf("%s_twA_2d.fits", RECIPE_STRING) ;
826 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
827 tw_2d_a, NULL, ext_plista, CR2RES_OBS_POL_TWA_PROCATG,
828 RECIPE_STRING);
829 cpl_free(out_file);
830 out_file = cpl_sprintf("%s_twA_3u.fits", RECIPE_STRING) ;
831 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
832 tw_3u_a, NULL, ext_plista, CR2RES_OBS_POL_TWA_PROCATG,
833 RECIPE_STRING);
834 cpl_free(out_file);
835 out_file = cpl_sprintf("%s_twA_3d.fits", RECIPE_STRING) ;
836 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
837 tw_3d_a, NULL, ext_plista, CR2RES_OBS_POL_TWA_PROCATG,
838 RECIPE_STRING);
839 cpl_free(out_file);
840 out_file = cpl_sprintf("%s_twA_4u.fits", RECIPE_STRING) ;
841 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
842 tw_4u_a, NULL, ext_plista, CR2RES_OBS_POL_TWA_PROCATG,
843 RECIPE_STRING);
844 cpl_free(out_file);
845 out_file = cpl_sprintf("%s_twA_4d.fits", RECIPE_STRING) ;
846 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
847 tw_4d_a, NULL, ext_plista, CR2RES_OBS_POL_TWA_PROCATG,
848 RECIPE_STRING);
849 cpl_free(out_file);
850
851 /* Extracted Nodding A */
852 out_file = cpl_sprintf("%s_extractedA_1u.fits", RECIPE_STRING) ;
853 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
854 extract1D_1u_a, NULL, ext_plista,
855 CR2RES_OBS_POL_EXTRACTA_PROCATG, RECIPE_STRING);
856 cpl_free(out_file);
857 out_file = cpl_sprintf("%s_extractedA_1d.fits", RECIPE_STRING) ;
858 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
859 extract1D_1d_a, NULL, ext_plista,
860 CR2RES_OBS_POL_EXTRACTA_PROCATG, RECIPE_STRING);
861 cpl_free(out_file);
862 out_file = cpl_sprintf("%s_extractedA_2u.fits", RECIPE_STRING) ;
863 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
864 extract1D_2u_a, NULL, ext_plista,
865 CR2RES_OBS_POL_EXTRACTA_PROCATG, RECIPE_STRING);
866 cpl_free(out_file);
867 out_file = cpl_sprintf("%s_extractedA_2d.fits", RECIPE_STRING) ;
868 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
869 extract1D_2d_a, NULL, ext_plista,
870 CR2RES_OBS_POL_EXTRACTA_PROCATG, RECIPE_STRING);
871 cpl_free(out_file);
872 out_file = cpl_sprintf("%s_extractedA_3u.fits", RECIPE_STRING) ;
873 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
874 extract1D_3u_a, NULL, ext_plista,
875 CR2RES_OBS_POL_EXTRACTA_PROCATG, RECIPE_STRING);
876 cpl_free(out_file);
877 out_file = cpl_sprintf("%s_extractedA_3d.fits", RECIPE_STRING) ;
878 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
879 extract1D_3d_a, NULL, ext_plista,
880 CR2RES_OBS_POL_EXTRACTA_PROCATG, RECIPE_STRING);
881 cpl_free(out_file);
882 out_file = cpl_sprintf("%s_extractedA_4u.fits", RECIPE_STRING) ;
883 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
884 extract1D_4u_a, NULL, ext_plista,
885 CR2RES_OBS_POL_EXTRACTA_PROCATG, RECIPE_STRING);
886 cpl_free(out_file);
887 out_file = cpl_sprintf("%s_extractedA_4d.fits", RECIPE_STRING) ;
888 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
889 extract1D_4d_a, NULL, ext_plista,
890 CR2RES_OBS_POL_EXTRACTA_PROCATG, RECIPE_STRING);
891 cpl_free(out_file);
892
893 /* Calibrated images b */
894 out_file = cpl_sprintf("%s_in_calibB_1.fits", RECIPE_STRING) ;
895 cr2res_io_save_CALIBRATED(out_file, frameset, rawframes, parlist,
896 in_calib_1_b, NULL, ext_plista,
897 CR2RES_OBS_POL_CALIB_B_PROCATG, RECIPE_STRING);
898 cpl_free(out_file);
899 out_file = cpl_sprintf("%s_in_calibB_2.fits", RECIPE_STRING) ;
900 cr2res_io_save_CALIBRATED(out_file, frameset, rawframes, parlist,
901 in_calib_2_b, NULL, ext_plista,
902 CR2RES_OBS_POL_CALIB_B_PROCATG, RECIPE_STRING);
903 cpl_free(out_file);
904 out_file = cpl_sprintf("%s_in_calibB_3.fits", RECIPE_STRING) ;
905 cr2res_io_save_CALIBRATED(out_file, frameset, rawframes, parlist,
906 in_calib_3_b, NULL, ext_plista,
907 CR2RES_OBS_POL_CALIB_B_PROCATG, RECIPE_STRING);
908 cpl_free(out_file);
909 out_file = cpl_sprintf("%s_in_calibB_4.fits", RECIPE_STRING) ;
910 cr2res_io_save_CALIBRATED(out_file, frameset, rawframes, parlist,
911 in_calib_4_b, NULL, ext_plista,
912 CR2RES_OBS_POL_CALIB_B_PROCATG, RECIPE_STRING);
913 cpl_free(out_file);
914
915 /* TW Nodding b */
916 out_file = cpl_sprintf("%s_twB_1u.fits", RECIPE_STRING) ;
917 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
918 tw_1u_b, NULL, ext_plistb, CR2RES_OBS_POL_TWB_PROCATG,
919 RECIPE_STRING);
920 cpl_free(out_file);
921 out_file = cpl_sprintf("%s_twB_1d.fits", RECIPE_STRING) ;
922 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
923 tw_1d_b, NULL, ext_plistb, CR2RES_OBS_POL_TWB_PROCATG,
924 RECIPE_STRING);
925 cpl_free(out_file);
926 out_file = cpl_sprintf("%s_twB_2u.fits", RECIPE_STRING) ;
927 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
928 tw_2u_b, NULL, ext_plistb, CR2RES_OBS_POL_TWB_PROCATG,
929 RECIPE_STRING);
930 cpl_free(out_file);
931 out_file = cpl_sprintf("%s_twB_2d.fits", RECIPE_STRING) ;
932 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
933 tw_2d_b, NULL, ext_plistb, CR2RES_OBS_POL_TWB_PROCATG,
934 RECIPE_STRING);
935 cpl_free(out_file);
936 out_file = cpl_sprintf("%s_twB_3u.fits", RECIPE_STRING) ;
937 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
938 tw_3u_b, NULL, ext_plistb, CR2RES_OBS_POL_TWB_PROCATG,
939 RECIPE_STRING);
940 cpl_free(out_file);
941 out_file = cpl_sprintf("%s_twB_3d.fits", RECIPE_STRING) ;
942 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
943 tw_3d_b, NULL, ext_plistb, CR2RES_OBS_POL_TWB_PROCATG,
944 RECIPE_STRING);
945 cpl_free(out_file);
946 out_file = cpl_sprintf("%s_twB_4u.fits", RECIPE_STRING) ;
947 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
948 tw_4u_b, NULL, ext_plistb, CR2RES_OBS_POL_TWB_PROCATG,
949 RECIPE_STRING);
950 cpl_free(out_file);
951 out_file = cpl_sprintf("%s_twB_4d.fits", RECIPE_STRING) ;
952 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
953 tw_4d_b, NULL, ext_plistb, CR2RES_OBS_POL_TWB_PROCATG,
954 RECIPE_STRING);
955 cpl_free(out_file);
956
957 /* Extracted Nodding B */
958 out_file = cpl_sprintf("%s_extractedB_1u.fits", RECIPE_STRING) ;
959 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
960 extract1D_1u_b, NULL, ext_plistb,
961 CR2RES_OBS_POL_EXTRACTB_PROCATG, RECIPE_STRING);
962 cpl_free(out_file);
963 out_file = cpl_sprintf("%s_extractedB_1d.fits", RECIPE_STRING) ;
964 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
965 extract1D_1d_b, NULL, ext_plistb,
966 CR2RES_OBS_POL_EXTRACTB_PROCATG, RECIPE_STRING);
967 cpl_free(out_file);
968 out_file = cpl_sprintf("%s_extractedB_2u.fits", RECIPE_STRING) ;
969 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
970 extract1D_2u_b, NULL, ext_plistb,
971 CR2RES_OBS_POL_EXTRACTB_PROCATG, RECIPE_STRING);
972 cpl_free(out_file);
973 out_file = cpl_sprintf("%s_extractedB_2d.fits", RECIPE_STRING) ;
974 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
975 extract1D_2d_b, NULL, ext_plistb,
976 CR2RES_OBS_POL_EXTRACTB_PROCATG, RECIPE_STRING);
977 cpl_free(out_file);
978 out_file = cpl_sprintf("%s_extractedB_3u.fits", RECIPE_STRING) ;
979 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
980 extract1D_3u_b, NULL, ext_plistb,
981 CR2RES_OBS_POL_EXTRACTB_PROCATG, RECIPE_STRING);
982 cpl_free(out_file);
983 out_file = cpl_sprintf("%s_extractedB_3d.fits", RECIPE_STRING) ;
984 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
985 extract1D_3d_b, NULL, ext_plistb,
986 CR2RES_OBS_POL_EXTRACTB_PROCATG, RECIPE_STRING);
987 cpl_free(out_file);
988 out_file = cpl_sprintf("%s_extractedB_4u.fits", RECIPE_STRING) ;
989 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
990 extract1D_4u_b, NULL, ext_plistb,
991 CR2RES_OBS_POL_EXTRACTB_PROCATG, RECIPE_STRING);
992 cpl_free(out_file);
993 out_file = cpl_sprintf("%s_extractedB_4d.fits", RECIPE_STRING) ;
994 cr2res_io_save_EXTRACT_1D(out_file, frameset, rawframes, parlist,
995 extract1D_4d_b, NULL, ext_plistb,
996 CR2RES_OBS_POL_EXTRACTB_PROCATG, RECIPE_STRING);
997 cpl_free(out_file);
998 }
999
1000 /* Polarimetry Spectra */
1001 out_file = cpl_sprintf("%s_pol_specA.fits", RECIPE_STRING) ;
1002 cr2res_io_save_POL_SPEC(out_file, frameset, rawframes, parlist,
1003 pol_speca, qc_main, ext_plista, CR2RES_OBS_POL_SPECA_PROCATG,
1004 RECIPE_STRING) ;
1005 if (create_idp) {
1006 cr2res_idp_save(out_file, frameset, rawframes, parlist,
1007 pol_speca, qc_main, ext_plista,
1008 CR2RES_OBS_POL_EXTRACTA_IDP_PROCATG,
1009 RECIPE_STRING);
1010 }
1011 cpl_free(out_file);
1012
1013 out_file = cpl_sprintf("%s_pol_specB.fits", RECIPE_STRING) ;
1014 cr2res_io_save_POL_SPEC(out_file, frameset, rawframes, parlist,
1015 pol_specb, qc_main, ext_plistb, CR2RES_OBS_POL_SPECB_PROCATG,
1016 RECIPE_STRING) ;
1017 if (create_idp) {
1018 cr2res_idp_save(out_file, frameset, rawframes, parlist,
1019 pol_specb, qc_main, ext_plistb,
1020 CR2RES_OBS_POL_EXTRACTB_IDP_PROCATG,
1021 RECIPE_STRING);
1022 }
1023 //cpl_msg_info(__func__,"ERR: %d", cpl_error_get_code());
1024 cpl_free(out_file);
1025
1026 /* Free */
1027 cpl_frameset_delete(rawframes) ;
1028 cpl_propertylist_delete(qc_main) ;
1029 if (raw_flat_frames != NULL) cpl_frameset_delete(raw_flat_frames) ;
1030 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
1031 if (in_calib_1_a[det_nr-1] != NULL)
1032 hdrl_image_delete(in_calib_1_a[det_nr-1]) ;
1033 if (in_calib_2_a[det_nr-1] != NULL)
1034 hdrl_image_delete(in_calib_2_a[det_nr-1]) ;
1035 if (in_calib_3_a[det_nr-1] != NULL)
1036 hdrl_image_delete(in_calib_3_a[det_nr-1]) ;
1037 if (in_calib_4_a[det_nr-1] != NULL)
1038 hdrl_image_delete(in_calib_4_a[det_nr-1]) ;
1039 if (in_calib_1_b[det_nr-1] != NULL)
1040 hdrl_image_delete(in_calib_1_b[det_nr-1]) ;
1041 if (in_calib_2_b[det_nr-1] != NULL)
1042 hdrl_image_delete(in_calib_2_b[det_nr-1]) ;
1043 if (in_calib_3_b[det_nr-1] != NULL)
1044 hdrl_image_delete(in_calib_3_b[det_nr-1]) ;
1045 if (in_calib_4_b[det_nr-1] != NULL)
1046 hdrl_image_delete(in_calib_4_b[det_nr-1]) ;
1047 if (tw_1u_a[det_nr-1] != NULL) cpl_table_delete(tw_1u_a[det_nr-1]) ;
1048 if (tw_1d_a[det_nr-1] != NULL) cpl_table_delete(tw_1d_a[det_nr-1]) ;
1049 if (tw_2u_a[det_nr-1] != NULL) cpl_table_delete(tw_2u_a[det_nr-1]) ;
1050 if (tw_2d_a[det_nr-1] != NULL) cpl_table_delete(tw_2d_a[det_nr-1]) ;
1051 if (tw_3u_a[det_nr-1] != NULL) cpl_table_delete(tw_3u_a[det_nr-1]) ;
1052 if (tw_3d_a[det_nr-1] != NULL) cpl_table_delete(tw_3d_a[det_nr-1]) ;
1053 if (tw_4u_a[det_nr-1] != NULL) cpl_table_delete(tw_4u_a[det_nr-1]) ;
1054 if (tw_4d_a[det_nr-1] != NULL) cpl_table_delete(tw_4d_a[det_nr-1]) ;
1055 if (tw_1u_b[det_nr-1] != NULL) cpl_table_delete(tw_1u_b[det_nr-1]) ;
1056 if (tw_1d_b[det_nr-1] != NULL) cpl_table_delete(tw_1d_b[det_nr-1]) ;
1057 if (tw_2u_b[det_nr-1] != NULL) cpl_table_delete(tw_2u_b[det_nr-1]) ;
1058 if (tw_2d_b[det_nr-1] != NULL) cpl_table_delete(tw_2d_b[det_nr-1]) ;
1059 if (tw_3u_b[det_nr-1] != NULL) cpl_table_delete(tw_3u_b[det_nr-1]) ;
1060 if (tw_3d_b[det_nr-1] != NULL) cpl_table_delete(tw_3d_b[det_nr-1]) ;
1061 if (tw_4u_b[det_nr-1] != NULL) cpl_table_delete(tw_4u_b[det_nr-1]) ;
1062 if (tw_4d_b[det_nr-1] != NULL) cpl_table_delete(tw_4d_b[det_nr-1]) ;
1063
1064 if (extract1D_1u_a[det_nr-1] != NULL)
1065 cpl_table_delete(extract1D_1u_a[det_nr-1]) ;
1066 if (extract1D_1d_a[det_nr-1] != NULL)
1067 cpl_table_delete(extract1D_1d_a[det_nr-1]) ;
1068 if (extract1D_2u_a[det_nr-1] != NULL)
1069 cpl_table_delete(extract1D_2u_a[det_nr-1]) ;
1070 if (extract1D_2d_a[det_nr-1] != NULL)
1071 cpl_table_delete(extract1D_2d_a[det_nr-1]) ;
1072 if (extract1D_3u_a[det_nr-1] != NULL)
1073 cpl_table_delete(extract1D_3u_a[det_nr-1]) ;
1074 if (extract1D_3d_a[det_nr-1] != NULL)
1075 cpl_table_delete(extract1D_3d_a[det_nr-1]) ;
1076 if (extract1D_4u_a[det_nr-1] != NULL)
1077 cpl_table_delete(extract1D_4u_a[det_nr-1]) ;
1078 if (extract1D_4d_a[det_nr-1] != NULL)
1079 cpl_table_delete(extract1D_4d_a[det_nr-1]) ;
1080 if (extract1D_1u_b[det_nr-1] != NULL)
1081 cpl_table_delete(extract1D_1u_b[det_nr-1]) ;
1082 if (extract1D_1d_b[det_nr-1] != NULL)
1083 cpl_table_delete(extract1D_1d_b[det_nr-1]) ;
1084 if (extract1D_2u_b[det_nr-1] != NULL)
1085 cpl_table_delete(extract1D_2u_b[det_nr-1]) ;
1086 if (extract1D_2d_b[det_nr-1] != NULL)
1087 cpl_table_delete(extract1D_2d_b[det_nr-1]) ;
1088 if (extract1D_3u_b[det_nr-1] != NULL)
1089 cpl_table_delete(extract1D_3u_b[det_nr-1]) ;
1090 if (extract1D_3d_b[det_nr-1] != NULL)
1091 cpl_table_delete(extract1D_3d_b[det_nr-1]) ;
1092 if (extract1D_4u_b[det_nr-1] != NULL)
1093 cpl_table_delete(extract1D_4u_b[det_nr-1]) ;
1094 if (extract1D_4d_b[det_nr-1] != NULL)
1095 cpl_table_delete(extract1D_4d_b[det_nr-1]) ;
1096 if (pol_speca[det_nr-1] != NULL) cpl_table_delete(pol_speca[det_nr-1]) ;
1097 if (pol_specb[det_nr-1] != NULL) cpl_table_delete(pol_specb[det_nr-1]) ;
1098 if (ext_plista[det_nr-1] != NULL)
1099 cpl_propertylist_delete(ext_plista[det_nr-1]) ;
1100 if (ext_plistb[det_nr-1] != NULL)
1101 cpl_propertylist_delete(ext_plistb[det_nr-1]) ;
1102 }
1103
1104 return (int)cpl_error_get_code();
1105}
1106
1107/*----------------------------------------------------------------------------*/
1139/*----------------------------------------------------------------------------*/
1140static int cr2res_obs_pol_reduce(
1141 const cpl_frameset * rawframes,
1142 const cpl_frame * trace_wave_frame,
1143 const cpl_frame * detlin_frame,
1144 const cpl_frame * master_dark_frame,
1145 const cpl_frame * master_flat_frame,
1146 const cpl_frame * bpm_frame,
1147 const cpl_frame * blaze_frame,
1148 int subtract_nolight_rows,
1149 int subtract_interorder_column,
1150 int cosmics,
1151 int extract_oversample,
1152 int extract_swath_width,
1153 int extract_height,
1154 double extract_smooth_slit,
1155 double extract_smooth_spec,
1156 int save_group,
1157 int reduce_det,
1158 hdrl_image ** in_calib_1_a,
1159 hdrl_image ** in_calib_2_a,
1160 hdrl_image ** in_calib_3_a,
1161 hdrl_image ** in_calib_4_a,
1162 cpl_table ** trace_wave_1u_a,
1163 cpl_table ** trace_wave_1d_a,
1164 cpl_table ** trace_wave_2u_a,
1165 cpl_table ** trace_wave_2d_a,
1166 cpl_table ** trace_wave_3u_a,
1167 cpl_table ** trace_wave_3d_a,
1168 cpl_table ** trace_wave_4u_a,
1169 cpl_table ** trace_wave_4d_a,
1170 cpl_table ** extract1D_1u_a,
1171 cpl_table ** extract1D_1d_a,
1172 cpl_table ** extract1D_2u_a,
1173 cpl_table ** extract1D_2d_a,
1174 cpl_table ** extract1D_3u_a,
1175 cpl_table ** extract1D_3d_a,
1176 cpl_table ** extract1D_4u_a,
1177 cpl_table ** extract1D_4d_a,
1178 cpl_table ** pol_speca,
1179 hdrl_image ** in_calib_1_b,
1180 hdrl_image ** in_calib_2_b,
1181 hdrl_image ** in_calib_3_b,
1182 hdrl_image ** in_calib_4_b,
1183 cpl_table ** trace_wave_1u_b,
1184 cpl_table ** trace_wave_1d_b,
1185 cpl_table ** trace_wave_2u_b,
1186 cpl_table ** trace_wave_2d_b,
1187 cpl_table ** trace_wave_3u_b,
1188 cpl_table ** trace_wave_3d_b,
1189 cpl_table ** trace_wave_4u_b,
1190 cpl_table ** trace_wave_4d_b,
1191 cpl_table ** extract1D_1u_b,
1192 cpl_table ** extract1D_1d_b,
1193 cpl_table ** extract1D_2u_b,
1194 cpl_table ** extract1D_2d_b,
1195 cpl_table ** extract1D_3u_b,
1196 cpl_table ** extract1D_3d_b,
1197 cpl_table ** extract1D_4u_b,
1198 cpl_table ** extract1D_4d_b,
1199 cpl_table ** pol_specb,
1200 cpl_propertylist ** ext_plista,
1201 cpl_propertylist ** ext_plistb)
1202{
1203 cpl_frameset * rawframes_a ;
1204 cpl_frameset * rawframes_b ;
1205 cr2res_nodding_pos * nod_positions ;
1206 hdrl_image ** in_calib_a_loc ;
1207 hdrl_image ** in_calib_b_loc ;
1208 cpl_table ** trace_wave_a_loc ;
1209 cpl_table ** trace_wave_b_loc ;
1210 cpl_table ** extract1D_a_loc ;
1211 cpl_table ** extract1D_b_loc ;
1212 cpl_table * pol_speca_loc ;
1213 cpl_table * pol_specb_loc ;
1214 cpl_propertylist * ext_plista_loc ;
1215 cpl_propertylist * ext_plistb_loc ;
1216 cpl_size ngroups ;
1217
1218 /* Check Inputs */
1219 if (pol_speca == NULL || pol_specb == NULL || ext_plista == NULL ||
1220 ext_plistb == NULL || rawframes == NULL ||
1221 trace_wave_frame == NULL) return -1 ;
1222
1223 if (cr2res_obs_pol_check_inputs_validity(rawframes, &ngroups) != 1) {
1224 cpl_msg_error(__func__, "Validity Checks failed") ;
1225 return -1 ;
1226 }
1227
1228 /* Initialize */
1229 *in_calib_1_a = *in_calib_2_a = *in_calib_3_a = *in_calib_4_a = NULL ;
1230 *trace_wave_1u_a = *trace_wave_1d_a = *trace_wave_2u_a =
1231 *trace_wave_2d_a = *trace_wave_3u_a = *trace_wave_3d_a =
1232 *trace_wave_4u_a = *trace_wave_4d_a = NULL ;
1233 *extract1D_1u_a = *extract1D_1d_a = *extract1D_2u_a =
1234 *extract1D_2d_a = *extract1D_3u_a = *extract1D_3d_a =
1235 *extract1D_4u_a = *extract1D_4d_a = NULL ;
1236 *in_calib_1_b = *in_calib_2_b = *in_calib_3_b = *in_calib_4_b = NULL ;
1237 *trace_wave_1u_b = *trace_wave_1d_b = *trace_wave_2u_b =
1238 *trace_wave_2d_b = *trace_wave_3u_b = *trace_wave_3d_b =
1239 *trace_wave_4u_b = *trace_wave_4d_b = NULL ;
1240 *extract1D_1u_b = *extract1D_1d_b = *extract1D_2u_b =
1241 *extract1D_2d_b = *extract1D_3u_b = *extract1D_3d_b =
1242 *extract1D_4u_b = *extract1D_4d_b = NULL ;
1243
1244 /* Get the Nodding positions */
1245 nod_positions = cr2res_nodding_read_positions(rawframes) ;
1246
1247 /* Split the frames */
1248 if (cr2res_combine_nodding_split_frames(rawframes, nod_positions,
1249 &rawframes_a, &rawframes_b)) {
1250 cpl_msg_error(__func__, "Failed to split the nodding positions") ;
1251 cpl_free(nod_positions) ;
1252 return -1 ;
1253 }
1254 cpl_free(nod_positions) ;
1255
1256 /* Reduce A position */
1257 cpl_msg_info(__func__, "Compute Polarimetry for nodding A position") ;
1258 cpl_msg_indent_more() ;
1259 if (cr2res_obs_pol_reduce_one(rawframes_a, rawframes_b,
1260 trace_wave_frame, detlin_frame, master_dark_frame,
1261 master_flat_frame, bpm_frame, blaze_frame,
1262 subtract_nolight_rows, subtract_interorder_column, cosmics,
1263 extract_oversample, extract_swath_width, extract_height,
1264 extract_smooth_slit, extract_smooth_spec, save_group,
1265 reduce_det,
1266 &in_calib_a_loc, &trace_wave_a_loc, &extract1D_a_loc,
1267 &pol_speca_loc, &ext_plista_loc) == -1) {
1268 cpl_msg_warning(__func__, "Failed to Reduce A nodding frames") ;
1269 }
1270 cpl_msg_indent_less() ;
1271
1272 /* Reduce B position */
1273 cpl_msg_info(__func__, "Compute Polarimetry for nodding B position") ;
1274 cpl_msg_indent_more() ;
1275 if (cr2res_obs_pol_reduce_one(rawframes_b, rawframes_a,
1276 trace_wave_frame, detlin_frame, master_dark_frame,
1277 master_flat_frame, bpm_frame, blaze_frame,
1278 subtract_nolight_rows, subtract_interorder_column, cosmics,
1279 extract_oversample, extract_swath_width, extract_height,
1280 extract_smooth_slit, extract_smooth_spec, save_group,
1281 reduce_det,
1282 &in_calib_b_loc, &trace_wave_b_loc, &extract1D_b_loc,
1283 &pol_specb_loc, &ext_plistb_loc) == -1) {
1284 cpl_msg_warning(__func__, "Failed to Reduce B nodding frames") ;
1285 }
1286 cpl_msg_indent_less() ;
1287 if (rawframes_a != NULL) cpl_frameset_delete(rawframes_a);
1288 if (rawframes_b != NULL) cpl_frameset_delete(rawframes_b);
1289
1290 /* Return */
1291 if (in_calib_a_loc != NULL) {
1292 *in_calib_1_a = in_calib_a_loc[0] ;
1293 *in_calib_2_a = in_calib_a_loc[1] ;
1294 *in_calib_3_a = in_calib_a_loc[2] ;
1295 *in_calib_4_a = in_calib_a_loc[3] ;
1296 cpl_free(in_calib_a_loc) ;
1297 }
1298 if (trace_wave_a_loc != NULL) {
1299 *trace_wave_1u_a = trace_wave_a_loc[0] ;
1300 *trace_wave_1d_a = trace_wave_a_loc[1] ;
1301 *trace_wave_2u_a = trace_wave_a_loc[2] ;
1302 *trace_wave_2d_a = trace_wave_a_loc[3] ;
1303 *trace_wave_3u_a = trace_wave_a_loc[4] ;
1304 *trace_wave_3d_a = trace_wave_a_loc[5] ;
1305 *trace_wave_4u_a = trace_wave_a_loc[6] ;
1306 *trace_wave_4d_a = trace_wave_a_loc[7] ;
1307 cpl_free(trace_wave_a_loc) ;
1308 }
1309 if (extract1D_a_loc != NULL) {
1310 *extract1D_1u_a = extract1D_a_loc[0] ;
1311 *extract1D_1d_a = extract1D_a_loc[1] ;
1312 *extract1D_2u_a = extract1D_a_loc[2] ;
1313 *extract1D_2d_a = extract1D_a_loc[3] ;
1314 *extract1D_3u_a = extract1D_a_loc[4] ;
1315 *extract1D_3d_a = extract1D_a_loc[5] ;
1316 *extract1D_4u_a = extract1D_a_loc[6] ;
1317 *extract1D_4d_a = extract1D_a_loc[7] ;
1318 cpl_free(extract1D_a_loc) ;
1319 }
1320 if (in_calib_b_loc != NULL) {
1321 *in_calib_1_b = in_calib_b_loc[0] ;
1322 *in_calib_2_b = in_calib_b_loc[1] ;
1323 *in_calib_3_b = in_calib_b_loc[2] ;
1324 *in_calib_4_b = in_calib_b_loc[3] ;
1325 cpl_free(in_calib_b_loc) ;
1326 }
1327 if (trace_wave_b_loc != NULL) {
1328 *trace_wave_1u_b = trace_wave_b_loc[0] ;
1329 *trace_wave_1d_b = trace_wave_b_loc[1] ;
1330 *trace_wave_2u_b = trace_wave_b_loc[2] ;
1331 *trace_wave_2d_b = trace_wave_b_loc[3] ;
1332 *trace_wave_3u_b = trace_wave_b_loc[4] ;
1333 *trace_wave_3d_b = trace_wave_b_loc[5] ;
1334 *trace_wave_4u_b = trace_wave_b_loc[6] ;
1335 *trace_wave_4d_b = trace_wave_b_loc[7] ;
1336 cpl_free(trace_wave_b_loc) ;
1337 }
1338 if (extract1D_b_loc != NULL) {
1339 *extract1D_1u_b = extract1D_b_loc[0] ;
1340 *extract1D_1d_b = extract1D_b_loc[1] ;
1341 *extract1D_2u_b = extract1D_b_loc[2] ;
1342 *extract1D_2d_b = extract1D_b_loc[3] ;
1343 *extract1D_3u_b = extract1D_b_loc[4] ;
1344 *extract1D_3d_b = extract1D_b_loc[5] ;
1345 *extract1D_4u_b = extract1D_b_loc[6] ;
1346 *extract1D_4d_b = extract1D_b_loc[7] ;
1347 cpl_free(extract1D_b_loc) ;
1348 }
1349 *pol_speca = pol_speca_loc ;
1350 *pol_specb = pol_specb_loc ;
1351 *ext_plista = ext_plista_loc ;
1352 *ext_plistb = ext_plistb_loc ;
1353 return 0 ;
1354}
1355
1356/*----------------------------------------------------------------------------*/
1383/*----------------------------------------------------------------------------*/
1384static int cr2res_obs_pol_reduce_one(
1385 const cpl_frameset * rawframes,
1386 const cpl_frameset * raw_background_frames,
1387 const cpl_frame * trace_wave_frame,
1388 const cpl_frame * detlin_frame,
1389 const cpl_frame * master_dark_frame,
1390 const cpl_frame * master_flat_frame,
1391 const cpl_frame * bpm_frame,
1392 const cpl_frame * blaze_frame,
1393 int subtract_nolight_rows,
1394 int subtract_interorder_column,
1395 int cosmics,
1396 int extract_oversample,
1397 int extract_swath_width,
1398 int extract_height,
1399 double extract_smooth_slit,
1400 double extract_smooth_spec,
1401 int save_group,
1402 int reduce_det,
1403 hdrl_image *** in_calib,
1404 cpl_table *** tw,
1405 cpl_table *** extract1D,
1406 cpl_table ** pol_spec,
1407 cpl_propertylist ** ext_plist)
1408{
1409 cpl_vector * dits ;
1410 cpl_vector * ndits ;
1411 cr2res_decker * decker_positions ;
1412 hdrl_imagelist * in ;
1413 hdrl_imagelist * in_calib_loc ;
1414 cpl_image * contrib;
1415 hdrl_image * backgr;
1416 cpl_table * blaze_table ;
1417 cpl_table * trace_wave ;
1418 //cpl_table * trace_wave_corrected ;
1419 cpl_table ** trace_wave_extract ;
1420 const char * fname ;
1421 char * decker_name ;
1422 cpl_table * slit_func ;
1423 hdrl_image * model_master ;
1424 hdrl_image ** input_images ;
1425 cpl_table ** pol_spec_one_group ;
1426 cpl_table ** extract_1d ;
1427 char * colname ;
1428 const double * pcol_data ;
1429 double * pvec_data ;
1430 cpl_vector ** intens ;
1431 cpl_vector ** wl ;
1432 cpl_vector ** errors ;
1433 cpl_vector ** demod_wl ;
1434 cpl_bivector ** demod_stokes ;
1435 cpl_bivector ** demod_null ;
1436 cpl_bivector ** demod_intens ;
1437 int * orders ;
1438 cpl_table * pol_spec_merged ;
1439 cpl_propertylist * plist ;
1440 cpl_propertylist * ext_plist_loc ;
1441 const char * first_fname ;
1442 cpl_size nframes, nspec_group, spec_size ;
1443 int ngroups, i, j, k, l, o, norders, frame_idx ;
1444 double gain, error_factor, blaze_norm ;
1445 int * order_idx_values ;
1446 int nb_order_idx_values, order_zp;
1447
1448 /* TODO, make parameters */
1449 int extract_niter = 10;
1450 double extract_kappa = 10;
1451
1452 /* Check Inputs */
1453 if (in_calib == NULL || tw == NULL || extract1D == NULL ||
1454 pol_spec == NULL || ext_plist == NULL || rawframes == NULL ||
1455 trace_wave_frame == NULL)
1456 return -1 ;
1457
1458 /* Initialise */
1459 *in_calib = NULL ;
1460 *tw = NULL ;
1461 *extract1D = NULL ;
1462 *pol_spec = NULL ;
1463 *ext_plist = NULL ;
1464 first_fname = cpl_frame_get_filename(
1465 cpl_frameset_get_position_const(rawframes, 0)) ;
1466
1467 /* Get the Gain */
1468 if (reduce_det == 1) gain = CR2RES_GAIN_CHIP1 ;
1469 else if (reduce_det == 2) gain = CR2RES_GAIN_CHIP2 ;
1470 else if (reduce_det == 3) gain = CR2RES_GAIN_CHIP3 ;
1471 else {
1472 cpl_msg_error(__func__, "Failed to get the Gain value") ;
1473 return -1 ;
1474 }
1475
1476 /* Get the order zeropoint */
1477 if ((plist = cpl_propertylist_load(cpl_frame_get_filename(trace_wave_frame),
1478 0)) == NULL) {
1479 cpl_msg_error(__func__, "Cannot read the ORDER_ZP from the input TW") ;
1480 return -1 ;
1481 }
1482 order_zp = cr2res_pfits_get_order_zp(plist) ;
1483 cpl_propertylist_delete(plist) ;
1484 if (cpl_error_get_code()) {
1485 cpl_msg_error(__func__, "Missing ORDER_ZP in the header - Skip") ;
1486 cpl_error_reset() ;
1487 /* Negative Zerop to log the fact that it is missing */
1488 order_zp = -100 ;
1489 }
1490
1491 /* Check number of frames */
1492 nframes = cpl_frameset_get_size(rawframes) ;
1493 if (nframes == 0 || nframes % CR2RES_POLARIMETRY_GROUP_SIZE) {
1494 cpl_msg_error(__func__,
1495 "Input number of frames is %"CPL_SIZE_FORMAT" and should be multiple of %d",
1496 nframes, CR2RES_POLARIMETRY_GROUP_SIZE) ;
1497 return -1 ;
1498 }
1499
1500 /* Load the DITs if necessary */
1501 if (master_dark_frame != NULL) dits = cr2res_io_read_dits(rawframes) ;
1502 else dits = NULL ;
1503 if (cpl_msg_get_level() == CPL_MSG_DEBUG && dits != NULL)
1504 cpl_vector_dump(dits, stdout) ;
1505
1506 /* Load the NDITs */
1507 ndits = cr2res_io_read_ndits(rawframes) ;
1508
1509 /* Set the error factor. Note that we don't multiply by 4 because */
1510 /* each the beams get extracted from each frame, then errors propagated on.*/
1511 error_factor = gain * cpl_vector_get(ndits, 0);
1512
1513 for (i=0; i<cpl_vector_get_size(ndits); i++){
1514 if (cpl_vector_get(ndits,i) != cpl_vector_get(ndits, 0))
1515 cpl_msg_warning(__func__, "Raw frames have different NDIT! "
1516 "Error spectrum will likely be scaled incorrectly.");
1517 }
1518
1519 /* Get the decker positions */
1520 if ((decker_positions = cr2res_io_read_decker_positions(rawframes))==NULL) {
1521 cpl_msg_error(__func__, "Cannot read the Decker positions") ;
1522 if (dits != NULL) cpl_vector_delete(dits) ;
1523 return -1 ;
1524 }
1525
1526 /* Load image list */
1527 cpl_msg_info(__func__, "Load the images") ;
1528 if ((in = cr2res_io_load_image_list_from_set(rawframes,
1529 reduce_det)) == NULL) {
1530 cpl_msg_error(__func__, "Cannot load images") ;
1531 if (dits != NULL) cpl_vector_delete(dits) ;
1532 if (ndits != NULL) cpl_vector_delete(ndits) ;
1533 cpl_free(decker_positions) ;
1534 return -1 ;
1535 }
1536 if (hdrl_imagelist_get_size(in) != cpl_frameset_get_size(rawframes)) {
1537 cpl_msg_error(__func__, "Inconsistent number of loaded images") ;
1538 if (dits != NULL) cpl_vector_delete(dits) ;
1539 if (ndits != NULL) cpl_vector_delete(ndits) ;
1540 cpl_free(decker_positions) ;
1542 return -1 ;
1543 }
1544
1545 /* Calibrate the images */
1546 cpl_msg_info(__func__, "Apply the calibrations") ;
1547 cpl_msg_indent_more() ;
1548 if ((in_calib_loc = cr2res_calib_imagelist(in, reduce_det, 0,
1549 subtract_nolight_rows, subtract_interorder_column, cosmics,
1550 master_flat_frame, master_dark_frame, bpm_frame, detlin_frame,
1551 dits, ndits))==NULL) {
1552 cpl_msg_error(__func__, "Failed to apply the calibrations") ;
1553 cpl_msg_indent_less() ;
1554 if (dits != NULL) cpl_vector_delete(dits) ;
1555 if (ndits != NULL) cpl_vector_delete(ndits) ;
1556 cpl_free(decker_positions) ;
1558 return -1 ;
1559 }
1560 cpl_msg_indent_less() ;
1562 if (dits != NULL) {
1563 cpl_vector_delete(dits) ;
1564 dits = NULL ;
1565 }
1566 if (ndits != NULL) cpl_vector_delete(ndits) ;
1567
1568 /* Apply Background Correction using the other nodding position */
1569 if (cpl_frameset_get_size(raw_background_frames) > 1 ) {
1570
1571 hdrl_imagelist * in_backgr ;
1572 cpl_msg_info(__func__, "Apply the background Correction") ;
1573 cpl_msg_indent_more() ;
1574
1575 /* Load image list for BACKGROUND frames */
1576 cpl_msg_info(__func__, "Load the background images") ;
1577 if ((in = cr2res_io_load_image_list_from_set(raw_background_frames,
1578 reduce_det)) == NULL) {
1579 cpl_msg_error(__func__, "Cannot load background images") ;
1580 cpl_msg_indent_less() ;
1581 cpl_free(decker_positions) ;
1582 hdrl_imagelist_delete(in_calib_loc) ;
1583 return -1 ;
1584 }
1585 /* Load the DITs & NDITs */
1586 if (master_dark_frame != NULL) dits = cr2res_io_read_dits(rawframes) ;
1587 else dits = NULL ;
1588 ndits = cr2res_io_read_ndits(rawframes) ;
1589
1590 /* Calibrate the background same as science images */
1591 cpl_msg_info(__func__, "Apply the calibrations to background") ;
1592 cpl_msg_indent_more() ;
1593 if ((in_backgr = cr2res_calib_imagelist(in, reduce_det, 0,
1594 subtract_nolight_rows, 1, cosmics, master_flat_frame,
1595 master_dark_frame, bpm_frame, detlin_frame,
1596 dits, ndits)) == NULL) {
1597 cpl_msg_error(__func__,
1598 "Failed to apply the calibrations to background") ;
1599 cpl_msg_indent_less() ;
1600 cpl_msg_indent_less() ;
1601 if (dits != NULL) cpl_vector_delete(dits) ;
1602 if (ndits != NULL) cpl_vector_delete(ndits) ;
1603 cpl_free(decker_positions) ;
1605 hdrl_imagelist_delete(in_calib_loc) ;
1606 return -1 ;
1607 }
1608 cpl_msg_indent_less() ;
1610
1611 /* Collapse background images */
1612 if (hdrl_imagelist_collapse_mean(in_backgr, &backgr, &contrib) != \
1613 CPL_ERROR_NONE) {
1614 cpl_msg_error(__func__, "Failed to collapse background") ;
1615 cpl_msg_indent_less() ;
1616 if (dits != NULL) cpl_vector_delete(dits) ;
1617 if (ndits != NULL) cpl_vector_delete(ndits) ;
1618 cpl_free(decker_positions) ;
1619 hdrl_imagelist_delete(in_calib_loc) ;
1620 hdrl_imagelist_delete(in_backgr) ;
1621 return -1;
1622 }
1623 if (contrib != NULL) cpl_image_delete(contrib) ;
1624 if (in_backgr != NULL) hdrl_imagelist_delete(in_backgr) ;
1625
1626 /* Subtract background from calibrated images */
1627 if (hdrl_imagelist_sub_image(in_calib_loc, backgr) != CPL_ERROR_NONE) {
1628 cpl_msg_error(__func__, "Failed to subtract background") ;
1629 cpl_msg_indent_less() ;
1630 if (dits != NULL) cpl_vector_delete(dits) ;
1631 if (ndits != NULL) cpl_vector_delete(ndits) ;
1632 cpl_free(decker_positions) ;
1633 hdrl_imagelist_delete(in_calib_loc);
1634 hdrl_image_delete(backgr);
1635 return -1;
1636 }
1637 hdrl_image_delete(backgr);
1638 cpl_msg_indent_less() ;
1639 } else {
1640 cpl_msg_warning(__func__, "No background subtraction");
1641 }
1642 if (dits != NULL) cpl_vector_delete(dits) ;
1643 if (ndits != NULL) cpl_vector_delete(ndits) ;
1644
1645 /* Load the trace wave */
1646 cpl_msg_info(__func__, "Load the TRACE WAVE") ;
1647 if ((trace_wave = cr2res_io_load_TRACE_WAVE(cpl_frame_get_filename(
1648 trace_wave_frame), reduce_det)) == NULL) {
1649 cpl_msg_error(__func__, "Failed to Load the traces file") ;
1650 cpl_free(decker_positions) ;
1651 hdrl_imagelist_delete(in_calib_loc) ;
1652 return -1 ;
1653 }
1654
1655 /* Correct trace_wave with some provided raw flats */
1656 cpl_msg_warning(__func__, "TRACE ADJUST NOT YET IMPLEMENTED") ;
1657 /*if (raw_flat_frames != NULL) {
1658 cpl_msg_info(__func__, "Try to correct the reproducibility error") ;
1659 cpl_msg_indent_more() ;
1660 trace_wave_corrected = cr2res_trace_adjust(trace_wave, raw_flat_frames,
1661 reduce_det) ;
1662 if (trace_wave_corrected != NULL) {
1663 cpl_table_delete(trace_wave) ;
1664 trace_wave = trace_wave_corrected ;
1665 trace_wave_corrected = NULL ;
1666 }
1667 cpl_msg_indent_less() ;
1668 }*/
1669
1670 /* Load Blaze */
1671 blaze_table = NULL ;
1672 blaze_norm = 0 ;
1673 if (blaze_frame != NULL) {
1674 cpl_msg_info(__func__, "Load the BLAZE") ;
1675 if ((blaze_table = cr2res_io_load_EXTRACT_1D(cpl_frame_get_filename(
1676 blaze_frame), reduce_det)) == NULL) {
1677 cpl_msg_error(__func__, "Failed to Load the Blaze file") ;
1678 cpl_free(decker_positions) ;
1679 hdrl_imagelist_delete(in_calib_loc) ;
1680 cpl_table_delete(trace_wave) ;
1681 return -1 ;
1682 }
1683 cpl_propertylist * blaze_plist ;
1684 blaze_plist = cpl_propertylist_load_regexp(cpl_frame_get_filename(
1685 blaze_frame),0,CR2RES_HEADER_QC_BLAZE_NORM,0);
1686 if(cpl_propertylist_get_size(blaze_plist)>0){
1687 blaze_norm = cpl_propertylist_get_double(blaze_plist, CR2RES_HEADER_QC_BLAZE_NORM);
1688 }
1689 else {
1690 blaze_norm = -1;
1691 cpl_msg_warning(__func__, "QC BLAZE NORM value not found, reverting to per trace normalization") ;
1692 }
1693 if(blaze_plist!=NULL){
1694 cpl_propertylist_delete(blaze_plist);
1695 }
1696 }
1697
1698 /* Compute the number of groups */
1699 ngroups = nframes/CR2RES_POLARIMETRY_GROUP_SIZE ;
1700 nspec_group = 2*CR2RES_POLARIMETRY_GROUP_SIZE ;
1701
1702 /* Allocate pol_spec_group containers */
1703 pol_spec_one_group = cpl_malloc(ngroups * sizeof(cpl_table*)) ;
1704 for (i = 0; i < ngroups; i++) pol_spec_one_group[i] = NULL;
1705
1706 /* Loop on the groups */
1707 for (i = 0; i < ngroups; i++) {
1708 int *pol_sorting;
1709 cpl_msg_info(__func__, "Process %d-group number %d/%d",
1710 CR2RES_POLARIMETRY_GROUP_SIZE, i+1, ngroups) ;
1711 cpl_msg_indent_more() ;
1712
1713 /* Compute the proper order of the frames group */
1714 if ((pol_sorting = cr2res_pol_sort_frames(
1715 cpl_frameset_get_position_const(rawframes,
1716 i * CR2RES_POLARIMETRY_GROUP_SIZE),
1717 cpl_frameset_get_position_const(rawframes,
1718 i * CR2RES_POLARIMETRY_GROUP_SIZE + 1),
1719 cpl_frameset_get_position_const(rawframes,
1720 i * CR2RES_POLARIMETRY_GROUP_SIZE + 2),
1721 cpl_frameset_get_position_const(rawframes,
1722 i * CR2RES_POLARIMETRY_GROUP_SIZE + 3))) == NULL) {
1723 cpl_msg_warning(__func__, "Failed to sort the files") ;
1724 continue ;
1725 }
1726 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1727 for (j=0 ; j<CR2RES_POLARIMETRY_GROUP_SIZE ; j++) {
1728 if (pol_sorting[j] != j)
1729 cpl_msg_warning(__func__,
1730 "Frame #%d moved to position #%d",
1731 j+1, pol_sorting[j]+1) ;
1732 }
1733 }
1734
1735 /* Container for the current group calibrated images 1 2 3 4 */
1736 input_images = cpl_malloc(CR2RES_POLARIMETRY_GROUP_SIZE *
1737 sizeof(hdrl_image*));
1738 for (j = 0; j < CR2RES_POLARIMETRY_GROUP_SIZE; j++)
1739 input_images[j] = NULL ;
1740
1741 /* Container for extracted tables: 1u, 1d, 2u, 2d, 3u, 3d, 4u, 4d */
1742 extract_1d = cpl_malloc(nspec_group * sizeof(cpl_table*));
1743 trace_wave_extract = cpl_malloc(nspec_group * sizeof(cpl_table*));
1744 for (j = 0; j < nspec_group; j++) {
1745 extract_1d[j] = NULL;
1746 trace_wave_extract[j] = NULL;
1747 }
1748
1749 /* Loop on the frames */
1750 for (j=0 ; j<CR2RES_POLARIMETRY_GROUP_SIZE ; j++) {
1751 frame_idx = i * CR2RES_POLARIMETRY_GROUP_SIZE + pol_sorting[j] ;
1752 fname = cpl_frame_get_filename(cpl_frameset_get_position_const(
1753 rawframes,frame_idx)) ;
1754
1755 /* Store the input image */
1756 input_images[j] = hdrl_image_duplicate(
1757 hdrl_imagelist_get_const(in_calib_loc, frame_idx)) ;
1758
1759 /* Extract up */
1760 decker_name = cr2res_decker_print_position(
1761 decker_positions[frame_idx]) ;
1762 cpl_msg_info(__func__,
1763 "Extract Up Spectrum from %s (Det %d / Decker %s)",
1764 fname, reduce_det, decker_name) ;
1765 cpl_free(decker_name) ;
1766 cpl_msg_indent_more();
1767
1768 trace_wave_extract[2 * j] = cr2res_pol_get_beam_trace(trace_wave, decker_positions[frame_idx], 1);
1769
1770 /* Execute the extraction */
1771 cpl_msg_info(__func__, "Spectra Extraction") ;
1772 if (cr2res_extract_traces(input_images[j], trace_wave_extract[2*j],
1773 NULL, blaze_table, blaze_norm, -1, -1, CR2RES_EXTR_OPT_CURV,
1774 extract_height, extract_swath_width, extract_oversample,
1775 extract_smooth_slit, extract_smooth_spec,
1776 extract_niter, extract_kappa, error_factor, 0, 0, 0,
1777 &(extract_1d[2*j]), &slit_func, &model_master) == -1) {
1778 cpl_msg_error(__func__, "Failed Extraction") ;
1779 extract_1d[2*j] = NULL ;
1780 cpl_table_delete(trace_wave_extract[2*j]) ;
1781 trace_wave_extract[2*j] = NULL ;
1782 } else {
1783 cpl_table_delete(slit_func) ;
1784 hdrl_image_delete(model_master) ;
1785 }
1786 cpl_msg_indent_less() ;
1787
1788 /* Extract Down */
1789 decker_name = cr2res_decker_print_position(
1790 decker_positions[frame_idx]) ;
1791 cpl_msg_info(__func__,
1792 "Extract Down Spectrum from %s (Det %d / Decker %s)",
1793 fname, reduce_det, decker_name) ;
1794 cpl_free(decker_name) ;
1795 cpl_msg_indent_more() ;
1796
1797 trace_wave_extract[2*j+1] = cr2res_pol_get_beam_trace(trace_wave, decker_positions[frame_idx], 2);
1798
1799 /* Execute the extraction */
1800 cpl_msg_info(__func__, "Spectra Extraction") ;
1801 if (cr2res_extract_traces(input_images[j],
1802 trace_wave_extract[2*j+1], NULL, blaze_table, blaze_norm, -1, -1,
1803 CR2RES_EXTR_OPT_CURV, extract_height,
1804 extract_swath_width, extract_oversample,
1805 extract_smooth_slit, extract_smooth_spec,
1806 extract_niter, extract_kappa, error_factor, 0, 0, 0,
1807 &(extract_1d[2*j+1]), &slit_func, &model_master)== -1) {
1808 cpl_msg_error(__func__, "Failed Extraction") ;
1809 extract_1d[2*j+1] = NULL ;
1810 cpl_table_delete(trace_wave_extract[2*j+1]) ;
1811 trace_wave_extract[2*j+1] = NULL ;
1812 } else {
1813 cpl_table_delete(slit_func) ;
1814 hdrl_image_delete(model_master) ;
1815 }
1816 cpl_msg_indent_less() ;
1817 }
1818 cpl_free(pol_sorting) ;
1819
1820 /* How many orders */
1821 if ((orders = cr2res_obs_pol_get_order_numbers(
1822 (const cpl_table **)extract_1d,
1823 nspec_group,
1824 &norders)) == NULL) {
1825 cpl_msg_warning(__func__, "No Order found in the extracted tables");
1826 for (j = 0; j < CR2RES_POLARIMETRY_GROUP_SIZE; j++) {
1827 hdrl_image_delete(input_images[j]) ;
1828 input_images[j] = NULL ;
1829 }
1830 cpl_free(input_images) ;
1831 for (j=0 ; j<nspec_group ; j++) {
1832 if (extract_1d[j] != NULL)
1833 cpl_table_delete(extract_1d[j]) ;
1834 if (trace_wave_extract[j] != NULL)
1835 cpl_table_delete(trace_wave_extract[j]) ;
1836 }
1837 cpl_free(extract_1d) ;
1838 cpl_free(trace_wave_extract) ;
1839 continue ;
1840 }
1841 cpl_msg_debug(__func__, "%d different orders found", norders) ;
1842
1843 /* Allocate data containers */
1844 demod_wl = cpl_malloc(norders * sizeof(cpl_vector*)) ;
1845 demod_stokes = cpl_malloc(norders * sizeof(cpl_bivector*)) ;
1846 demod_null = cpl_malloc(norders * sizeof(cpl_bivector*)) ;
1847 demod_intens = cpl_malloc(norders * sizeof(cpl_bivector*)) ;
1848 for (o = 0; o < norders; o++){
1849 demod_wl[o] = NULL;
1850 demod_stokes[o] = NULL;
1851 demod_null[o] = NULL;
1852 demod_intens[o] = NULL;
1853 }
1854
1855 intens = cpl_malloc(nspec_group * sizeof(cpl_vector*));
1856 wl = cpl_malloc(nspec_group * sizeof(cpl_vector*));
1857 errors = cpl_malloc(nspec_group * sizeof(cpl_vector*));
1858 for (k = 0; k < nspec_group; k++){
1859 intens[k] = NULL;
1860 wl[k] = NULL;
1861 errors[k] = NULL;
1862 }
1863
1864 /* Loop on the orders */
1865 for (o=0 ; o<norders ; o++) {
1866 cpl_msg_info(__func__, "Compute Polarimetry for order %d",
1867 orders[o]) ;
1868 /* Get the inputs for the demod functions calls */
1869 for (k=0 ; k<nspec_group ; k++) {
1870 spec_size = cpl_table_get_nrow(extract_1d[k]) ;
1871 /* Get the SPEC for this order/trace 1 */
1872 colname = cr2res_dfs_SPEC_colname(orders[o], 1) ;
1873 if (cpl_table_has_valid(extract_1d[k], colname)){
1874 if ((pcol_data = cpl_table_get_data_double_const(
1875 extract_1d[k], colname)) == NULL) {
1876 cpl_error_reset() ;
1877 } else {
1878 intens[k] = cpl_vector_new(spec_size) ;
1879 pvec_data = cpl_vector_get_data(intens[k]) ;
1880 for (l=0 ; l<spec_size ; l++)
1881 pvec_data[l] = pcol_data[l] ;
1882 }
1883 }
1884 cpl_free(colname) ;
1885
1886 /* Get the WAVELENGTH for this order/trace 1 */
1887 colname = cr2res_dfs_WAVELENGTH_colname(orders[o], 1) ;
1888 if (cpl_table_has_valid(extract_1d[k], colname)){
1889 if ((pcol_data = cpl_table_get_data_double_const(
1890 extract_1d[k], colname)) == NULL) {
1891 cpl_error_reset() ;
1892 } else {
1893 wl[k] = cpl_vector_new(spec_size) ;
1894 pvec_data = cpl_vector_get_data(wl[k]) ;
1895 for (l=0 ; l<spec_size ; l++)
1896 pvec_data[l] = pcol_data[l] ;
1897 }
1898 }
1899 cpl_free(colname) ;
1900
1901 /* Get the ERROR for this order/trace 1 */
1902 colname = cr2res_dfs_SPEC_ERR_colname(orders[o], 1) ;
1903 if (cpl_table_has_valid(extract_1d[k], colname)){
1904 if ((pcol_data = cpl_table_get_data_double_const(
1905 extract_1d[k], colname)) == NULL) {
1906 cpl_error_reset() ;
1907 } else {
1908 errors[k] = cpl_vector_new(spec_size) ;
1909 pvec_data = cpl_vector_get_data(errors[k]) ;
1910 for (l=0 ; l<spec_size ; l++)
1911 pvec_data[l] = pcol_data[l] ;
1912 }
1913 }
1914 cpl_free(colname) ;
1915 }
1916
1917 /* Keep the 1st wl of the 8 as reference for the output file*/
1918 if (wl[0] != NULL) demod_wl[o] = cpl_vector_duplicate(wl[0]) ;
1919 else demod_wl[o] = NULL ;
1920
1921 /* Call Library Demodulation functions */
1922 demod_stokes[o] = cr2res_pol_demod_stokes(intens, wl, errors,
1923 nspec_group) ;
1924 demod_null[o] = cr2res_pol_demod_null(intens, wl, errors,
1925 nspec_group) ;
1926 demod_intens[o] = cr2res_pol_demod_intens(intens, wl, errors,
1927 nspec_group) ;
1928
1929 /* Free */
1930 for (k=0 ; k<nspec_group ; k++) {
1931 if (intens[k] != NULL) {
1932 cpl_vector_delete(intens[k]) ;
1933 intens[k] = NULL;
1934 }
1935 if (wl[k] != NULL) {
1936 cpl_vector_delete(wl[k]) ;
1937 wl[k] = NULL;
1938 }
1939 if (errors[k] != NULL) {
1940 cpl_vector_delete(errors[k]) ;
1941 errors[k] = NULL;
1942 }
1943 }
1944 }
1945 cpl_free(intens) ;
1946 cpl_free(wl) ;
1947 cpl_free(errors) ;
1948
1949 /* Save the extra products for this group */
1950 if (i+1==save_group) {
1951 *in_calib = input_images ;
1952 *tw = trace_wave_extract ;
1953 *extract1D = extract_1d ;
1954 } else {
1955 /* Free the input images */
1956 for (j = 0; j < CR2RES_POLARIMETRY_GROUP_SIZE; j++)
1957 if (input_images[j] != NULL)
1958 hdrl_image_delete(input_images[j]) ;
1959 cpl_free(input_images) ;
1960 /* Free the extracted tables / the TW */
1961 for (j=0 ; j<nspec_group ; j++) {
1962 if (trace_wave_extract[j] != NULL)
1963 cpl_table_delete(trace_wave_extract[j]) ;
1964 if (extract_1d[j] != NULL) cpl_table_delete(extract_1d[j]) ;
1965 }
1966 cpl_free(trace_wave_extract) ;
1967 cpl_free(extract_1d) ;
1968 }
1969
1970 /* Create the pol_spec table */
1971 cpl_msg_info(__func__, "Create the POL_SPEC table for this group");
1972 pol_spec_one_group[i] = cr2res_pol_POL_SPEC_create(orders, demod_wl,
1973 demod_stokes, demod_null, demod_intens, norders) ;
1974
1975 /* Deallocate */
1976 for (o=0 ; o<norders ; o++) {
1977 if (demod_wl[o] != NULL) cpl_vector_delete(demod_wl[o]) ;
1978 if (demod_stokes[o] != NULL) cpl_bivector_delete(demod_stokes[o]) ;
1979 if (demod_null[o] != NULL) cpl_bivector_delete(demod_null[o]) ;
1980 if (demod_intens[o] != NULL) cpl_bivector_delete(demod_intens[o]) ;
1981 }
1982 cpl_free(demod_wl) ;
1983 cpl_free(demod_stokes) ;
1984 cpl_free(demod_null) ;
1985 cpl_free(demod_intens) ;
1986 cpl_free(orders) ;
1987 cpl_msg_indent_less() ;
1988 }
1989 if (blaze_table != NULL) cpl_table_delete(blaze_table) ;
1990 cpl_free(decker_positions) ;
1991 hdrl_imagelist_delete(in_calib_loc) ;
1992
1993 /* Merge the groups together */
1994 if (ngroups > 1) {
1995 cpl_msg_info(__func__, "Merge the %d groups POL_SPEC tables into one",
1996 ngroups);
1997 pol_spec_merged = cr2res_pol_spec_pol_merge(
1998 (const cpl_table **)pol_spec_one_group, ngroups) ;
1999 } else {
2000 if (pol_spec_one_group[0] == NULL) {
2001 pol_spec_merged = NULL ;
2002 } else {
2003 pol_spec_merged = cpl_table_duplicate(pol_spec_one_group[0]) ;
2004 }
2005 }
2006
2007 /* Deallocate */
2008 for (i=0 ; i<ngroups ; i++) cpl_table_delete(pol_spec_one_group[i]) ;
2009 cpl_free(pol_spec_one_group) ;
2010
2011 /* Check */
2012 if (pol_spec_merged == NULL) {
2013 cpl_msg_error(__func__, "Cannot create the POL_SPEC table");
2014 cpl_table_delete(trace_wave) ;
2015 for (j=0 ; j<nspec_group ; j++) {
2016 cpl_table **temp_extract1D = extract1D[j];
2017 if (temp_extract1D != NULL && *temp_extract1D != NULL)
2018 cpl_table_delete(*temp_extract1D);
2019 cpl_table **temp_tw = tw[j];
2020 if (temp_tw != NULL && *temp_tw != NULL)
2021 cpl_table_delete(*temp_tw) ;
2022 }
2023 cpl_free(*tw) ; *tw = NULL ;
2024 cpl_free(*extract1D) ; *extract1D = NULL ;
2025 return -1 ;
2026 }
2027
2028 /* Store the extension header for product saving */
2029 ext_plist_loc = cpl_propertylist_load(first_fname,
2030 cr2res_io_get_ext_idx(first_fname, reduce_det, 1)) ;
2031
2032 cpl_msg_info(__func__,"Order zero-point: %d", order_zp );
2033 /* Real Orders in QCs */
2034 if (order_zp > 0) {
2035 /* Get the order numbers from the TW rows */
2036 order_idx_values = cr2res_trace_get_order_idx_values(trace_wave,
2037 &nb_order_idx_values);
2038 /* Compute the Real Order numbers and store them in QCs */
2039 for (i = 0; i < nb_order_idx_values; i++) {
2040 char *key_name;
2041 char *spec_name;
2042 char *err_name;
2043 cpl_vector *spec_vec;
2044 cpl_vector *err_vec;
2045 double snr;
2046 int order_real, order_idx, order_idxp;
2047 order_idx = order_idx_values[i] ;
2048 order_idxp = cr2res_io_convert_order_idx_to_idxp(order_idx) ;
2049 order_real = cr2res_order_idx_to_real(order_idx, order_zp) ;
2050 key_name = cpl_sprintf(CR2RES_HEADER_QC_REAL_ORDER, order_idxp) ;
2051 cpl_propertylist_append_int(ext_plist_loc, key_name, order_real) ;
2052 cpl_free(key_name) ;
2053
2054 /* Compute SNR and store QC*/
2055 key_name = cpl_sprintf(CR2RES_HEADER_QC_SNR, order_idxp);
2056 spec_name = cr2res_dfs_POL_INTENS_colname(order_idxp);
2057 err_name = cr2res_dfs_POL_INTENS_ERROR_colname(order_idxp);
2058
2059 spec_vec = cpl_vector_wrap(cpl_table_get_nrow(pol_spec_merged),
2060 cpl_table_get_data_double(pol_spec_merged, spec_name));
2061 err_vec = cpl_vector_wrap(cpl_table_get_nrow(pol_spec_merged),
2062 cpl_table_get_data_double(pol_spec_merged, err_name));
2063 snr = cr2res_qc_compute_snr(spec_vec, err_vec);
2064 cpl_propertylist_append_double(ext_plist_loc, key_name, snr);
2065
2066 cpl_vector_unwrap(spec_vec);
2067 cpl_vector_unwrap(err_vec);
2068 cpl_free(key_name);
2069 cpl_free(spec_name) ;
2070 cpl_free(err_name) ;
2071 }
2072 cpl_free(order_idx_values) ;
2073 }
2074 cpl_table_delete(trace_wave) ;
2075
2076 /* Return */
2077 *pol_spec = pol_spec_merged ;
2078 *ext_plist = ext_plist_loc ;
2079 return 0 ;
2080}
2081
2082/*----------------------------------------------------------------------------*/
2093/*----------------------------------------------------------------------------*/
2094static int * cr2res_obs_pol_get_order_numbers(
2095 const cpl_table ** extracted,
2096 int next,
2097 int * norders)
2098{
2099 const char * col_name ;
2100 char * col_type ;
2101 int * tmp_orders_list ;
2102 int count_orders ;
2103 int * out_orders ;
2104 cpl_size j;
2105 int i, k, order, trace_nb, max_possible_spectra, new_order ;
2106
2107 /* Check entries */
2108 if (extracted == NULL || norders == NULL) return NULL ;
2109 for (i=0 ; i<next ; i++)
2110 if (extracted[i] == NULL) return NULL ;
2111
2112 /* Initialize */
2113 max_possible_spectra = 1000 ;
2114
2115 /* Allocate orders list */
2116 tmp_orders_list = cpl_malloc(max_possible_spectra * sizeof(int)) ;
2117
2118 /* Count the different orders */
2119 count_orders = 0 ;
2120 /* Loop over all columns */
2121 for (i = 0; i < next; i++) {
2122 cpl_size ncols;
2123 cpl_array *col_names;
2124 col_names = cpl_table_get_column_names(extracted[i]);
2125 ncols = cpl_table_get_ncol(extracted[i]) ;
2126 for (j=0 ; j<ncols ; j++) {
2127 col_name = cpl_array_get_string(col_names, j);
2128 col_type = cr2res_dfs_SPEC_colname_parse(col_name, &order,
2129 &trace_nb) ;
2130 if (col_type != NULL && !strcmp(col_type, CR2RES_COL_SPEC_SUFFIX)) {
2131 /* Is the current order a new one ? */
2132 new_order = 1 ;
2133 for (k=0 ; k<count_orders ; k++)
2134 if (tmp_orders_list[k] == order)
2135 new_order = 0 ;
2136
2137 /* Current order not yet stored */
2138 if (new_order) {
2139 tmp_orders_list[count_orders] = order ;
2140 count_orders ++ ;
2141 }
2142 }
2143 if (col_type != NULL) cpl_free(col_type) ;
2144 }
2145 cpl_array_delete(col_names) ;
2146 }
2147
2148 /* Allocate and fill output array */
2149 out_orders = cpl_malloc(count_orders * sizeof(int)) ;
2150 for (i=0 ; i<count_orders ; i++) out_orders[i] = tmp_orders_list[i] ;
2151
2152 /* Free and return */
2153 cpl_free(tmp_orders_list) ;
2154 *norders = count_orders ;
2155 return out_orders ;
2156}
2157
2158/*----------------------------------------------------------------------------*/
2165/*----------------------------------------------------------------------------*/
2166static int cr2res_obs_pol_check_inputs_validity(
2167 const cpl_frameset * rawframes,
2168 cpl_size * ngroups)
2169{
2170 cr2res_nodding_pos * nod_positions ;
2171 cpl_frameset * raw_a ;
2172 cpl_frameset * raw_b ;
2173 cpl_size nframes, nframes_a, nframes_b, i ;
2174
2175 /* Check Inputs */
2176 if (rawframes == NULL || ngroups == NULL) return -1 ;
2177 nframes = cpl_frameset_get_size(rawframes) ;
2178
2179 /* Check that the MJD-OBS is increasing (only when several frames) */
2180 if (nframes > 1) {
2181 cpl_propertylist *plist;
2182 cpl_frame *cur_frame;
2183 const char *cur_fname;
2184 double mjd_obs_previous;
2185 /* Get the first MJDOBS */
2186 cur_frame = cpl_frameset_get_position((cpl_frameset*)rawframes, 0) ;
2187 cur_fname = cpl_frame_get_filename(cur_frame);
2188 plist = cpl_propertylist_load(cur_fname, 0) ;
2189 mjd_obs_previous = cr2res_pfits_get_mjd_obs(plist) ;
2190 cpl_propertylist_delete(plist) ;
2191 if (cpl_error_get_code() != CPL_ERROR_NONE) {
2192 cpl_msg_error(__func__, "Cannot access MJD-OBS") ;
2193 return -1 ;
2194 }
2195 /* Loop on the n-1 last frames */
2196 for (i=1 ; i<nframes ; i++) {
2197 double mjd_obs;
2198 /* Get the current MJDOBS */
2199 cur_frame = cpl_frameset_get_position((cpl_frameset*)rawframes, i) ;
2200 cur_fname = cpl_frame_get_filename(cur_frame);
2201 plist = cpl_propertylist_load(cur_fname, 0) ;
2202 mjd_obs = cr2res_pfits_get_mjd_obs(plist) ;
2203 cpl_propertylist_delete(plist) ;
2204 if (cpl_error_get_code() != CPL_ERROR_NONE) {
2205 cpl_msg_error(__func__, "Cannot access MJD-OBS") ;
2206 return -1 ;
2207 }
2208 if (mjd_obs <= mjd_obs_previous) {
2209 cpl_msg_error(__func__, "Rawframes MJD-OBS is not increasing") ;
2210 return 0 ;
2211 }
2212 mjd_obs_previous = mjd_obs ;
2213 }
2214 }
2215
2216 /* Get the nodding positions */
2217 nod_positions = cr2res_nodding_read_positions(rawframes) ;
2218 if (nod_positions == NULL) {
2219 cpl_msg_error(__func__, "Cannot read nodding positions") ;
2220 return -1 ;
2221 }
2222 if (cpl_msg_get_level() == CPL_MSG_DEBUG)
2223 for (i=0 ; i<nframes ; i++)
2224 cpl_msg_debug(__func__, "Frame %s - Nodding %c",
2225 cpl_frame_get_filename(
2226 cpl_frameset_get_position_const(rawframes,i)),
2227 cr2res_nodding_position_char(nod_positions[i])) ;
2228
2229 /* Split the frames */
2230 if (cr2res_combine_nodding_split_frames(rawframes, nod_positions,
2231 &raw_a, &raw_b)) {
2232 cpl_msg_error(__func__, "Cannot split the nodding positions") ;
2233 cpl_free(nod_positions) ;
2234 return -1 ;
2235 }
2236 cpl_free(nod_positions) ;
2237
2238 /* Check the sizes of A and B */
2239 nframes_a = cpl_frameset_get_size(raw_a) ;
2240 nframes_b = cpl_frameset_get_size(raw_b) ;
2241 if (nframes_a != nframes_b) {
2242 cpl_msg_error(__func__, "Number of A and B positions differ") ;
2243 cpl_frameset_delete(raw_a);
2244 cpl_frameset_delete(raw_b);
2245 return 0 ;
2246 }
2247 cpl_frameset_delete(raw_a);
2248 cpl_frameset_delete(raw_b);
2249
2250 /* number of frames must be modulo 4 */
2251 if (nframes_a % CR2RES_POLARIMETRY_GROUP_SIZE) {
2252 cpl_msg_error(__func__, "Require a multiple of 4 raw frames") ;
2253 return 0 ;
2254 }
2255
2256 /* Return */
2257 *ngroups = nframes_a/CR2RES_POLARIMETRY_GROUP_SIZE ;
2258 return 1 ;
2259}
2260
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)
The images calibration routine for a given chip on a list.
Definition: cr2res_calib.c:71
char * cr2res_dfs_SPEC_ERR_colname(int order_idx, int trace)
Get the ERR column name for a given order/trace.
Definition: cr2res_dfs.c:414
char * cr2res_dfs_POL_INTENS_ERROR_colname(int order_idx)
Get the POL_INTENS_ERROR column name for a given order.
Definition: cr2res_dfs.c:306
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
char * cr2res_dfs_WAVELENGTH_colname(int order_idx, int trace)
Get the WAVELENGTH column name for a given order/trace.
Definition: cr2res_dfs.c:396
char * cr2res_dfs_SPEC_colname_parse(const char *colname, int *order_idx, int *trace)
Parse a column name ORDER_TRACE_TYPE format.
Definition: cr2res_dfs.c:505
char * cr2res_dfs_POL_INTENS_colname(int order_idx)
Get the POL_INTENS column name for a given order.
Definition: cr2res_dfs.c:290
char * cr2res_dfs_SPEC_colname(int order_idx, int trace)
Get the SPEC column name for a given order/trace.
Definition: cr2res_dfs.c:378
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 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:82
cpl_table * cr2res_io_load_EXTRACT_1D(const char *filename, int detector)
Load a table from a EXTRACT_1D.
Definition: cr2res_io.c:1296
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
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
int cr2res_io_convert_order_idx_to_idxp(int order_idx)
Convert the order_idx to the order_idxp.
Definition: cr2res_io.c:583
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:1732
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:808
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:644
int cr2res_io_save_CALIBRATED(const char *filename, cpl_frameset *allframes, cpl_frameset *inframes, const cpl_parameterlist *parlist, hdrl_image **calib_collapsed, const cpl_propertylist *qc_list, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save a CALIBRATED frame.
Definition: cr2res_io.c:1608
cr2res_decker * cr2res_io_read_decker_positions(const cpl_frameset *in)
Get the decker positions from a frame set.
Definition: cr2res_io.c:491
cpl_table * cr2res_io_load_TRACE_WAVE(const char *filename, int detector)
Load a table from a TRACE_WAVE.
Definition: cr2res_io.c:1109
cpl_vector * cr2res_io_read_ndits(const cpl_frameset *in)
Get the NDITs from a frame set.
Definition: cr2res_io.c:462
int cr2res_io_save_POL_SPEC(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 Polarimetry spectrum.
Definition: cr2res_io.c:2039
double cr2res_pfits_get_mjd_obs(const cpl_propertylist *plist)
find out the MJD-OBS value
Definition: cr2res_pfits.c:217
cpl_bivector * cr2res_pol_demod_intens(cpl_vector **intens, cpl_vector **wl, cpl_vector **errors, int n)
Combine extracted spectra into Intensity spectrum.
Definition: cr2res_pol.c:528
cpl_table * cr2res_pol_POL_SPEC_create(int *orders, cpl_vector **wl, cpl_bivector **stokes, cpl_bivector **null, cpl_bivector **intens, int norders)
Create the POL_SPEC table to be saved.
Definition: cr2res_pol.c:696
cpl_table * cr2res_pol_spec_pol_merge(const cpl_table **pol_spec_list, int pol_spec_nb)
Merge several POL_SPEC tables together, by averaging.
Definition: cr2res_pol.c:915
int * cr2res_pol_sort_frames(const cpl_frame *frame1, const cpl_frame *frame2, const cpl_frame *frame3, const cpl_frame *frame4)
Compute the positions of the passed frames.
Definition: cr2res_pol.c:833
cpl_table * cr2res_pol_get_beam_trace(const cpl_table *tw_in, cr2res_decker decker_position, int up_or_down)
Compute the traces for the polarimetric beams.
Definition: cr2res_pol.c:970
cpl_bivector * cr2res_pol_demod_stokes(cpl_vector **intens, cpl_vector **wl, cpl_vector **errors, int n)
Demodulate extracted spectra into Stokes parameter.
Definition: cr2res_pol.c:106
cpl_bivector * cr2res_pol_demod_null(cpl_vector **intens, cpl_vector **wl, cpl_vector **errors, int n)
Demodulate extracted spectra into Null spectrum.
Definition: cr2res_pol.c:410
int cr2res_qc_numsat(const cpl_frameset *frameset)
Calculate the number of saturated pixels.
Definition: cr2res_qc.c:1183
double cr2res_qc_compute_snr(cpl_vector *spec, cpl_vector *err)
Computes the SNR of one spectrum.
Definition: cr2res_qc.c:1065
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.
Definition: cr2res_trace.c:431
char * cr2res_decker_print_position(cr2res_decker dpos)
Get the decker position string for display.
int cr2res_order_idx_to_real(int order_idx, int order_zp)
Convert the order_idx into order_real.
Definition: cr2res_utils.c:89
int cr2res_combine_nodding_split_frames(const cpl_frameset *in, const cr2res_nodding_pos *positions, cpl_frameset **pos_a, cpl_frameset **pos_b)
Split A/B positions in 2 framesets.
char cr2res_nodding_position_char(cr2res_nodding_pos pos)
Get the nodding position character for display.
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_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 ...
hdrl_image * hdrl_image_duplicate(const hdrl_image *himg)
copy hdrl_image
Definition: hdrl_image.c:391
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.
void hdrl_imagelist_delete(hdrl_imagelist *himlist)
Free all memory used by a hdrl_imagelist object including the images.
const hdrl_image * hdrl_imagelist_get_const(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of 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_image(hdrl_imagelist *himlist, const hdrl_image *himg)
Subtract an image from an image list.