23#define _DEFAULT_SOURCE
41#include "kmos_pfits.h"
43#include "kmo_priv_functions.h"
44#include "kmo_cpl_extensions.h"
45#include "kmo_constants.h"
46#include "kmo_priv_combine.h"
47#include "kmo_priv_extract_spec.h"
53#define CPL_DFS_PRO_DID "PRO-1.16"
59static double kmos_get_median_from_positives(
60 cpl_image * exp_mask) ;
61static double kmos_get_mode(
62 cpl_imagelist * error) ;
63static int kmos_idp_set_nans(
65 cpl_imagelist * error) ;
66static int kmos_combine_collect_data(
67 const cpl_propertylist * recons_prim_header,
68 const cpl_propertylist * recons_ext_header,
72static char * kmos_combine_create_ifus_string(
const int *,
const int *,
int);
73static cpl_bivector * kmos_combine_parse_skipped(
const char *) ;
74static int kmos_combine_is_skipped(
const cpl_bivector *,
int,
int) ;
76static int kmos_combine_create(cpl_plugin *);
77static int kmos_combine_exec(cpl_plugin *);
78static int kmos_combine_destroy(cpl_plugin *);
79static int kmos_combine(cpl_parameterlist *, cpl_frameset *);
81cpl_frame * kmos_setup_idp_prime_header(cpl_propertylist * main_header,
char * filename,
82 char * base_filename, cpl_frameset * frameset,
83 cpl_frame * frame, cpl_parameterlist * parlist,
84 double pixnoise, cpl_propertylist ** plist) ;
90static char kmos_combine_description[] =
91"This recipe shifts several exposures of an object and combines them. Diffe-\n"
92"rent methods to match the exposures are described here (--method parameter).\n"
93"The output cube is larger than the input cubes, according to the shifts to\n"
94"be applied. Additionally a border of NaN values is added. The WCS is the\n"
95"same as for the first exposure.\n"
96"For each spatial/spectral pixel a new value is calculated (according the\n"
97"--cmethod parameter) and written into the output cube.\n"
98"Only exposures with the same WCS orientation can be combined (except\n"
99"-–method=”none”), north must point to the same direction. It is recommended\n"
100"to apply any rotation possibly after combining.\n"
102"The behavior of the selection of IFUs to combine differs for some templates\n"
103"and can be controlled with the parameters --name and --ifus.\n"
104"If the input data cubes stem from templates KMOS_spec_obs_mapping8 or\n"
105"KMOS_spec_obs_mapping24 all extensions from all input frames are combined\n"
106"into a single map by default (like in recipe kmo_sci_red). If just the area\n"
107"of a specific IFU should be combined, the parameter --ifus can be specified,\n"
108"or more easily --name.\n"
109"If the input data cubes stem from other templates like e.g.\n"
110"KMOS_spec_obs_freedither all extensions of all input frames are combined\n"
111"into several output frames by default. The input IFUs are grouped according\n"
112"to their targeted object name stored in the keywords ESO OCS ARMx NAME. If \n"
113"just a specific object should be combined, its name can be specified with \n"
114"--name. If arbitrary IFUs shoukd be comined, one can specify these with the\n"
117"The default mapping mode is done via the --name parameter, where the name of\n"
118"the object has to be provided. The recipe searches in input data cubes IFUs\n"
119"pointing to that object.\n"
121"---------------------------------------------------------------------------\n"
125" category Type Explanation Required #Frames\n"
126" -------- ----- ----------- -------- -------\n"
127" CUBE_OBJECT F3I data frame Y 2-n \n"
132" category Type Explanation\n"
133" -------- ----- -----------\n"
134" COMBINE_ F3I Combined data cube\n"
135" EXP_MASK F3I Exposure time mask\n"
136" SCI_COMBINED_COLL (optional) Collapsed combined cube\n"
137" (set --collapse_combined)\n"
138"---------------------------------------------------------------------------\n"
165 cpl_recipe *recipe = cpl_calloc(1,
sizeof *recipe);
166 cpl_plugin *plugin = &recipe->interface;
168 cpl_plugin_init(plugin,
171 CPL_PLUGIN_TYPE_RECIPE,
173 "Combine reconstructed cubes",
174 kmos_combine_description,
175 "Alex Agudo Berbel, Y. Jung",
176 "https://support.eso.org/",
180 kmos_combine_destroy);
181 cpl_pluginlist_append(list, plugin);
195static int kmos_combine_create(cpl_plugin *plugin)
201 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
202 recipe = (cpl_recipe *)plugin;
207 recipe->parameters = cpl_parameterlist_new();
211 p = cpl_parameter_new_value(
"kmos.kmos_combine.name", CPL_TYPE_STRING,
212 "Name of the object to combine.",
"kmos.kmos_combine",
"");
213 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"name");
214 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
215 cpl_parameterlist_append(recipe->parameters, p);
218 p = cpl_parameter_new_value(
"kmos.kmos_combine.ifus", CPL_TYPE_STRING,
219 "The indices of the IFUs to combine. " "\"ifu1;ifu2;...\"",
220 "kmos.kmos_combine",
"");
221 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ifus");
222 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
223 cpl_parameterlist_append(recipe->parameters, p);
226 p = cpl_parameter_new_value(
"kmos.kmos_combine.method", CPL_TYPE_STRING,
227 "The shifting method: "
228 "'none': no shifting, combined directly (default), "
229 "'header': shift according to WCS, "
230 "'center': centering algorithm, "
231 "'user': read shifts from file",
232 "kmos.kmos_combine",
"none");
233 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"method");
234 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
235 cpl_parameterlist_append(recipe->parameters, p);
238 p = cpl_parameter_new_value(
"kmos.kmos_combine.fmethod", CPL_TYPE_STRING,
239 "The fitting method (applies only when method='center'): "
240 "'gauss': fit a gauss function to collapsed image (default), "
241 "'moffat': fit a moffat function to collapsed image",
242 "kmos.kmos_combine",
"gauss");
243 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"fmethod");
244 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
245 cpl_parameterlist_append(recipe->parameters, p);
248 p = cpl_parameter_new_value(
"kmos.kmos_combine.filename", CPL_TYPE_STRING,
249 "The path to the file with the shift vectors (method='user')",
250 "kmos.kmos_combine",
"");
251 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"filename");
252 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
253 cpl_parameterlist_append(recipe->parameters, p);
256 p = cpl_parameter_new_value(
"kmos.kmos_combine.flux", CPL_TYPE_BOOL,
257 "Apply flux conservation: (TRUE (apply) or FALSE (don't apply)",
258 "kmos.kmos_combine", FALSE);
259 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"flux");
260 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
261 cpl_parameterlist_append(recipe->parameters, p);
264 p = cpl_parameter_new_value(
"kmos.kmos_combine.edge_nan", CPL_TYPE_BOOL,
265 "Set borders of cubes to NaN before combining them."
266 "(TRUE (apply) or FALSE (don't apply)",
"kmos.kmos_combine", FALSE);
267 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"edge_nan");
268 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
269 cpl_parameterlist_append(recipe->parameters, p);
272 p = cpl_parameter_new_value(
"kmos.kmos_combine.skipped_frames",
274 "Comma separated List of IFUs to skip for the combination. "
275 "An IFU is specified with R:I."
276 "R is the index (start 1) of the recons. frame, I the IFU nb",
277 "kmos.kmos_combine",
"");
278 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skipped_frames");
279 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
280 cpl_parameterlist_append(recipe->parameters, p);
283 p = cpl_parameter_new_value(
"kmos.kmos_combine.suppress_extension",
284 CPL_TYPE_BOOL,
"Suppress arbitrary filename extension.",
285 "kmos.kmos_combine", FALSE);
286 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"suppress_extension");
287 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
288 cpl_parameterlist_append(recipe->parameters, p);
291 p = cpl_parameter_new_value(
"kmos.kmos_combine.collapse_combined",
292 CPL_TYPE_BOOL,
"Flag to collapse the combined images",
293 "kmos.kmos_combine", FALSE);
294 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"collapse_combined");
295 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
296 cpl_parameterlist_append(recipe->parameters, p);
299 p = cpl_parameter_new_value(
"kmos.kmos_combine.qc_spec", CPL_TYPE_BOOL,
300 "Output quicklook quality control spectrum with IDP files",
"kmos.kmos_combine", FALSE);
301 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"qc_spec");
302 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
303 cpl_parameterlist_append(recipe->parameters, p);
305 return kmos_combine_pars_create(recipe->parameters,
"kmos.kmos_combine",
306 DEF_REJ_METHOD, FALSE);
316static int kmos_combine_exec(cpl_plugin *plugin)
321 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
322 recipe = (cpl_recipe *)plugin;
325 return kmos_combine(recipe->parameters, recipe->frames);
335static int kmos_combine_destroy(cpl_plugin *plugin)
340 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
341 recipe = (cpl_recipe *)plugin;
344 cpl_parameterlist_delete(recipe->parameters);
362static int kmos_combine(cpl_parameterlist *parlist, cpl_frameset *frameset)
364 const cpl_parameter * par ;
365 cpl_frameset * rawframes ;
366 const char * raw_tag,
373 double cpos_rej, cneg_rej, fwhm_ar_med, fwhm_ne_med,
374 spec_res, fwhm_ar_val, fwhm_ne_val, pos_ar_val,
375 pos_ne_val, airmass, lambda, seeing, sky_res,
376 sky_rerr, abmaglim, outer_scale,
377 crval1, crval2, pos_ar_med, pos_ne_med,
380 int citer, cmin, cmax, nr_frames, index,
381 data_cube_counter, skip_cube_counter,
382 noise_cube_counter, flux, edge_nan, name_vec_size,
383 found, suppress_extension, ifu_nr,
384 nv, collapse_combined, mapping_id, fwhm_count,
386 int suppress_index = 0;
394 const char * frame_filename,
396 cpl_image * exp_mask ;
397 cpl_imagelist ** data_cube_list,
399 * cube_combined_data,
400 * cube_combined_noise ;
401 cpl_propertylist * main_header,
403 ** noise_header_list,
406 cpl_vector * pos_ar ;
407 cpl_vector * pos_ne ;
408 cpl_vector * fwhm_ar ;
409 cpl_vector * fwhm_ne ;
410 cpl_vector * sky_res_vec ;
411 cpl_vector * airmass_vec ;
412 cpl_vector * seeing_vec ;
413 cpl_vector * lambda_vec ;
414 cpl_vector * tmp_vec ;
415 char * reflex_suffix ;
416 cpl_bivector * skipped_bivector ;
420 int * used_frame_idx ;
422 char * used_ifus_str ;
423 int * skip_frame_idx ;
425 char * skip_ifus_str ;
426 enum extrapolationType extrapol_enum = NONE_CLIPPING;
427 double light_speed, mjd_start, mjd_end ;
430 char * object_data_key ;
431 char * object_stat_key ;
435 if (kmos_check_and_set_groups(frameset) != CPL_ERROR_NONE) {
436 return cpl_error_get_code();
440 light_speed = 299792.48 ;
443 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_combine.method");
444 method = cpl_parameter_get_string(par) ;
445 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_combine.fmethod");
446 fmethod = cpl_parameter_get_string(par) ;
447 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_combine.filename");
448 filename = cpl_parameter_get_string(par) ;
449 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_combine.ifus");
450 ifus_txt = cpl_parameter_get_string(par) ;
451 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_combine.name");
452 name = cpl_parameter_get_string(par) ;
453 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_combine.flux");
454 flux = cpl_parameter_get_bool(par) ;
455 par = cpl_parameterlist_find_const(parlist,
456 "kmos.kmos_combine.skipped_frames");
457 skipped_frames = cpl_parameter_get_string(par) ;
458 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_combine.edge_nan");
459 edge_nan = cpl_parameter_get_bool(par) ;
460 par = cpl_parameterlist_find_const(parlist,
461 "kmos.kmos_combine.suppress_extension");
462 suppress_extension = cpl_parameter_get_bool(par) ;
463 kmos_combine_pars_load(parlist,
"kmos.kmos_combine", &cmethod, &cpos_rej,
464 &cneg_rej, &citer, &cmin, &cmax, FALSE);
465 par = cpl_parameterlist_find_const(parlist,
466 "kmos.kmos_combine.collapse_combined");
467 collapse_combined = cpl_parameter_get_bool(par);
468 par = cpl_parameterlist_find_const(parlist,
469 "kmos.kmos_combine.qc_spec");
470 qc_spec = cpl_parameter_get_bool(par);
473 if (strcmp(method,
"none") && strcmp(method,
"header") &&
474 strcmp(method,
"center") && strcmp(method,
"user")) {
475 cpl_msg_error(__func__,
476 "shift methods must be 'none', 'header', 'center' or 'user'") ;
477 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
480 if (strcmp(ifus_txt,
"") && strcmp(name,
"")) {
481 cpl_msg_error(__func__,
482 "name and IFU indices cannot be both provided") ;
483 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
486 if (!strcmp(method,
"user") && !strcmp(filename,
"")) {
487 cpl_msg_error(__func__,
488 "path of file with shift information must be provided") ;
489 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
494 skipped_bivector = NULL ;
495 if (strcmp(skipped_frames,
"")) {
496 skipped_bivector = kmos_combine_parse_skipped(skipped_frames) ;
497 if (skipped_bivector != NULL)
498 cpl_msg_info(__func__,
"Skip the following IFU: %s",
503 rawframes = cpl_frameset_duplicate(frameset) ;
504 cpl_frameset_erase(rawframes,
"OH_SPEC") ;
507 nr_frames = cpl_frameset_get_size(rawframes);
509 if (skipped_bivector!=NULL) cpl_bivector_delete(skipped_bivector) ;
510 cpl_frameset_delete(rawframes) ;
511 cpl_msg_error(__func__,
"At least one frames must be provided") ;
512 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
517 frame = cpl_frameset_get_position(rawframes, 0);
518 raw_tag = cpl_frame_get_tag(frame) ;
521 if (strcmp(ifus_txt,
"")) {
522 ifus = kmo_identify_values(ifus_txt);
523 if (ifus == NULL || cpl_vector_get_size(ifus) != nr_frames) {
524 if (ifus != NULL) cpl_vector_delete(ifus);
525 if (skipped_bivector!=NULL) cpl_bivector_delete(skipped_bivector) ;
526 cpl_frameset_delete(rawframes) ;
527 cpl_msg_error(__func__,
"ifus size must match the science frames") ;
528 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
536 mapping_mode = NULL ;
537 cpl_size fs_size = cpl_frameset_get_size(rawframes);
538 for (ci = 0; ci < fs_size; ci++) {
539 frame = cpl_frameset_get_position(rawframes, ci);
540 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(frame),0);
541 if (cpl_propertylist_has(tmp_header, TPL_ID)) {
542 tmp_strc = cpl_propertylist_get_string(tmp_header, TPL_ID);
543 if (mapping_mode == NULL) {
544 if (!strcmp(tmp_strc, MAPPING8))
545 mapping_mode = cpl_sprintf(
"%s", tmp_strc);
546 if (!strcmp(tmp_strc, MAPPING24))
547 mapping_mode = cpl_sprintf(
"%s", tmp_strc);
549 if (strcmp(tmp_strc, mapping_mode)) {
550 cpl_msg_warning(__func__,
551 "There are different TPL IDs in input: %s and %s",
552 tmp_strc, mapping_mode);
556 cpl_propertylist_delete(tmp_header);
560 if (mapping_mode != NULL) {
561 if (!strcmp(ifus_txt,
"") && !strcmp(name,
"")) {
562 cpl_msg_info(__func__,
"A map with all IFUs will be generated");
563 extrapol_enum = BCS_NATURAL;
565 if (strcmp(ifus_txt,
"")) {
566 cpl_msg_info(__func__,
567 "IFUs %s are requested - switch off mapping mode",
570 if (strcmp(name,
"")) {
571 cpl_msg_info(__func__,
572 "Object name %s is requested - switch off mapping mode",
575 cpl_free(mapping_mode);
576 mapping_mode = NULL ;
582 if (mapping_mode == NULL) {
584 cpl_msg_info(__func__,
"Mode : Non-Mapping") ;
586 if (!strcmp(mapping_mode, MAPPING8)) {
588 cpl_msg_info(__func__,
"Mode : Mapping 8") ;
590 if (!strcmp(mapping_mode, MAPPING24)) {
592 cpl_msg_info(__func__,
"Mode : Mapping 24") ;
597 name_vec = cpl_calloc(nr_frames*KMOS_NR_IFUS,
sizeof(
char*));
600 if (!strcmp(ifus_txt,
"") && !strcmp(name,
"") && mapping_mode==NULL) {
603 for (i = 0; i < nr_frames; i++) {
604 tmp_str = cpl_sprintf(
"%d", i);
605 frame = kmo_dfs_get_frame(rawframes, tmp_str);
607 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) {
609 tmp_str = kmo_get_name_from_ocs_ifu(frame, ifu_nr);
610 if (tmp_str != NULL) {
611 for (j = 0; j < name_vec_size; j++) {
612 if (!strcmp(name_vec[j], tmp_str)) {
617 if (!found) name_vec[name_vec_size++] = tmp_str;
618 else cpl_free(tmp_str);
625 if (mapping_mode != NULL) {
626 name_vec[0] = cpl_sprintf(
"mapping");
632 char *found_char = NULL;
633 found_char = strstr(ifus_txt,
";");
634 while (found_char != NULL) {
636 found_char = strstr(ifus_txt,
";");
639 if (strlen(ifus_txt) > 10) {
640 tmptmp = kmo_shorten_ifu_string(ifus_txt);
641 cpl_msg_info(__func__,
"Truncate to ..ifu%s..", tmptmp);
643 tmptmp = cpl_sprintf(
"%s", ifus_txt);
645 name_vec[0] = cpl_sprintf(
"IFU%s", tmptmp);
649 name_vec[0] = cpl_sprintf(
"%s", name);
655 cpl_msg_info(__func__,
"List of Objects to combine:") ;
656 cpl_msg_indent_more() ;
657 for (i = 0; i < name_vec_size ; i++) {
658 cpl_msg_info(__func__,
"* %s", name_vec[i]) ;
660 cpl_msg_indent_less() ;
663 data_cube_list = cpl_calloc(nr_frames*KMOS_NR_IFUS,
664 sizeof(cpl_imagelist*));
665 data_header_list = cpl_calloc(nr_frames*KMOS_NR_IFUS,
666 sizeof(cpl_propertylist*));
667 noise_cube_list = cpl_calloc(nr_frames*KMOS_NR_IFUS,
668 sizeof(cpl_imagelist*));
669 noise_header_list = cpl_calloc(nr_frames*KMOS_NR_IFUS,
670 sizeof(cpl_propertylist*));
673 for (nv = 0; nv < name_vec_size; nv++) {
674 obj_name = name_vec[nv];
676 fwhm_ar = cpl_vector_new(nr_frames*KMOS_NR_IFUS) ;
677 fwhm_ne = cpl_vector_new(nr_frames*KMOS_NR_IFUS) ;
678 pos_ar = cpl_vector_new(nr_frames*KMOS_NR_IFUS) ;
679 pos_ne = cpl_vector_new(nr_frames*KMOS_NR_IFUS) ;
680 airmass_vec = cpl_vector_new(nr_frames*KMOS_NR_IFUS) ;
681 seeing_vec = cpl_vector_new(nr_frames*KMOS_NR_IFUS) ;
682 lambda_vec = cpl_vector_new(nr_frames*KMOS_NR_IFUS) ;
683 used_frame_idx = cpl_calloc(nr_frames*KMOS_NR_IFUS,
sizeof(
int)) ;
684 used_ifus = cpl_calloc(nr_frames*KMOS_NR_IFUS,
sizeof(
int)) ;
685 skip_frame_idx = cpl_calloc(nr_frames*KMOS_NR_IFUS,
sizeof(
int)) ;
686 skip_ifus = cpl_calloc(nr_frames*KMOS_NR_IFUS,
sizeof(
int)) ;
688 data_cube_counter = 0;
689 skip_cube_counter = 0;
690 noise_cube_counter = 0;
693 for (i = 0; i < nr_frames; i++) {
694 tmp_str = cpl_sprintf(
"%d", i);
695 frame = kmo_dfs_get_frame(rawframes, tmp_str);
696 frame_filename = cpl_frame_get_filename(frame);
697 kmo_init_fits_desc(&desc);
698 desc = kmo_identify_fits_header(frame_filename);
699 main_header = cpl_propertylist_load(frame_filename, 0) ;
701 if (mapping_mode != NULL) {
703 for (j = 1; j <= KMOS_NR_IFUS; j++) {
705 if (desc.sub_desc[j-1].valid_data == TRUE &&
706 !kmos_combine_is_skipped(skipped_bivector,i+1,j)) {
708 override_err_msg = TRUE;
709 data_cube_list[data_cube_counter] =
710 kmo_dfs_load_cube(rawframes, tmp_str, j,FALSE);
711 override_err_msg = FALSE;
712 if (data_cube_list[data_cube_counter] == NULL) {
715 if (edge_nan) kmo_edge_nan(
716 data_cube_list[data_cube_counter], j);
717 data_header_list[data_cube_counter] =
718 kmo_dfs_load_sub_header(rawframes,
722 if (kmos_combine_collect_data(main_header,
723 data_header_list[data_cube_counter],
724 &lambda, &seeing, &airmass) == -1) {
727 cpl_vector_set(lambda_vec, data_count, lambda) ;
728 cpl_vector_set(seeing_vec, data_count, seeing) ;
729 cpl_vector_set(airmass_vec,data_count,airmass) ;
734 fwhm_ar_val = kmos_pfits_get_qc_ar_fwhm_mean(
735 data_header_list[data_cube_counter]) ;
736 fwhm_ne_val = kmos_pfits_get_qc_ne_fwhm_mean(
737 data_header_list[data_cube_counter]) ;
738 pos_ar_val = kmos_pfits_get_qc_ar_pos_stdev(
739 data_header_list[data_cube_counter]) ;
740 pos_ne_val = kmos_pfits_get_qc_ne_pos_stdev(
741 data_header_list[data_cube_counter]) ;
742 if (cpl_error_get_code() != CPL_ERROR_NONE) {
745 cpl_vector_set(fwhm_ar,fwhm_count,
746 light_speed/fwhm_ar_val) ;
747 cpl_vector_set(fwhm_ne,fwhm_count,
748 light_speed/fwhm_ne_val) ;
749 cpl_vector_set(pos_ar,fwhm_count,
750 pos_ar_val*lambda/light_speed) ;
751 cpl_vector_set(pos_ne,fwhm_count,
752 pos_ne_val*lambda/light_speed) ;
756 cpl_propertylist_update_string(
757 data_header_list[data_cube_counter],
758 "ESO PRO FRNAME", frame_filename);
759 cpl_propertylist_update_int(
760 data_header_list[data_cube_counter],
762 used_frame_idx[data_cube_counter] = i+1 ;
763 used_ifus[data_cube_counter] = j ;
768 override_err_msg = TRUE;
769 noise_cube_list[noise_cube_counter] =
770 kmo_dfs_load_cube(rawframes, tmp_str, j, TRUE);
772 override_err_msg = FALSE;
773 if (noise_cube_list[noise_cube_counter] == NULL) {
776 if (edge_nan) kmo_edge_nan(
777 noise_cube_list[noise_cube_counter], j);
778 noise_header_list[noise_cube_counter] =
779 kmo_dfs_load_sub_header(rawframes, tmp_str,
781 noise_cube_counter++;
785 if (noise_cube_counter > 0) {
786 if (data_cube_counter != noise_cube_counter) {
787 cpl_msg_error(__func__,
"Noise missing") ;
788 cpl_error_set(__func__,CPL_ERROR_ILLEGAL_INPUT);
793 }
else if (kmos_combine_is_skipped(skipped_bivector,
795 skip_frame_idx[skip_cube_counter] = i+1 ;
796 skip_ifus[skip_cube_counter] = j ;
802 if (ifus != NULL) ifu_nr = cpl_vector_get(ifus, i);
803 else ifu_nr = kmo_get_index_from_ocs_name(frame, obj_name);
805 index = kmo_identify_index(frame_filename, ifu_nr , FALSE);
806 if (desc.sub_desc[index-1].valid_data == TRUE &&
807 !kmos_combine_is_skipped(skipped_bivector,i+1,
810 override_err_msg = TRUE;
811 data_cube_list[data_cube_counter] =
812 kmo_dfs_load_cube(rawframes, tmp_str, ifu_nr,
814 override_err_msg = FALSE;
815 if (data_cube_list[data_cube_counter] == NULL) {
819 cpl_msg_warning(cpl_func,
820 "IFU %d miѕsing in frame %s",
821 ifu_nr, frame_filename);
823 cpl_msg_warning(cpl_func,
824 "Object %s missing in Frame %d (%s)",
825 obj_name, i+1, frame_filename) ;
827 if (edge_nan) kmo_edge_nan(
828 data_cube_list[data_cube_counter], ifu_nr);
829 data_header_list[data_cube_counter] =
830 kmo_dfs_load_sub_header(rawframes, tmp_str,
834 if (kmos_combine_collect_data(main_header,
835 data_header_list[data_cube_counter],
836 &lambda, &seeing, &airmass) == -1) {
839 cpl_vector_set(lambda_vec, data_count, lambda) ;
840 cpl_vector_set(seeing_vec, data_count, seeing) ;
841 cpl_vector_set(airmass_vec,data_count,airmass) ;
846 fwhm_ar_val = kmos_pfits_get_qc_ar_fwhm_mean(
847 data_header_list[data_cube_counter]) ;
848 fwhm_ne_val = kmos_pfits_get_qc_ne_fwhm_mean(
849 data_header_list[data_cube_counter]) ;
850 pos_ar_val = kmos_pfits_get_qc_ar_pos_stdev(
851 data_header_list[data_cube_counter]) ;
852 pos_ne_val = kmos_pfits_get_qc_ne_pos_stdev(
853 data_header_list[data_cube_counter]) ;
854 if (cpl_error_get_code() != CPL_ERROR_NONE) {
857 cpl_vector_set(fwhm_ar,fwhm_count,
858 light_speed/fwhm_ar_val) ;
859 cpl_vector_set(fwhm_ne,fwhm_count,
860 light_speed/fwhm_ne_val) ;
861 cpl_vector_set(pos_ar,fwhm_count,
862 pos_ar_val*lambda/light_speed) ;
863 cpl_vector_set(pos_ne,fwhm_count,
864 pos_ne_val*lambda/light_speed) ;
868 cpl_propertylist_update_string(
869 data_header_list[data_cube_counter],
870 "ESO PRO FRNAME", frame_filename);
871 cpl_propertylist_update_int(
872 data_header_list[data_cube_counter],
873 "ESO PRO IFUNR", ifu_nr);
874 used_frame_idx[data_cube_counter] = i+1 ;
875 used_ifus[data_cube_counter] = ifu_nr ;
880 override_err_msg = TRUE;
881 noise_cube_list[noise_cube_counter] =
882 kmo_dfs_load_cube(rawframes, tmp_str, ifu_nr,
884 override_err_msg = FALSE;
885 if (noise_cube_list[noise_cube_counter] == NULL) {
889 if (edge_nan) kmo_edge_nan(
890 noise_cube_list[noise_cube_counter],ifu_nr);
891 noise_header_list[noise_cube_counter] =
892 kmo_dfs_load_sub_header(rawframes,
893 tmp_str, ifu_nr, TRUE);
894 noise_cube_counter++;
898 if (noise_cube_counter > 0) {
899 if (data_cube_counter != noise_cube_counter) {
901 cpl_msg_error(__func__,
"Noise missing") ;
902 cpl_error_set(__func__,CPL_ERROR_ILLEGAL_INPUT);
906 }
else if (kmos_combine_is_skipped(skipped_bivector,
908 skip_frame_idx[skip_cube_counter] = i+1 ;
909 skip_ifus[skip_cube_counter] = ifu_nr ;
914 cpl_propertylist_delete(main_header) ;
915 kmo_free_fits_desc(&desc);
920 if (fwhm_count > 2) {
921 tmp_vec = cpl_vector_extract(fwhm_ar, 0, fwhm_count-1, 1) ;
922 fwhm_ar_med = cpl_vector_get_median(tmp_vec) ;
923 cpl_vector_delete(tmp_vec) ;
924 tmp_vec = cpl_vector_extract(fwhm_ne, 0, fwhm_count-1, 1) ;
925 fwhm_ne_med = cpl_vector_get_median(tmp_vec) ;
926 cpl_vector_delete(tmp_vec) ;
927 tmp_vec = cpl_vector_extract(pos_ar, 0, fwhm_count-1, 1) ;
928 pos_ar_med = cpl_vector_get_median(tmp_vec) ;
929 cpl_vector_delete(tmp_vec) ;
930 tmp_vec = cpl_vector_extract(pos_ne, 0, fwhm_count-1, 1) ;
931 pos_ne_med = cpl_vector_get_median(tmp_vec) ;
932 cpl_vector_delete(tmp_vec) ;
933 spec_res = (fwhm_ar_med + fwhm_ne_med) / 2.0 ;
934 crder3 = (pos_ar_med + pos_ne_med) / 2.0 ;
935 }
else if (fwhm_count > 0) {
936 tmp_vec = cpl_vector_extract(fwhm_ar, 0, fwhm_count-1, 1) ;
937 fwhm_ar_med = cpl_vector_get_mean(tmp_vec) ;
938 cpl_vector_delete(tmp_vec) ;
939 tmp_vec = cpl_vector_extract(fwhm_ne, 0, fwhm_count-1, 1) ;
940 fwhm_ne_med = cpl_vector_get_mean(tmp_vec) ;
941 cpl_vector_delete(tmp_vec) ;
942 tmp_vec = cpl_vector_extract(pos_ar, 0, fwhm_count-1, 1) ;
943 pos_ar_med = cpl_vector_get_mean(tmp_vec) ;
944 cpl_vector_delete(tmp_vec) ;
945 tmp_vec = cpl_vector_extract(pos_ne, 0, fwhm_count-1, 1) ;
946 pos_ne_med = cpl_vector_get_mean(tmp_vec) ;
947 cpl_vector_delete(tmp_vec) ;
948 spec_res = (fwhm_ar_med + fwhm_ne_med) / 2.0 ;
949 crder3 = (pos_ar_med + pos_ne_med) / 2.0 ;
951 cpl_msg_debug(__func__,
"Cound not retrieve QC ARC - FWHM MEAN") ;
955 cpl_vector_delete(fwhm_ar) ;
956 cpl_vector_delete(fwhm_ne) ;
957 cpl_vector_delete(pos_ar) ;
958 cpl_vector_delete(pos_ne) ;
961 sky_res_vec = cpl_vector_new(data_count) ;
962 for (i=0 ; i<data_count ; i++) {
963 lambda = cpl_vector_get(lambda_vec, i) ;
964 seeing = cpl_vector_get(seeing_vec, i) ;
965 airmass = cpl_vector_get(airmass_vec, i) ;
966 outer_scale=sqrt(1-78.08*((pow(lambda*1e-6,0.4)*pow(airmass,-0.2))/
967 (pow(seeing,1./3.)))) ;
968 sky_res = seeing * pow(0.5/lambda, 0.2) * pow(airmass, 3./5.) *
970 cpl_vector_set(sky_res_vec, i, sky_res) ;
972 cpl_vector_delete(airmass_vec) ;
973 cpl_vector_delete(seeing_vec) ;
974 cpl_vector_delete(lambda_vec) ;
976 if (data_count > 2) {
977 sky_res = cpl_vector_get_median_const(sky_res_vec) ;
978 sky_rerr = sqrt((0.2*0.2)+pow(cpl_vector_get_stdev(sky_res_vec),2));
980 sky_res = cpl_vector_get_mean(sky_res_vec) ;
983 cpl_vector_delete(sky_res_vec) ;
986 if (sky_rerr > 1.0) sky_rerr = 0.3;
987 if (sky_rerr < 0.0) sky_rerr = 0.3;
990 used_ifus_str = kmos_combine_create_ifus_string(used_frame_idx,
991 used_ifus, data_cube_counter);
992 cpl_free(used_ifus) ;
993 skip_ifus_str = kmos_combine_create_ifus_string(skip_frame_idx,
994 skip_ifus, skip_cube_counter);
995 cpl_free(skip_frame_idx) ;
996 cpl_free(skip_ifus) ;
999 main_header = kmo_dfs_load_primary_header(rawframes,
"0");
1000 const char *tag = cpl_propertylist_get_string(main_header,
1005 cube_combined_noise = NULL ;
1006 cube_combined_data = NULL ;
1008 if (!suppress_extension || strcmp(obj_name,
"mapping") == 0) {
1009 err = kmo_priv_combine(data_cube_list, noise_cube_list,
1010 data_header_list, noise_header_list,
1011 data_cube_counter, noise_cube_counter,
1012 obj_name, ifus_txt, method,
"BCS",
1013 fmethod, filename, cmethod,
1014 cpos_rej, cneg_rej, citer, cmin, cmax,
1015 extrapol_enum, flux, &cube_combined_data,
1016 &cube_combined_noise, &exp_mask);
1018 char *name_suppress = cpl_sprintf(
"%d", suppress_index);
1019 err = kmo_priv_combine(data_cube_list, noise_cube_list,
1020 data_header_list, noise_header_list,
1021 data_cube_counter, noise_cube_counter,
1022 name_suppress, ifus_txt, method,
"BCS",
1023 fmethod, filename, cmethod,
1024 cpos_rej, cneg_rej, citer, cmin, cmax,
1025 extrapol_enum, flux, &cube_combined_data,
1026 &cube_combined_noise, &exp_mask);
1027 cpl_free(name_suppress);
1029 if (err != CPL_ERROR_NONE) {
1030 for (i = 0; i < data_cube_counter ; i++)
1031 cpl_imagelist_delete(data_cube_list[i]);
1032 for (i = 0; i < noise_cube_counter ; i++)
1033 cpl_imagelist_delete(noise_cube_list[i]);
1034 for (i = 0; i < data_cube_counter ; i++)
1035 cpl_propertylist_delete(data_header_list[i]);
1036 for (i = 0; i < noise_cube_counter ; i++)
1037 cpl_propertylist_delete(noise_header_list[i]);
1038 if (ifus != NULL) cpl_vector_delete(ifus);
1039 cpl_free(data_cube_list);
1040 cpl_free(noise_cube_list);
1041 cpl_free(data_header_list);
1042 cpl_free(noise_header_list);
1043 for (i = 0; i < name_vec_size ; i++) cpl_free(name_vec[i]);
1045 cpl_free(used_ifus_str) ;
1046 cpl_free(skip_ifus_str) ;
1047 cpl_frameset_delete(rawframes) ;
1048 cpl_free(used_frame_idx) ;
1049 if (mapping_mode != NULL) cpl_free(mapping_mode) ;
1050 cpl_msg_error(__func__,
"Failed Combination") ;
1051 cpl_error_set(__func__,CPL_ERROR_ILLEGAL_INPUT);
1055 for (i = 0; i < data_cube_counter ; i++)
1056 cpl_imagelist_delete(data_cube_list[i]);
1057 for (i = 0; i < noise_cube_counter ; i++)
1058 cpl_imagelist_delete(noise_cube_list[i]);
1061 kmos_idp_set_nans(cube_combined_data, cube_combined_noise) ;
1064 abmaglim = kmos_idp_compute_abmaglim(cube_combined_data,
1065 sky_res, data_header_list[0]) ;
1066 if (cpl_error_get_code()) {
1068 __func__,
"kmos_idp_compute_abmaglim raised CPL error: \"%s\"; "
1069 "setting abmaglim to 1.0", cpl_error_get_message());
1075 if (!suppress_extension) {
1076 fn_combine = cpl_sprintf(
"%s_%s_%s", COMBINE, tag, name_vec[nv] );
1077 fn_mask = cpl_sprintf(
"%s_%s_%s", EXP_MASK, tag, name_vec[nv] );
1079 fn_combine = cpl_sprintf(
"%s_%s_%d", COMBINE, tag, suppress_index);
1080 fn_mask = cpl_sprintf(
"%s_%s_%d", EXP_MASK, tag, suppress_index);
1084 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1086 cft_fn = cpl_sprintf(
"%s_%s.fits",
"convolved_fov_trimmed", name_vec[nv]);
1087 cpl_image *cft = cpl_image_load(
"convolved_fov_trimmed.fits", CPL_TYPE_DOUBLE, 0, 0);
1088 cpl_image_save(cft, cft_fn, CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
1089 cpl_image_delete(cft);
1091 cft_fn = cpl_sprintf(
"%s_%s.fits",
"convolved_fov", name_vec[nv]);
1092 cft = cpl_image_load(
"convolved_fov.fits", CPL_TYPE_DOUBLE, 0, 0);
1093 cpl_image_save(cft, cft_fn, CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
1094 cpl_image_delete(cft);
1096 cft_fn = cpl_sprintf(
"%s_%s.fits",
"mirrored", name_vec[nv]);
1097 cft = cpl_image_load(
"mirrored.fits", CPL_TYPE_DOUBLE, 0, 0);
1098 cpl_image_save(cft, cft_fn, CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
1099 cpl_image_delete(cft);
1101 cft_fn = cpl_sprintf(
"%s_%s.fits",
"cropped", name_vec[nv]);
1102 cft = cpl_image_load(
"cropped.fits", CPL_TYPE_DOUBLE, 0, 0);
1103 cpl_image_save(cft, cft_fn, CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
1104 cpl_image_delete(cft);
1106 cft_fn = cpl_sprintf(
"%s_%s.fits",
"collapse", name_vec[nv]);
1107 cft = cpl_image_load(
"collapse.fits", CPL_TYPE_DOUBLE, 0, 0);
1108 cpl_image_save(cft, cft_fn, CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
1109 cpl_image_delete(cft);
1111 cft_fn = cpl_sprintf(
"%s_%s.fits",
"mode_limited", name_vec[nv]);
1112 cft = cpl_image_load(
"mode_limited.fits", CPL_TYPE_DOUBLE, 0, 0);
1113 cpl_image_save(cft, cft_fn, CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
1114 cpl_image_delete(cft);
1120 plist = cpl_propertylist_new() ;
1121 if (used_ifus_str != NULL)
1122 cpl_propertylist_update_string(plist,
"ESO PRO USEDIFUS",
1124 if (skip_ifus_str != NULL)
1125 cpl_propertylist_update_string(plist,
"ESO PRO SKIPPEDIFUS",
1129 cpl_propertylist_update_double(plist,
"ESO QC EXPMASK AVG",
1130 kmos_get_median_from_positives(exp_mask)) ;
1133 cpl_propertylist_update_double(plist, KEY_SPEC_RES, spec_res) ;
1134 cpl_propertylist_set_comment(plist, KEY_SPEC_RES, KEY_SPEC_RES_COMMENT);
1137 cpl_propertylist_update_int(plist,
"ESO QC COMBINED_CUBES NB",
1138 data_cube_counter) ;
1141 tmp_str = cpl_sprintf(
"%s.fits", fn_mask) ;
1142 cpl_propertylist_update_string(plist,
"ESO QC EXPMASK NAME", tmp_str) ;
1146 if (collapse_combined) {
1147 tmp_str = cpl_sprintf(
"make_image_%s.fits", fn_combine) ;
1148 cpl_propertylist_update_string(plist,
"ESO QC COLLAPSE NAME",
1154 if (abmaglim > 5.0 && abmaglim < 30.0)
1156 cpl_propertylist_update_double(plist, KEY_ABMAGLIM, abmaglim) ;
1157 cpl_propertylist_set_comment(plist, KEY_ABMAGLIM, KEY_ABMAGLIM_COMMENT);
1162 if (sky_res > 0.15 && sky_res < 5.0)
1164 cpl_propertylist_update_double(plist, KEY_SKY_RES, sky_res) ;
1165 cpl_propertylist_set_comment(plist, KEY_SKY_RES, KEY_SKY_RES_COMMENT) ;
1166 cpl_propertylist_update_double(plist, KEY_SKY_RERR, sky_rerr) ;
1167 cpl_propertylist_set_comment(plist, KEY_SKY_RERR,KEY_SKY_RERR_COMMENT) ;
1171 reflex_suffix = kmos_get_reflex_suffix(mapping_id, ifus_txt, name,
1173 cpl_propertylist_update_string(plist,
"ESO PRO REFLEX SUFFIX",
1175 cpl_free(reflex_suffix) ;
1178 kmos_idp_compute_mjd(frameset, raw_tag, used_frame_idx,
1179 data_cube_counter, &mjd_start, &mjd_end, &date_obs) ;
1182 frame = cpl_frameset_find(rawframes, NULL);
1186 cpl_sprintf(
"%s/%s",
1187 kmos_pfits_get_reflex_suffix(plist),
1188 kmos_pfits_get_obs_targ_name(main_header));
1190 cpl_sprintf(
"%s/%s (DATA)",
1191 kmos_pfits_get_reflex_suffix(plist),
1192 kmos_pfits_get_obs_targ_name(main_header));
1194 cpl_sprintf(
"%s/%s (STAT)",
1195 kmos_pfits_get_reflex_suffix(plist),
1196 kmos_pfits_get_obs_targ_name(main_header));
1199 if (strlen(object_key) > 68) object_key[68] = 0;
1200 if (strlen(object_data_key) > 68) object_data_key[68] = 0;
1201 if (strlen(object_stat_key) > 68) object_stat_key[68] = 0;
1209 cpl_propertylist * plist2 = cpl_propertylist_duplicate(plist) ;
1211 char * fname_expmap = cpl_sprintf(
"%s%s", fn_mask,
".fits") ;
1212 char * my_procatg_expmap = NULL ;
1213 char * my_prodcatg_expmap = NULL ;
1216 if (!strncmp(fn_mask, EXP_MASK_RECONS,
1217 strlen(EXP_MASK_RECONS))||
1218 !strncmp(fn_mask, EXP_MASK_SINGLE_CUBES,
1219 strlen(EXP_MASK_SINGLE_CUBES)) ){
1223 my_procatg_expmap = cpl_sprintf(EXP_MASK) ;
1225 my_prodcatg_expmap = cpl_sprintf(
"ANCILLARY.PIXELCOUNTMAP") ;
1227 my_procatg_expmap = cpl_strdup(fn_mask) ;
1229 cpl_propertylist_update_string(plist2, CPL_DFS_PRO_CATG,
1231 if (my_prodcatg_expmap != NULL) {
1232 cpl_propertylist_update_string(plist2, KEY_PRODCATG,
1233 my_prodcatg_expmap);
1234 cpl_free(my_prodcatg_expmap) ;
1235 cpl_propertylist_set_comment(plist2, KEY_PRODCATG,
1236 KEY_PRODCATG_COMMENT);
1238 cpl_propertylist_update_string(plist2, INSTRUMENT,
"KMOS") ;
1240 cpl_msg_info(cpl_func,
"Writing FITS propertylist product(%s): %s",
1241 my_procatg_expmap, fname_expmap);
1243 cpl_frame * product_frame_expmap = cpl_frame_new();
1244 cpl_frame_set_filename(product_frame_expmap, fname_expmap);
1245 cpl_frame_set_tag(product_frame_expmap, my_procatg_expmap);
1246 cpl_frame_set_type(product_frame_expmap, CPL_FRAME_TYPE_ANY);
1247 cpl_frame_set_group(product_frame_expmap, CPL_FRAME_GROUP_PRODUCT);
1248 cpl_frame_set_level(product_frame_expmap, CPL_FRAME_LEVEL_FINAL);
1249 cpl_free(my_procatg_expmap) ;
1252 cpl_dfs_setup_product_header(plist2, product_frame_expmap, frameset,
1253 parlist, cpl_func, PACKAGE
"/" PACKAGE_VERSION, CPL_DFS_PRO_DID, frame);
1259 crval1 = cpl_propertylist_get_double(data_header_list[0], CRVAL1);
1260 crval2 = cpl_propertylist_get_double(data_header_list[0], CRVAL2);
1261 kmclipm_update_property_double(plist2,
"RA", crval1,
"") ;
1262 kmclipm_update_property_double(plist2,
"DEC", crval2,
"") ;
1265 cpl_propertylist_update_string(plist2,
"OBJECT", object_key) ;
1268 cpl_propertylist_save(plist2, fname_expmap, CPL_IO_CREATE);
1269 cpl_free(fname_expmap) ;
1270 cpl_frameset_insert(frameset, product_frame_expmap);
1273 cpl_propertylist_delete(plist2) ;
1276 kmos_idp_add_files_infos(plist, frameset, raw_tag, used_frame_idx,
1277 data_cube_counter) ;
1278 cpl_free(used_frame_idx) ;
1283 char * fname = cpl_sprintf(
"%s%s", fn_combine,
".fits") ;
1284 char * my_procatg = NULL ;
1285 char * my_prodcatg = NULL ;
1288 if (!strncmp(fn_combine, COMBINED_RECONS, strlen(COMBINED_RECONS)) ||
1289 !strncmp(fn_combine, COMBINED_SINGLE_CUBES,
1290 strlen(COMBINED_SINGLE_CUBES))){
1294 my_procatg = cpl_sprintf(COMBINED_CUBE);
1296 my_procatg = cpl_strdup(fn_combine) ;
1298 cpl_propertylist_update_string(plist, CPL_DFS_PRO_CATG, my_procatg);
1299 if (my_prodcatg != NULL) {
1300 cpl_propertylist_update_string(plist, KEY_PRODCATG, my_prodcatg);
1301 cpl_free(my_prodcatg) ;
1302 cpl_propertylist_set_comment(plist, KEY_PRODCATG,
1303 KEY_PRODCATG_COMMENT);
1305 cpl_propertylist_update_string(plist, INSTRUMENT,
"KMOS") ;
1307 cpl_msg_info(cpl_func,
"Writing FITS propertylist product(%s): %s",
1310 cpl_frame * product_frame = cpl_frame_new();
1311 cpl_frame_set_filename(product_frame, fname);
1312 cpl_frame_set_tag(product_frame, my_procatg);
1313 cpl_frame_set_type(product_frame, CPL_FRAME_TYPE_ANY);
1314 cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
1315 cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
1316 cpl_free(my_procatg) ;
1319 cpl_dfs_setup_product_header(plist, product_frame, frameset, parlist,
1320 cpl_func, PACKAGE
"/" PACKAGE_VERSION, CPL_DFS_PRO_DID, frame);
1323 if (mjd_start > 0.0) {
1324 if (date_obs != NULL) {
1325 cpl_propertylist_update_string(plist, KEY_DATEOBS, date_obs) ;
1326 cpl_free(date_obs) ;
1328 cpl_propertylist_update_string(plist, KEY_DATEOBS,
"") ;
1330 cpl_propertylist_set_comment(plist, KEY_DATEOBS,
1331 KEY_DATEOBS_COMMENT);
1333 cpl_propertylist_update_double(plist, KEY_MJDOBS, mjd_start) ;
1334 cpl_propertylist_set_comment(plist, KEY_MJDOBS, KEY_MJDOBS_COMMENT);
1336 if (mjd_end > 0.0) {
1337 cpl_propertylist_update_double(plist, KEY_MJDEND, mjd_end) ;
1338 cpl_propertylist_set_comment(plist, KEY_MJDEND, KEY_MJDEND_COMMENT);
1342 cpl_propertylist_update_string(plist,
"OBJECT", object_key) ;
1346 cpl_msg_info(cpl_func,
" GETTING TO QC PARAMS LEVEL ");
1349 if (cpl_propertylist_has(main_header, QC_SAT_LEVEL)) {
1350 cpl_propertylist_update_double(plist, QC_SAT_LEVEL,
1351 cpl_propertylist_get_double(main_header, QC_SAT_LEVEL));
1354 if (cpl_propertylist_has(main_header, QC_SAT_NB)) {
1355 cpl_propertylist_update_int(plist, QC_SAT_NB,
1356 cpl_propertylist_get_int(main_header, QC_SAT_NB));
1359 if (cpl_propertylist_has(main_header, QC_PERS_LEVEL)) {
1360 cpl_propertylist_update_double(plist, QC_PERS_LEVEL,
1361 cpl_propertylist_get_double(main_header, QC_PERS_LEVEL));
1364 if (cpl_propertylist_has(main_header, QC_PERS_NB)) {
1365 cpl_propertylist_update_int(plist, QC_PERS_NB,
1366 cpl_propertylist_get_int(main_header, QC_PERS_NB));
1369 if (cpl_propertylist_has(main_header, QC_MASTER_FLAT_MJD_OBS)) {
1371 cpl_propertylist_update_double(plist, QC_DELTA_TIME_FLAT,
1372 (cpl_propertylist_get_double(main_header,
1373 QC_MASTER_FLAT_MJD_OBS)-mjd_start));
1376 if (cpl_propertylist_has(main_header, QC_TELLURIC_GEN_MJD_OBS)) {
1377 cpl_propertylist_update_double(plist, QC_DELTA_TIME_TELL,
1378 (cpl_propertylist_get_double(main_header,
1379 QC_TELLURIC_GEN_MJD_OBS)-mjd_start));
1382 cpl_propertylist_update_string(plist, QC_PROC_SCHEME,
1383 QC_PROC_SCHEME_VAL) ;
1384 cpl_propertylist_set_comment(plist, QC_PROC_SCHEME, QC_PROC_SCHEME_TXT);
1387 if (cpl_propertylist_has(main_header, QC_PARAM_H2O_AVG)) {
1388 cpl_propertylist_update_double(plist, QC_PARAM_H2O_AVG,
1389 cpl_propertylist_get_double(main_header, QC_PARAM_H2O_AVG));
1392 if (cpl_propertylist_has(main_header, QC_PARAM_H2O_RMS)) {
1393 cpl_propertylist_update_double(plist, QC_PARAM_H2O_RMS,
1394 cpl_propertylist_get_double(main_header, QC_PARAM_H2O_RMS));
1397 if (cpl_propertylist_has(main_header, QC_PARAM_AIRM_STD)) {
1399 cpl_msg_info(cpl_func,
" QC_PARAM_AIRM_STD exists ");
1400 cpl_propertylist_update_double(plist,
"ESO QC AIRM DIFF",
1401 fabs(cpl_propertylist_get_double(main_header, QC_PARAM_AIRM_STD)-
1403 (cpl_propertylist_get_double(main_header,
"ESO TEL AIRM START")+
1404 cpl_propertylist_get_double(main_header,
"ESO TEL AIRM END"))/2));
1407 if (cpl_propertylist_has(main_header, QC_PARAM_MEAS_IWV)) {
1408 cpl_propertylist_update_double(plist, QC_PARAM_MEAS_IWV,
1409 cpl_propertylist_get_double(main_header, QC_PARAM_MEAS_IWV));
1412 if (cpl_propertylist_has(main_header,
"ESO TEL AMBI IWV START")){
1413 cpl_propertylist_update_double(plist, QC_PARAM_MEAS_IWV,
1414 (cpl_propertylist_get_double(main_header,
"ESO TEL AMBI IWV START")+
1415 cpl_propertylist_get_double(main_header,
"ESO TEL AMBI IWV END"))/2);
1419 if (cpl_propertylist_has(main_header, QC_PARAM_MEAS_IWV30D)) {
1420 cpl_propertylist_update_double(plist, QC_PARAM_MEAS_IWV30D,
1421 cpl_propertylist_get_double(main_header, QC_PARAM_MEAS_IWV30D));
1424 if (cpl_propertylist_has(main_header,
"ESO TEL AMBI IWV30D START")){
1425 cpl_propertylist_update_double(plist, QC_PARAM_MEAS_IWV30D,
1426 (cpl_propertylist_get_double(main_header,
"ESO TEL AMBI IWV30D START")+
1427 cpl_propertylist_get_double(main_header,
"ESO TEL AMBI IWV30D END"))/2);
1432 if (cpl_propertylist_has(main_header, QC_PARAM_H2O_RATIO)) {
1433 cpl_propertylist_update_double(plist, QC_PARAM_H2O_RATIO,
1434 cpl_propertylist_get_double(main_header, QC_PARAM_H2O_RATIO));
1437 if (cpl_propertylist_has(main_header, QC_PARAM_H2O_AVG ) &&
1438 cpl_propertylist_has(plist,
"ESO TEL AMBI IWV START" ) ){
1439 cpl_propertylist_update_double(plist, QC_PARAM_H2O_RATIO,
1440 (cpl_propertylist_get_double(plist, QC_PARAM_H2O_AVG )/
1441 ((cpl_propertylist_get_double(main_header,
"ESO TEL AMBI IWV START")+
1442 cpl_propertylist_get_double(main_header,
"ESO TEL AMBI IWV END"))/2)));
1452 if (cpl_propertylist_has(main_header, QC_PARAM_H2O_AVG ) &&
1453 cpl_propertylist_has(plist, QC_PARAM_MEAS_IWV )){
1454 cpl_propertylist_update_double(plist, QC_PARAM_H2O_DELTA,
1455 (cpl_propertylist_get_double(plist, QC_PARAM_H2O_AVG )-
1456 cpl_propertylist_get_double(plist, QC_PARAM_MEAS_IWV)));
1467 cpl_propertylist_delete(main_header);
1470 cpl_propertylist_save(plist, fname, CPL_IO_CREATE);
1472 cpl_frameset_insert(frameset, product_frame);
1474 cpl_propertylist_delete(plist) ;
1475 cpl_free(used_ifus_str) ;
1476 cpl_free(skip_ifus_str) ;
1479 if (data_header_list[0] != NULL) {
1480 if (cpl_propertylist_has(data_header_list[0],
"ESO PRO FRNAME")) {
1481 cpl_propertylist_erase(data_header_list[0],
"ESO PRO FRNAME");
1483 if (cpl_propertylist_has(data_header_list[0],
"ESO PRO IFUNR")) {
1484 cpl_propertylist_erase(data_header_list[0],
"ESO PRO IFUNR");
1487 if (noise_header_list[0] != NULL) {
1488 if (cpl_propertylist_has(noise_header_list[0],
"ESO PRO FRNAME")) {
1489 cpl_propertylist_erase(noise_header_list[0],
"ESO PRO FRNAME");
1491 if (cpl_propertylist_has(noise_header_list[0],
"ESO PRO IFUNR")) {
1492 cpl_propertylist_erase(noise_header_list[0],
"ESO PRO IFUNR");
1497 cpl_propertylist_update_string(data_header_list[0],
"BUNIT",
1498 kmos_pfits_get_qc_cube_unit(data_header_list[0])) ;
1499 if (noise_header_list[0] != NULL)
1500 cpl_propertylist_update_string(noise_header_list[0],
"BUNIT",
1501 kmos_pfits_get_qc_cube_unit(noise_header_list[0])) ;
1504 plist = cpl_propertylist_duplicate(data_header_list[0]) ;
1507 cpl_propertylist_update_double(plist, KEY_CRDER3, crder3) ;
1508 cpl_propertylist_set_comment(plist, KEY_CRDER3, KEY_CRDER3_COMMENT);
1511 cpl_propertylist_erase(plist,
"EXPTIME") ;
1514 cpl_propertylist_update_string(plist,
"OBJECT", object_data_key) ;
1516 kmo_dfs_save_cube(cube_combined_data, fn_combine,
"", plist, 0./0.);
1517 cpl_propertylist_delete(plist) ;
1518 cpl_imagelist_delete(cube_combined_data);
1521 plist = cpl_propertylist_duplicate(noise_header_list[0]) ;
1524 cpl_propertylist_erase(plist,
"EXPTIME") ;
1527 cpl_propertylist_update_string(plist,
"OBJECT", object_stat_key) ;
1529 kmo_dfs_save_cube(cube_combined_noise, fn_combine,
"", plist, 0./0.);
1530 cpl_imagelist_delete(cube_combined_noise);
1531 cpl_propertylist_delete(plist) ;
1532 cpl_free(fn_combine);
1535 plist = cpl_propertylist_duplicate(data_header_list[0]) ;
1536 kmos_3dim_clean_plist(plist) ;
1539 cpl_propertylist_update_string(plist,
"BUNIT",
"") ;
1542 cpl_propertylist_update_string(plist,
"OBJECT", object_data_key) ;
1544 kmo_dfs_save_image(exp_mask, fn_mask,
"", plist, 0./0.);
1545 cpl_propertylist_delete(plist) ;
1547 cpl_image_delete(exp_mask);
1549 for (i = 0; i < data_cube_counter ; i++)
1550 cpl_propertylist_delete(data_header_list[i]);
1551 for (i = 0; i < noise_cube_counter ; i++)
1552 cpl_propertylist_delete(noise_header_list[i]);
1553 if (noise_header_list!=NULL && noise_cube_counter==0)
1554 cpl_propertylist_delete(noise_header_list[0]) ;
1555 cpl_free(object_key) ;
1556 cpl_free(object_data_key) ;
1557 cpl_free(object_stat_key) ;
1559 if (skipped_bivector!=NULL) cpl_bivector_delete(skipped_bivector) ;
1560 if (ifus != NULL) cpl_vector_delete(ifus);
1561 cpl_free(data_cube_list);
1562 cpl_free(noise_cube_list);
1563 cpl_free(data_header_list);
1564 cpl_free(noise_header_list);
1565 for (i = 0; i < name_vec_size ; i++) cpl_free(name_vec[i]);
1567 cpl_free(mapping_mode) ;
1572 if (collapse_combined) {
1573 kmos_collapse_cubes(COMBINED_CUBE, frameset, parlist, 0.1,
"",
1574 DEF_REJ_METHOD, DEF_POS_REJ_THRES, DEF_NEG_REJ_THRES,
1575 DEF_ITERATIONS, DEF_NR_MIN_REJ, DEF_NR_MAX_REJ);
1581 cpl_frame * combined_frame ;
1582 const char * combined_fname ;
1583 char * idp_combined_fname ;
1584 cpl_imagelist * cube_combined_error ;
1585 const char * const_data_extname ;
1586 char * data_extname ;
1587 char * error_extname ;
1588 cpl_frameset * combined_frames ;
1589 cpl_frameset * exp_frames ;
1590 cpl_frame * exp_frame;
1591 const char * exp_fname ;
1593 cpl_vector * spec_data_out;
1594 cpl_vector * spec_noise_out;
1597 combined_frames = kmos_extract_frameset(frameset, COMBINED_CUBE) ;
1598 combined_frame = kmo_dfs_get_frame(combined_frames, COMBINED_CUBE);
1599 exp_frames = kmos_extract_frameset(frameset, EXP_MASK) ;
1600 exp_frame = kmo_dfs_get_frame(exp_frames, EXP_MASK);
1601 while (combined_frame != NULL ) {
1602 combined_fname = cpl_frame_get_filename(combined_frame);
1605 cube_combined_data=cpl_imagelist_load(combined_fname, CPL_TYPE_FLOAT,1);
1608 cube_combined_error = kmos_idp_compute_error(cube_combined_data);
1611 pixnoise = kmos_get_mode(cube_combined_error) ;
1614 main_header = cpl_propertylist_load(combined_fname, 0) ;
1615 plist = cpl_propertylist_load(combined_fname, 1) ;
1616 kmos_idp_prepare_main_keys(main_header, frameset, plist,
1617 raw_tag, cube_combined_error) ;
1618 cpl_propertylist_delete(plist) ;
1619 frame = cpl_frameset_find(rawframes, NULL);
1622 idp_combined_fname = cpl_sprintf(
"IDP_%s", combined_fname) ;
1626 cpl_frame * product_frame = kmos_setup_idp_prime_header(main_header, idp_combined_fname,
1627 combined_fname,frameset, frame, parlist, pixnoise, &plist);
1630 cpl_propertylist_save(plist, idp_combined_fname, CPL_IO_CREATE);
1632 cpl_propertylist_delete(plist) ;
1633 cpl_frameset_insert(frameset, product_frame);
1637 plist = cpl_propertylist_load(combined_fname, 1) ;
1638 const_data_extname = kmos_pfits_get_extname(plist) ;
1639 error_extname = kmos_idp_compute_error_extname(const_data_extname) ;
1642 kmos_idp_prepare_data_keys(plist, error_extname) ;
1643 kmos_idp_prepare_data_hduclas(plist);
1644 cpl_free(error_extname) ;
1647 cpl_imagelist_save(cube_combined_data, idp_combined_fname,
1649 plist, CPL_IO_EXTEND) ;
1650 cpl_propertylist_delete(plist) ;
1654 plist = cpl_propertylist_load(combined_fname, 1) ;
1655 kmclipm_update_property_string(plist, EXTNAME,
"DATA",
"");
1656 data_extname = cpl_strdup(kmos_pfits_get_extname(plist)) ;
1657 error_extname = kmos_idp_compute_error_extname(data_extname) ;
1658 kmos_idp_prepare_error_keys(plist, error_extname, data_extname);
1659 kmos_idp_prepare_error_hduclas(plist);
1660 cpl_free(error_extname) ;
1661 cpl_free(data_extname) ;
1665 cpl_sprintf(
"%s/%s (STAT)",
1666 kmos_pfits_get_reflex_suffix(main_header),
1667 kmos_pfits_get_obs_targ_name(main_header));
1670 if (strlen(object_stat_key) > 68) object_stat_key[68] = 0;
1673 cpl_propertylist_update_string(plist,
"OBJECT", object_stat_key) ;
1676 cpl_imagelist_save(cube_combined_error, idp_combined_fname,
1678 plist, CPL_IO_EXTEND) ;
1679 cpl_free(idp_combined_fname);
1681 cpl_propertylist_delete(plist);
1686 exp_fname = cpl_frame_get_filename(exp_frame);
1687 exp_mask = cpl_image_load(exp_fname, CPL_TYPE_FLOAT, 0, 1);
1688 cpl_image_threshold(exp_mask, 0.0, 1.0, 0.0, 1.0);
1690 kmo_priv_extract_spec(cube_combined_data, cube_combined_error, exp_mask, &spec_data_out,
1696 char *idp_spec_fname = cpl_sprintf(
"IDP_QC_SPEC_%s", combined_fname);
1698 cpl_frame *product_spec_frame = kmos_setup_idp_prime_header(main_header, idp_spec_fname,
1699 combined_fname, frameset, frame, parlist, pixnoise, &plist);
1701 cpl_frameset_insert(frameset, product_spec_frame);
1705 cpl_propertylist *spec_plist = cpl_propertylist_load(combined_fname, 1);
1710 int spec_npix = cpl_vector_get_size(spec_data_out);
1711 double crval3_local = kmos_pfits_get_crval3(spec_plist);
1712 double cd3_3_local = kmos_pfits_get_cd3_3(spec_plist);
1713 double crpix3_local = kmos_pfits_get_crpix3(spec_plist);
1714 cpl_vector *wavelength_vec = NULL;
1715 if (spec_npix > 0) {
1716 wavelength_vec = cpl_vector_new(spec_npix);
1717 for (i = 0; i < spec_npix; i++) {
1718 double pix = (double)(i + 1);
1719 double wave = crval3_local + (pix - crpix3_local) * cd3_3_local;
1720 cpl_vector_set(wavelength_vec, i, wave);
1723 char *const_data_extname = kmos_pfits_get_extname(spec_plist);
1724 error_extname = kmos_idp_compute_error_extname(const_data_extname);
1727 kmos_idp_prepare_data_keys(spec_plist, error_extname);
1728 kmos_idp_prepare_data_hduclas(spec_plist);
1729 cpl_free(error_extname);
1732 spec_plist = kmo_priv_update_header(spec_plist);
1734 cpl_table * spec_table = cpl_table_new(cpl_vector_get_size(spec_data_out));
1735 cpl_table_wrap_double(spec_table, cpl_vector_get_data(wavelength_vec),
"wavelength");
1736 cpl_table_wrap_double(spec_table, cpl_vector_get_data(spec_data_out),
"flux");
1737 cpl_table_wrap_double(spec_table, cpl_vector_get_data(spec_noise_out),
"flux_error");
1739 cpl_table_save(spec_table, plist, spec_plist, idp_spec_fname, CPL_IO_CREATE);
1740 cpl_table_unwrap(spec_table,
"wavelength");
1741 cpl_table_unwrap(spec_table,
"flux");
1742 cpl_table_unwrap(spec_table,
"flux_error");
1743 cpl_table_delete(spec_table);
1746 cpl_propertylist_delete(plist);
1747 cpl_propertylist_delete(spec_plist);
1748 cpl_vector_delete(wavelength_vec);
1749 cpl_vector_delete(spec_data_out);
1750 cpl_vector_delete(spec_noise_out);
1753 cpl_image_delete(exp_mask);
1754 cpl_free(idp_spec_fname);
1757 cpl_propertylist_delete(main_header);
1758 cpl_free(object_stat_key);
1759 cpl_imagelist_delete(cube_combined_data);
1760 cpl_imagelist_delete(cube_combined_error);
1763 combined_frame = kmo_dfs_get_frame(combined_frames, NULL);
1764 exp_frame = kmo_dfs_get_frame(exp_frames, NULL);
1766 cpl_frameset_delete(rawframes);
1767 cpl_frameset_delete(combined_frames);
1768 cpl_frameset_delete(exp_frames);
1782static char * kmos_combine_create_ifus_string(
1783 const int * frame_idx,
1791 if (nb > 1000)
return NULL ;
1792 if (nb == 0)
return NULL ;
1793 for (i=0 ; i<nb ; i++) {
1795 if (frame_idx[i] < 10 && ifus[i] < 10)
1796 if (i==0) sprintf(tmp,
"%1d:%1d", frame_idx[i], ifus[i]);
1797 else sprintf(tmp,
",%1d:%1d", frame_idx[i], ifus[i]);
1798 else if (frame_idx[i] < 10 && ifus[i] >= 10)
1799 if (i==0) sprintf(tmp,
"%1d:%2d", frame_idx[i], ifus[i]);
1800 else sprintf(tmp,
",%1d:%2d", frame_idx[i], ifus[i]);
1801 else if (frame_idx[i] >= 10 && ifus[i] < 10)
1802 if (i==0) sprintf(tmp,
"%2d:%1d", frame_idx[i], ifus[i]);
1803 else sprintf(tmp,
",%2d:%1d", frame_idx[i], ifus[i]);
1804 else if (frame_idx[i] >= 10 && ifus[i] >= 10)
1805 if (i==0) sprintf(tmp,
"%2d:%2d", frame_idx[i], ifus[i]);
1806 else sprintf(tmp,
",%2d:%2d", frame_idx[i], ifus[i]);
1809 if (i==0) strcpy(out, tmp) ;
1810 else strcat(out, tmp);
1814 if (strlen(out) > 51)
return NULL ;
1816 return cpl_strdup(out) ;
1826static int kmos_combine_collect_data(
1827 const cpl_propertylist * recons_prim_header,
1828 const cpl_propertylist * recons_ext_header,
1834 double crval3, cd3_3, crpix3, airm_start, airm_end, fwhmlin ;
1838 if (recons_prim_header == NULL || recons_ext_header == NULL)
return -1;
1839 if (lambda == NULL || seeing == NULL || airmass == NULL)
return -1;
1842 crval3 = kmos_pfits_get_crval3(recons_ext_header) ;
1843 cd3_3 = kmos_pfits_get_cd3_3(recons_ext_header) ;
1844 crpix3 = kmos_pfits_get_crpix3(recons_ext_header) ;
1845 naxis3 = kmos_pfits_get_naxis3(recons_ext_header) ;
1846 airm_start = kmos_pfits_get_airmass_start(recons_prim_header) ;
1847 airm_end = kmos_pfits_get_airmass_end(recons_prim_header) ;
1848 fwhmlin = kmos_pfits_get_ia_fwhmlin(recons_prim_header) ;
1849 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1851 cpl_msg_error(__func__,
"Cannot collect data from header") ;
1856 *lambda = (crval3 + (crval3 + cd3_3 * naxis3 - (crpix3-1) * cd3_3)) / 2.0;
1859 *airmass = (airm_start + airm_end) / 2.0 ;
1874static cpl_bivector * kmos_combine_parse_skipped(
const char * str)
1876 cpl_bivector * out ;
1877 cpl_vector * out_x ;
1878 cpl_vector * out_y ;
1886 if (str == NULL)
return NULL ;
1890 my_str = cpl_strdup(str) ;
1893 for (s2 = my_str; s2; ) {
1894 while (*s2 ==
' ' || *s2 ==
'\t') s2++;
1895 s1 = strsep(&s2,
",") ;
1897 if (sscanf(s1,
" %i:%i", &val1, &val2) == 2) {
1903 if (nb_values == 0)
return NULL ;
1906 out = cpl_bivector_new(nb_values) ;
1907 out_x = cpl_bivector_get_x(out) ;
1908 out_y = cpl_bivector_get_y(out) ;
1912 my_str = cpl_strdup(str) ;
1913 for (s2 = my_str; s2; ) {
1914 while (*s2 ==
' ' || *s2 ==
'\t') s2++;
1915 s1 = strsep(&s2,
",") ;
1917 if (sscanf(s1,
" %i:%i", &val1, &val2) == 2) {
1918 cpl_vector_set(out_x, nb_values, val1) ;
1919 cpl_vector_set(out_y, nb_values, val2) ;
1937static int kmos_combine_is_skipped(
1938 const cpl_bivector * skipped,
1942 const cpl_vector * vec_x ;
1943 const cpl_vector * vec_y ;
1948 if (skipped == NULL)
return 0;
1951 vec_x = cpl_bivector_get_x_const(skipped) ;
1952 vec_y = cpl_bivector_get_y_const(skipped) ;
1955 for (i=0 ; i<cpl_bivector_get_size(skipped) ; i++) {
1956 val1 = cpl_vector_get(vec_x, i) ;
1957 val2 = cpl_vector_get(vec_y, i) ;
1958 if (fabs(val1-frame_idx)<1e-3 && fabs(val2-ifu_nr)<1e-3)
return 1 ;
1971static int kmos_idp_set_nans(
1972 cpl_imagelist * data,
1973 cpl_imagelist * error)
1975 cpl_image * data_curr ;
1976 float * pdata_curr ;
1978 cpl_size i, j, k, nx, ny, ni ;
1981 if (data == NULL || error == NULL)
return -1 ;
1984 data_curr = cpl_imagelist_get(data, 0) ;
1985 nx = cpl_image_get_size_x(data_curr) ;
1986 ny = cpl_image_get_size_y(data_curr) ;
1987 ni = cpl_imagelist_get_size(data) ;
1990 for (j=0 ; j<ny ; j++) {
1991 for (i=0 ; i<nx ; i++) {
1993 for (k=0 ; k<ni && set_to_nan ; k++) {
1994 data_curr = cpl_imagelist_get(data, k) ;
1995 pdata_curr = cpl_image_get_data_float(data_curr) ;
1997 if (fabs(pdata_curr[i+j*nx])<1e-50) {
1998 pdata_curr[i+j*nx] = 0./0. ;
2007 for (j=0 ; j<ny ; j++) {
2008 for (i=0 ; i<nx ; i++) {
2010 for (k=ni-1 ; k>=0 && set_to_nan ; k--) {
2011 data_curr = cpl_imagelist_get(data, k) ;
2012 pdata_curr = cpl_image_get_data_float(data_curr) ;
2014 if (fabs(pdata_curr[i+j*nx])<1e-50) {
2015 pdata_curr[i+j*nx] = 0./0. ;
2032static double kmos_get_mode(
2033 cpl_imagelist * cube)
2035 cpl_image * data_curr ;
2036 float * pdata_curr ;
2037 cpl_vector * values ;
2039 double min, max, modevalue ;
2040 cpl_size i, j, k, nx, ny, ni, nval ;
2045 if (cube == NULL)
return -1 ;
2048 data_curr = cpl_imagelist_get(cube, 0) ;
2049 nx = cpl_image_get_size_x(data_curr) ;
2050 ny = cpl_image_get_size_y(data_curr) ;
2051 ni = cpl_imagelist_get_size(cube) ;
2056 for (k=0 ; k<ni ; k++) {
2057 data_curr = cpl_imagelist_get(cube, k) ;
2058 pdata_curr = cpl_image_get_data_float(data_curr) ;
2059 for (j=0 ; j<ny ; j++) {
2060 for (i=0 ; i<nx ; i++) {
2061 if ((!isnan(pdata_curr[i+j*nx])) &&
2062 fabs(pdata_curr[i+j*nx])>1e-30) {
2068 if (nval < 3)
return 0.0 ;
2071 values = cpl_vector_new(nval) ;
2072 pvalues = cpl_vector_get_data(values) ;
2074 for (k=0 ; k<ni ; k++) {
2075 data_curr = cpl_imagelist_get(cube, k) ;
2076 pdata_curr = cpl_image_get_data_float(data_curr) ;
2077 for (j=0 ; j<ny ; j++) {
2078 for (i=0 ; i<nx ; i++) {
2079 if ((!isnan(pdata_curr[i+j*nx])) &&
2080 fabs(pdata_curr[i+j*nx])>1e-30) {
2081 pvalues[nval] = pdata_curr[i+j*nx] ;
2089 cpl_vector_sort(values, CPL_SORT_ASCENDING) ;
2090 pvalues = cpl_vector_get_data(values) ;
2094 max = pvalues[nval-1] ;
2095 bins = cpl_calloc(nbins,
sizeof(
int)) ;
2096 for (k=0 ; k<nval ; k++) {
2097 if (fabs(max-min) > 1e-12)
2098 ind = (int)(nbins * (pvalues[k] - min) / (max - min)) ;
2104 cpl_vector_delete(values) ;
2108 for (k=0 ; k<nbins ; k++) {
2109 if (bins[k] > bins[ind]) ind = k ;
2115 modevalue = min + (ind * (max-min) / nbins) ;
2116 if (modevalue < (max-min) / nbins) modevalue = (max-min) / nbins ;
2127static double kmos_get_median_from_positives(
2128 cpl_image * exp_mask)
2132 cpl_size nx, ny, i, j, npos ;
2133 cpl_vector * pos_values ;
2134 double * ppos_values ;
2137 if (exp_mask == NULL)
return -1.0 ;
2141 pexp_mask = cpl_image_get_data_float(exp_mask) ;
2142 nx = cpl_image_get_size_x(exp_mask) ;
2143 ny = cpl_image_get_size_y(exp_mask) ;
2146 for (j=0 ; j<ny ; j++) {
2147 for (i=0 ; i<nx ; i++) {
2148 if (pexp_mask[i+j*nx] > 1e-3) npos++ ;
2154 pos_values = cpl_vector_new(npos) ;
2155 ppos_values = cpl_vector_get_data(pos_values) ;
2157 for (j=0 ; j<ny ; j++) {
2158 for (i=0 ; i<nx ; i++) {
2159 if (pexp_mask[i+j*nx] > 1e-3) {
2160 ppos_values[npos] = pexp_mask[i+j*nx] ;
2167 med = cpl_vector_get_median(pos_values);
2168 cpl_vector_delete(pos_values) ;
2173 cpl_frame * kmos_setup_idp_prime_header(cpl_propertylist * main_header,
char * filename,
2174 char * base_filename, cpl_frameset * frameset,
2175 cpl_frame * frame, cpl_parameterlist * parlist,
2176 double pixnoise, cpl_propertylist ** plist)
2179 if (strstr(filename,
"QC_SPEC") != NULL)
2181 procat =
"IDP_QC_SPEC";
2185 procat = cpl_propertylist_get_string(main_header, CPL_DFS_PRO_CATG);
2187 cpl_msg_info(cpl_func,
"Writing FITS propertylist product(%s): %s", procat, filename);
2189 cpl_frame *product_frame = cpl_frame_new();
2190 cpl_frame_set_filename(product_frame, filename);
2191 cpl_frame_set_tag(product_frame, procat);
2192 cpl_frame_set_type(product_frame, CPL_FRAME_TYPE_ANY);
2193 cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
2194 cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
2196 *plist = cpl_propertylist_duplicate(main_header);
2199 if (strcmp(procat,
"IDP_QC_SPEC") == 0)
2201 if (cpl_propertylist_has(*plist, KEY_PRODCATG))
2203 cpl_propertylist_erase(*plist, KEY_PRODCATG);
2208 double mjd_start = cpl_propertylist_get_double(*plist, KEY_MJDOBS);
2209 char *date_obs = cpl_strdup(cpl_propertylist_get_string(*plist, KEY_DATEOBS));
2210 double mjd_end = cpl_propertylist_get_double(*plist, KEY_MJDEND);
2212 if (cpl_error_get_code())
2216 char *object_key = cpl_strdup(kmos_pfits_get_object(*plist));
2219 cpl_dfs_setup_product_header(*plist, product_frame, frameset, parlist,
2220 cpl_func, PACKAGE
"/" PACKAGE_VERSION, CPL_DFS_PRO_DID, frame);
2223 cpl_propertylist_update_string(*plist,
"OBJECT", object_key);
2224 cpl_free(object_key);
2228 cpl_propertylist *plist2 = cpl_propertylist_load(base_filename, 1);
2229 double crval1 = cpl_propertylist_get_double(plist2, CRVAL1);
2230 double crval2 = cpl_propertylist_get_double(plist2, CRVAL2);
2231 cpl_propertylist_delete(plist2);
2232 kmclipm_update_property_double(*plist,
"RA", crval1,
"");
2233 kmclipm_update_property_double(*plist,
"DEC", crval2,
"");
2237 kmclipm_update_property_string(*plist,
"SPECSYS",
"TOPOCENT",
"");
2240 if (mjd_start > 0.0)
2242 if (date_obs != NULL)
2244 cpl_propertylist_update_string(*plist, KEY_DATEOBS, date_obs);
2245 cpl_propertylist_set_comment(*plist, KEY_DATEOBS,
2246 KEY_DATEOBS_COMMENT);
2248 cpl_propertylist_update_double(*plist, KEY_MJDOBS, mjd_start);
2249 cpl_propertylist_set_comment(*plist, KEY_MJDOBS, KEY_MJDOBS_COMMENT);
2251 if (date_obs != NULL)
2255 cpl_propertylist_update_double(*plist, KEY_MJDEND, mjd_end);
2256 cpl_propertylist_set_comment(*plist, KEY_MJDEND, KEY_MJDEND_COMMENT);
2260 cpl_propertylist_update_double(*plist, KEY_PIXNOISE, pixnoise);
2261 cpl_propertylist_set_comment(*plist, KEY_PIXNOISE, KEY_PIXNOISE_COMMENT);
2263 return product_frame;
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.