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"
52#define CPL_DFS_PRO_DID "PRO-1.16"
58static double kmos_get_median_from_positives(
59 cpl_image * exp_mask) ;
60static double kmos_get_mode(
61 cpl_imagelist * error) ;
62static int kmos_idp_set_nans(
64 cpl_imagelist * error) ;
65static int kmos_combine_collect_data(
66 const cpl_propertylist * recons_prim_header,
67 const cpl_propertylist * recons_ext_header,
71static char * kmos_combine_create_ifus_string(
const int *,
const int *,
int);
72static cpl_bivector * kmos_combine_parse_skipped(
const char *) ;
73static int kmos_combine_is_skipped(
const cpl_bivector *,
int,
int) ;
75static int kmos_combine_create(cpl_plugin *);
76static int kmos_combine_exec(cpl_plugin *);
77static int kmos_combine_destroy(cpl_plugin *);
78static int kmos_combine(cpl_parameterlist *, cpl_frameset *);
84static char kmos_combine_description[] =
85"This recipe shifts several exposures of an object and combines them. Diffe-\n"
86"rent methods to match the exposures are described here (--method parameter).\n"
87"The output cube is larger than the input cubes, according to the shifts to\n"
88"be applied. Additionally a border of NaN values is added. The WCS is the\n"
89"same as for the first exposure.\n"
90"For each spatial/spectral pixel a new value is calculated (according the\n"
91"--cmethod parameter) and written into the output cube.\n"
92"Only exposures with the same WCS orientation can be combined (except\n"
93"-–method=”none”), north must point to the same direction. It is recommended\n"
94"to apply any rotation possibly after combining.\n"
96"The behavior of the selection of IFUs to combine differs for some templates\n"
97"and can be controlled with the parameters --name and --ifus.\n"
98"If the input data cubes stem from templates KMOS_spec_obs_mapping8 or\n"
99"KMOS_spec_obs_mapping24 all extensions from all input frames are combined\n"
100"into a single map by default (like in recipe kmo_sci_red). If just the area\n"
101"of a specific IFU should be combined, the parameter --ifus can be specified,\n"
102"or more easily --name.\n"
103"If the input data cubes stem from other templates like e.g.\n"
104"KMOS_spec_obs_freedither all extensions of all input frames are combined\n"
105"into several output frames by default. The input IFUs are grouped according\n"
106"to their targeted object name stored in the keywords ESO OCS ARMx NAME. If \n"
107"just a specific object should be combined, its name can be specified with \n"
108"--name. If arbitrary IFUs shoukd be comined, one can specify these with the\n"
111"The default mapping mode is done via the --name parameter, where the name of\n"
112"the object has to be provided. The recipe searches in input data cubes IFUs\n"
113"pointing to that object.\n"
115"---------------------------------------------------------------------------\n"
119" category Type Explanation Required #Frames\n"
120" -------- ----- ----------- -------- -------\n"
121" CUBE_OBJECT F3I data frame Y 2-n \n"
126" category Type Explanation\n"
127" -------- ----- -----------\n"
128" COMBINE_ F3I Combined data cube\n"
129" EXP_MASK F3I Exposure time mask\n"
130" SCI_COMBINED_COLL (optional) Collapsed combined cube\n"
131" (set --collapse_combined)\n"
132"---------------------------------------------------------------------------\n"
159 cpl_recipe *recipe = cpl_calloc(1,
sizeof *recipe);
160 cpl_plugin *plugin = &recipe->interface;
162 cpl_plugin_init(plugin,
165 CPL_PLUGIN_TYPE_RECIPE,
167 "Combine reconstructed cubes",
168 kmos_combine_description,
169 "Alex Agudo Berbel, Y. Jung",
170 "https://support.eso.org/",
174 kmos_combine_destroy);
175 cpl_pluginlist_append(list, plugin);
189static int kmos_combine_create(cpl_plugin *plugin)
195 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
196 recipe = (cpl_recipe *)plugin;
201 recipe->parameters = cpl_parameterlist_new();
205 p = cpl_parameter_new_value(
"kmos.kmos_combine.name", CPL_TYPE_STRING,
206 "Name of the object to combine.",
"kmos.kmos_combine",
"");
207 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"name");
208 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
209 cpl_parameterlist_append(recipe->parameters, p);
212 p = cpl_parameter_new_value(
"kmos.kmos_combine.ifus", CPL_TYPE_STRING,
213 "The indices of the IFUs to combine. " "\"ifu1;ifu2;...\"",
214 "kmos.kmos_combine",
"");
215 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ifus");
216 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
217 cpl_parameterlist_append(recipe->parameters, p);
220 p = cpl_parameter_new_value(
"kmos.kmos_combine.method", CPL_TYPE_STRING,
221 "The shifting method: "
222 "'none': no shifting, combined directly (default), "
223 "'header': shift according to WCS, "
224 "'center': centering algorithm, "
225 "'user': read shifts from file",
226 "kmos.kmos_combine",
"none");
227 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"method");
228 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
229 cpl_parameterlist_append(recipe->parameters, p);
232 p = cpl_parameter_new_value(
"kmos.kmos_combine.fmethod", CPL_TYPE_STRING,
233 "The fitting method (applies only when method='center'): "
234 "'gauss': fit a gauss function to collapsed image (default), "
235 "'moffat': fit a moffat function to collapsed image",
236 "kmos.kmos_combine",
"gauss");
237 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"fmethod");
238 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
239 cpl_parameterlist_append(recipe->parameters, p);
242 p = cpl_parameter_new_value(
"kmos.kmos_combine.filename", CPL_TYPE_STRING,
243 "The path to the file with the shift vectors (method='user')",
244 "kmos.kmos_combine",
"");
245 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"filename");
246 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
247 cpl_parameterlist_append(recipe->parameters, p);
250 p = cpl_parameter_new_value(
"kmos.kmos_combine.flux", CPL_TYPE_BOOL,
251 "Apply flux conservation: (TRUE (apply) or FALSE (don't apply)",
252 "kmos.kmos_combine", FALSE);
253 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"flux");
254 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
255 cpl_parameterlist_append(recipe->parameters, p);
258 p = cpl_parameter_new_value(
"kmos.kmos_combine.edge_nan", CPL_TYPE_BOOL,
259 "Set borders of cubes to NaN before combining them."
260 "(TRUE (apply) or FALSE (don't apply)",
"kmos.kmos_combine", FALSE);
261 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"edge_nan");
262 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
263 cpl_parameterlist_append(recipe->parameters, p);
266 p = cpl_parameter_new_value(
"kmos.kmos_combine.skipped_frames",
268 "Comma separated List of IFUs to skip for the combination. "
269 "An IFU is specified with R:I."
270 "R is the index (start 1) of the recons. frame, I the IFU nb",
271 "kmos.kmos_combine",
"");
272 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skipped_frames");
273 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
274 cpl_parameterlist_append(recipe->parameters, p);
277 p = cpl_parameter_new_value(
"kmos.kmos_combine.suppress_extension",
278 CPL_TYPE_BOOL,
"Suppress arbitrary filename extension.",
279 "kmos.kmos_combine", FALSE);
280 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"suppress_extension");
281 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
282 cpl_parameterlist_append(recipe->parameters, p);
285 p = cpl_parameter_new_value(
"kmos.kmos_combine.collapse_combined",
286 CPL_TYPE_BOOL,
"Flag to collapse the combined images",
287 "kmos.kmos_combine", FALSE);
288 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"collapse_combined");
289 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
290 cpl_parameterlist_append(recipe->parameters, p);
292 return kmos_combine_pars_create(recipe->parameters,
"kmos.kmos_combine",
293 DEF_REJ_METHOD, FALSE);
303static int kmos_combine_exec(cpl_plugin *plugin)
308 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
309 recipe = (cpl_recipe *)plugin;
312 return kmos_combine(recipe->parameters, recipe->frames);
322static int kmos_combine_destroy(cpl_plugin *plugin)
327 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
328 recipe = (cpl_recipe *)plugin;
331 cpl_parameterlist_delete(recipe->parameters);
349static int kmos_combine(cpl_parameterlist *parlist, cpl_frameset *frameset)
351 const cpl_parameter * par ;
352 cpl_frameset * rawframes ;
353 const char * raw_tag,
360 double cpos_rej, cneg_rej, fwhm_ar_med, fwhm_ne_med,
361 spec_res, fwhm_ar_val, fwhm_ne_val, pos_ar_val,
362 pos_ne_val, airmass, lambda, seeing, sky_res,
363 sky_rerr, abmaglim, outer_scale,
364 crval1, crval2, pos_ar_med, pos_ne_med,
367 int citer, cmin, cmax, nr_frames, index,
368 data_cube_counter, skip_cube_counter,
369 noise_cube_counter, flux, edge_nan, name_vec_size,
370 found, suppress_extension, ifu_nr,
371 nv, collapse_combined, mapping_id, fwhm_count,
373 int suppress_index = 0;
381 const char * frame_filename,
383 cpl_image * exp_mask ;
384 cpl_imagelist ** data_cube_list,
386 * cube_combined_data,
387 * cube_combined_noise ;
388 cpl_propertylist * main_header,
390 ** noise_header_list,
393 cpl_vector * pos_ar ;
394 cpl_vector * pos_ne ;
395 cpl_vector * fwhm_ar ;
396 cpl_vector * fwhm_ne ;
397 cpl_vector * sky_res_vec ;
398 cpl_vector * airmass_vec ;
399 cpl_vector * seeing_vec ;
400 cpl_vector * lambda_vec ;
401 cpl_vector * tmp_vec ;
402 char * reflex_suffix ;
403 cpl_bivector * skipped_bivector ;
407 int * used_frame_idx ;
409 char * used_ifus_str ;
410 int * skip_frame_idx ;
412 char * skip_ifus_str ;
413 enum extrapolationType extrapol_enum = NONE_CLIPPING;
414 double light_speed, mjd_start, mjd_end ;
417 char * object_data_key ;
418 char * object_stat_key ;
422 if (kmos_check_and_set_groups(frameset) != CPL_ERROR_NONE) {
423 return cpl_error_get_code();
427 light_speed = 299792.48 ;
430 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_combine.method");
431 method = cpl_parameter_get_string(par) ;
432 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_combine.fmethod");
433 fmethod = cpl_parameter_get_string(par) ;
434 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_combine.filename");
435 filename = cpl_parameter_get_string(par) ;
436 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_combine.ifus");
437 ifus_txt = cpl_parameter_get_string(par) ;
438 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_combine.name");
439 name = cpl_parameter_get_string(par) ;
440 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_combine.flux");
441 flux = cpl_parameter_get_bool(par) ;
442 par = cpl_parameterlist_find_const(parlist,
443 "kmos.kmos_combine.skipped_frames");
444 skipped_frames = cpl_parameter_get_string(par) ;
445 par = cpl_parameterlist_find_const(parlist,
"kmos.kmos_combine.edge_nan");
446 edge_nan = cpl_parameter_get_bool(par) ;
447 par = cpl_parameterlist_find_const(parlist,
448 "kmos.kmos_combine.suppress_extension");
449 suppress_extension = cpl_parameter_get_bool(par) ;
450 kmos_combine_pars_load(parlist,
"kmos.kmos_combine", &cmethod, &cpos_rej,
451 &cneg_rej, &citer, &cmin, &cmax, FALSE);
452 par = cpl_parameterlist_find_const(parlist,
453 "kmos.kmos_combine.collapse_combined");
454 collapse_combined = cpl_parameter_get_bool(par);
457 if (strcmp(method,
"none") && strcmp(method,
"header") &&
458 strcmp(method,
"center") && strcmp(method,
"user")) {
459 cpl_msg_error(__func__,
460 "shift methods must be 'none', 'header', 'center' or 'user'") ;
461 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
464 if (strcmp(ifus_txt,
"") && strcmp(name,
"")) {
465 cpl_msg_error(__func__,
466 "name and IFU indices cannot be both provided") ;
467 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
470 if (!strcmp(method,
"user") && !strcmp(filename,
"")) {
471 cpl_msg_error(__func__,
472 "path of file with shift information must be provided") ;
473 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
478 skipped_bivector = NULL ;
479 if (strcmp(skipped_frames,
"")) {
480 skipped_bivector = kmos_combine_parse_skipped(skipped_frames) ;
481 if (skipped_bivector != NULL)
482 cpl_msg_info(__func__,
"Skip the following IFU: %s",
487 rawframes = cpl_frameset_duplicate(frameset) ;
488 cpl_frameset_erase(rawframes,
"OH_SPEC") ;
491 nr_frames = cpl_frameset_get_size(rawframes);
493 if (skipped_bivector!=NULL) cpl_bivector_delete(skipped_bivector) ;
494 cpl_frameset_delete(rawframes) ;
495 cpl_msg_error(__func__,
"At least one frames must be provided") ;
496 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
501 frame = cpl_frameset_get_position(rawframes, 0);
502 raw_tag = cpl_frame_get_tag(frame) ;
505 if (strcmp(ifus_txt,
"")) {
506 ifus = kmo_identify_values(ifus_txt);
507 if (ifus == NULL || cpl_vector_get_size(ifus) != nr_frames) {
508 if (ifus != NULL) cpl_vector_delete(ifus);
509 if (skipped_bivector!=NULL) cpl_bivector_delete(skipped_bivector) ;
510 cpl_frameset_delete(rawframes) ;
511 cpl_msg_error(__func__,
"ifus size must match the science frames") ;
512 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
520 mapping_mode = NULL ;
521 cpl_size fs_size = cpl_frameset_get_size(rawframes);
522 for (ci = 0; ci < fs_size; ci++) {
523 frame = cpl_frameset_get_position(rawframes, ci);
524 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(frame),0);
525 if (cpl_propertylist_has(tmp_header, TPL_ID)) {
526 tmp_strc = cpl_propertylist_get_string(tmp_header, TPL_ID);
527 if (mapping_mode == NULL) {
528 if (!strcmp(tmp_strc, MAPPING8))
529 mapping_mode = cpl_sprintf(
"%s", tmp_strc);
530 if (!strcmp(tmp_strc, MAPPING24))
531 mapping_mode = cpl_sprintf(
"%s", tmp_strc);
533 if (strcmp(tmp_strc, mapping_mode)) {
534 cpl_msg_warning(__func__,
535 "There are different TPL IDs in input: %s and %s",
536 tmp_strc, mapping_mode);
540 cpl_propertylist_delete(tmp_header);
544 if (mapping_mode != NULL) {
545 if (!strcmp(ifus_txt,
"") && !strcmp(name,
"")) {
546 cpl_msg_info(__func__,
"A map with all IFUs will be generated");
547 extrapol_enum = BCS_NATURAL;
549 if (strcmp(ifus_txt,
"")) {
550 cpl_msg_info(__func__,
551 "IFUs %s are requested - switch off mapping mode",
554 if (strcmp(name,
"")) {
555 cpl_msg_info(__func__,
556 "Object name %s is requested - switch off mapping mode",
559 cpl_free(mapping_mode);
560 mapping_mode = NULL ;
566 if (mapping_mode == NULL) {
568 cpl_msg_info(__func__,
"Mode : Non-Mapping") ;
570 if (!strcmp(mapping_mode, MAPPING8)) {
572 cpl_msg_info(__func__,
"Mode : Mapping 8") ;
574 if (!strcmp(mapping_mode, MAPPING24)) {
576 cpl_msg_info(__func__,
"Mode : Mapping 24") ;
581 name_vec = cpl_calloc(nr_frames*KMOS_NR_IFUS,
sizeof(
char*));
584 if (!strcmp(ifus_txt,
"") && !strcmp(name,
"") && mapping_mode==NULL) {
587 for (i = 0; i < nr_frames; i++) {
588 tmp_str = cpl_sprintf(
"%d", i);
589 frame = kmo_dfs_get_frame(rawframes, tmp_str);
591 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) {
593 tmp_str = kmo_get_name_from_ocs_ifu(frame, ifu_nr);
594 if (tmp_str != NULL) {
595 for (j = 0; j < name_vec_size; j++) {
596 if (!strcmp(name_vec[j], tmp_str)) {
601 if (!found) name_vec[name_vec_size++] = tmp_str;
602 else cpl_free(tmp_str);
609 if (mapping_mode != NULL) {
610 name_vec[0] = cpl_sprintf(
"mapping");
616 char *found_char = NULL;
617 found_char = strstr(ifus_txt,
";");
618 while (found_char != NULL) {
620 found_char = strstr(ifus_txt,
";");
623 if (strlen(ifus_txt) > 10) {
624 tmptmp = kmo_shorten_ifu_string(ifus_txt);
625 cpl_msg_info(__func__,
"Truncate to ..ifu%s..", tmptmp);
627 tmptmp = cpl_sprintf(
"%s", ifus_txt);
629 name_vec[0] = cpl_sprintf(
"IFU%s", tmptmp);
633 name_vec[0] = cpl_sprintf(
"%s", name);
639 cpl_msg_info(__func__,
"List of Objects to combine:") ;
640 cpl_msg_indent_more() ;
641 for (i = 0; i < name_vec_size ; i++) {
642 cpl_msg_info(__func__,
"* %s", name_vec[i]) ;
644 cpl_msg_indent_less() ;
647 data_cube_list = cpl_calloc(nr_frames*KMOS_NR_IFUS,
648 sizeof(cpl_imagelist*));
649 data_header_list = cpl_calloc(nr_frames*KMOS_NR_IFUS,
650 sizeof(cpl_propertylist*));
651 noise_cube_list = cpl_calloc(nr_frames*KMOS_NR_IFUS,
652 sizeof(cpl_imagelist*));
653 noise_header_list = cpl_calloc(nr_frames*KMOS_NR_IFUS,
654 sizeof(cpl_propertylist*));
657 for (nv = 0; nv < name_vec_size; nv++) {
658 obj_name = name_vec[nv];
660 fwhm_ar = cpl_vector_new(nr_frames*KMOS_NR_IFUS) ;
661 fwhm_ne = cpl_vector_new(nr_frames*KMOS_NR_IFUS) ;
662 pos_ar = cpl_vector_new(nr_frames*KMOS_NR_IFUS) ;
663 pos_ne = cpl_vector_new(nr_frames*KMOS_NR_IFUS) ;
664 airmass_vec = cpl_vector_new(nr_frames*KMOS_NR_IFUS) ;
665 seeing_vec = cpl_vector_new(nr_frames*KMOS_NR_IFUS) ;
666 lambda_vec = cpl_vector_new(nr_frames*KMOS_NR_IFUS) ;
667 used_frame_idx = cpl_calloc(nr_frames*KMOS_NR_IFUS,
sizeof(
int)) ;
668 used_ifus = cpl_calloc(nr_frames*KMOS_NR_IFUS,
sizeof(
int)) ;
669 skip_frame_idx = cpl_calloc(nr_frames*KMOS_NR_IFUS,
sizeof(
int)) ;
670 skip_ifus = cpl_calloc(nr_frames*KMOS_NR_IFUS,
sizeof(
int)) ;
672 data_cube_counter = 0;
673 skip_cube_counter = 0;
674 noise_cube_counter = 0;
677 for (i = 0; i < nr_frames; i++) {
678 tmp_str = cpl_sprintf(
"%d", i);
679 frame = kmo_dfs_get_frame(rawframes, tmp_str);
680 frame_filename = cpl_frame_get_filename(frame);
681 kmo_init_fits_desc(&desc);
682 desc = kmo_identify_fits_header(frame_filename);
683 main_header = cpl_propertylist_load(frame_filename, 0) ;
685 if (mapping_mode != NULL) {
687 for (j = 1; j <= KMOS_NR_IFUS; j++) {
689 if (desc.sub_desc[j-1].valid_data == TRUE &&
690 !kmos_combine_is_skipped(skipped_bivector,i+1,j)) {
692 override_err_msg = TRUE;
693 data_cube_list[data_cube_counter] =
694 kmo_dfs_load_cube(rawframes, tmp_str, j,FALSE);
695 override_err_msg = FALSE;
696 if (data_cube_list[data_cube_counter] == NULL) {
699 if (edge_nan) kmo_edge_nan(
700 data_cube_list[data_cube_counter], j);
701 data_header_list[data_cube_counter] =
702 kmo_dfs_load_sub_header(rawframes,
706 if (kmos_combine_collect_data(main_header,
707 data_header_list[data_cube_counter],
708 &lambda, &seeing, &airmass) == -1) {
711 cpl_vector_set(lambda_vec, data_count, lambda) ;
712 cpl_vector_set(seeing_vec, data_count, seeing) ;
713 cpl_vector_set(airmass_vec,data_count,airmass) ;
718 fwhm_ar_val = kmos_pfits_get_qc_ar_fwhm_mean(
719 data_header_list[data_cube_counter]) ;
720 fwhm_ne_val = kmos_pfits_get_qc_ne_fwhm_mean(
721 data_header_list[data_cube_counter]) ;
722 pos_ar_val = kmos_pfits_get_qc_ar_pos_stdev(
723 data_header_list[data_cube_counter]) ;
724 pos_ne_val = kmos_pfits_get_qc_ne_pos_stdev(
725 data_header_list[data_cube_counter]) ;
726 if (cpl_error_get_code() != CPL_ERROR_NONE) {
729 cpl_vector_set(fwhm_ar,fwhm_count,
730 light_speed/fwhm_ar_val) ;
731 cpl_vector_set(fwhm_ne,fwhm_count,
732 light_speed/fwhm_ne_val) ;
733 cpl_vector_set(pos_ar,fwhm_count,
734 pos_ar_val*lambda/light_speed) ;
735 cpl_vector_set(pos_ne,fwhm_count,
736 pos_ne_val*lambda/light_speed) ;
740 cpl_propertylist_update_string(
741 data_header_list[data_cube_counter],
742 "ESO PRO FRNAME", frame_filename);
743 cpl_propertylist_update_int(
744 data_header_list[data_cube_counter],
746 used_frame_idx[data_cube_counter] = i+1 ;
747 used_ifus[data_cube_counter] = j ;
752 override_err_msg = TRUE;
753 noise_cube_list[noise_cube_counter] =
754 kmo_dfs_load_cube(rawframes, tmp_str, j, TRUE);
756 override_err_msg = FALSE;
757 if (noise_cube_list[noise_cube_counter] == NULL) {
760 if (edge_nan) kmo_edge_nan(
761 noise_cube_list[noise_cube_counter], j);
762 noise_header_list[noise_cube_counter] =
763 kmo_dfs_load_sub_header(rawframes, tmp_str,
765 noise_cube_counter++;
769 if (noise_cube_counter > 0) {
770 if (data_cube_counter != noise_cube_counter) {
771 cpl_msg_error(__func__,
"Noise missing") ;
772 cpl_error_set(__func__,CPL_ERROR_ILLEGAL_INPUT);
777 }
else if (kmos_combine_is_skipped(skipped_bivector,
779 skip_frame_idx[skip_cube_counter] = i+1 ;
780 skip_ifus[skip_cube_counter] = j ;
786 if (ifus != NULL) ifu_nr = cpl_vector_get(ifus, i);
787 else ifu_nr = kmo_get_index_from_ocs_name(frame, obj_name);
789 index = kmo_identify_index(frame_filename, ifu_nr , FALSE);
790 if (desc.sub_desc[index-1].valid_data == TRUE &&
791 !kmos_combine_is_skipped(skipped_bivector,i+1,
794 override_err_msg = TRUE;
795 data_cube_list[data_cube_counter] =
796 kmo_dfs_load_cube(rawframes, tmp_str, ifu_nr,
798 override_err_msg = FALSE;
799 if (data_cube_list[data_cube_counter] == NULL) {
803 cpl_msg_warning(cpl_func,
804 "IFU %d miѕsing in frame %s",
805 ifu_nr, frame_filename);
807 cpl_msg_warning(cpl_func,
808 "Object %s missing in Frame %d (%s)",
809 obj_name, i+1, frame_filename) ;
811 if (edge_nan) kmo_edge_nan(
812 data_cube_list[data_cube_counter], ifu_nr);
813 data_header_list[data_cube_counter] =
814 kmo_dfs_load_sub_header(rawframes, tmp_str,
818 if (kmos_combine_collect_data(main_header,
819 data_header_list[data_cube_counter],
820 &lambda, &seeing, &airmass) == -1) {
823 cpl_vector_set(lambda_vec, data_count, lambda) ;
824 cpl_vector_set(seeing_vec, data_count, seeing) ;
825 cpl_vector_set(airmass_vec,data_count,airmass) ;
830 fwhm_ar_val = kmos_pfits_get_qc_ar_fwhm_mean(
831 data_header_list[data_cube_counter]) ;
832 fwhm_ne_val = kmos_pfits_get_qc_ne_fwhm_mean(
833 data_header_list[data_cube_counter]) ;
834 pos_ar_val = kmos_pfits_get_qc_ar_pos_stdev(
835 data_header_list[data_cube_counter]) ;
836 pos_ne_val = kmos_pfits_get_qc_ne_pos_stdev(
837 data_header_list[data_cube_counter]) ;
838 if (cpl_error_get_code() != CPL_ERROR_NONE) {
841 cpl_vector_set(fwhm_ar,fwhm_count,
842 light_speed/fwhm_ar_val) ;
843 cpl_vector_set(fwhm_ne,fwhm_count,
844 light_speed/fwhm_ne_val) ;
845 cpl_vector_set(pos_ar,fwhm_count,
846 pos_ar_val*lambda/light_speed) ;
847 cpl_vector_set(pos_ne,fwhm_count,
848 pos_ne_val*lambda/light_speed) ;
852 cpl_propertylist_update_string(
853 data_header_list[data_cube_counter],
854 "ESO PRO FRNAME", frame_filename);
855 cpl_propertylist_update_int(
856 data_header_list[data_cube_counter],
857 "ESO PRO IFUNR", ifu_nr);
858 used_frame_idx[data_cube_counter] = i+1 ;
859 used_ifus[data_cube_counter] = ifu_nr ;
864 override_err_msg = TRUE;
865 noise_cube_list[noise_cube_counter] =
866 kmo_dfs_load_cube(rawframes, tmp_str, ifu_nr,
868 override_err_msg = FALSE;
869 if (noise_cube_list[noise_cube_counter] == NULL) {
873 if (edge_nan) kmo_edge_nan(
874 noise_cube_list[noise_cube_counter],ifu_nr);
875 noise_header_list[noise_cube_counter] =
876 kmo_dfs_load_sub_header(rawframes,
877 tmp_str, ifu_nr, TRUE);
878 noise_cube_counter++;
882 if (noise_cube_counter > 0) {
883 if (data_cube_counter != noise_cube_counter) {
885 cpl_msg_error(__func__,
"Noise missing") ;
886 cpl_error_set(__func__,CPL_ERROR_ILLEGAL_INPUT);
890 }
else if (kmos_combine_is_skipped(skipped_bivector,
892 skip_frame_idx[skip_cube_counter] = i+1 ;
893 skip_ifus[skip_cube_counter] = ifu_nr ;
898 cpl_propertylist_delete(main_header) ;
899 kmo_free_fits_desc(&desc);
904 if (fwhm_count > 2) {
905 tmp_vec = cpl_vector_extract(fwhm_ar, 0, fwhm_count-1, 1) ;
906 fwhm_ar_med = cpl_vector_get_median(tmp_vec) ;
907 cpl_vector_delete(tmp_vec) ;
908 tmp_vec = cpl_vector_extract(fwhm_ne, 0, fwhm_count-1, 1) ;
909 fwhm_ne_med = cpl_vector_get_median(tmp_vec) ;
910 cpl_vector_delete(tmp_vec) ;
911 tmp_vec = cpl_vector_extract(pos_ar, 0, fwhm_count-1, 1) ;
912 pos_ar_med = cpl_vector_get_median(tmp_vec) ;
913 cpl_vector_delete(tmp_vec) ;
914 tmp_vec = cpl_vector_extract(pos_ne, 0, fwhm_count-1, 1) ;
915 pos_ne_med = cpl_vector_get_median(tmp_vec) ;
916 cpl_vector_delete(tmp_vec) ;
917 spec_res = (fwhm_ar_med + fwhm_ne_med) / 2.0 ;
918 crder3 = (pos_ar_med + pos_ne_med) / 2.0 ;
919 }
else if (fwhm_count > 0) {
920 tmp_vec = cpl_vector_extract(fwhm_ar, 0, fwhm_count-1, 1) ;
921 fwhm_ar_med = cpl_vector_get_mean(tmp_vec) ;
922 cpl_vector_delete(tmp_vec) ;
923 tmp_vec = cpl_vector_extract(fwhm_ne, 0, fwhm_count-1, 1) ;
924 fwhm_ne_med = cpl_vector_get_mean(tmp_vec) ;
925 cpl_vector_delete(tmp_vec) ;
926 tmp_vec = cpl_vector_extract(pos_ar, 0, fwhm_count-1, 1) ;
927 pos_ar_med = cpl_vector_get_mean(tmp_vec) ;
928 cpl_vector_delete(tmp_vec) ;
929 tmp_vec = cpl_vector_extract(pos_ne, 0, fwhm_count-1, 1) ;
930 pos_ne_med = cpl_vector_get_mean(tmp_vec) ;
931 cpl_vector_delete(tmp_vec) ;
932 spec_res = (fwhm_ar_med + fwhm_ne_med) / 2.0 ;
933 crder3 = (pos_ar_med + pos_ne_med) / 2.0 ;
935 cpl_msg_debug(__func__,
"Cound not retrieve QC ARC - FWHM MEAN") ;
939 cpl_vector_delete(fwhm_ar) ;
940 cpl_vector_delete(fwhm_ne) ;
941 cpl_vector_delete(pos_ar) ;
942 cpl_vector_delete(pos_ne) ;
945 sky_res_vec = cpl_vector_new(data_count) ;
946 for (i=0 ; i<data_count ; i++) {
947 lambda = cpl_vector_get(lambda_vec, i) ;
948 seeing = cpl_vector_get(seeing_vec, i) ;
949 airmass = cpl_vector_get(airmass_vec, i) ;
950 outer_scale=sqrt(1-78.08*((pow(lambda*1e-6,0.4)*pow(airmass,-0.2))/
951 (pow(seeing,1./3.)))) ;
952 sky_res = seeing * pow(0.5/lambda, 0.2) * pow(airmass, 3./5.) *
954 cpl_vector_set(sky_res_vec, i, sky_res) ;
956 cpl_vector_delete(airmass_vec) ;
957 cpl_vector_delete(seeing_vec) ;
958 cpl_vector_delete(lambda_vec) ;
960 if (data_count > 2) {
961 sky_res = cpl_vector_get_median_const(sky_res_vec) ;
962 sky_rerr = sqrt((0.2*0.2)+pow(cpl_vector_get_stdev(sky_res_vec),2));
964 sky_res = cpl_vector_get_mean(sky_res_vec) ;
967 cpl_vector_delete(sky_res_vec) ;
970 if (sky_rerr > 1.0) sky_rerr = 0.3;
971 if (sky_rerr < 0.0) sky_rerr = 0.3;
974 used_ifus_str = kmos_combine_create_ifus_string(used_frame_idx,
975 used_ifus, data_cube_counter);
976 cpl_free(used_ifus) ;
977 skip_ifus_str = kmos_combine_create_ifus_string(skip_frame_idx,
978 skip_ifus, skip_cube_counter);
979 cpl_free(skip_frame_idx) ;
980 cpl_free(skip_ifus) ;
983 main_header = kmo_dfs_load_primary_header(rawframes,
"0");
984 const char *tag = cpl_propertylist_get_string(main_header,
989 cube_combined_noise = NULL ;
990 cube_combined_data = NULL ;
992 if (!suppress_extension || strcmp(obj_name,
"mapping") == 0) {
993 err = kmo_priv_combine(data_cube_list, noise_cube_list,
994 data_header_list, noise_header_list,
995 data_cube_counter, noise_cube_counter,
996 obj_name, ifus_txt, method,
"BCS",
997 fmethod, filename, cmethod,
998 cpos_rej, cneg_rej, citer, cmin, cmax,
999 extrapol_enum, flux, &cube_combined_data,
1000 &cube_combined_noise, &exp_mask);
1002 char *name_suppress = cpl_sprintf(
"%d", suppress_index);
1003 err = kmo_priv_combine(data_cube_list, noise_cube_list,
1004 data_header_list, noise_header_list,
1005 data_cube_counter, noise_cube_counter,
1006 name_suppress, ifus_txt, method,
"BCS",
1007 fmethod, filename, cmethod,
1008 cpos_rej, cneg_rej, citer, cmin, cmax,
1009 extrapol_enum, flux, &cube_combined_data,
1010 &cube_combined_noise, &exp_mask);
1011 cpl_free(name_suppress);
1013 if (err != CPL_ERROR_NONE) {
1014 for (i = 0; i < data_cube_counter ; i++)
1015 cpl_imagelist_delete(data_cube_list[i]);
1016 for (i = 0; i < noise_cube_counter ; i++)
1017 cpl_imagelist_delete(noise_cube_list[i]);
1018 for (i = 0; i < data_cube_counter ; i++)
1019 cpl_propertylist_delete(data_header_list[i]);
1020 for (i = 0; i < noise_cube_counter ; i++)
1021 cpl_propertylist_delete(noise_header_list[i]);
1022 if (ifus != NULL) cpl_vector_delete(ifus);
1023 cpl_free(data_cube_list);
1024 cpl_free(noise_cube_list);
1025 cpl_free(data_header_list);
1026 cpl_free(noise_header_list);
1027 for (i = 0; i < name_vec_size ; i++) cpl_free(name_vec[i]);
1029 cpl_free(used_ifus_str) ;
1030 cpl_free(skip_ifus_str) ;
1031 cpl_frameset_delete(rawframes) ;
1032 cpl_free(used_frame_idx) ;
1033 if (mapping_mode != NULL) cpl_free(mapping_mode) ;
1034 cpl_msg_error(__func__,
"Failed Combination") ;
1035 cpl_error_set(__func__,CPL_ERROR_ILLEGAL_INPUT);
1039 for (i = 0; i < data_cube_counter ; i++)
1040 cpl_imagelist_delete(data_cube_list[i]);
1041 for (i = 0; i < noise_cube_counter ; i++)
1042 cpl_imagelist_delete(noise_cube_list[i]);
1045 kmos_idp_set_nans(cube_combined_data, cube_combined_noise) ;
1048 abmaglim = kmos_idp_compute_abmaglim(cube_combined_data,
1049 sky_res, data_header_list[0]) ;
1050 if (cpl_error_get_code()) {
1052 __func__,
"kmos_idp_compute_abmaglim raised CPL error: \"%s\"; "
1053 "setting abmaglim to 1.0", cpl_error_get_message());
1059 if (!suppress_extension) {
1060 fn_combine = cpl_sprintf(
"%s_%s_%s", COMBINE, tag, name_vec[nv] );
1061 fn_mask = cpl_sprintf(
"%s_%s_%s", EXP_MASK, tag, name_vec[nv] );
1063 fn_combine = cpl_sprintf(
"%s_%s_%d", COMBINE, tag, suppress_index);
1064 fn_mask = cpl_sprintf(
"%s_%s_%d", EXP_MASK, tag, suppress_index);
1068 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1070 cft_fn = cpl_sprintf(
"%s_%s.fits",
"convolved_fov_trimmed", name_vec[nv]);
1071 cpl_image *cft = cpl_image_load(
"convolved_fov_trimmed.fits", CPL_TYPE_DOUBLE, 0, 0);
1072 cpl_image_save(cft, cft_fn, CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
1073 cpl_image_delete(cft);
1075 cft_fn = cpl_sprintf(
"%s_%s.fits",
"convolved_fov", name_vec[nv]);
1076 cft = cpl_image_load(
"convolved_fov.fits", CPL_TYPE_DOUBLE, 0, 0);
1077 cpl_image_save(cft, cft_fn, CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
1078 cpl_image_delete(cft);
1080 cft_fn = cpl_sprintf(
"%s_%s.fits",
"mirrored", name_vec[nv]);
1081 cft = cpl_image_load(
"mirrored.fits", CPL_TYPE_DOUBLE, 0, 0);
1082 cpl_image_save(cft, cft_fn, CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
1083 cpl_image_delete(cft);
1085 cft_fn = cpl_sprintf(
"%s_%s.fits",
"cropped", name_vec[nv]);
1086 cft = cpl_image_load(
"cropped.fits", CPL_TYPE_DOUBLE, 0, 0);
1087 cpl_image_save(cft, cft_fn, CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
1088 cpl_image_delete(cft);
1090 cft_fn = cpl_sprintf(
"%s_%s.fits",
"collapse", name_vec[nv]);
1091 cft = cpl_image_load(
"collapse.fits", CPL_TYPE_DOUBLE, 0, 0);
1092 cpl_image_save(cft, cft_fn, CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
1093 cpl_image_delete(cft);
1095 cft_fn = cpl_sprintf(
"%s_%s.fits",
"mode_limited", name_vec[nv]);
1096 cft = cpl_image_load(
"mode_limited.fits", CPL_TYPE_DOUBLE, 0, 0);
1097 cpl_image_save(cft, cft_fn, CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
1098 cpl_image_delete(cft);
1104 plist = cpl_propertylist_new() ;
1105 if (used_ifus_str != NULL)
1106 cpl_propertylist_update_string(plist,
"ESO PRO USEDIFUS",
1108 if (skip_ifus_str != NULL)
1109 cpl_propertylist_update_string(plist,
"ESO PRO SKIPPEDIFUS",
1113 cpl_propertylist_update_double(plist,
"ESO QC EXPMASK AVG",
1114 kmos_get_median_from_positives(exp_mask)) ;
1117 cpl_propertylist_update_double(plist, KEY_SPEC_RES, spec_res) ;
1118 cpl_propertylist_set_comment(plist, KEY_SPEC_RES, KEY_SPEC_RES_COMMENT);
1121 cpl_propertylist_update_int(plist,
"ESO QC COMBINED_CUBES NB",
1122 data_cube_counter) ;
1125 tmp_str = cpl_sprintf(
"%s.fits", fn_mask) ;
1126 cpl_propertylist_update_string(plist,
"ESO QC EXPMASK NAME", tmp_str) ;
1130 if (collapse_combined) {
1131 tmp_str = cpl_sprintf(
"make_image_%s.fits", fn_combine) ;
1132 cpl_propertylist_update_string(plist,
"ESO QC COLLAPSE NAME",
1138 if (abmaglim > 5.0 && abmaglim < 30.0)
1140 cpl_propertylist_update_double(plist, KEY_ABMAGLIM, abmaglim) ;
1141 cpl_propertylist_set_comment(plist, KEY_ABMAGLIM, KEY_ABMAGLIM_COMMENT);
1146 if (sky_res > 0.15 && sky_res < 5.0)
1148 cpl_propertylist_update_double(plist, KEY_SKY_RES, sky_res) ;
1149 cpl_propertylist_set_comment(plist, KEY_SKY_RES, KEY_SKY_RES_COMMENT) ;
1150 cpl_propertylist_update_double(plist, KEY_SKY_RERR, sky_rerr) ;
1151 cpl_propertylist_set_comment(plist, KEY_SKY_RERR,KEY_SKY_RERR_COMMENT) ;
1155 reflex_suffix = kmos_get_reflex_suffix(mapping_id, ifus_txt, name,
1157 cpl_propertylist_update_string(plist,
"ESO PRO REFLEX SUFFIX",
1159 cpl_free(reflex_suffix) ;
1162 kmos_idp_compute_mjd(frameset, raw_tag, used_frame_idx,
1163 data_cube_counter, &mjd_start, &mjd_end, &date_obs) ;
1166 frame = cpl_frameset_find(rawframes, NULL);
1170 cpl_sprintf(
"%s/%s",
1171 kmos_pfits_get_reflex_suffix(plist),
1172 kmos_pfits_get_obs_targ_name(main_header));
1174 cpl_sprintf(
"%s/%s (DATA)",
1175 kmos_pfits_get_reflex_suffix(plist),
1176 kmos_pfits_get_obs_targ_name(main_header));
1178 cpl_sprintf(
"%s/%s (STAT)",
1179 kmos_pfits_get_reflex_suffix(plist),
1180 kmos_pfits_get_obs_targ_name(main_header));
1183 if (strlen(object_key) > 68) object_key[68] = 0;
1184 if (strlen(object_data_key) > 68) object_data_key[68] = 0;
1185 if (strlen(object_stat_key) > 68) object_stat_key[68] = 0;
1193 cpl_propertylist * plist2 = cpl_propertylist_duplicate(plist) ;
1195 char * fname_expmap = cpl_sprintf(
"%s%s", fn_mask,
".fits") ;
1196 char * my_procatg_expmap = NULL ;
1197 char * my_prodcatg_expmap = NULL ;
1200 if (!strncmp(fn_mask, EXP_MASK_RECONS,
1201 strlen(EXP_MASK_RECONS))||
1202 !strncmp(fn_mask, EXP_MASK_SINGLE_CUBES,
1203 strlen(EXP_MASK_SINGLE_CUBES)) ){
1207 my_procatg_expmap = cpl_sprintf(EXP_MASK) ;
1209 my_prodcatg_expmap = cpl_sprintf(
"ANCILLARY.PIXELCOUNTMAP") ;
1211 my_procatg_expmap = cpl_strdup(fn_mask) ;
1213 cpl_propertylist_update_string(plist2, CPL_DFS_PRO_CATG,
1215 if (my_prodcatg_expmap != NULL) {
1216 cpl_propertylist_update_string(plist2, KEY_PRODCATG,
1217 my_prodcatg_expmap);
1218 cpl_free(my_prodcatg_expmap) ;
1219 cpl_propertylist_set_comment(plist2, KEY_PRODCATG,
1220 KEY_PRODCATG_COMMENT);
1222 cpl_propertylist_update_string(plist2, INSTRUMENT,
"KMOS") ;
1224 cpl_msg_info(cpl_func,
"Writing FITS propertylist product(%s): %s",
1225 my_procatg_expmap, fname_expmap);
1227 cpl_frame * product_frame_expmap = cpl_frame_new();
1228 cpl_frame_set_filename(product_frame_expmap, fname_expmap);
1229 cpl_frame_set_tag(product_frame_expmap, my_procatg_expmap);
1230 cpl_frame_set_type(product_frame_expmap, CPL_FRAME_TYPE_ANY);
1231 cpl_frame_set_group(product_frame_expmap, CPL_FRAME_GROUP_PRODUCT);
1232 cpl_frame_set_level(product_frame_expmap, CPL_FRAME_LEVEL_FINAL);
1233 cpl_free(my_procatg_expmap) ;
1236 cpl_dfs_setup_product_header(plist2, product_frame_expmap, frameset,
1237 parlist, cpl_func, PACKAGE
"/" PACKAGE_VERSION, CPL_DFS_PRO_DID, frame);
1243 crval1 = cpl_propertylist_get_double(data_header_list[0], CRVAL1);
1244 crval2 = cpl_propertylist_get_double(data_header_list[0], CRVAL2);
1245 kmclipm_update_property_double(plist2,
"RA", crval1,
"") ;
1246 kmclipm_update_property_double(plist2,
"DEC", crval2,
"") ;
1249 cpl_propertylist_update_string(plist2,
"OBJECT", object_key) ;
1252 cpl_propertylist_save(plist2, fname_expmap, CPL_IO_CREATE);
1253 cpl_free(fname_expmap) ;
1254 cpl_frameset_insert(frameset, product_frame_expmap);
1257 cpl_propertylist_delete(plist2) ;
1260 kmos_idp_add_files_infos(plist, frameset, raw_tag, used_frame_idx,
1261 data_cube_counter) ;
1262 cpl_free(used_frame_idx) ;
1267 char * fname = cpl_sprintf(
"%s%s", fn_combine,
".fits") ;
1268 char * my_procatg = NULL ;
1269 char * my_prodcatg = NULL ;
1272 if (!strncmp(fn_combine, COMBINED_RECONS, strlen(COMBINED_RECONS)) ||
1273 !strncmp(fn_combine, COMBINED_SINGLE_CUBES,
1274 strlen(COMBINED_SINGLE_CUBES))){
1278 my_procatg = cpl_sprintf(COMBINED_CUBE);
1280 my_procatg = cpl_strdup(fn_combine) ;
1282 cpl_propertylist_update_string(plist, CPL_DFS_PRO_CATG, my_procatg);
1283 if (my_prodcatg != NULL) {
1284 cpl_propertylist_update_string(plist, KEY_PRODCATG, my_prodcatg);
1285 cpl_free(my_prodcatg) ;
1286 cpl_propertylist_set_comment(plist, KEY_PRODCATG,
1287 KEY_PRODCATG_COMMENT);
1289 cpl_propertylist_update_string(plist, INSTRUMENT,
"KMOS") ;
1291 cpl_msg_info(cpl_func,
"Writing FITS propertylist product(%s): %s",
1293 cpl_msg_info(cpl_func,
" WRITING FITS FOR 2");
1295 cpl_frame * product_frame = cpl_frame_new();
1296 cpl_frame_set_filename(product_frame, fname);
1297 cpl_frame_set_tag(product_frame, my_procatg);
1298 cpl_frame_set_type(product_frame, CPL_FRAME_TYPE_ANY);
1299 cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
1300 cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
1301 cpl_free(my_procatg) ;
1304 cpl_dfs_setup_product_header(plist, product_frame, frameset, parlist,
1305 cpl_func, PACKAGE
"/" PACKAGE_VERSION, CPL_DFS_PRO_DID, frame);
1308 if (mjd_start > 0.0) {
1309 if (date_obs != NULL) {
1310 cpl_propertylist_update_string(plist, KEY_DATEOBS, date_obs) ;
1311 cpl_free(date_obs) ;
1313 cpl_propertylist_update_string(plist, KEY_DATEOBS,
"") ;
1315 cpl_propertylist_set_comment(plist, KEY_DATEOBS,
1316 KEY_DATEOBS_COMMENT);
1318 cpl_propertylist_update_double(plist, KEY_MJDOBS, mjd_start) ;
1319 cpl_propertylist_set_comment(plist, KEY_MJDOBS, KEY_MJDOBS_COMMENT);
1321 if (mjd_end > 0.0) {
1322 cpl_propertylist_update_double(plist, KEY_MJDEND, mjd_end) ;
1323 cpl_propertylist_set_comment(plist, KEY_MJDEND, KEY_MJDEND_COMMENT);
1327 cpl_propertylist_update_string(plist,
"OBJECT", object_key) ;
1331 cpl_msg_info(cpl_func,
" GETTING TO QC PARAMS LEVEL ");
1334 if (cpl_propertylist_has(main_header, QC_SAT_LEVEL)) {
1335 cpl_propertylist_update_double(plist, QC_SAT_LEVEL,
1336 cpl_propertylist_get_double(main_header, QC_SAT_LEVEL));
1339 if (cpl_propertylist_has(main_header, QC_SAT_NB)) {
1340 cpl_propertylist_update_int(plist, QC_SAT_NB,
1341 cpl_propertylist_get_int(main_header, QC_SAT_NB));
1344 if (cpl_propertylist_has(main_header, QC_PERS_LEVEL)) {
1345 cpl_propertylist_update_double(plist, QC_PERS_LEVEL,
1346 cpl_propertylist_get_double(main_header, QC_PERS_LEVEL));
1349 if (cpl_propertylist_has(main_header, QC_PERS_NB)) {
1350 cpl_propertylist_update_int(plist, QC_PERS_NB,
1351 cpl_propertylist_get_int(main_header, QC_PERS_NB));
1354 if (cpl_propertylist_has(main_header, QC_MASTER_FLAT_MJD_OBS)) {
1356 cpl_propertylist_update_double(plist, QC_DELTA_TIME_FLAT,
1357 (cpl_propertylist_get_double(main_header,
1358 QC_MASTER_FLAT_MJD_OBS)-mjd_start));
1361 if (cpl_propertylist_has(main_header, QC_TELLURIC_GEN_MJD_OBS)) {
1362 cpl_propertylist_update_double(plist, QC_DELTA_TIME_TELL,
1363 (cpl_propertylist_get_double(main_header,
1364 QC_TELLURIC_GEN_MJD_OBS)-mjd_start));
1367 cpl_propertylist_update_string(plist, QC_PROC_SCHEME,
1368 QC_PROC_SCHEME_VAL) ;
1369 cpl_propertylist_set_comment(plist, QC_PROC_SCHEME, QC_PROC_SCHEME_TXT);
1372 if (cpl_propertylist_has(main_header, QC_PARAM_H2O_AVG)) {
1373 cpl_propertylist_update_double(plist, QC_PARAM_H2O_AVG,
1374 cpl_propertylist_get_double(main_header, QC_PARAM_H2O_AVG));
1377 if (cpl_propertylist_has(main_header, QC_PARAM_H2O_RMS)) {
1378 cpl_propertylist_update_double(plist, QC_PARAM_H2O_RMS,
1379 cpl_propertylist_get_double(main_header, QC_PARAM_H2O_RMS));
1382 if (cpl_propertylist_has(main_header, QC_PARAM_AIRM_STD)) {
1384 cpl_msg_info(cpl_func,
" QC_PARAM_AIRM_STD exists ");
1385 cpl_propertylist_update_double(plist,
"ESO QC AIRM DIFF",
1386 fabs(cpl_propertylist_get_double(main_header, QC_PARAM_AIRM_STD)-
1388 (cpl_propertylist_get_double(main_header,
"ESO TEL AIRM START")+
1389 cpl_propertylist_get_double(main_header,
"ESO TEL AIRM END"))/2));
1392 if (cpl_propertylist_has(main_header, QC_PARAM_MEAS_IWV)) {
1393 cpl_propertylist_update_double(plist, QC_PARAM_MEAS_IWV,
1394 cpl_propertylist_get_double(main_header, QC_PARAM_MEAS_IWV));
1397 if (cpl_propertylist_has(main_header,
"ESO TEL AMBI IWV START")){
1398 cpl_propertylist_update_double(plist, QC_PARAM_MEAS_IWV,
1399 (cpl_propertylist_get_double(main_header,
"ESO TEL AMBI IWV START")+
1400 cpl_propertylist_get_double(main_header,
"ESO TEL AMBI IWV END"))/2);
1404 if (cpl_propertylist_has(main_header, QC_PARAM_MEAS_IWV30D)) {
1405 cpl_propertylist_update_double(plist, QC_PARAM_MEAS_IWV30D,
1406 cpl_propertylist_get_double(main_header, QC_PARAM_MEAS_IWV30D));
1409 if (cpl_propertylist_has(main_header,
"ESO TEL AMBI IWV30D START")){
1410 cpl_propertylist_update_double(plist, QC_PARAM_MEAS_IWV30D,
1411 (cpl_propertylist_get_double(main_header,
"ESO TEL AMBI IWV30D START")+
1412 cpl_propertylist_get_double(main_header,
"ESO TEL AMBI IWV30D END"))/2);
1417 if (cpl_propertylist_has(main_header, QC_PARAM_H2O_RATIO)) {
1418 cpl_propertylist_update_double(plist, QC_PARAM_H2O_RATIO,
1419 cpl_propertylist_get_double(main_header, QC_PARAM_H2O_RATIO));
1422 if (cpl_propertylist_has(main_header, QC_PARAM_H2O_AVG ) &&
1423 cpl_propertylist_has(plist,
"ESO TEL AMBI IWV START" ) ){
1424 cpl_propertylist_update_double(plist, QC_PARAM_H2O_RATIO,
1425 (cpl_propertylist_get_double(plist, QC_PARAM_H2O_AVG )/
1426 ((cpl_propertylist_get_double(main_header,
"ESO TEL AMBI IWV START")+
1427 cpl_propertylist_get_double(main_header,
"ESO TEL AMBI IWV END"))/2)));
1437 if (cpl_propertylist_has(main_header, QC_PARAM_H2O_AVG ) &&
1438 cpl_propertylist_has(plist, QC_PARAM_MEAS_IWV )){
1439 cpl_propertylist_update_double(plist, QC_PARAM_H2O_DELTA,
1440 (cpl_propertylist_get_double(plist, QC_PARAM_H2O_AVG )-
1441 cpl_propertylist_get_double(plist, QC_PARAM_MEAS_IWV)));
1452 cpl_propertylist_delete(main_header);
1455 cpl_propertylist_save(plist, fname, CPL_IO_CREATE);
1457 cpl_frameset_insert(frameset, product_frame);
1459 cpl_propertylist_delete(plist) ;
1460 cpl_free(used_ifus_str) ;
1461 cpl_free(skip_ifus_str) ;
1464 if (data_header_list[0] != NULL) {
1465 if (cpl_propertylist_has(data_header_list[0],
"ESO PRO FRNAME")) {
1466 cpl_propertylist_erase(data_header_list[0],
"ESO PRO FRNAME");
1468 if (cpl_propertylist_has(data_header_list[0],
"ESO PRO IFUNR")) {
1469 cpl_propertylist_erase(data_header_list[0],
"ESO PRO IFUNR");
1472 if (noise_header_list[0] != NULL) {
1473 if (cpl_propertylist_has(noise_header_list[0],
"ESO PRO FRNAME")) {
1474 cpl_propertylist_erase(noise_header_list[0],
"ESO PRO FRNAME");
1476 if (cpl_propertylist_has(noise_header_list[0],
"ESO PRO IFUNR")) {
1477 cpl_propertylist_erase(noise_header_list[0],
"ESO PRO IFUNR");
1482 cpl_propertylist_update_string(data_header_list[0],
"BUNIT",
1483 kmos_pfits_get_qc_cube_unit(data_header_list[0])) ;
1484 if (noise_header_list[0] != NULL)
1485 cpl_propertylist_update_string(noise_header_list[0],
"BUNIT",
1486 kmos_pfits_get_qc_cube_unit(noise_header_list[0])) ;
1489 plist = cpl_propertylist_duplicate(data_header_list[0]) ;
1492 cpl_propertylist_update_double(plist, KEY_CRDER3, crder3) ;
1493 cpl_propertylist_set_comment(plist, KEY_CRDER3, KEY_CRDER3_COMMENT);
1496 cpl_propertylist_erase(plist,
"EXPTIME") ;
1499 cpl_propertylist_update_string(plist,
"OBJECT", object_data_key) ;
1501 kmo_dfs_save_cube(cube_combined_data, fn_combine,
"", plist, 0./0.);
1502 cpl_propertylist_delete(plist) ;
1503 cpl_imagelist_delete(cube_combined_data);
1506 plist = cpl_propertylist_duplicate(noise_header_list[0]) ;
1509 cpl_propertylist_erase(plist,
"EXPTIME") ;
1512 cpl_propertylist_update_string(plist,
"OBJECT", object_stat_key) ;
1514 kmo_dfs_save_cube(cube_combined_noise, fn_combine,
"", plist, 0./0.);
1515 cpl_imagelist_delete(cube_combined_noise);
1516 cpl_propertylist_delete(plist) ;
1517 cpl_free(fn_combine);
1520 plist = cpl_propertylist_duplicate(data_header_list[0]) ;
1521 kmos_3dim_clean_plist(plist) ;
1524 cpl_propertylist_update_string(plist,
"BUNIT",
"") ;
1527 cpl_propertylist_update_string(plist,
"OBJECT", object_data_key) ;
1529 kmo_dfs_save_image(exp_mask, fn_mask,
"", plist, 0./0.);
1530 cpl_propertylist_delete(plist) ;
1532 cpl_image_delete(exp_mask);
1534 for (i = 0; i < data_cube_counter ; i++)
1535 cpl_propertylist_delete(data_header_list[i]);
1536 for (i = 0; i < noise_cube_counter ; i++)
1537 cpl_propertylist_delete(noise_header_list[i]);
1538 if (noise_header_list!=NULL && noise_cube_counter==0)
1539 cpl_propertylist_delete(noise_header_list[0]) ;
1540 cpl_free(object_key) ;
1541 cpl_free(object_data_key) ;
1542 cpl_free(object_stat_key) ;
1544 if (skipped_bivector!=NULL) cpl_bivector_delete(skipped_bivector) ;
1545 if (ifus != NULL) cpl_vector_delete(ifus);
1546 cpl_free(data_cube_list);
1547 cpl_free(noise_cube_list);
1548 cpl_free(data_header_list);
1549 cpl_free(noise_header_list);
1550 for (i = 0; i < name_vec_size ; i++) cpl_free(name_vec[i]);
1552 cpl_free(mapping_mode) ;
1557 if (collapse_combined) {
1558 kmos_collapse_cubes(COMBINED_CUBE, frameset, parlist, 0.1,
"",
1559 DEF_REJ_METHOD, DEF_POS_REJ_THRES, DEF_NEG_REJ_THRES,
1560 DEF_ITERATIONS, DEF_NR_MIN_REJ, DEF_NR_MAX_REJ);
1566 cpl_frame * combined_frame ;
1567 const char * combined_fname ;
1568 char * idp_combined_fname ;
1569 cpl_imagelist * cube_combined_error ;
1570 const char * const_data_extname ;
1571 char * data_extname ;
1572 char * error_extname ;
1573 cpl_frameset * combined_frames ;
1577 combined_frames = kmos_extract_frameset(frameset, COMBINED_CUBE) ;
1578 combined_frame = kmo_dfs_get_frame(combined_frames, COMBINED_CUBE);
1579 while (combined_frame != NULL ) {
1580 combined_fname = cpl_frame_get_filename(combined_frame);
1583 cube_combined_data=cpl_imagelist_load(combined_fname, CPL_TYPE_FLOAT,1);
1586 cube_combined_error = kmos_idp_compute_error(cube_combined_data);
1589 pixnoise = kmos_get_mode(cube_combined_error) ;
1592 main_header = cpl_propertylist_load(combined_fname, 0) ;
1593 plist = cpl_propertylist_load(combined_fname, 1) ;
1594 kmos_idp_prepare_main_keys(main_header, frameset, plist,
1595 raw_tag, cube_combined_error) ;
1596 cpl_propertylist_delete(plist) ;
1597 frame = cpl_frameset_find(rawframes, NULL);
1600 idp_combined_fname = cpl_sprintf(
"IDP_%s", combined_fname) ;
1602 const char * procat = cpl_propertylist_get_string(main_header,
1604 cpl_msg_info(cpl_func,
"Writing FITS propertylist product(%s): %s",
1605 procat, idp_combined_fname);
1606 cpl_msg_info(cpl_func,
" WRITING FITS FOR 3");
1608 cpl_frame * product_frame = cpl_frame_new();
1609 cpl_frame_set_filename(product_frame, idp_combined_fname);
1610 cpl_frame_set_tag(product_frame, procat);
1611 cpl_frame_set_type(product_frame, CPL_FRAME_TYPE_ANY);
1612 cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
1613 cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
1615 plist = cpl_propertylist_duplicate(main_header);
1618 mjd_start = cpl_propertylist_get_double(plist, KEY_MJDOBS);
1619 date_obs = cpl_strdup(cpl_propertylist_get_string(plist, KEY_DATEOBS));
1620 mjd_end = cpl_propertylist_get_double(plist, KEY_MJDEND);
1622 if (cpl_error_get_code()) cpl_error_reset() ;
1625 object_key = cpl_strdup(kmos_pfits_get_object(plist)) ;
1628 cpl_dfs_setup_product_header(plist, product_frame, frameset, parlist,
1629 cpl_func, PACKAGE
"/" PACKAGE_VERSION, CPL_DFS_PRO_DID, frame);
1632 cpl_propertylist_update_string(plist,
"OBJECT", object_key) ;
1633 cpl_free(object_key) ;
1637 cpl_propertylist * plist2 = cpl_propertylist_load(combined_fname, 1) ;
1638 crval1 = cpl_propertylist_get_double(plist2, CRVAL1);
1639 crval2 = cpl_propertylist_get_double(plist2, CRVAL2);
1640 cpl_propertylist_delete(plist2) ;
1641 kmclipm_update_property_double(plist,
"RA", crval1,
"") ;
1642 kmclipm_update_property_double(plist,
"DEC", crval2,
"") ;
1646 kmclipm_update_property_string(plist,
"SPECSYS",
"TOPOCENT",
"") ;
1649 if (mjd_start > 0.0) {
1650 if (date_obs != NULL) {
1651 cpl_propertylist_update_string(plist, KEY_DATEOBS, date_obs) ;
1652 cpl_propertylist_set_comment(plist, KEY_DATEOBS,
1653 KEY_DATEOBS_COMMENT);
1655 cpl_propertylist_update_double(plist, KEY_MJDOBS, mjd_start) ;
1656 cpl_propertylist_set_comment(plist, KEY_MJDOBS, KEY_MJDOBS_COMMENT);
1658 if (date_obs != NULL) cpl_free(date_obs) ;
1659 if (mjd_end > 0.0) {
1660 cpl_propertylist_update_double(plist, KEY_MJDEND, mjd_end) ;
1661 cpl_propertylist_set_comment(plist, KEY_MJDEND, KEY_MJDEND_COMMENT);
1665 cpl_propertylist_update_double(plist, KEY_PIXNOISE, pixnoise) ;
1666 cpl_propertylist_set_comment(plist, KEY_PIXNOISE, KEY_PIXNOISE_COMMENT);
1669 cpl_propertylist_save(plist, idp_combined_fname, CPL_IO_CREATE);
1670 cpl_propertylist_delete(plist) ;
1671 cpl_frameset_insert(frameset, product_frame);
1675 plist = cpl_propertylist_load(combined_fname, 1) ;
1676 const_data_extname = kmos_pfits_get_extname(plist) ;
1677 error_extname = kmos_idp_compute_error_extname(const_data_extname) ;
1680 kmos_idp_prepare_data_keys(plist, error_extname) ;
1681 kmos_idp_prepare_data_hduclas(plist);
1682 cpl_free(error_extname) ;
1685 cpl_imagelist_save(cube_combined_data, idp_combined_fname,
1687 plist, CPL_IO_EXTEND) ;
1688 cpl_propertylist_delete(plist) ;
1689 cpl_imagelist_delete(cube_combined_data);
1693 plist = cpl_propertylist_load(combined_fname, 1) ;
1694 kmclipm_update_property_string(plist, EXTNAME,
"DATA",
"");
1695 data_extname = cpl_strdup(kmos_pfits_get_extname(plist)) ;
1696 error_extname = kmos_idp_compute_error_extname(data_extname) ;
1697 kmos_idp_prepare_error_keys(plist, error_extname, data_extname);
1698 kmos_idp_prepare_error_hduclas(plist);
1699 cpl_free(error_extname) ;
1700 cpl_free(data_extname) ;
1704 cpl_sprintf(
"%s/%s (STAT)",
1705 kmos_pfits_get_reflex_suffix(main_header),
1706 kmos_pfits_get_obs_targ_name(main_header));
1709 if (strlen(object_stat_key) > 68) object_stat_key[68] = 0;
1712 cpl_propertylist_update_string(plist,
"OBJECT", object_stat_key) ;
1715 cpl_imagelist_save(cube_combined_error, idp_combined_fname,
1717 plist, CPL_IO_EXTEND) ;
1718 cpl_imagelist_delete(cube_combined_error);
1719 cpl_propertylist_delete(plist) ;
1720 cpl_free(idp_combined_fname) ;
1721 cpl_propertylist_delete(main_header) ;
1723 cpl_free(object_stat_key);
1726 combined_frame = kmo_dfs_get_frame(combined_frames, NULL);
1728 cpl_frameset_delete(rawframes) ;
1729 cpl_frameset_delete(combined_frames) ;
1743static char * kmos_combine_create_ifus_string(
1744 const int * frame_idx,
1752 if (nb > 1000)
return NULL ;
1753 if (nb == 0)
return NULL ;
1754 for (i=0 ; i<nb ; i++) {
1756 if (frame_idx[i] < 10 && ifus[i] < 10)
1757 if (i==0) sprintf(tmp,
"%1d:%1d", frame_idx[i], ifus[i]);
1758 else sprintf(tmp,
",%1d:%1d", frame_idx[i], ifus[i]);
1759 else if (frame_idx[i] < 10 && ifus[i] >= 10)
1760 if (i==0) sprintf(tmp,
"%1d:%2d", frame_idx[i], ifus[i]);
1761 else sprintf(tmp,
",%1d:%2d", frame_idx[i], ifus[i]);
1762 else if (frame_idx[i] >= 10 && ifus[i] < 10)
1763 if (i==0) sprintf(tmp,
"%2d:%1d", frame_idx[i], ifus[i]);
1764 else sprintf(tmp,
",%2d:%1d", frame_idx[i], ifus[i]);
1765 else if (frame_idx[i] >= 10 && ifus[i] >= 10)
1766 if (i==0) sprintf(tmp,
"%2d:%2d", frame_idx[i], ifus[i]);
1767 else sprintf(tmp,
",%2d:%2d", frame_idx[i], ifus[i]);
1770 if (i==0) strcpy(out, tmp) ;
1771 else strcat(out, tmp);
1775 if (strlen(out) > 51)
return NULL ;
1777 return cpl_strdup(out) ;
1787static int kmos_combine_collect_data(
1788 const cpl_propertylist * recons_prim_header,
1789 const cpl_propertylist * recons_ext_header,
1795 double crval3, cd3_3, crpix3, airm_start, airm_end, fwhmlin ;
1799 if (recons_prim_header == NULL || recons_ext_header == NULL)
return -1;
1800 if (lambda == NULL || seeing == NULL || airmass == NULL)
return -1;
1803 crval3 = kmos_pfits_get_crval3(recons_ext_header) ;
1804 cd3_3 = kmos_pfits_get_cd3_3(recons_ext_header) ;
1805 crpix3 = kmos_pfits_get_crpix3(recons_ext_header) ;
1806 naxis3 = kmos_pfits_get_naxis3(recons_ext_header) ;
1807 airm_start = kmos_pfits_get_airmass_start(recons_prim_header) ;
1808 airm_end = kmos_pfits_get_airmass_end(recons_prim_header) ;
1809 fwhmlin = kmos_pfits_get_ia_fwhmlin(recons_prim_header) ;
1810 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1812 cpl_msg_error(__func__,
"Cannot collect data from header") ;
1817 *lambda = (crval3 + (crval3 + cd3_3 * naxis3 - (crpix3-1) * cd3_3)) / 2.0;
1820 *airmass = (airm_start + airm_end) / 2.0 ;
1835static cpl_bivector * kmos_combine_parse_skipped(
const char * str)
1837 cpl_bivector * out ;
1838 cpl_vector * out_x ;
1839 cpl_vector * out_y ;
1847 if (str == NULL)
return NULL ;
1851 my_str = cpl_strdup(str) ;
1854 for (s2 = my_str; s2; ) {
1855 while (*s2 ==
' ' || *s2 ==
'\t') s2++;
1856 s1 = strsep(&s2,
",") ;
1858 if (sscanf(s1,
" %i:%i", &val1, &val2) == 2) {
1864 if (nb_values == 0)
return NULL ;
1867 out = cpl_bivector_new(nb_values) ;
1868 out_x = cpl_bivector_get_x(out) ;
1869 out_y = cpl_bivector_get_y(out) ;
1873 my_str = cpl_strdup(str) ;
1874 for (s2 = my_str; s2; ) {
1875 while (*s2 ==
' ' || *s2 ==
'\t') s2++;
1876 s1 = strsep(&s2,
",") ;
1878 if (sscanf(s1,
" %i:%i", &val1, &val2) == 2) {
1879 cpl_vector_set(out_x, nb_values, val1) ;
1880 cpl_vector_set(out_y, nb_values, val2) ;
1898static int kmos_combine_is_skipped(
1899 const cpl_bivector * skipped,
1903 const cpl_vector * vec_x ;
1904 const cpl_vector * vec_y ;
1909 if (skipped == NULL)
return 0;
1912 vec_x = cpl_bivector_get_x_const(skipped) ;
1913 vec_y = cpl_bivector_get_y_const(skipped) ;
1916 for (i=0 ; i<cpl_bivector_get_size(skipped) ; i++) {
1917 val1 = cpl_vector_get(vec_x, i) ;
1918 val2 = cpl_vector_get(vec_y, i) ;
1919 if (fabs(val1-frame_idx)<1e-3 && fabs(val2-ifu_nr)<1e-3)
return 1 ;
1932static int kmos_idp_set_nans(
1933 cpl_imagelist * data,
1934 cpl_imagelist * error)
1936 cpl_image * data_curr ;
1937 float * pdata_curr ;
1939 cpl_size i, j, k, nx, ny, ni ;
1942 if (data == NULL || error == NULL)
return -1 ;
1945 data_curr = cpl_imagelist_get(data, 0) ;
1946 nx = cpl_image_get_size_x(data_curr) ;
1947 ny = cpl_image_get_size_y(data_curr) ;
1948 ni = cpl_imagelist_get_size(data) ;
1951 for (j=0 ; j<ny ; j++) {
1952 for (i=0 ; i<nx ; i++) {
1954 for (k=0 ; k<ni && set_to_nan ; k++) {
1955 data_curr = cpl_imagelist_get(data, k) ;
1956 pdata_curr = cpl_image_get_data_float(data_curr) ;
1958 if (fabs(pdata_curr[i+j*nx])<1e-50) {
1959 pdata_curr[i+j*nx] = 0./0. ;
1968 for (j=0 ; j<ny ; j++) {
1969 for (i=0 ; i<nx ; i++) {
1971 for (k=ni-1 ; k>=0 && set_to_nan ; k--) {
1972 data_curr = cpl_imagelist_get(data, k) ;
1973 pdata_curr = cpl_image_get_data_float(data_curr) ;
1975 if (fabs(pdata_curr[i+j*nx])<1e-50) {
1976 pdata_curr[i+j*nx] = 0./0. ;
1993static double kmos_get_mode(
1994 cpl_imagelist * cube)
1996 cpl_image * data_curr ;
1997 float * pdata_curr ;
1998 cpl_vector * values ;
2000 double min, max, modevalue ;
2001 cpl_size i, j, k, nx, ny, ni, nval ;
2006 if (cube == NULL)
return -1 ;
2009 data_curr = cpl_imagelist_get(cube, 0) ;
2010 nx = cpl_image_get_size_x(data_curr) ;
2011 ny = cpl_image_get_size_y(data_curr) ;
2012 ni = cpl_imagelist_get_size(cube) ;
2017 for (k=0 ; k<ni ; k++) {
2018 data_curr = cpl_imagelist_get(cube, k) ;
2019 pdata_curr = cpl_image_get_data_float(data_curr) ;
2020 for (j=0 ; j<ny ; j++) {
2021 for (i=0 ; i<nx ; i++) {
2022 if ((!isnan(pdata_curr[i+j*nx])) &&
2023 fabs(pdata_curr[i+j*nx])>1e-30) {
2029 if (nval < 3)
return 0.0 ;
2032 values = cpl_vector_new(nval) ;
2033 pvalues = cpl_vector_get_data(values) ;
2035 for (k=0 ; k<ni ; k++) {
2036 data_curr = cpl_imagelist_get(cube, k) ;
2037 pdata_curr = cpl_image_get_data_float(data_curr) ;
2038 for (j=0 ; j<ny ; j++) {
2039 for (i=0 ; i<nx ; i++) {
2040 if ((!isnan(pdata_curr[i+j*nx])) &&
2041 fabs(pdata_curr[i+j*nx])>1e-30) {
2042 pvalues[nval] = pdata_curr[i+j*nx] ;
2050 cpl_vector_sort(values, CPL_SORT_ASCENDING) ;
2051 pvalues = cpl_vector_get_data(values) ;
2055 max = pvalues[nval-1] ;
2056 bins = cpl_calloc(nbins,
sizeof(
int)) ;
2057 for (k=0 ; k<nval ; k++) {
2058 if (fabs(max-min) > 1e-12)
2059 ind = (int)(nbins * (pvalues[k] - min) / (max - min)) ;
2065 cpl_vector_delete(values) ;
2069 for (k=0 ; k<nbins ; k++) {
2070 if (bins[k] > bins[ind]) ind = k ;
2076 modevalue = min + (ind * (max-min) / nbins) ;
2077 if (modevalue < (max-min) / nbins) modevalue = (max-min) / nbins ;
2088static double kmos_get_median_from_positives(
2089 cpl_image * exp_mask)
2093 cpl_size nx, ny, i, j, npos ;
2094 cpl_vector * pos_values ;
2095 double * ppos_values ;
2098 if (exp_mask == NULL)
return -1.0 ;
2102 pexp_mask = cpl_image_get_data_float(exp_mask) ;
2103 nx = cpl_image_get_size_x(exp_mask) ;
2104 ny = cpl_image_get_size_y(exp_mask) ;
2107 for (j=0 ; j<ny ; j++) {
2108 for (i=0 ; i<nx ; i++) {
2109 if (pexp_mask[i+j*nx] > 1e-3) npos++ ;
2115 pos_values = cpl_vector_new(npos) ;
2116 ppos_values = cpl_vector_get_data(pos_values) ;
2118 for (j=0 ; j<ny ; j++) {
2119 for (i=0 ; i<nx ; i++) {
2120 if (pexp_mask[i+j*nx] > 1e-3) {
2121 ppos_values[npos] = pexp_mask[i+j*nx] ;
2128 med = cpl_vector_get_median(pos_values);
2129 cpl_vector_delete(pos_values) ;
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.