36#include "detmon_darkron.h"
38#include "detmon_ronbias.h"
41#include "irplib_ksigma_clip.h"
42#include "irplib_hist.h"
43#include "irplib_utils.h"
64#define pdist(x1,y1,x2,y2) (((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)))
66#define cpl_drand() ((double)rand()/(double)RAND_MAX)
93 const char * ron_method;
94 const char * dsnu_method;
109detmon_dark_dfs_set_groups(cpl_frameset *,
113detmon_dark_dsnu(cpl_frameset *,
121detmon_dark_save(
const cpl_parameterlist *,
135 const cpl_frameset *);
140detmon_retrieve_dark_params(
const char *,
142 const cpl_parameterlist *);
145detmon_dark_qc(cpl_propertylist *,
167detmon_darkron_fill_parlist_default(cpl_parameterlist * parlist,
168 const char *recipe_name,
169 const char *pipeline_name)
171 const cpl_error_code error =
172 detmon_ronbias_fill_parlist(parlist, recipe_name, pipeline_name,
196 cpl_ensure_code(!error, error);
198 return cpl_error_get_code();
214detmon_compare_dits(
const cpl_frame * frame1,
const cpl_frame * frame2)
217 cpl_propertylist *plist1;
218 cpl_propertylist *plist2;
222 if(frame1 == NULL || frame2 == NULL)
226 if((plist1 = cpl_propertylist_load(cpl_frame_get_filename(frame1),
228 cpl_msg_error(cpl_func,
"getting header from reference frame");
231 if((plist2 = cpl_propertylist_load(cpl_frame_get_filename(frame2),
233 cpl_msg_error(cpl_func,
"getting header from reference frame");
234 cpl_propertylist_delete(plist1);
239 if(cpl_error_get_code()) {
240 cpl_propertylist_delete(plist1);
241 cpl_propertylist_delete(plist2);
247 dval1 = irplib_pfits_get_exptime(plist1);
248 dval2 = irplib_pfits_get_exptime(plist2);
249 if(cpl_error_get_code()) {
250 cpl_msg_error(cpl_func,
"cannot get exposure time");
251 cpl_propertylist_delete(plist1);
252 cpl_propertylist_delete(plist2);
255 if(fabs(dval1 - dval2) > 1e-3)
259 cpl_propertylist_delete(plist1);
260 cpl_propertylist_delete(plist2);
286detmon_dark(cpl_frameset * frameset,
287 const cpl_parameterlist * parlist,
289 const char * recipe_name,
290 const char * pipeline_name,
291 const char * procatg_master,
292 const char * procatg_dsnu,
293 const char * procatg_tbl,
294 const char * package,
295 int (*compare)(
const cpl_frame *,
299 cpl_size *selection = NULL;
301 cpl_error_code error;
303 if(detmon_dark_dfs_set_groups(frameset, tag)) {
304 cpl_msg_error(cpl_func,
"Cannot identify RAW and CALIB frames");
312 error = detmon_retrieve_dark_params(pipeline_name,
313 recipe_name, parlist);
314 cpl_ensure_code(!error, error);
320 cpl_msg_info(cpl_func,
"Identify the different settings");
321 selection = cpl_frameset_labelise(frameset, compare, &nsets);
322 if(selection == NULL)
323 cpl_msg_error(cpl_func,
"Cannot labelise input frames");
326 detmon_dark_config.nb_extensions = 1;
327 if(detmon_dark_config.exts < 0) {
328 const cpl_frame *cur_frame =
329 cpl_frameset_get_position_const(frameset, 0);
331 detmon_dark_config.nb_extensions =
332 cpl_frame_get_nextensions(cur_frame);
336 for(i = 0; i < nsets; i++) {
337 cpl_size *select_dits = NULL;
338 cpl_frameset *cur_fset =
339 nsets == 1 ? cpl_frameset_duplicate(frameset) :
340 cpl_frameset_extract(frameset, selection, i);
344 cpl_table ** dsnu_table = NULL;
345 cpl_imagelist ** dsnu = NULL;
347 cpl_propertylist ** qclist =
348 (cpl_propertylist **)
349 cpl_malloc(detmon_dark_config.nb_extensions *
350 sizeof(cpl_propertylist *));
353 cpl_imagelist ** masters =
355 cpl_malloc(detmon_dark_config.nb_extensions *
356 sizeof(cpl_imagelist *));
359 if(detmon_dark_config.opt_nir == OPT) {
361 (cpl_table **) cpl_malloc(detmon_dark_config.nb_extensions *
362 sizeof(cpl_table *));
365 cpl_malloc(detmon_dark_config.nb_extensions *
366 sizeof(cpl_imagelist *));
369 select_dits = cpl_frameset_labelise(cur_fset,
373 if(detmon_dark_config.exts >= 0) {
374 *masters = cpl_imagelist_new();
375 if(detmon_dark_config.opt_nir == OPT) {
376 *dsnu = cpl_imagelist_new();
377 *dsnu_table = cpl_table_new(ndits);
379 *qclist = cpl_propertylist_new();
380 cpl_table_new_column(*dsnu_table,
"DIT", CPL_TYPE_DOUBLE);
381 cpl_table_new_column(*dsnu_table,
"STDEV", CPL_TYPE_DOUBLE);
383 for ( j = 0; j < detmon_dark_config.nb_extensions; j ++) {
384 masters[j] = cpl_imagelist_new();
385 if(detmon_dark_config.opt_nir == OPT) {
386 dsnu[j] = cpl_imagelist_new();
387 dsnu_table[j] = cpl_table_new(ndits);
389 qclist[j] = cpl_propertylist_new();
390 cpl_table_new_column(dsnu_table[j],
"DIT", CPL_TYPE_DOUBLE);
391 cpl_table_new_column(dsnu_table[j],
"STDEV", CPL_TYPE_DOUBLE);
395 for(j = 0; j < ndits; j++) {
396 cpl_frameset * cur_fdit = cpl_frameset_extract(cur_fset,
398 cpl_imagelist ** raws =
400 cpl_malloc(detmon_dark_config.nb_extensions *
401 sizeof(cpl_imagelist *));
403 if(detmon_dark_config.exts >= 0) {
404 cpl_image * collapsed;
406 cpl_imagelist_load_frameset(cur_fdit, CPL_TYPE_FLOAT, 1,
407 detmon_dark_config.exts);
408 collapsed = cpl_imagelist_collapse_create(*raws);
409 cpl_imagelist_set(*masters, collapsed, j);
410 if(detmon_dark_config.opt_nir == OPT) {
411 detmon_dark_dsnu(cur_fdit, *dsnu, *dsnu_table,
414 detmon_dark_qc(*qclist, collapsed);
416 cpl_imagelist *raws_all_exts =
417 cpl_imagelist_load_frameset(cur_fdit, CPL_TYPE_FLOAT, 1,
419 for(k = 0; k < detmon_dark_config.nb_extensions; k++) {
420 int nframes = cpl_frameset_get_size(cur_fdit);
422 cpl_image * collapsed;
423 for(h = 0; h < nframes; h++) {
425 cpl_imagelist_unset(raws_all_exts,
427 nb_extensions - 1 - k) * h);
428 cpl_imagelist_set(raws[k], image, h);
430 collapsed = cpl_imagelist_collapse_create(raws[k]);
431 cpl_imagelist_set(masters[k],collapsed, j);
432 if(detmon_dark_config.opt_nir == OPT) {
433 detmon_dark_dsnu(cur_fdit, dsnu[k],
434 dsnu_table[j], collapsed, j);
436 detmon_dark_qc(qclist[k], collapsed);
440 cpl_frameset_delete(cur_fdit);
441 for(k = 0; k < detmon_dark_config.nb_extensions; k++) {
442 cpl_imagelist_delete(raws[k]);
447 cpl_frameset_delete(cur_fset);
449 detmon_dark_save(parlist, frameset, recipe_name, pipeline_name,
450 procatg_master, procatg_tbl, procatg_dsnu,
451 package, masters, dsnu_table, dsnu, qclist,
454 if(detmon_dark_config.opt_nir == OPT) {
455 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
456 cpl_table_delete(dsnu_table[j]);
457 cpl_imagelist_delete(dsnu[j]);
459 cpl_free(dsnu_table);
463 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
464 cpl_propertylist_delete(qclist[j]);
465 cpl_imagelist_delete(masters[j]);
469 cpl_free(select_dits);
475 return cpl_error_get_code();
491detmon_dark_dfs_set_groups(cpl_frameset * set,
const char *tag)
501 int nframes = cpl_frameset_get_size(set);
504 for(
int i = 0; i < nframes; i++) {
505 cpl_frame* cur_frame = cpl_frameset_get_position(set, i);
506 const char* cur_tag = cpl_frame_get_tag(cur_frame);
509 if(!strcmp(cur_tag, tag))
510 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW);
532detmon_retrieve_dark_params(
const char *pipeline_name,
533 const char *recipe_name,
534 const cpl_parameterlist * parlist)
537 const cpl_parameter *par;
540 par_name = cpl_sprintf(
"%s.%s.ron.method", pipeline_name, recipe_name);
541 assert(par_name != NULL);
542 par = cpl_parameterlist_find_const(parlist, par_name);
543 detmon_dark_config.ron_method = cpl_parameter_get_string(par);
547 par_name = cpl_sprintf(
"%s.%s.dsnu.method", pipeline_name, recipe_name);
548 assert(par_name != NULL);
549 par = cpl_parameterlist_find_const(parlist, par_name);
550 detmon_dark_config.dsnu_method = cpl_parameter_get_string(par);
554 par_name = cpl_sprintf(
"%s.%s.opt_nir", pipeline_name, recipe_name);
555 assert(par_name != NULL);
556 par = cpl_parameterlist_find_const(parlist, par_name);
557 detmon_dark_config.opt_nir = cpl_parameter_get_bool(par);
561 detmon_dark_config.exts =
562 detmon_retrieve_par_int(
"exts", pipeline_name, recipe_name,
565 if(cpl_error_get_code()) {
566 cpl_msg_error(cpl_func,
"Failed to retrieve the input parameters");
567 cpl_ensure_code(0, CPL_ERROR_DATA_NOT_FOUND);
571 return CPL_ERROR_NONE;
590detmon_fill_dark_params(cpl_parameterlist * parlist,
591 const char *recipe_name,
592 const char *pipeline_name,
593 const char * ron_method,
594 const char * dsnu_method,
595 const char * opt_nir,
598 detmon_fill_parlist(parlist, recipe_name, pipeline_name, 4,
601 "Method used to compute RON. Currently no "
602 "change is possible, RMS computed",
603 "CPL_TYPE_STRING", ron_method,
606 "Method used to compute DSNU map. Currently no "
607 "change is possible. Method used STDEV",
608 "CPL_TYPE_STRING", dsnu_method,
611 "Boolean, OPT (FALSE) or NIR(TRUE)",
612 "CPL_TYPE_BOOL", opt_nir,
615 "Activate the multi-exts option. Default 0"
616 "(primary unit), -1 (all exts)",
617 "CPL_TYPE_INT", exts);
619 return cpl_error_get_code();
633detmon_fill_dark_params_default(cpl_parameterlist * parlist,
634 const char *recipe_name,
635 const char *pipeline_name)
637 detmon_fill_dark_params(parlist, recipe_name, pipeline_name,
642 return cpl_error_get_code();
659detmon_dark_dsnu(cpl_frameset * cur_fdit,
660 cpl_imagelist * dsnu,
661 cpl_table * dsnu_table,
662 cpl_image * collapsed,
665 cpl_frame * first = cpl_frameset_get_position(cur_fdit, 0);
666 cpl_propertylist * plist =
667 cpl_propertylist_load(cpl_frame_get_filename(first), 0);
668 double dit = irplib_pfits_get_exptime(plist);
669 double mean = cpl_image_get_mean(collapsed);
671 cpl_image * dsnu_map =
672 cpl_image_subtract_scalar_create(collapsed, mean);
674 cpl_image_divide_scalar(dsnu_map, mean);
675 stdev = cpl_image_get_stdev(dsnu_map);
677 cpl_imagelist_set(dsnu, dsnu_map, pos);
679 cpl_table_set(dsnu_table,
"DIT", pos, dit);
680 cpl_table_set(dsnu_table,
"STDEV", pos, stdev);
682 cpl_propertylist_delete(plist);
684 return cpl_error_get_code();
712detmon_dark_save(
const cpl_parameterlist * parlist,
713 cpl_frameset * frameset,
714 const char *recipe_name,
715 const char *pipeline_name,
716 const char *procatg_master,
717 const char *procatg_tbl,
718 const char *procatg_dsnu,
720 cpl_imagelist ** masters,
721 cpl_table ** dsnu_table,
722 cpl_imagelist ** dsnu,
723 cpl_propertylist ** qclist,
726 const cpl_frameset * usedframes)
729 cpl_frame *ref_frame;
730 cpl_propertylist *plist;
733 cpl_propertylist *paflist;
734 cpl_error_code error;
741 nb_images = cpl_imagelist_get_size(masters[0]);
742 cpl_ensure_code(nb_images > 0, CPL_ERROR_DATA_NOT_FOUND);
745 for(i = 0; i < nb_images; i++) {
749 cpl_sprintf(
"%s_master_dit_%d.fits", recipe_name, i+1);
750 assert(name_o != NULL);
753 cpl_sprintf(
"%s_master_dit_%d_set%02d.fits",
754 recipe_name, i, which_set);
755 assert(name_o != NULL);
760 if(detmon_dark_config.exts >= 0) {
761 cpl_propertylist * pro_master = cpl_propertylist_new();
763 cpl_propertylist_append_string(pro_master,
764 CPL_DFS_PRO_CATG, procatg_master);
766 cpl_propertylist_append(pro_master, qclist[0]);
768 if(cpl_dfs_save_image
769 (frameset, NULL, parlist, usedframes, NULL,
770 cpl_imagelist_get(*masters, i), CPL_BPP_IEEE_FLOAT,
771 recipe_name, pro_master, NULL, package,
773 cpl_msg_error(cpl_func,
"Cannot save the product: %s",
776 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
780 cpl_propertylist_delete(pro_master);
782 cpl_propertylist * pro_master = cpl_propertylist_new();
784 cpl_propertylist_append_string(pro_master,
785 CPL_DFS_PRO_CATG, procatg_master);
787 cpl_propertylist_append(pro_master, qclist[0]);
789 if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,
790 NULL, CPL_BPP_IEEE_FLOAT, recipe_name,
793 cpl_msg_error(cpl_func,
"Cannot save the product: %s",
796 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
799 cpl_propertylist_delete(pro_master);
800 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
802 cpl_image_save(cpl_imagelist_get(masters[j], i),
803 name_o, CPL_BPP_IEEE_FLOAT, qclist[j],
805 cpl_ensure_code(!error, error);
811 if (detmon_dark_config.opt_nir == OPT) {
812 cpl_propertylist * pro_tbl = cpl_propertylist_new();
814 cpl_propertylist_append_string(pro_tbl,
815 CPL_DFS_PRO_CATG, procatg_tbl);
817 cpl_propertylist_append(pro_tbl, qclist[0]);
824 name_o = cpl_sprintf(
"%s_dsnu_table.fits", recipe_name);
825 assert(name_o != NULL);
828 cpl_sprintf(
"%s_dsnu_table_set%02d.fits", recipe_name,
830 assert(name_o != NULL);
833 if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL,
834 dsnu_table[0], NULL, recipe_name, pro_tbl, NULL,
836 cpl_msg_error(cpl_func,
"Cannot save the product: %s", name_o);
838 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
841 cpl_propertylist_delete(pro_tbl);
843 if(detmon_dark_config.exts < 0) {
845 for(i = 1; i < detmon_dark_config.nb_extensions; i++) {
847 cpl_table_save(dsnu_table[i], NULL, qclist[i], name_o,
849 cpl_ensure_code(!error, error);
860 for(i = 0; i < nb_images; i++) {
864 cpl_sprintf(
"%s_dsnu_map_dit_%d.fits", recipe_name, i+1);
865 assert(name_o != NULL);
868 cpl_sprintf(
"%s_dsnu_map_dit_%d_set%02d.fits",
869 recipe_name, i, which_set);
870 assert(name_o != NULL);
875 if(detmon_dark_config.exts >= 0) {
876 cpl_propertylist * pro_dsnu = cpl_propertylist_new();
878 cpl_propertylist_append_string(pro_dsnu,
879 CPL_DFS_PRO_CATG, procatg_dsnu);
881 cpl_propertylist_append(pro_dsnu, qclist[0]);
883 if(cpl_dfs_save_image
884 (frameset, NULL, parlist, usedframes, NULL,
885 cpl_imagelist_get(*dsnu, i), CPL_BPP_IEEE_FLOAT,
886 recipe_name, pro_dsnu, NULL, package,
888 cpl_msg_error(cpl_func,
"Cannot save the product: %s",
891 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
895 cpl_propertylist_delete(pro_dsnu);
897 cpl_propertylist * pro_dsnu = cpl_propertylist_new();
899 cpl_propertylist_append_string(pro_dsnu,
900 CPL_DFS_PRO_CATG, procatg_dsnu);
902 cpl_propertylist_append(pro_dsnu, qclist[0]);
904 if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes,
906 CPL_BPP_IEEE_FLOAT, recipe_name,
909 cpl_msg_error(cpl_func,
"Cannot save the product: %s",
912 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
915 cpl_propertylist_delete(pro_dsnu);
916 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
918 cpl_image_save(cpl_imagelist_get(dsnu[j], i),
919 name_o, CPL_BPP_IEEE_FLOAT, qclist[j],
921 cpl_ensure_code(!error, error);
936 ref_frame = cpl_frameset_get_position(frameset, 0);
937 if((plist = cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
939 cpl_msg_error(cpl_func,
"getting header from reference frame");
940 cpl_ensure_code(0, cpl_error_get_code());
944 paflist = cpl_propertylist_new();
945 cpl_propertylist_copy_property_regexp(paflist, plist,
946 "^(ARCFILE|MJD-OBS|ESO TPL ID|"
947 "DATE-OBS|ESO DET DIT|ESO DET NDIT|"
949 "ESO DET MODE NAME)$", 0);
951 for(i = 0; i < detmon_dark_config.nb_extensions; i++) {
952 cpl_propertylist * c_paflist = cpl_propertylist_duplicate(paflist);
953 error = cpl_propertylist_append(c_paflist, qclist[i]);
954 cpl_ensure_code(!error, error);
957 if(detmon_dark_config.exts >= 0) {
959 name_o = cpl_sprintf(
"%s.paf", recipe_name);
960 assert(name_o != NULL);
962 name_o = cpl_sprintf(
"%s_set%02d.paf", recipe_name, which_set);
963 assert(name_o != NULL);
967 name_o = cpl_sprintf(
"%s_ext%02d.paf", recipe_name, i+1);
968 assert(name_o != NULL);
970 name_o = cpl_sprintf(
"%s_set%02d_ext%02d.paf", recipe_name, which_set, i+1);
971 assert(name_o != NULL);
975 if(cpl_dfs_save_paf(pipeline_name, recipe_name, c_paflist, name_o)) {
976 cpl_msg_error(cpl_func,
"Cannot save the product: %s", name_o);
978 cpl_propertylist_delete(paflist);
979 cpl_propertylist_delete(plist);
981 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
983 cpl_propertylist_delete(c_paflist);
987 cpl_propertylist_delete(plist);
988 cpl_propertylist_delete(paflist);
990 return cpl_error_get_code();
1001detmon_dark_qc(cpl_propertylist * qclist,
1002 cpl_image * collapsed)
1004 double mean = cpl_image_get_mean(collapsed);
1005 double stdev = cpl_image_get_stdev(collapsed);
1008 cpl_propertylist_append_double(qclist,DETMON_QC_DARK, mean);
1009 cpl_propertylist_set_comment(qclist,DETMON_QC_DARK,
1012 cpl_propertylist_append_double(qclist,DETMON_QC_DARK_STDEV, stdev);
1013 cpl_propertylist_set_comment(qclist,DETMON_QC_DARK_STDEV,
1014 DETMON_QC_DARK_STDEV_C);
1015 detmon_print_rec_status();
1017 return cpl_error_get_code();