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