33#include "kmclipm_constants.h"
34#include "kmclipm_functions.h"
37#include "kmo_constants.h"
38#include "kmo_cpl_extensions.h"
39#include "kmo_priv_lcorr.h"
43#include "kmos_pfits.h"
44#include "kmo_functions.h"
45#include "kmo_priv_make_image.h"
47#include "kmo_priv_arithmetic.h"
48#include "kmo_priv_combine.h"
49#include "kmo_priv_functions.h"
50#include "kmo_priv_reconstruct.h"
51#include "kmos_priv_sky_tweak.h"
56static kmclipm_vector * kmo_tweak_load_telluric(
57 cpl_frameset * frameset,
61 const char * telluric_tag,
62 int * ifu_nr_telluric) ;
64static int kmos_sci_red_propagate_qc(
65 const cpl_propertylist * main_input,
66 cpl_propertylist * to_update,
67 const cpl_frame * inframe,
70static double kmos_sci_red_get_f0(
const char *,
int,
double,
double) ;
71static double kmos_sci_red_get_zpoint(cpl_frame *,
int) ;
72static int kmos_sci_red_check_inputs(cpl_frameset *,
double,
int *,
const char *);
74static int kmos_sci_red_create(cpl_plugin *);
75static int kmos_sci_red_exec(cpl_plugin *);
76static int kmos_sci_red_destroy(cpl_plugin *);
77static int kmos_sci_red(cpl_parameterlist *, cpl_frameset *);
83static char kmos_sci_red_description[] =
84"Two data frames are expected in order to have a sky IFU for the IFU Objects.\n"
85"If an OH spectrum is given in the SOF file the lambda axis will be corrected\n"
86"using the OH lines as reference.\n"
87"Every IFU containing an object will be reconstructed and divided by telluric\n"
88"and illumination correction. By default these intermediate cubes are saved\n"
89"to disk. The reconstructed objects with the same object name are combined.\n"
90"In order to combine a specific object, the parameters --name or --ifus can\n"
92"For exposures taken with the templates KMOS_spec_obs_mapping8 and\n"
93"KMOS_spec_obs_mapping24, all active IFUs are combined.\n"
95"--------------------------------------------------------------------------\n"
99" category Type Explanation Required #Frames\n"
100" -------- ----- ----------- -------- -------\n"
101" SCIENCE RAW The science frames Y >=1 \n"
102"or LEVEL_CORRECTED RAW The science frames Y >=1 \n"
103" XCAL F2D x calibration frame Y 1 \n"
104" YCAL F2D y calibration frame Y 1 \n"
105" LCAL F2D Wavelength calib. frame Y 1 \n"
106" WAVE_BAND F2L Table with start-/end-wavelengths Y 1 \n"
107" MASTER_FLAT F2D Master flat Y 0,1 \n"
108" BADPIXEL_DARK B2D Bad pixels frame N 0,1 \n"
109" ILLUM_CORR F2I Illumination correction N 0,1 \n"
110" TELLURIC F1I normalised telluric spectrum N 0,1 \n"
111" TELLURIC_GEN F1I normalised telluric spectrum N 0,1 \n"
112" OH_SPEC F1S Vector holding OH lines N 0,1 \n"
117" category Type Explanation\n"
118" -------- ----- -----------\n"
119" SCI_COMBINED F3I Combined cubes with noise\n"
120" SCI_RECONSTRUCTED F3I Reconstructed cube with noise\n"
121" EXP_MASK F3I Exposure time mask (not for mapping-templates!)\n"
122" SCI_INTERIM_OBJECT F3I (optional) Intermediate reconstructed object \n"
123" cubes used for sky tweaking, no noise \n"
124" (set --sky_tweak and --save_interims)\n"
125" SCI_INTERIM_SKY F3I (optional) Intermediate reconstructed sky \n"
126" cubes used for sky tweaking, no noise\n"
127" (set --sky_tweak and --save_interims)\n"
128" SCI_COMBINED_COLL (optional) Collapsed combined cube\n"
129" (set --collapse_combined)\n"
130" SCI_RECONSTRUCTED_COLL (optional) Collapsed reconstructed cube\n"
131" (set --collapse_reconstructed)\n"
132"--------------------------------------------------------------------------\n"
160 cpl_recipe *recipe = cpl_calloc(1,
sizeof *recipe);
161 cpl_plugin *plugin = &recipe->interface;
163 cpl_plugin_init(plugin,
166 CPL_PLUGIN_TYPE_RECIPE,
168 "Reconstruct obj/sky-pairs individually and combine "
170 kmos_sci_red_description,
171 "Alex Agudo Berbel, Yves Jung",
172 "https://support.eso.org/",
176 kmos_sci_red_destroy);
178 cpl_pluginlist_append(list, plugin);
192static int kmos_sci_red_create(cpl_plugin *plugin)
198 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
199 recipe = (cpl_recipe *)plugin;
204 recipe->parameters = cpl_parameterlist_new();
207 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.lcmethod", CPL_TYPE_STRING,
208 "Method to use for the level correction "
209 "[\"NONE\" (no correction), "
210 "\"OSCAN\" (overscan), "
211 "\"SLICES_MEAN\" (intra slices with average), "
212 "\"SLICES_MEDIAN\" (intra slices with median)]",
213 "kmos.kmos_sci_red",
"NONE");
214 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"lcmethod");
215 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
216 cpl_parameterlist_append(recipe->parameters, p);
219 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.imethod", CPL_TYPE_STRING,
220 "Method to use for interpolation during reconstruction. "
221 "[\"NN\" (nearest neighbour), "
222 "\"lwNN\" (linear weighted nearest neighbor), "
223 "\"swNN\" (square weighted nearest neighbor), "
224 "\"MS\" (Modified Shepard's method)"
225 "\"CS\" (Cubic spline)]",
226 "kmos.kmos_sci_red",
"CS");
227 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"imethod");
228 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
229 cpl_parameterlist_append(recipe->parameters, p);
232 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.smethod", CPL_TYPE_STRING,
233 "Method to use for interpolation during shifting. "
234 "[\"NN\" (nearest neighbour), "
235 "\"CS\" (Cubic spline)]",
236 "kmos.kmos_sci_red",
"CS");
237 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"smethod");
238 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
239 cpl_parameterlist_append(recipe->parameters, p);
242 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.method", CPL_TYPE_STRING,
243 "The shifting method: "
244 "'none': no shifting, combined directly, "
245 "'header': shift according to WCS (default), "
246 "'center': centering algorithm, "
247 "'user': read shifts from file",
248 "kmos.kmos_sci_red",
"header");
249 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"method");
250 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
251 cpl_parameterlist_append(recipe->parameters, p);
254 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.fmethod", CPL_TYPE_STRING,
255 "The fitting method (applies only when method='center'): "
256 "'gauss': fit a gauss function to collapsed image (default), "
257 "'moffat': fit a moffat function to collapsed image",
258 "kmos.kmos_sci_red",
"gauss");
259 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"fmethod");
260 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
261 cpl_parameterlist_append(recipe->parameters, p);
264 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.name", CPL_TYPE_STRING,
265 "Name of the object to combine.",
"kmos.kmos_sci_red",
"");
266 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"name");
267 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
268 cpl_parameterlist_append(recipe->parameters, p);
271 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.ifus", CPL_TYPE_STRING,
272 "The indices of the IFUs to combine. \"ifu1;ifu2;...\"",
273 "kmos.kmos_sci_red",
"");
274 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ifus");
275 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
276 cpl_parameterlist_append(recipe->parameters, p);
279 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.pix_scale", CPL_TYPE_DOUBLE,
280 "Change the pixel scale [arcsec]. "
281 "Default of 0.2\" results into cubes of 14x14pix, "
282 "a scale of 0.1\" results into cubes of 28x28pix, etc.",
283 "kmos.kmos_sci_red", KMOS_PIX_RESOLUTION);
284 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"pix_scale");
285 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
286 cpl_parameterlist_append(recipe->parameters, p);
289 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.suppress_extension",
291 "Suppress arbitrary filename extension."
292 "(TRUE (apply) or FALSE (don't apply)",
293 "kmos.kmos_sci_red", FALSE);
294 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"suppress_extension");
295 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
296 cpl_parameterlist_append(recipe->parameters, p);
299 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.neighborhoodRange",
301 "Defines the range to search for neighbors in pixels",
302 "kmos.kmos_sci_red", 1.001);
303 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"neighborhoodRange");
304 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
305 cpl_parameterlist_append(recipe->parameters, p);
308 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.filename", CPL_TYPE_STRING,
309 "The path to the file with the shift vectors."
310 "(Applies only to method='user')",
311 "kmos.kmos_sci_red",
"");
312 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"filename");
313 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
314 cpl_parameterlist_append(recipe->parameters, p);
317 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.flux", CPL_TYPE_BOOL,
318 "TRUE: Apply flux conservation. FALSE: otherwise",
319 "kmos.kmos_sci_red", FALSE);
320 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"flux");
321 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
322 cpl_parameterlist_append(recipe->parameters, p);
325 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.background", CPL_TYPE_BOOL,
326 "TRUE: Apply background removal. FALSE: otherwise",
327 "kmos.kmos_sci_red", FALSE);
328 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"background");
329 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
330 cpl_parameterlist_append(recipe->parameters, p);
333 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.fast_mode", CPL_TYPE_BOOL,
334 "FALSE: cubes are shifted and combined,"
335 "TRUE: cubes are collapsed and then shifted and combined",
336 "kmos.kmos_sci_red", FALSE);
337 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"fast_mode");
338 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
339 cpl_parameterlist_append(recipe->parameters, p);
342 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.extrapolate", CPL_TYPE_BOOL,
343 "Applies only to 'smethod=CS' when doing sub-pixel shifts: "
344 "FALSE: shifted IFU will be filled with NaN's at the borders,"
345 "TRUE: shifted IFU will be extrapolated at the borders",
346 "kmos.kmos_sci_red", FALSE);
347 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extrapolate");
348 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
349 cpl_parameterlist_append(recipe->parameters, p);
352 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.xcal_interpolation",
354 "TRUE: Interpolate xcal between rotator angles. FALSE: otherwise",
355 "kmos.kmos_sci_red", TRUE);
356 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"xcal_interpolation");
357 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
358 cpl_parameterlist_append(recipe->parameters, p);
361 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.edge_nan", CPL_TYPE_BOOL,
362 "Set borders of cubes to NaN before combining them."
363 "(TRUE (apply) or FALSE (don't apply)",
364 "kmos.kmos_sci_red", FALSE);
365 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"edge_nan");
366 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
367 cpl_parameterlist_append(recipe->parameters, p);
370 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.no_combine", CPL_TYPE_BOOL,
371 "Don't combine cubes after reconstruction."
372 "(TRUE (apply) or FALSE (don't apply)",
373 "kmos.kmos_sci_red", FALSE);
374 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"no_combine");
375 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
376 cpl_parameterlist_append(recipe->parameters, p);
379 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.no_subtract", CPL_TYPE_BOOL,
380 "Don't sky subtract object and references."
381 "(TRUE (apply) or FALSE (don't apply)",
382 "kmos.kmos_sci_red", FALSE);
383 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"no_subtract");
384 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
385 cpl_parameterlist_append(recipe->parameters, p);
388 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.sky_tweak", CPL_TYPE_BOOL,
389 "Use modified sky cube for sky subtraction."
390 "(TRUE (apply) or FALSE (don't apply)",
391 "kmos.kmos_sci_red", FALSE);
392 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky_tweak");
393 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
394 cpl_parameterlist_append(recipe->parameters, p);
397 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.skip_sky_oh_align",
398 CPL_TYPE_BOOL,
"Skip the OH alignment for the SKY",
399 "kmos.kmos_sci_red", FALSE);
400 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skip_sky_oh_align");
401 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
402 cpl_parameterlist_append(recipe->parameters, p);
405 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.discard_subband",
406 CPL_TYPE_BOOL,
"Ignore last sub-band in the sky tweaking",
407 "kmos.kmos_sci_red", FALSE);
408 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"discard_subband");
409 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
410 cpl_parameterlist_append(recipe->parameters, p);
413 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.stretch_sky",
414 CPL_TYPE_BOOL,
"Stretch sky in the sky tweaking",
415 "kmos.kmos_sci_red", FALSE);
416 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"stretch");
417 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
418 cpl_parameterlist_append(recipe->parameters, p);
421 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.stretch_degree",
422 CPL_TYPE_INT,
"Stretch polynomial degree",
"kmos.kmos_sci_red",
424 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"stretch_degree");
425 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
426 cpl_parameterlist_append(recipe->parameters, p);
429 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.stretch_resampling",
430 CPL_TYPE_STRING,
"Stretch resampling method (linear/spline)",
431 "kmos.kmos_sci_red",
"spline");
432 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"stretch_resampling");
433 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
434 cpl_parameterlist_append(recipe->parameters, p);
437 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.tbsub", CPL_TYPE_BOOL,
438 "Subtract thermal background from input cube."
439 "(TRUE (apply) or FALSE (don't apply)",
440 "kmos.kmos_sci_red", TRUE);
441 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"tbsub");
442 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
443 cpl_parameterlist_append(recipe->parameters, p);
446 kmos_band_pars_create(recipe->parameters,
"kmos.kmos_sci_red");
449 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.obj_sky_table",
451 "The path to the file with the modified obj/sky associations.",
452 "kmos.kmos_sci_red",
"");
453 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"obj_sky_table");
454 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
455 cpl_parameterlist_append(recipe->parameters, p);
458 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.velocity_offset",
460 "Specify velocity offset correction in km/s for lambda scale",
461 "kmos.kmos_sci_red", 0.0);
462 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"velocity_offset");
463 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
464 cpl_parameterlist_append(recipe->parameters, p);
467 p=cpl_parameter_new_value(
"kmos.kmos_sci_red.save_interims", CPL_TYPE_BOOL,
468 "Save interim object and sky cubes. "
469 "Can only be used together with --sky_tweak",
470 "kmos.kmos_sci_red", FALSE);
471 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"save_interims");
472 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
473 cpl_parameterlist_append(recipe->parameters, p);
476 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.collapse_reconstructed",
477 CPL_TYPE_BOOL,
"Flag to collapse the reconstructed images",
478 "kmos.kmos_sci_red", FALSE);
479 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"collapse_reconstructed");
480 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
481 cpl_parameterlist_append(recipe->parameters, p);
484 p = cpl_parameter_new_value(
"kmos.kmos_sci_red.collapse_combined",
485 CPL_TYPE_BOOL,
"Flag to collapse the combined images",
486 "kmos.kmos_sci_red", FALSE);
487 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"collapse_combined");
488 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
489 cpl_parameterlist_append(recipe->parameters, p);
491 return kmos_combine_pars_create(recipe->parameters,
"kmos.kmos_sci_red",
492 DEF_REJ_METHOD, FALSE);
502static int kmos_sci_red_exec(cpl_plugin *plugin)
507 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
508 recipe = (cpl_recipe *)plugin;
511 return kmos_sci_red(recipe->parameters, recipe->frames);
521static int kmos_sci_red_destroy(cpl_plugin *plugin)
526 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
527 recipe = (cpl_recipe *)plugin;
530 cpl_parameterlist_delete(recipe->parameters);
548static int kmos_sci_red(cpl_parameterlist * parlist, cpl_frameset * frameset)
550 const cpl_parameter * par ;
553 int flux, background, extrapolate, fast_mode, edge_nan, no_combine,
554 no_subtract, sky_tweak, tbsub, xcal_interpolation, suppress_extension,
555 save_interims, citer, cmin, cmax, collapse_combined,
556 collapse_reconstructed ;
557 double neighborhoodRange, pix_scale, cpos_rej, cneg_rej,
558 velo_offset, velo_corr ;
559 double * velo_corr_ptr ;
560 const char * imethod, * smethod, * cmethod, * comb_method, * fmethod,
561 * sval, * filename, * ifus_txt, * name, * fn_obj_sky_table,
562 * fn_reconstr, * lcmethod ;
565 double scaling, conversion, f_0, zpoint, dit, angle;
566 int print_once, cube_counter_data, cube_counter_noise, do_sky_subtraction,
567 suppress_index, mapping_id, nb_science, nb_telluric, nb_illum_corr,
568 telluric_ok, actual_msg_level, nr_data, discard_subband,
569 stretch, stretch_degree, stretch_resampling, skip_sky_oh ;
570 int i, j, jj, sf, ifu_nr, sky_ifu_nr, det_nr, ifu_nr_telluric ;
572 const char * mapping_mode ;
577 const char * tmp_str ;
578 const char * fn_obj ;
579 const char * filter_id ;
580 const char * fn_out ;
584 enum kmo_frame_type ft ;
586 main_fits_desc desc_telluric, desc1 ;
590 enum extrapolationType extrapol_enum ;
591 cpl_propertylist * header_tmp ;
592 cpl_propertylist * main_header ;
593 cpl_propertylist * keys_plist ;
594 char * reflex_suffix ;
595 int * qc_output_unit = NULL;
598 armNameStruct * arm_name_struct ;
600 cpl_propertylist * plist ;
601 cpl_polynomial * oh_lcorr_coeffs ;
603 cpl_array ** unused_ifus_before ;
604 cpl_array ** unused_ifus_after ;
605 cpl_frame * obj_frame ;
606 cpl_frame * illum_frame ;
607 cpl_frame * sky_frame ;
608 cpl_frame * sky_as_object_frame ;
609 cpl_frame * ref_spectrum_frame ;
610 cpl_frame * bpm_frame ;
611 cpl_frame * xcal_frame ;
612 cpl_frame * ycal_frame ;
613 cpl_frame * lcal_frame ;
614 cpl_frame * flat_frame ;
615 cpl_frame * telluric_frame ;
616 cpl_frame * tmp_frame ;
618 cpl_table * band_table ;
620 cpl_imagelist * combined_data ;
621 cpl_imagelist * combined_noise ;
622 cpl_imagelist * tmp_cube1 ;
623 cpl_imagelist * tmp_cube2 ;
624 cpl_imagelist * new_sky ;
627 cpl_image * exp_mask ;
628 cpl_image * illum_data ;
630 cpl_imagelist ** cube_data ;
631 cpl_imagelist ** cube_noise ;
632 cpl_imagelist ** cube_interim_object = NULL;
633 cpl_imagelist ** cube_interim_sky = NULL;
635 cpl_propertylist ** header_data ;
636 cpl_propertylist ** header_noise ;
637 cpl_propertylist ** header_sky = NULL;
639 kmclipm_vector * telluric_data ;
640 kmclipm_vector * telluric_noise ;
642 const char * telluric_tag ;
643 const char * science_tag ;
646 if (kmos_check_and_set_groups(frameset) != CPL_ERROR_NONE) {
647 return cpl_error_get_code();
651 telluric_tag = TELLURIC ;
653 cube_counter_data = cube_counter_noise = 0 ;
654 do_sky_subtraction = FALSE ;
657 combined_data = combined_noise = NULL ;
658 sky_as_object_frame = NULL ;
661 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_sci_red.flux");
662 flux = cpl_parameter_get_bool(par);
663 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_sci_red.background");
664 background = cpl_parameter_get_bool(par);
665 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_sci_red.lcmethod");
666 lcmethod = cpl_parameter_get_string(par) ;
667 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_sci_red.imethod");
668 imethod = cpl_parameter_get_string(par) ;
669 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_sci_red.smethod");
670 smethod = cpl_parameter_get_string(par) ;
671 par = cpl_parameterlist_find_const(parlist,
672 "kmos.kmos_sci_red.neighborhoodRange");
673 neighborhoodRange = cpl_parameter_get_double(par) ;
674 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_sci_red.method");
675 comb_method = cpl_parameter_get_string(par) ;
676 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_sci_red.fmethod");
677 fmethod = cpl_parameter_get_string(par) ;
678 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_sci_red.filename");
679 filename = cpl_parameter_get_string(par) ;
680 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_sci_red.ifus");
681 ifus_txt = cpl_parameter_get_string(par) ;
682 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_sci_red.name");
683 name = cpl_parameter_get_string(par) ;
684 kmos_band_pars_load(parlist,
"kmos.kmos_sci_red");
685 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_sci_red.extrapolate");
686 extrapolate = cpl_parameter_get_bool(par);
687 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_sci_red.fast_mode");
688 fast_mode = cpl_parameter_get_bool(par);
689 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_sci_red.edge_nan");
690 edge_nan = cpl_parameter_get_bool(par);
691 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_sci_red.no_combine");
692 no_combine = cpl_parameter_get_bool(par);
693 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_sci_red.no_subtract");
694 no_subtract = cpl_parameter_get_bool(par);
695 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_sci_red.sky_tweak");
696 sky_tweak = cpl_parameter_get_bool(par);
697 par = cpl_parameterlist_find_const(parlist,
698 "kmos.kmos_sci_red.skip_sky_oh_align");
699 skip_sky_oh = cpl_parameter_get_bool(par);
700 par = cpl_parameterlist_find_const(parlist,
701 "kmos.kmos_sci_red.discard_subband");
702 discard_subband = cpl_parameter_get_bool(par);
703 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_sci_red.stretch_sky");
704 stretch = cpl_parameter_get_bool(par);
706 par=cpl_parameterlist_find_const(parlist,
707 "kmos.kmos_sci_red.stretch_degree");
708 stretch_degree = cpl_parameter_get_int(par);
709 par=cpl_parameterlist_find_const(parlist,
710 "kmos.kmos_sci_red.stretch_resampling");
711 sval = cpl_parameter_get_string(par);
712 if (!strcmp(sval,
"linear")) {
713 stretch_resampling = 1 ;
714 }
else if (!strcmp(sval,
"spline")) {
715 stretch_resampling = 2 ;
717 stretch_resampling = -1 ;
719 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_sci_red.tbsub");
720 tbsub = cpl_parameter_get_bool(par);
721 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_sci_red.pix_scale");
722 pix_scale = cpl_parameter_get_double(par) ;
723 par = cpl_parameterlist_find_const(parlist,
724 "kmos.kmos_sci_red.xcal_interpolation");
725 xcal_interpolation = cpl_parameter_get_bool(par);
726 par = cpl_parameterlist_find_const(parlist,
727 "kmos.kmos_sci_red.suppress_extension");
728 suppress_extension = cpl_parameter_get_bool(par);
729 par = cpl_parameterlist_find_const(parlist,
730 "kmos.kmos_sci_red.obj_sky_table");
731 fn_obj_sky_table = cpl_parameter_get_string(par) ;
732 kmos_combine_pars_load(parlist,
"kmos.kmos_sci_red", &cmethod, &cpos_rej,
733 &cneg_rej, &citer, &cmin, &cmax, FALSE);
734 par = cpl_parameterlist_find_const(parlist,
735 "kmos.kmos_sci_red.velocity_offset");
736 velo_offset = cpl_parameter_get_double(par) ;
737 velo_corr = 1. + velo_offset * 1000. / CPL_PHYS_C;
738 velo_corr_ptr = &velo_corr;
739 par = cpl_parameterlist_find_const(parlist,
740 "kmos.kmos_sci_red.save_interims");
741 save_interims = cpl_parameter_get_bool(par);
742 par = cpl_parameterlist_find_const(parlist,
743 "kmos.kmos_sci_red.collapse_combined");
744 collapse_combined = cpl_parameter_get_bool(par);
745 par = cpl_parameterlist_find_const(parlist,
746 "kmos.kmos_sci_red.collapse_reconstructed");
747 collapse_reconstructed = cpl_parameter_get_bool(par);
751 if (stretch == 0) skip_sky_oh = 0 ;
752 if (strcmp(lcmethod,
"OSCAN") && strcmp(lcmethod,
"SLICES_MEAN") &&
753 strcmp(lcmethod,
"SLICES_MEDIAN") && strcmp(lcmethod,
"NONE")) {
754 cpl_msg_error(__func__,
755 "lcmethod can be 'NONE', 'OSCAN','SLICES_MEAN' or 'SLICES_MEDIAN'") ;
756 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
759 if (strcmp(imethod,
"NN") && strcmp(imethod,
"lwNN") &&
760 strcmp(imethod,
"swNN") && strcmp(imethod,
"MS") &&
761 strcmp(imethod,
"CS")) {
762 cpl_msg_error(__func__,
763 "imethod must be 'NN','lwNN','swNN','MS' or 'CS'") ;
764 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
767 if (strcmp(smethod,
"NN") && strcmp(smethod,
"CS")) {
768 cpl_msg_error(__func__,
769 "smethod must be 'NN' or 'CS'") ;
770 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
773 if (neighborhoodRange <= 0.0) {
774 cpl_msg_error(__func__,
775 "neighborhoodRange must be greater than 0.0") ;
776 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
779 if (strcmp(comb_method,
"none") && strcmp(comb_method,
"header") &&
780 strcmp(comb_method,
"center") && strcmp(comb_method,
"user")) {
781 cpl_msg_error(__func__,
782 "shift methods must be 'none', 'header', 'center' or 'user'") ;
783 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
786 if (strcmp(ifus_txt,
"") && strcmp(name,
"")) {
787 cpl_msg_error(__func__,
788 "name and IFU indices cannot be both provided") ;
789 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
792 if (strcmp(smethod,
"NN") && strcmp(smethod,
"CS")) {
793 cpl_msg_error(__func__,
"smethod must be 'NN' or 'CS'") ;
794 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
797 if (!strcmp(smethod,
"NN") && extrapolate == TRUE) {
798 cpl_msg_error(__func__,
799 "extrapolation in not compatible with smethod 'NN'");
800 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
803 if (!strcmp(smethod,
"CS")) smethod =
"BCS";
804 if (!strcmp(smethod,
"BCS") && extrapolate == TRUE)
805 extrapol_enum = BCS_NATURAL;
807 extrapol_enum = NONE_NANS;
809 if (no_subtract && sky_tweak) {
810 cpl_msg_error(__func__,
"no_subtract and sky_tweak cannot be both TRUE");
811 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
814 if (sky_tweak == 0 && stretch == 1) {
815 cpl_msg_warning(__func__,
"stretch can only be used with sky_tweak");
817 if (stretch_resampling < 0) {
818 cpl_msg_warning(__func__,
819 "Invalid resampling method specified - use spline") ;
820 stretch_resampling = 2 ;
822 if (pix_scale < 0.01 || pix_scale > 0.4) {
823 cpl_msg_error(__func__,
"pix_scale must be between 0.01 and 0.4");
824 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
829 if (cpl_frameset_count_tags(frameset, SCIENCE) > 0)
830 science_tag = SCIENCE ;
831 else if (cpl_frameset_count_tags(frameset, LEVEL_CORRECTED) > 0)
832 science_tag = LEVEL_CORRECTED ;
834 cpl_msg_error(__func__,
"Missing input RAW frames");
835 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
841 cpl_msg_info(__func__,
"--no_combine set to TRUE because --no_subtract");
845 if (kmos_sci_red_check_inputs(frameset, pix_scale, &mapping_id,
847 cpl_msg_error(__func__,
"Input frameset is not consistent") ;
848 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
851 if (mapping_id == 0) mapping_mode = NULL ;
852 if (mapping_id == 1) mapping_mode =
"mapping8" ;
853 if (mapping_id == 2) mapping_mode =
"mapping24" ;
856 suffix = kmo_dfs_get_suffix(kmo_dfs_get_frame(frameset,science_tag), TRUE,
858 cpl_msg_info(__func__,
"Detected instrument setup: %s", suffix+1);
862 if (strcmp(ifus_txt,
"")) {
863 nb_science = cpl_frameset_count_tags(frameset, science_tag);
864 ifus = kmo_identify_values(ifus_txt);
865 if (ifus == NULL || cpl_vector_get_size(ifus) != nb_science) {
866 if (ifus != NULL) cpl_vector_delete(ifus);
867 cpl_msg_error(__func__,
"ifus size must match the science frames") ;
868 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
876 if (mapping_id > 0) {
877 if ((ifus != NULL) || (strcmp(name,
""))) {
878 cpl_msg_warning(__func__,
"Mapping Mode ٍ+ Specific IFUs requested") ;
880 if (!strcmp(smethod,
"BCS")) {
881 extrapol_enum = BCS_NATURAL;
882 cpl_msg_info(__func__,
"Mapping Mode : extrapolation set") ;
888 unused_ifus_before = kmo_get_unused_ifus(frameset, 1, 1);
889 unused_ifus_after = kmo_duplicate_unused_ifus(unused_ifus_before);
890 kmo_print_unused_ifus(unused_ifus_before, FALSE);
891 kmo_free_unused_ifus(unused_ifus_before);
894 kmclipm_setup_grid(&gd, imethod, neighborhoodRange, pix_scale, 0.);
897 bpm_frame = kmo_dfs_get_frame(frameset, BADPIXEL_DARK) ;
898 xcal_frame = kmo_dfs_get_frame(frameset, XCAL) ;
899 ycal_frame = kmo_dfs_get_frame(frameset, YCAL) ;
900 lcal_frame = kmo_dfs_get_frame(frameset, LCAL) ;
901 flat_frame = kmo_dfs_get_frame(frameset, MASTER_FLAT) ;
902 ref_spectrum_frame = kmo_dfs_get_frame(frameset, OH_SPEC) ;
903 nb_illum_corr = cpl_frameset_count_tags(frameset, ILLUM_CORR);
906 cpl_propertylist *flat_properties =
907 kmclipm_propertylist_load(
908 cpl_frame_get_filename(flat_frame),0);
909 double flat_mjd = kmos_pfits_get_mjd_obs(flat_properties);
910 cpl_propertylist_delete(flat_properties);
911 double tel_gen_mjd = 0.0;
914 header_tmp = kmo_dfs_load_primary_header(frameset, XCAL);
915 bounds = kmclipm_extract_bounds(header_tmp);
916 cpl_propertylist_delete(header_tmp);
917 if (bounds == NULL) {
918 if (ifus != NULL) cpl_vector_delete(ifus);
919 kmo_free_unused_ifus(unused_ifus_after);
920 cpl_msg_error(__func__,
"Cannot compute bounds") ;
921 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
929 if (!strcmp(fn_obj_sky_table,
"")) {
930 arm_name_struct = kmo_create_armNameStruct(frameset, science_tag, ifus,
931 name, unused_ifus_after, bounds, mapping_mode, no_subtract);
933 kmo_save_objSkyStruct(arm_name_struct->obj_sky_struct);
936 objSkyStruct *obj_sky_struct = NULL;
937 obj_sky_struct = kmo_read_objSkyStruct(fn_obj_sky_table, frameset,
943 for (i = 0; i < obj_sky_struct->size; i++) {
944 if (obj_sky_struct->table[i].objFrame != NULL) {
945 for (j = 0; j < KMOS_NR_IFUS; j++) {
946 if ((obj_sky_struct->table[i].skyIfus[j] > 0) &&
947 (sky_tweak == FALSE)) {
948 kmo_print_objSkyStruct(obj_sky_struct);
949 kmo_delete_objSkyStruct(obj_sky_struct);
950 cpl_msg_error(__func__,
951 "--sky_tweak needs to be set when sky are used from other IFUs");
952 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
958 arm_name_struct = kmo_create_armNameStruct2(obj_sky_struct, frameset,
959 science_tag, ifus, name, unused_ifus_after, bounds,
960 mapping_mode, no_subtract);
962 if (ifus != NULL) cpl_vector_delete(ifus);
963 if (arm_name_struct == NULL) {
964 kmo_free_unused_ifus(unused_ifus_after);
966 cpl_msg_error(__func__,
"Cannot compute ARM/name structure") ;
967 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
970 kmo_print_armNameStruct(frameset, arm_name_struct);
975 nb_telluric = cpl_frameset_count_tags(frameset, TELLURIC_GEN);
976 if (nb_telluric == 0) {
977 nb_telluric = cpl_frameset_count_tags(frameset, telluric_tag);
979 telluric_tag = TELLURIC_GEN ;
981 if (nb_telluric > 0 && mapping_id > 0) {
982 for (i = 0; i < arm_name_struct->nrNames; i++) {
983 if (arm_name_struct->telluricCnt[i] != arm_name_struct->namesCnt[i]
984 && (arm_name_struct->telluricCnt[i] != 0)) {
985 cpl_msg_error(__func__,
"Mosaics need a telluric per detector");
986 cpl_error_set(__func__, CPL_ERROR_UNSUPPORTED_MODE) ;
993 cube_data=(cpl_imagelist**)cpl_calloc(KMOS_NR_IFUS,
sizeof(cpl_imagelist*));
994 cube_noise=(cpl_imagelist**)cpl_calloc(KMOS_NR_IFUS,
sizeof(cpl_imagelist*));
995 header_data = (cpl_propertylist**)cpl_calloc(KMOS_NR_IFUS,
996 sizeof(cpl_propertylist*));
997 header_noise = (cpl_propertylist**)cpl_calloc(KMOS_NR_IFUS,
998 sizeof(cpl_propertylist*));
1000 cube_interim_object=(cpl_imagelist**)cpl_calloc(KMOS_NR_IFUS,
1001 sizeof(cpl_imagelist*));
1002 cube_interim_sky =(cpl_imagelist**)cpl_calloc(KMOS_NR_IFUS,
1003 sizeof(cpl_imagelist*));
1004 header_sky = (cpl_propertylist**)cpl_calloc(KMOS_NR_IFUS,
1005 sizeof(cpl_propertylist*));
1008 cpl_size pers_nr = 0;
1009 cpl_size sat_nr = 0;
1012 cpl_msg_info(__func__,
"Reconstructing & saving cubes with objects");
1013 for (sf = 0; sf < arm_name_struct->size; sf++) {
1014 fn_obj = cpl_frame_get_filename(
1015 arm_name_struct->obj_sky_struct->table[sf].objFrame);
1016 if ((main_header = kmclipm_propertylist_load(fn_obj, 0)) == NULL) {
1017 kmo_free_unused_ifus(unused_ifus_after);
1019 kmo_delete_armNameStruct(arm_name_struct);
1021 if (qc_output_unit) cpl_free(qc_output_unit) ;
1023 cpl_free(cube_data) ;
1024 cpl_free(cube_noise) ;
1025 cpl_free(header_data) ;
1026 cpl_free(header_noise) ;
1028 if (cube_interim_object) cpl_free(cube_interim_object) ;
1029 if (cube_interim_sky ) cpl_free(cube_interim_sky ) ;
1030 if (header_sky ) cpl_free(header_sky ) ;
1032 cpl_msg_error(__func__,
"Cannot Load main header");
1033 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
1036 actual_msg_level = cpl_msg_get_level();
1039 qc_output_unit = cpl_calloc(KMOS_NR_IFUS,
sizeof(
int)) ;
1043 cpl_msg_info(__func__,
" > processing frame: %s", fn_obj);
1044 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) {
1047 cube_data[ifu_nr-1] = cube_noise[ifu_nr-1] = NULL ;
1049 sky_ifu_nr = ifu_nr;
1050 det_nr = (ifu_nr - 1)/KMOS_IFUS_PER_DETECTOR + 1;
1057 header_data[ifu_nr-1] = kmclipm_propertylist_load(fn_obj, det_nr);
1058 extname = kmo_extname_creator(ifu_frame, ifu_nr, EXT_DATA);
1059 kmclipm_update_property_string(header_data[ifu_nr-1],
1060 EXTNAME, extname,
"FITS extension name");
1064 kmos_sci_red_propagate_qc(main_header, header_data[ifu_nr-1],
1065 lcal_frame, det_nr) ;
1067 if (arm_name_struct->name_ids[ifu_nr-1+sf*KMOS_NR_IFUS] >= 1) {
1070 cpl_image * sci_image = kmclipm_image_load(fn_obj, CPL_TYPE_FLOAT, 0, det_nr);
1071 cpl_mask * sat_mask = cpl_mask_threshold_image_create(sci_image, QC_SAT_LEVEL_SCI_RED, INFINITY );
1072 cpl_mask * pers_mask = cpl_mask_threshold_image_create(sci_image, QC_PERS_LEVEL_VAL, INFINITY);
1073 sat_nr = (cpl_mask_count(sat_mask) >= sat_nr)? cpl_mask_count(sat_mask): sat_nr;
1074 pers_nr = (cpl_mask_count(pers_mask) >= pers_nr)? cpl_mask_count(pers_mask): pers_nr;
1076 cpl_msg_info(__func__,
"Saturated number: %lld, Persistance number : %lld", sat_nr, pers_nr);
1078 cpl_image_delete(sci_image);
1079 cpl_mask_delete(sat_mask);
1080 cpl_mask_delete(pers_mask);
1084 sky_as_object_frame = NULL ;
1085 if ((arm_name_struct->obj_sky_struct->table[sf].skyFrames[ifu_nr-1] != NO_CORRESPONDING_SKYFRAME) && !no_subtract) {
1086 do_sky_subtraction = TRUE;
1087 if (no_subtract) sky_frame = NULL;
1089 arm_name_struct->obj_sky_struct->table[sf].skyFrames[ifu_nr-1];
1092 sky_as_object_frame = sky_frame;
1094 sky_ifu_nr = arm_name_struct->obj_sky_struct->table[sf].skyIfus[ifu_nr-1];
1097 do_sky_subtraction = FALSE;
1102 keyword = cpl_sprintf(
"%s%d%s", IFU_FILTID_PREFIX, det_nr,
1103 IFU_FILTID_POSTFIX);
1104 filter_id = cpl_propertylist_get_string(main_header, keyword);
1107 if (print_once) cpl_msg_set_level(CPL_MSG_WARNING);
1110 band_table = kmo_dfs_load_table(frameset, WAVE_BAND, 1, 0);
1111 kmclipm_setup_grid_band_lcal(&gd, filter_id, band_table);
1112 cpl_table_delete(band_table);
1114 cpl_msg_set_level(actual_msg_level);
1117 kmo_calc_wcs_gd(main_header, header_data[ifu_nr-1], ifu_nr, gd);
1120 kmclipm_update_property_int(header_data[ifu_nr-1], NAXIS, 3,
1121 "number of data axes");
1122 kmclipm_update_property_int(header_data[ifu_nr-1], NAXIS1,
1123 gd.x.dim,
"length of data axis 1");
1124 kmclipm_update_property_int(header_data[ifu_nr-1], NAXIS2,
1125 gd.y.dim,
"length of data axis 2");
1126 kmclipm_update_property_int(header_data[ifu_nr-1], NAXIS3,
1127 gd.l.dim,
"length of data axis 3");
1130 if (save_interims && sky_as_object_frame != NULL) {
1131 header_tmp = kmclipm_propertylist_load(
1132 cpl_frame_get_filename(sky_as_object_frame), 0);
1134 header_sky[ifu_nr-1]=kmclipm_propertylist_load(
1135 cpl_frame_get_filename(sky_as_object_frame),det_nr);
1136 extname = kmo_extname_creator(ifu_frame, ifu_nr, EXT_DATA);
1137 kmclipm_update_property_string(header_sky[ifu_nr-1],
1138 EXTNAME, extname,
"FITS extension name");
1141 kmo_calc_wcs_gd(header_tmp, header_sky[ifu_nr-1],
1143 kmclipm_update_property_int(header_sky[ifu_nr-1], NAXIS, 3,
1144 "number of data axes");
1145 kmclipm_update_property_int(header_sky[ifu_nr-1], NAXIS1,
1146 gd.x.dim,
"length of data axis 1");
1147 kmclipm_update_property_int(header_sky[ifu_nr-1], NAXIS2,
1148 gd.y.dim,
"length of data axis 2");
1149 kmclipm_update_property_int(header_sky[ifu_nr-1], NAXIS3,
1150 gd.l.dim,
"length of data axis 3");
1151 cpl_propertylist_delete(header_tmp);
1155 oh_lcorr_coeffs = NULL ;
1156 if (ref_spectrum_frame != NULL) {
1157 if (kmo_reconstruct_sci(ifu_nr, bounds[2*(ifu_nr-1)],
1158 bounds[2*(ifu_nr-1)+1],
1159 arm_name_struct->obj_sky_struct->table[sf].objFrame,
1160 science_tag, NULL, NULL, flat_frame, bpm_frame,
1161 xcal_frame, ycal_frame, lcal_frame, NULL, NULL,
1162 &gd, &tmp_cube1, &tmp_cube2, FALSE, FALSE,
1163 xcal_interpolation, lcmethod) == CPL_ERROR_NONE) {
1164 oh_lcorr_coeffs = kmo_lcorr_get(tmp_cube1,
1165 header_data[ifu_nr-1], ref_spectrum_frame, gd,
1167 cpl_imagelist_delete(tmp_cube1);
1168 cpl_imagelist_delete(tmp_cube2);
1173 kmo_reconstruct_sci(ifu_nr, bounds[2*(ifu_nr-1)],
1174 bounds[2*(ifu_nr-1)+1],
1175 arm_name_struct->obj_sky_struct->table[sf].objFrame,
1176 science_tag, sky_frame, science_tag, flat_frame,
1177 bpm_frame, xcal_frame, ycal_frame, lcal_frame,
1178 oh_lcorr_coeffs, velo_corr_ptr, &gd,
1179 &cube_data[ifu_nr-1], &cube_noise[ifu_nr-1], flux,
1180 background, xcal_interpolation, lcmethod);
1182 if (oh_lcorr_coeffs != NULL)
1183 cpl_polynomial_delete(oh_lcorr_coeffs);
1185 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1186 kmo_free_unused_ifus(unused_ifus_after);
1188 kmo_delete_armNameStruct(arm_name_struct);
1189 for (j=0 ; j<ifu_nr-1 ; j++) {
1190 if (cube_data[j] != NULL)
1191 cpl_imagelist_delete(cube_data[j]);
1192 if (cube_noise[j] != NULL)
1193 cpl_imagelist_delete(cube_noise[j]);
1194 cpl_propertylist_delete(header_data[j]);
1195 cpl_propertylist_delete(header_noise[j]);
1196 if (save_interims) {
1197 cpl_imagelist_delete(cube_interim_object[j]);
1198 cpl_imagelist_delete(cube_interim_sky[j]);
1199 cpl_propertylist_delete(header_sky[j]);
1202 cpl_propertylist_delete(header_data[ifu_nr-1]);
1203 cpl_free(cube_data) ;
1204 cpl_free(cube_noise) ;
1205 cpl_free(header_data) ;
1206 cpl_free(header_noise) ;
1207 if (save_interims) {
1208 cpl_free(cube_interim_object) ;
1209 cpl_free(cube_interim_sky) ;
1210 cpl_free(header_sky) ;
1212 cpl_msg_error(__func__,
"Cannot reconstruct");
1213 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
1219 if (do_sky_subtraction && sky_tweak) {
1222 oh_lcorr_coeffs = NULL ;
1223 if (ref_spectrum_frame != NULL && skip_sky_oh == 0) {
1224 if (kmo_reconstruct_sci(sky_ifu_nr,
1225 bounds[2*(sky_ifu_nr-1)],
1226 bounds[2*(sky_ifu_nr-1)+1],
1227 sky_as_object_frame, science_tag, NULL,
1228 NULL, flat_frame, bpm_frame, xcal_frame,
1229 ycal_frame, lcal_frame, NULL, NULL, &gd,
1230 &tmp_cube1, &tmp_cube2, FALSE, FALSE,
1232 lcmethod) == CPL_ERROR_NONE) {
1233 oh_lcorr_coeffs = kmo_lcorr_get(tmp_cube1,
1234 header_data[ifu_nr-1], ref_spectrum_frame,
1235 gd, filter_id, ifu_nr);
1236 cpl_imagelist_delete(tmp_cube1);
1237 cpl_imagelist_delete(tmp_cube2);
1242 kmo_reconstruct_sci(sky_ifu_nr,
1243 bounds[2*(sky_ifu_nr-1)],
1244 bounds[2*(sky_ifu_nr-1)+1], sky_as_object_frame,
1245 science_tag, sky_frame, science_tag, flat_frame,
1246 bpm_frame, xcal_frame, ycal_frame, lcal_frame,
1247 oh_lcorr_coeffs, velo_corr_ptr, &gd, &tmp_cube1,
1248 &tmp_cube2, flux, background, xcal_interpolation,
1251 cpl_imagelist_delete(tmp_cube2);
1252 if (oh_lcorr_coeffs != NULL)
1253 cpl_polynomial_delete(oh_lcorr_coeffs);
1255 if (save_interims && (sky_as_object_frame != NULL)) {
1256 cube_interim_object[ifu_nr-1]=
1257 cpl_imagelist_duplicate(cube_data[ifu_nr-1]);
1258 cube_interim_sky[ifu_nr-1]=
1259 cpl_imagelist_duplicate(tmp_cube1);
1263 tmp_cube2 = kmos_priv_sky_tweak(cube_data[ifu_nr-1],
1264 tmp_cube1, header_data[ifu_nr-1], .3, tbsub,
1265 discard_subband, stretch, stretch_degree,
1266 stretch_resampling, 0, &new_sky);
1267 cpl_imagelist_delete(cube_data[ifu_nr-1]);
1268 cpl_imagelist_delete(tmp_cube1);
1269 cpl_imagelist_delete(new_sky);
1270 cube_data[ifu_nr-1] = tmp_cube2 ;
1279 tmpImg = cpl_imagelist_get(cube_data[ifu_nr-1], 0);
1280 scaling = (cpl_image_get_size_x(tmpImg) *
1281 cpl_image_get_size_y(tmpImg)) /
1282 (KMOS_SLITLET_X*KMOS_SLITLET_Y);
1283 cpl_imagelist_divide_scalar(cube_data[ifu_nr-1], scaling);
1284 if (cube_noise[ifu_nr-1] != NULL) {
1285 cpl_imagelist_divide_scalar(cube_noise[ifu_nr-1], scaling);
1289 qc_output_unit[ifu_nr-1] = 0 ;
1290 if (nb_telluric > 0) {
1292 if (mapping_id == 0) {
1294 keyword = cpl_sprintf(
"%s%d%s", IFU_NAME_PREFIX,
1295 ifu_nr, IFU_NAME_POSTFIX);
1296 tmp_str = cpl_propertylist_get_string(
1297 header_data[ifu_nr-1], keyword);
1299 }
else if (mapping_id == 1) {
1300 tmp_str =
"mapping8";
1301 }
else if (mapping_id == 2) {
1302 tmp_str =
"mapping24";
1308 telluric_ok = FALSE;
1309 for (jj = 0; jj < arm_name_struct->nrNames; jj++) {
1310 if ((!strcmp(arm_name_struct->names[jj], tmp_str) ||
1311 !strcmp(arm_name_struct->names[jj], IFUS_USER_DEFINED)) &&
1312 arm_name_struct->telluricCnt[jj] == arm_name_struct->namesCnt[jj]) {
1319 telluric_data = kmo_tweak_load_telluric(frameset,
1320 ifu_nr, FALSE, no_subtract,
1321 telluric_tag, &ifu_nr_telluric);
1322 if (telluric_data != NULL) {
1324 kmo_dfs_get_frame(frameset, telluric_tag);
1325 kmo_init_fits_desc(&desc_telluric);
1329 cpl_propertylist *telluric_plist =
1330 kmclipm_propertylist_load(
1331 cpl_frame_get_filename(
1333 tel_gen_mjd = kmos_pfits_get_mjd_obs(telluric_plist);
1334 cpl_propertylist_delete(telluric_plist);
1336 desc_telluric=kmo_identify_fits_header(
1337 cpl_frame_get_filename(telluric_frame));
1340 idx = kmo_identify_index_desc(desc_telluric,
1342 if (desc_telluric.sub_desc[idx-1].valid_data) {
1344 telluric_noise = kmo_tweak_load_telluric(
1345 frameset,ifu_nr, TRUE, no_subtract,
1346 telluric_tag, &ifu_nr_telluric);
1348 telluric_noise = NULL ;
1350 kmo_free_fits_desc(&desc_telluric);
1352 kmo_arithmetic_3D_1D(cube_data[ifu_nr-1],
1353 telluric_data, cube_noise[ifu_nr-1],
1354 telluric_noise,
"/");
1355 if (telluric_noise != NULL)
1356 kmclipm_vector_delete(telluric_noise);
1357 kmclipm_vector_delete(telluric_data);
1360 zpoint = kmos_sci_red_get_zpoint(telluric_frame,
1363 f_0 = kmos_sci_red_get_f0(filter_id, gd.l.dim,
1364 gd.l.start, gd.l.delta) ;
1366 conversion = f_0*pow(10,-0.4*zpoint)/10.0 ;
1367 cpl_msg_info(__func__,
1368 "Apply Unit conversion factor %g for IFU nb %d",
1369 conversion, ifu_nr) ;
1370 kmo_arithmetic_3D_scalar(
1371 cube_data[ifu_nr-1], conversion,
1372 cube_noise[ifu_nr-1],
"*") ;
1373 qc_output_unit[ifu_nr-1] = 1 ;
1382 if (nb_illum_corr > 0) {
1384 arm_name_struct->obj_sky_struct->table[sf].objFrame ;
1385 plist = kmclipm_propertylist_load(
1386 cpl_frame_get_filename(obj_frame), 0) ;
1387 angle = kmo_dfs_get_property_double(plist, ROTANGLE);
1388 cpl_propertylist_delete(plist);
1390 illum_frame = kmo_dfs_get_frame(frameset, ILLUM_CORR);
1392 illum_data = kmos_illum_load(
1393 cpl_frame_get_filename(illum_frame),
1394 CPL_TYPE_FLOAT, ifu_nr, angle, &dummy1) ;
1395 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1396 cpl_msg_warning(__func__,
1397 "No illumination correction for IFU %d available! "
1398 "Proceeding anyway.", ifu_nr);
1399 if (illum_data != NULL) cpl_image_delete(illum_data);
1402 kmo_arithmetic_3D_2D(cube_data[ifu_nr-1], illum_data,
1403 cube_noise[ifu_nr-1], NULL,
"/");
1404 cpl_image_delete(illum_data);
1410 header_noise[ifu_nr-1] = cpl_propertylist_duplicate(
1411 header_data[ifu_nr-1]);
1412 extname = kmo_extname_creator(ifu_frame, ifu_nr, EXT_NOISE);
1413 kmclipm_update_property_string(header_noise[ifu_nr-1], EXTNAME,
1414 extname,
"FITS extension name");
1419 plist = cpl_propertylist_load(cpl_frame_get_filename(
1420 arm_name_struct->obj_sky_struct->table[sf].objFrame), 0);
1421 dit = kmos_pfits_get_dit(plist) ;
1422 cpl_propertylist_delete(plist) ;
1423 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) {
1425 if (cube_data[ifu_nr-1] != NULL) {
1426 kmo_arithmetic_3D_scalar(cube_data[ifu_nr-1], dit,
1427 cube_noise[ifu_nr-1],
"/") ;
1432 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) {
1433 if (cube_data[ifu_nr-1] != NULL) cube_counter_data++;
1434 if (cube_noise[ifu_nr-1] != NULL) cube_counter_noise++;
1438 if (cube_counter_data > 0) {
1439 cpl_msg_info(__func__,
" > saving...");
1441 if (!suppress_extension) {
1446 split = kmo_strsplit(fn_out,
"/", &nr_found);
1447 fn_suffix = cpl_sprintf(
"_%s", split[nr_found-1]);
1448 kmo_strfreev(split);
1451 char *fff = fn_suffix;
1452 fff += strlen(fn_suffix)-5;
1453 if (strcmp(fff,
".fits") == 0) {
1454 fn_suffix[strlen(fn_suffix)-5] =
'\0';
1457 fn_suffix = cpl_sprintf(
"_%d", suppress_index++);
1460 fn_out = RECONSTRUCTED_CUBE;
1463 keys_plist = cpl_propertylist_new() ;
1464 reflex_suffix = cpl_strdup(kmos_pfits_get_arcfile(main_header)) ;
1465 if (strlen(reflex_suffix) > 5)
1466 reflex_suffix[strlen(reflex_suffix)-5] =
'\0' ;
1467 cpl_propertylist_update_string(keys_plist,
"ESO PRO REFLEX SUFFIX",
1469 cpl_free(reflex_suffix) ;
1472 cpl_propertylist_update_double(keys_plist, PRO_MJD_OBS,
1473 kmos_pfits_get_mjd_obs(main_header)) ;
1476 cpl_propertylist_update_string(keys_plist, PRO_DATE_OBS,
1477 kmos_pfits_get_date_obs(main_header)) ;
1480 cpl_propertylist_update_double(keys_plist, QC_SAT_LEVEL,
1481 QC_SAT_LEVEL_SCI_RED) ;
1482 cpl_propertylist_update_int(keys_plist, QC_SAT_NB,
1484 cpl_propertylist_update_double(keys_plist, QC_PERS_LEVEL,
1485 QC_PERS_LEVEL_VAL) ;
1486 cpl_propertylist_update_int(keys_plist, QC_PERS_NB,
1490 cpl_propertylist_update_double(keys_plist, QC_MASTER_FLAT_MJD_OBS,
1492 cpl_propertylist_update_double(keys_plist, QC_TELLURIC_GEN_MJD_OBS,
1497 kmo_dfs_save_main_header(frameset, fn_out, fn_suffix,
1498 arm_name_struct->obj_sky_struct->table[sf].objFrame,
1499 keys_plist, parlist, cpl_func);
1500 cpl_propertylist_delete(keys_plist) ;
1503 if (save_interims && (sky_as_object_frame != NULL)) {
1504 kmo_dfs_save_main_header(frameset, INTERIM_OBJECT_CUBE,
1506 arm_name_struct->obj_sky_struct->table[sf].objFrame,
1507 NULL, parlist, cpl_func);
1508 kmo_dfs_save_main_header(frameset, INTERIM_OBJECT_SKY,
1510 arm_name_struct->obj_sky_struct->table[sf].objFrame,
1511 NULL, parlist, cpl_func);
1515 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) {
1518 if (qc_output_unit[ifu_nr-1] == 0) {
1519 kmclipm_update_property_string(header_data[ifu_nr-1],
1520 "ESO QC CUBE_UNIT",
"ADU/sec",
"Cube Unit");
1521 if (header_noise[ifu_nr-1] != NULL)
1522 kmclipm_update_property_string(header_noise[ifu_nr-1],
1523 "ESO QC CUBE_UNIT",
"ADU/sec",
"Cube Unit");
1525 kmclipm_update_property_string(header_data[ifu_nr-1],
1527 "erg.s**(-1).cm**(-2).angstrom**(-1)",
"Cube Unit");
1528 if (header_noise[ifu_nr-1] != NULL)
1529 kmclipm_update_property_string(header_noise[ifu_nr-1],
1531 "erg.s**(-1).cm**(-2).angstrom**(-1)",
1536 if (cube_data[ifu_nr-1] == NULL)
1537 kmos_all_clean_plist(header_data[ifu_nr-1]) ;
1538 kmo_dfs_save_cube(cube_data[ifu_nr-1], fn_out, fn_suffix,
1539 header_data[ifu_nr-1], 0./0.);
1540 cpl_imagelist_delete(cube_data[ifu_nr-1]);
1541 cube_data[ifu_nr-1] = NULL ;
1544 if (cube_counter_noise > 0) {
1545 if (cube_noise[ifu_nr-1] == NULL)
1546 kmos_all_clean_plist(header_noise[ifu_nr-1]) ;
1547 kmo_dfs_save_cube(cube_noise[ifu_nr-1], fn_out, fn_suffix,
1548 header_noise[ifu_nr-1], 0./0.);
1550 cpl_propertylist_delete(header_noise[ifu_nr-1]);
1551 header_noise[ifu_nr-1] = NULL ;
1552 cpl_imagelist_delete(cube_noise[ifu_nr-1]);
1553 cube_noise[ifu_nr-1] = NULL ;
1556 if (save_interims && (sky_as_object_frame != NULL)) {
1557 kmo_dfs_save_cube(cube_interim_object[ifu_nr-1],
1558 INTERIM_OBJECT_CUBE, fn_suffix,
1559 header_data[ifu_nr-1], 0./0.);
1560 kmo_dfs_save_cube(cube_interim_sky[ifu_nr-1],
1561 INTERIM_OBJECT_SKY, fn_suffix, header_sky[ifu_nr-1],
1564 cpl_propertylist_delete(header_data[ifu_nr-1]);
1565 header_data[ifu_nr-1] = NULL ;
1566 if (save_interims) {
1567 cpl_imagelist_delete(cube_interim_object[ifu_nr-1]);
1568 cube_interim_object[ifu_nr-1] = NULL ;
1569 cpl_imagelist_delete(cube_interim_sky[ifu_nr-1]);
1570 cube_interim_sky[ifu_nr-1] = NULL ;
1571 cpl_propertylist_delete(header_sky[ifu_nr-1]);
1572 header_sky[ifu_nr-1] = NULL ;
1575 cpl_free(fn_suffix);
1577 cpl_msg_info(__func__,
" > all IFUs invalid, don't save");
1578 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) {
1579 cpl_propertylist_delete(header_data[ifu_nr-1]);
1580 header_data[ifu_nr-1] = NULL ;
1581 cpl_propertylist_delete(header_noise[ifu_nr-1]);
1582 header_noise[ifu_nr-1] = NULL ;
1585 cpl_propertylist_delete(main_header) ;
1586 cpl_free(qc_output_unit) ;
1589 cpl_free(cube_data);
1590 cpl_free(cube_noise);
1591 cpl_free(header_data);
1592 cpl_free(header_noise);
1593 if (save_interims) {
1594 cpl_free(cube_interim_object);
1595 cpl_free(cube_interim_sky);
1596 cpl_free(header_sky);
1599 kmo_print_unused_ifus(unused_ifus_after, TRUE);
1600 kmo_free_unused_ifus(unused_ifus_after);
1607 cpl_msg_info(__func__,
"Combining reconstructed objects");
1608 if (mapping_id==0 || (mapping_id>0 && (strcmp(ifus_txt,
"") ||
1611 for (i = 0; i < arm_name_struct->nrNames; i++) {
1612 cpl_msg_info(__func__,
1613 " > object: %s", arm_name_struct->names[i]);
1614 nr_data = arm_name_struct->namesCnt[i];
1615 cube_data=(cpl_imagelist**)cpl_calloc(nr_data,
1616 sizeof(cpl_imagelist*));
1617 cube_noise=(cpl_imagelist**)cpl_calloc(nr_data,
1618 sizeof(cpl_imagelist*));
1619 header_data=(cpl_propertylist**)cpl_calloc(nr_data,
1620 sizeof(cpl_propertylist*));
1621 header_noise=(cpl_propertylist**)cpl_calloc(nr_data,
1622 sizeof(cpl_propertylist*));
1625 for (jj = 0; jj < nr_data; jj++) {
1626 cube_data[jj] = NULL ;
1627 cube_noise[jj] = NULL ;
1628 header_data[jj] = NULL ;
1629 header_noise[jj] = NULL ;
1633 cube_counter_data = 0;
1634 cube_counter_noise = 0;
1635 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE);
1636 while (tmp_frame != NULL ) {
1637 fn_reconstr = cpl_frame_get_filename(tmp_frame);
1638 main_header = kmclipm_propertylist_load(fn_reconstr, 0);
1640 kmo_init_fits_desc(&desc1);
1641 desc1 = kmo_identify_fits_header(fn_reconstr);
1643 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) {
1645 keyword = cpl_sprintf(
"%s%d%s", IFU_NAME_PREFIX, ifu_nr,
1647 tmp_str=cpl_propertylist_get_string(main_header,
1651 if (!strcmp(arm_name_struct->names[i],tmp_str) ||
1652 !strcmp(arm_name_struct->names[i], IFUS_USER_DEFINED)) {
1655 idx=kmo_identify_index(fn_reconstr,ifu_nr,FALSE);
1657 if (desc1.sub_desc[idx-1].valid_data) {
1658 cube_data[cube_counter_data] =
1659 kmclipm_imagelist_load(fn_reconstr,
1660 CPL_TYPE_FLOAT, idx);
1663 kmo_edge_nan(cube_data[cube_counter_data],
1667 header_data[cube_counter_data] =
1668 kmclipm_propertylist_load(fn_reconstr,
1670 cpl_propertylist_update_string(
1671 header_data[cube_counter_data],
1672 "ESO PRO FRNAME", fn_reconstr);
1673 cpl_propertylist_update_int(
1674 header_data[cube_counter_data],
1675 "ESO PRO IFUNR", ifu_nr);
1676 cube_counter_data++;
1680 if (desc1.ex_noise) {
1681 idx = kmo_identify_index(fn_reconstr, ifu_nr,
1683 if (desc1.sub_desc[idx-1].valid_data) {
1684 cube_noise[cube_counter_noise] =
1685 kmclipm_imagelist_load(fn_reconstr,
1686 CPL_TYPE_FLOAT, idx);
1689 cube_noise[cube_counter_noise],
1692 header_noise[cube_counter_noise] =
1693 kmclipm_propertylist_load(fn_reconstr,
1695 cube_counter_noise++;
1701 kmo_free_fits_desc(&desc1);
1702 cpl_propertylist_delete(main_header);
1703 tmp_frame = kmo_dfs_get_frame(frameset, NULL);
1706 if (cube_counter_noise == 0) {
1707 cpl_free(cube_noise);
1711 if (cube_counter_data > 1) {
1712 if (cube_counter_data == cube_counter_noise ||
1713 cube_counter_noise == 0) {
1714 kmo_priv_combine(cube_data, cube_noise, header_data,
1715 header_noise, cube_counter_data,
1716 cube_counter_noise, arm_name_struct->names[i],
1717 "", comb_method, smethod, fmethod, filename,
1718 cmethod, cpos_rej, cneg_rej, citer, cmin, cmax,
1719 extrapol_enum, flux, &combined_data,
1720 &combined_noise, &exp_mask);
1722 cpl_msg_error(__func__,
"Data/Noise cubes nb mismatch");
1723 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
1726 }
else if (cube_counter_data == 1) {
1727 cpl_msg_warning(__func__,
1728 "Only one reconstructed cube with this object");
1729 combined_data = cpl_imagelist_duplicate(cube_data[0]);
1730 tmpImg = cpl_imagelist_get(combined_data, 0);
1731 exp_mask = cpl_image_new(cpl_image_get_size_x(tmpImg),
1732 cpl_image_get_size_y(tmpImg), CPL_TYPE_FLOAT);
1733 kmo_image_fill(exp_mask, 1.);
1735 combined_noise = NULL ;
1736 if (cube_counter_noise > 0 && cube_noise[0] != NULL) {
1737 combined_noise = cpl_imagelist_duplicate(cube_noise[0]);
1740 cpl_msg_error(__func__,
"No cube found with this obj name");
1741 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
1744 for (jj = 0; jj < nr_data; jj++) {
1745 cpl_imagelist_delete(cube_data[jj]);
1746 if (cube_counter_noise > 0)
1747 cpl_imagelist_delete(cube_noise[jj]);
1749 cpl_free(cube_data);
1750 cpl_free(cube_noise);
1752 fn_out = COMBINED_CUBE;
1753 if (!suppress_extension) {
1754 char tmp_suffix[1024];
1755 tmp_suffix[0] =
'\0';
1757 if (arm_name_struct->telluricCnt[i] ==
1758 arm_name_struct->namesCnt[i]) {
1759 strcat(tmp_suffix,
"_telluric");
1761 if (nb_illum_corr > 0) strcat(tmp_suffix,
"_illum");
1762 if (sky_tweak) strcat(tmp_suffix,
"_skytweak");
1764 if (strlen(tmp_suffix) > 0) {
1765 fn_suffix = cpl_sprintf(
"_%s_%s",
1766 arm_name_struct->names[i], tmp_suffix);
1768 fn_suffix = cpl_sprintf(
"_%s",
1769 arm_name_struct->names[i]);
1772 fn_suffix = cpl_sprintf(
"_%d", suppress_index++);
1776 reflex_suffix = kmos_get_reflex_suffix(mapping_id,
1777 ifus_txt, name, arm_name_struct->names[i]) ;
1778 keys_plist = cpl_propertylist_new() ;
1779 cpl_propertylist_update_string(keys_plist,
1780 "ESO PRO REFLEX SUFFIX", reflex_suffix) ;
1781 cpl_free(reflex_suffix);
1784 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE);
1786 kmo_dfs_save_main_header(frameset, fn_out, fn_suffix,
1787 tmp_frame, keys_plist, parlist, cpl_func);
1789 kmo_dfs_save_main_header(frameset, EXP_MASK, fn_suffix,
1790 tmp_frame, keys_plist, parlist, cpl_func);
1791 cpl_propertylist_delete(keys_plist) ;
1793 kmo_dfs_save_cube(combined_data, fn_out, fn_suffix,
1794 header_data[0], 0./0.);
1796 kmo_dfs_save_image(exp_mask, EXP_MASK, fn_suffix,
1797 header_data[0], 0./0.);
1798 cpl_image_delete(exp_mask);
1800 if (combined_noise) {
1802 cpl_propertylist *final_noise_hdr = NULL;
1803 if (header_noise[0]) {
1804 final_noise_hdr = cpl_propertylist_duplicate(
1807 final_noise_hdr = cpl_propertylist_duplicate(
1809 tmp_str = cpl_propertylist_get_string(header_data[0],
1811 kmo_extname_extractor(tmp_str, &ft, &tmp_int, content);
1812 extname = kmo_extname_creator(ifu_frame, tmp_int,
1814 kmclipm_update_property_string(final_noise_hdr,
1815 EXTNAME, extname,
"FITS extension name");
1818 kmo_dfs_save_cube(combined_noise, fn_out, fn_suffix,
1819 final_noise_hdr, 0./0.);
1820 cpl_propertylist_delete(final_noise_hdr);
1821 cpl_imagelist_delete(combined_noise);
1823 cpl_free(fn_suffix);
1825 for (jj = 0; jj < nr_data; jj++) {
1826 cpl_propertylist_delete(header_data[jj]);
1827 cpl_propertylist_delete(header_noise[jj]);
1829 cpl_free(header_data);
1830 cpl_free(header_noise);
1831 cpl_imagelist_delete(combined_data);
1835 nr_data = KMOS_NR_IFUS *
1836 cpl_frameset_count_tags(frameset,RECONSTRUCTED_CUBE);
1837 cube_data = (cpl_imagelist**)cpl_calloc(nr_data,
1838 sizeof(cpl_imagelist*));
1839 cube_noise = (cpl_imagelist**)cpl_calloc(nr_data,
1840 sizeof(cpl_imagelist*));
1841 header_data=(cpl_propertylist**)cpl_calloc(nr_data,
1842 sizeof(cpl_propertylist*));
1843 header_noise=(cpl_propertylist**)cpl_calloc(nr_data,
1844 sizeof(cpl_propertylist*));
1847 for (jj = 0; jj < nr_data; jj++) {
1848 cube_data[jj] = NULL ;
1849 cube_noise[jj] = NULL ;
1850 header_data[jj] = NULL ;
1851 header_noise[jj] = NULL ;
1854 cube_counter_data = 0;
1855 cube_counter_noise = 0;
1856 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE);
1857 while (tmp_frame != NULL ) {
1858 fn_reconstr = cpl_frame_get_filename(tmp_frame);
1860 kmo_init_fits_desc(&desc1);
1861 desc1 = kmo_identify_fits_header(fn_reconstr);
1862 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) {
1863 idx = kmo_identify_index(fn_reconstr, ifu_nr, FALSE);
1865 if (desc1.sub_desc[idx-1].valid_data) {
1866 cpl_msg_debug(__func__,
1867 "Load in cube_data - Frame: %s IFU: %d",
1868 fn_reconstr, ifu_nr) ;
1869 cube_data[cube_counter_data] = kmclipm_imagelist_load(
1870 fn_reconstr, CPL_TYPE_FLOAT, idx);
1872 kmo_edge_nan(cube_data[cube_counter_data], ifu_nr);
1875 tmpImg = cpl_imagelist_collapse_median_create(
1876 cube_data[cube_counter_data]);
1877 tmp_cube1 = cpl_imagelist_new();
1878 cpl_imagelist_set(tmp_cube1, tmpImg, 0);
1879 cpl_imagelist_delete(cube_data[cube_counter_data]);
1880 cube_data[cube_counter_data] = tmp_cube1;
1883 cpl_msg_debug(__func__,
1884 "Load in header_data - Frame: %s IFU: %d",
1885 fn_reconstr, ifu_nr) ;
1886 header_data[cube_counter_data] =
1887 kmclipm_propertylist_load(fn_reconstr, idx);
1888 cpl_propertylist_update_string(
1889 header_data[cube_counter_data],
1890 "ESO PRO FRNAME", fn_reconstr);
1891 cpl_propertylist_update_int(
1892 header_data[cube_counter_data],
1893 "ESO PRO IFUNR", ifu_nr);
1894 cube_counter_data++;
1895 cpl_msg_debug(__func__,
"cube_counter_data: %d\n",
1896 cube_counter_data) ;
1900 if (desc1.ex_noise) {
1901 idx = kmo_identify_index(fn_reconstr,ifu_nr,TRUE);
1902 if (desc1.sub_desc[idx-1].valid_data) {
1903 cpl_msg_debug(__func__,
1904 "Load in cube_noise - Frame: %s IFU: %d",
1905 fn_reconstr, ifu_nr) ;
1906 cube_noise[cube_counter_noise] =
1907 kmclipm_imagelist_load(fn_reconstr,
1908 CPL_TYPE_FLOAT, idx);
1911 kmo_edge_nan(cube_noise[cube_counter_noise],
1914 tmpImg=cpl_imagelist_collapse_median_create(
1915 cube_noise[cube_counter_noise]);
1916 tmp_cube1 = cpl_imagelist_new();
1917 cpl_imagelist_set(tmp_cube1, tmpImg, 0);
1918 cpl_imagelist_delete(
1919 cube_noise[cube_counter_noise]);
1920 cube_noise[cube_counter_noise] = tmp_cube1;
1922 cpl_msg_debug(__func__,
1923 "Load in header_noise - Frame: %s IFU: %d",
1924 fn_reconstr, ifu_nr) ;
1925 header_noise[cube_counter_noise] =
1926 kmclipm_propertylist_load(fn_reconstr, idx);
1927 cube_counter_noise++;
1928 cpl_msg_debug(__func__,
"cube_counter_noise: %d\n",
1929 cube_counter_noise) ;
1934 kmo_free_fits_desc(&desc1);
1935 tmp_frame = kmo_dfs_get_frame(frameset, NULL);
1938 if (cube_counter_noise == 0) {
1939 cpl_free(cube_noise);
1943 if (cube_counter_data > 1) {
1944 if (cube_counter_data == cube_counter_noise ||
1945 cube_counter_noise == 0) {
1946 kmo_priv_combine(cube_data, cube_noise, header_data,
1947 header_noise, cube_counter_data, cube_counter_noise,
1948 mapping_mode,
"", comb_method, smethod, fmethod,
1949 filename, cmethod, cpos_rej, cneg_rej, citer, cmin,
1950 cmax, extrapol_enum, flux, &combined_data,
1951 &combined_noise, NULL);
1953 cpl_msg_error(__func__,
"Data/Noise cubes nb mismatch");
1954 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
1957 }
else if (cube_counter_data == 1) {
1958 cpl_msg_warning(__func__,
1959 "There is only one reconstructed cube - Save it");
1960 combined_data = cpl_imagelist_duplicate(cube_data[0]);
1962 if (cube_noise[0] != NULL) {
1963 combined_noise = cpl_imagelist_duplicate(cube_noise[0]);
1966 cpl_msg_error(__func__,
"No cube found with this obj name");
1967 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
1970 fn_out = COMBINED_CUBE;
1971 fn_suffix = cpl_sprintf(
"_%s", mapping_mode);
1974 keys_plist = cpl_propertylist_new() ;
1975 cpl_propertylist_update_string(keys_plist,
1976 "ESO PRO REFLEX SUFFIX",
"mapping") ;
1979 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE);
1980 kmo_dfs_save_main_header(frameset, fn_out, fn_suffix, tmp_frame,
1981 keys_plist, parlist, cpl_func);
1982 cpl_propertylist_delete(keys_plist) ;
1984 kmo_dfs_save_cube(combined_data, fn_out, fn_suffix, header_data[0],
1987 if (combined_noise) {
1988 cpl_propertylist *final_noise_hdr = NULL;
1989 if (cube_counter_noise > 0) {
1990 final_noise_hdr = cpl_propertylist_duplicate(
1993 final_noise_hdr = cpl_propertylist_duplicate(
1995 tmp_str = cpl_propertylist_get_string(header_data[0],
1997 kmo_extname_extractor(tmp_str, &ft, &tmp_int, content);
1998 extname = kmo_extname_creator(ifu_frame, tmp_int,
2000 kmclipm_update_property_string(final_noise_hdr, EXTNAME,
2001 extname,
"FITS extension name");
2004 kmo_dfs_save_cube(combined_noise, fn_out, fn_suffix,
2005 final_noise_hdr, 0./0.);
2006 cpl_propertylist_delete(final_noise_hdr);
2007 cpl_imagelist_delete(combined_noise);
2009 cpl_free(fn_suffix);
2011 for (i = 0; i < cube_counter_data ; i++) {
2012 cpl_propertylist_delete(header_data[i]);
2013 cpl_imagelist_delete(cube_data[i]);
2015 for (i = 0; i < cube_counter_noise ; i++) {
2016 cpl_propertylist_delete(header_noise[i]);
2017 cpl_imagelist_delete(cube_noise[i]);
2019 cpl_free(cube_data);
2020 cpl_free(cube_noise);
2021 cpl_free(header_data);
2022 cpl_free(header_noise);
2023 cpl_imagelist_delete(combined_data);
2026 kmo_delete_armNameStruct(arm_name_struct);
2029 if (collapse_reconstructed) {
2030 kmos_collapse_cubes(RECONSTRUCTED_CUBE, frameset, parlist, 0.1,
2031 "", DEF_REJ_METHOD, DEF_POS_REJ_THRES, DEF_NEG_REJ_THRES,
2032 DEF_ITERATIONS, DEF_NR_MIN_REJ, DEF_NR_MAX_REJ) ;
2036 if (collapse_combined) {
2037 kmos_collapse_cubes(COMBINED_CUBE, frameset, parlist, 0.1,
"",
2038 DEF_REJ_METHOD, DEF_POS_REJ_THRES, DEF_NEG_REJ_THRES,
2039 DEF_ITERATIONS, DEF_NR_MIN_REJ, DEF_NR_MAX_REJ) ;
2056static int kmos_sci_red_check_inputs(
2057 cpl_frameset * frameset,
2060 const char * science_tag)
2062 int nb_science, nb_xcal, nb_ycal, nb_lcal, nb_wave_band,
2063 nb_master_flat, nb_illum_corr, nb_telluric, nb_oh_spec,
2065 cpl_error_code err ;
2066 const cpl_frame * frame1 ;
2067 const cpl_frame * frame2 ;
2068 int next1, next2, mapping_id_loc,
2069 mapping_id_curr, nx, ny ;
2070 cpl_propertylist * mh ;
2071 cpl_propertylist * eh ;
2072 const char * tmp_str ;
2075 if (frameset == NULL || mapping_id == NULL)
return -1;
2078 nb_science = cpl_frameset_count_tags(frameset, science_tag) ;
2079 nb_xcal = cpl_frameset_count_tags(frameset, XCAL) ;
2080 nb_ycal = cpl_frameset_count_tags(frameset, YCAL) ;
2081 nb_lcal = cpl_frameset_count_tags(frameset, LCAL) ;
2082 nb_wave_band = cpl_frameset_count_tags(frameset, WAVE_BAND) ;
2083 nb_master_flat = cpl_frameset_count_tags(frameset, MASTER_FLAT);
2084 nb_illum_corr = cpl_frameset_count_tags(frameset, ILLUM_CORR);
2085 nb_telluric = cpl_frameset_count_tags(frameset, TELLURIC);
2086 nb_telluric_gen = cpl_frameset_count_tags(frameset, TELLURIC_GEN);
2087 nb_oh_spec = cpl_frameset_count_tags(frameset, OH_SPEC) ;
2090 if (nb_science < 1) {
2091 cpl_msg_error(__func__,
"At least one SCIENCE frame is required") ;
2092 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
2095 if (nb_science == 1) {
2096 cpl_msg_warning(__func__,
2097 "Only 1 SCIENCE: no sky subtraction - reconstruct all IFUs");
2099 if (nb_xcal != 1 || nb_ycal != 1 || nb_lcal != 1) {
2100 cpl_msg_error(__func__,
"Exactly 1 XCAL/YCAL/LCAL expected") ;
2101 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
2104 if (nb_wave_band != 1) {
2105 cpl_msg_error(__func__,
"At most one WAVE_BAND frame expected") ;
2106 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
2110 if (nb_master_flat > 1 || nb_illum_corr > 1 || nb_telluric > 1 ||
2112 cpl_msg_error(__func__,
2113 "MASTER_FLAT/ILLUM_CORR/OH_SPEC/TELLURIC: 0 or 1 frame expected") ;
2114 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
2119 err = CPL_ERROR_NONE ;
2120 err += kmo_check_frameset_setup(frameset, science_tag, TRUE, FALSE, TRUE);
2121 err += kmo_check_frame_setup(frameset, science_tag, YCAL, TRUE, FALSE,TRUE);
2122 err += kmo_check_frame_setup(frameset, XCAL, YCAL, TRUE, FALSE, TRUE);
2123 err += kmo_check_frame_setup(frameset, XCAL, LCAL, TRUE, FALSE, TRUE);
2124 if (nb_master_flat > 0) err += kmo_check_frame_setup(frameset, XCAL,
2125 MASTER_FLAT, TRUE, FALSE, TRUE);
2126 if (nb_telluric > 0) err += kmo_check_frame_setup(frameset, XCAL,
2127 TELLURIC, TRUE, FALSE, TRUE);
2128 if (nb_telluric_gen > 0) err += kmo_check_frame_setup(frameset, XCAL,
2129 TELLURIC_GEN, TRUE, FALSE, TRUE);
2130 if (nb_oh_spec > 0) err += kmo_check_oh_spec_setup(frameset, XCAL);
2133 frame1 = kmo_dfs_get_frame(frameset, XCAL);
2134 next1 = cpl_frame_get_nextensions(frame1);
2135 if (next1 % KMOS_NR_DETECTORS) {
2136 cpl_msg_error(__func__,
"XCAL wrong format") ;
2137 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
2141 frame2 = kmo_dfs_get_frame(frameset, YCAL);
2142 next2 = cpl_frame_get_nextensions(frame2);
2143 if (next1 != next2) {
2144 cpl_msg_error(__func__,
"YCAL wrong format") ;
2145 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
2149 frame2 = kmo_dfs_get_frame(frameset, LCAL);
2150 next2 = cpl_frame_get_nextensions(frame2);
2151 if (next1 != next2) {
2152 cpl_msg_error(__func__,
"LCAL wrong format") ;
2153 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
2157 if (nb_master_flat >= 1) {
2158 frame2 = kmo_dfs_get_frame(frameset, MASTER_FLAT);
2159 next2 = cpl_frame_get_nextensions(frame2);
2160 if (next2 % (2*KMOS_NR_DETECTORS)) {
2161 cpl_msg_error(__func__,
"MASTER_FLAT wrong format") ;
2162 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
2167 if (nb_illum_corr >= 1) {
2168 frame2 = kmo_dfs_get_frame(frameset, ILLUM_CORR);
2170 eh = cpl_propertylist_load(cpl_frame_get_filename(frame2), 1);
2171 nx = kmos_pfits_get_naxis1(eh) ;
2172 ny = kmos_pfits_get_naxis2(eh) ;
2173 cpl_propertylist_delete(eh) ;
2174 if (fabs(nx*pix_scale-2.8) > 1e-3 || fabs(ny*pix_scale-2.8) > 1e-3) {
2175 cpl_msg_error(__func__,
2176 "ILLUM wrong Size (nx/y*pix_scale= %g/%g <> 2.8)",
2177 nx*pix_scale, ny*pix_scale) ;
2178 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
2183 if (nb_telluric >= 1) {
2184 frame2 = kmo_dfs_get_frame(frameset, TELLURIC);
2185 next2 = cpl_frame_get_nextensions(frame2);
2186 if (next2 != 24 && next2 != 48) {
2187 cpl_msg_error(__func__,
"TELLURIC wrong format") ;
2188 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
2193 if (nb_telluric_gen >= 1) {
2194 frame2 = kmo_dfs_get_frame(frameset, TELLURIC_GEN);
2195 next2 = cpl_frame_get_nextensions(frame2);
2196 if (next2 != 24 && next2 != 48) {
2197 cpl_msg_error(__func__,
"TELLURIC_GEN wrong format") ;
2198 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
2204 frame2 = kmo_dfs_get_frame(frameset, science_tag);
2205 mapping_id_loc = -1 ;
2206 while (frame2 != NULL ) {
2207 next2 = cpl_frame_get_nextensions(frame2);
2209 cpl_msg_error(__func__,
"SCIENCE wrong format") ;
2210 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
2214 mh = cpl_propertylist_load(cpl_frame_get_filename(frame2), 0);
2215 tmp_str = cpl_propertylist_get_string(mh, TPL_ID);
2216 if (!strcmp(tmp_str, MAPPING8)) mapping_id_curr = 1 ;
2217 else if (strcmp(tmp_str, MAPPING24) == 0) mapping_id_curr = 2 ;
2218 else mapping_id_curr = 0 ;
2219 cpl_propertylist_delete(mh);
2221 if (mapping_id_loc < 0) mapping_id_loc = mapping_id_curr ;
2222 if (mapping_id_curr != mapping_id_loc) {
2223 cpl_msg_error(__func__,
"Inconsistent MAPPING information") ;
2224 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
2227 frame2 = kmo_dfs_get_frame(frameset, NULL);
2231 err += kmo_check_frame_setup_md5_xycal(frameset);
2233 err += kmo_check_frame_setup_md5(frameset);
2235 err += kmo_check_frame_setup_sampling(frameset);
2237 if (err != CPL_ERROR_NONE) {
2238 cpl_msg_warning(__func__,
"Frames are inconsistent") ;
2243 *mapping_id = mapping_id_loc ;
2255static double kmos_sci_red_get_zpoint(
2259 cpl_propertylist * plist ;
2261 int nb_ext, ext_nb ;
2264 if (frame == NULL)
return -1.0 ;
2265 if (cpl_error_get_code() != CPL_ERROR_NONE)
return -1.0 ;
2268 nb_ext = cpl_frame_get_nextensions(frame);
2271 if (nb_ext == KMOS_NR_IFUS) ext_nb = ifu_nr ;
2272 else if (nb_ext == 2 * KMOS_NR_IFUS) ext_nb = 2 * ifu_nr - 1 ;
2276 plist = cpl_propertylist_load(cpl_frame_get_filename(frame), ext_nb);
2277 zpoint = cpl_propertylist_get_double(plist,
"ESO QC ZPOINT") ;
2278 cpl_propertylist_delete(plist) ;
2280 if (cpl_error_get_code() != CPL_ERROR_NONE) {
2295static double kmos_sci_red_get_f0(
2296 const char * filter_id,
2302 if (!strcmp(filter_id,
"H")) f_0 = 1.133e-9 ;
2303 if (!strcmp(filter_id,
"HK")) f_0 = 6.954423052992941e-10 ;
2304 if (!strcmp(filter_id,
"K")) f_0 = 4.283e-10 ;
2305 if (!strcmp(filter_id,
"YJ")) f_0 = 3.129e-9 ;
2306 if (!strcmp(filter_id,
"IZ")) f_0 = 7.63e-9 ;
2338static kmclipm_vector * kmo_tweak_load_telluric(
2339 cpl_frameset * frameset,
2343 const char * telluric_tag,
2344 int * ifu_nr_telluric)
2346 kmclipm_vector *vec = NULL;
2347 int actual_msg_level = 0 ;
2351 if (frameset == NULL || ifu_nr_telluric == NULL)
return NULL ;
2352 if (ifu_nr < 1 || ifu_nr > KMOS_NR_IFUS)
return NULL ;
2354 *ifu_nr_telluric = kmo_tweak_find_ifu(frameset, ifu_nr);
2355 if (ifu_nr!=*ifu_nr_telluric && *ifu_nr_telluric!=-1 && no_subtract!=-1) {
2357 cpl_msg_info(__func__,
"Telluric IFU %d selected",
2360 cpl_msg_info(__func__,
"For IFU %d, telluric in IFU %d selected",
2361 ifu_nr, *ifu_nr_telluric);
2365 actual_msg_level = cpl_msg_get_level();
2366 cpl_msg_set_level(CPL_MSG_OFF);
2367 vec = kmo_dfs_load_vector(frameset, telluric_tag,*ifu_nr_telluric,is_noise);
2368 cpl_msg_set_level(actual_msg_level);
2370 if (cpl_error_get_code() != CPL_ERROR_NONE) cpl_error_reset();
2372 if ((vec == NULL) && !is_noise && (no_subtract != -1)) {
2374 cpl_msg_warning(__func__,
"No telluric on this detector");
2376 cpl_msg_warning(__func__,
"No telluric on this detector for IFU %d",
2384static int kmos_sci_red_propagate_qc(
2385 const cpl_propertylist * main_input,
2386 cpl_propertylist * to_update,
2387 const cpl_frame * inframe,
2390 cpl_propertylist * plist ;
2391 double rotangle, fwhm_ar, fwhm_ne,
2392 vscale_ar, vscale_ne, pos_ne, pos_ar ;
2396 rotangle = kmo_dfs_get_property_double(main_input, ROTANGLE);
2399 (void)kmclipm_cal_propertylist_find_angle(
2400 cpl_frame_get_filename(inframe), det_nr, 0, rotangle,
2404 plist = cpl_propertylist_load(cpl_frame_get_filename(inframe), xtnum) ;
2405 fwhm_ar = kmos_pfits_get_qc_ar_fwhm_mean(plist) ;
2406 vscale_ar = kmos_pfits_get_qc_ar_vscale(plist) ;
2407 fwhm_ne = kmos_pfits_get_qc_ne_fwhm_mean(plist) ;
2408 vscale_ne = kmos_pfits_get_qc_ne_vscale(plist) ;
2409 pos_ar = kmos_pfits_get_qc_ar_pos_stdev(plist) ;
2410 pos_ne = kmos_pfits_get_qc_ne_pos_stdev(plist) ;
2411 cpl_propertylist_delete(plist) ;
2412 if (cpl_error_get_code() != CPL_ERROR_NONE) {
2413 cpl_msg_warning(__func__,
2414 "Cannot propagate the QC ARC xx FWHM MEAN keyword") ;
2419 kmclipm_update_property_double(to_update,
"ESO QC ARC NE POS STDEV",
2420 pos_ne,
"[km/s] mean stdev of pos. of NE");
2421 kmclipm_update_property_double(to_update,
"ESO QC ARC AR POS STDEV",
2422 pos_ar,
"[km/s] mean stdev of pos. of AR");
2423 kmclipm_update_property_double(to_update,
"ESO QC ARC NE FWHM MEAN",
2424 fwhm_ne,
"[km/s] mean of fwhm for Ne");
2425 kmclipm_update_property_double(to_update,
"ESO QC ARC AR FWHM MEAN",
2426 fwhm_ar,
"[km/s] mean of fwhm for Ar");
2427 kmclipm_update_property_double(to_update,
"ESO QC ARC NE VSCALE",
2428 vscale_ne,
"Velocity scale for Ne");
2429 kmclipm_update_property_double(to_update,
"ESO QC ARC AR VSCALE",
2430 vscale_ar,
"Velocity scale for Ar");
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.