47 #include "irplib_ksigma_clip.h"
48 #include "irplib_hist.h"
49 #include "irplib_utils.h"
53 #define pdist(x1,y1,x2,y2) (((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)))
55 #define cpl_drand() ((double)rand()/(double)RAND_MAX)
70 #define HIST_FACT 2.354820045
99 irplib_ronbias_method method_bitmask;
108 cpl_size preoverscan_degree;
117 const char *stacking_method;
119 int stacking_ks_high;
120 int stacking_ks_iter;
129 } detmon_ronbias_config;
134 cpl_boolean direction;
143 } detmon_pernoise_config;
147 const char * ron_method;
148 const char * dsnu_method;
152 } detmon_dark_config;
163 static cpl_error_code
164 detmon_ronbias_retrieve_parlist(
const char *,
166 const cpl_parameterlist *,
169 static cpl_error_code
170 detmon_ronbias_random(
const cpl_imagelist *,
171 const cpl_image *, cpl_propertylist *);
173 static cpl_error_code
174 detmon_ronbias_histo(
const cpl_imagelist *,
175 const cpl_image *, cpl_propertylist *);
177 static cpl_error_code
178 detmon_ronbias_preoverscan(
const cpl_imagelist *,
179 cpl_propertylist *, cpl_image **);
181 static cpl_error_code
182 detmon_ronbias_region(
const cpl_imagelist *,
183 const cpl_image *, cpl_propertylist *);
186 detmon_ronbias_master(
const cpl_imagelist *,
187 cpl_mask **, cpl_mask **, cpl_mask **,
190 static cpl_error_code
191 detmon_ronbias_save(
const cpl_parameterlist *,
196 const cpl_propertylist *,
197 const cpl_propertylist *,
198 const cpl_propertylist *,
199 const cpl_propertylist *,
200 const cpl_propertylist *,
201 const cpl_propertylist *,
202 const cpl_propertylist *,
216 detmon_ronbias_dfs_set_groups(cpl_frameset *,
const char *);
219 static cpl_error_code
220 detmon_ronbias_dutycycl(
const cpl_frameset *, cpl_propertylist *);
223 detmon_rm_bpixs(cpl_image **,
232 static cpl_bivector *
233 irplib_bivector_gen_rect_poisson(
const int *r,
241 detmon_ronbias_check_defaults(
const cpl_frameset *,
const int whichext);
247 detmon_pernoise_dfs_set_groups(cpl_frameset *,
250 static cpl_error_code
251 detmon_pernoise_retrieve_parlist(
const char *,
253 const cpl_parameterlist *);
255 static cpl_error_code
256 detmon_pernoise_qc(cpl_propertylist *,
260 static cpl_error_code
261 detmon_pernoise_save(
const cpl_parameterlist *,
271 const cpl_frameset *);
274 detmon_pernoise_rm_bg(cpl_image *,
279 detmon_dark_dfs_set_groups(cpl_frameset *,
283 detmon_dark_dsnu(cpl_frameset *,
290 static cpl_error_code
291 detmon_dark_save(
const cpl_parameterlist *,
305 const cpl_frameset *);
309 static cpl_error_code
310 detmon_retrieve_dark_params(
const char *,
312 const cpl_parameterlist *);
315 detmon_dark_qc(cpl_propertylist *,
338 detmon_ronbias_fill_parlist_default(cpl_parameterlist * parlist,
339 const char *recipe_name,
340 const char *pipeline_name)
342 const cpl_error_code error =
343 detmon_ronbias_fill_parlist(parlist, recipe_name, pipeline_name,
367 cpl_ensure_code(!error, error);
369 return cpl_error_get_code();
388 detmon_darkron_fill_parlist_default(cpl_parameterlist * parlist,
389 const char *recipe_name,
390 const char *pipeline_name)
392 const cpl_error_code error =
393 detmon_ronbias_fill_parlist(parlist, recipe_name, pipeline_name,
417 cpl_ensure_code(!error, error);
419 return cpl_error_get_code();
461 detmon_ronbias_fill_parlist(cpl_parameterlist * parlist,
462 const char *recipe_name,
463 const char *pipeline_name,
465 const char * pmethod,
466 const int preoverscan_degree,
467 const int random_nsamples,
468 const int random_sizex,
469 const int random_sizey,
475 const char * stacking_method,
476 const int stacking_ks_low,
477 const int stacking_ks_high,
478 const int stacking_ks_iter,
479 const int master_shift_x,
480 const int master_shift_y,
489 const char * meth_desc_opt =
490 "Method to be used when computing bias. Methods appliable: "
491 "<RANDOM | HISTO | PREOVERSCAN | REGION | ALL>. By default ALL "
492 "methods are applied. More than a method can be chosen; in that "
493 "case selected methods must be separated by a single space and put "
494 "together between inverted commas (ex. --method=\"HISTO REGION\")."
495 "\n RANDOM: Bias is computed as the mean value on a given number "
496 "(--random.nsamples) of boxes (dimensions --random.sizex and "
497 "--random.sizey) randomly taken accross the detector.\n HISTO: "
498 "An histogram of the pixels of the image is built.\n PREOVERSCAN: "
499 "Mean, median and RMS values computed and designated areas. \n "
500 "REGION: Mean, median and RMS values on reference region.";
502 const char * meth_desc_nir =
503 "Method to be used when computing bias. Methods appliable: "
504 "<RANDOM | HISTO | REGION | ALL>. By default ALL "
505 "methods are applied. More than a method can be chosen; in that "
506 "case selected methods must be separated by a single space and put "
507 "together between inverted commas (ex. --method=\"HISTO REGION\")."
508 "\n RANDOM: Bias is computed as the mean value on a given number "
509 "(--random.nsamples) of boxes (dimensions --random.sizex and "
510 "--random.sizey) randomly taken accross the detector.\n HISTO: "
511 "An histogram of the pixels of the image is built.\n "
512 "REGION: Mean, median and RMS values on reference region.";
514 const char * method_desc = opt_nir == OPT ? meth_desc_opt : meth_desc_nir;
516 const cpl_error_code error =
517 detmon_fill_parlist(parlist, recipe_name, pipeline_name, 22,
520 "CPL_TYPE_STRING", method,
523 "Pre-method for RANDOM, HISTO and REGION."
524 "Difference raw frames or not",
525 "CPL_TYPE_STRING", pmethod,
527 "preoverscan.degree",
528 "Degree used for pre-overscan method",
529 "CPL_TYPE_INT", preoverscan_degree,
533 "CPL_TYPE_INT", random_nsamples,
536 "X size of the boxes",
537 "CPL_TYPE_INT", random_sizex,
540 "Y size of the boxes",
541 "CPL_TYPE_INT", random_sizey,
545 "CPL_TYPE_INT", criteria,
548 "x coordinate of the lower-left point "
549 "of the reference region of the frame",
550 "CPL_TYPE_INT", ref_llx,
553 "y coordinate of the lower-left point "
554 "of the reference region of the frame",
555 "CPL_TYPE_INT", ref_lly,
558 "x coordinate of the upper-right point "
559 "of the reference region of the frame",
560 "CPL_TYPE_INT", ref_urx,
563 "y coordinate of the upper-right point "
564 "of the reference region of the frame",
565 "CPL_TYPE_INT", ref_ury,
568 "Method to be used when stacking the master. Posible values < MINMAX | MEAN | MEDIAN | KSIGMA >",
569 "CPL_TYPE_STRING", stacking_method,
572 "Low threshold for kappa-sigma clipping",
573 "CPL_TYPE_INT", stacking_ks_low,
576 "High threshold for kappa-sigma clipping",
577 "CPL_TYPE_INT", stacking_ks_high,
580 "Nb of iterations for kappa-sigma clipping",
581 "CPL_TYPE_INT", stacking_ks_iter,
585 "CPL_TYPE_INT", master_shift_x,
589 "CPL_TYPE_INT", master_shift_y,
592 "x coordinate of the lower-left point "
594 "CPL_TYPE_INT", ron_llx,
597 "y coordinate of the lower-left point "
599 "CPL_TYPE_INT", ron_lly,
602 "x coordinate of the upper-right point "
604 "CPL_TYPE_INT", ron_urx,
607 "y coordinate of the upper-right point "
608 "of the RON frame",
"CPL_TYPE_INT", ron_ury,
611 "Activate the multi-exts option",
612 "CPL_TYPE_INT", exts);
615 cpl_ensure_code(!error, error);
617 return cpl_error_get_code();
637 detmon_fill_parlist(cpl_parameterlist * parlist,
638 const char *recipe_name,
639 const char *pipeline_name,
647 int pars_counter = 0;
649 group_name = cpl_sprintf(
"%s.%s", pipeline_name, recipe_name);
650 assert(group_name != NULL);
652 #define insert_par(PARNAME, PARDESC, PARVALUE, PARTYPE) \
654 char * par_name = cpl_sprintf("%s.%s", group_name, PARNAME); \
656 assert(par_name != NULL); \
657 p = cpl_parameter_new_value(par_name, PARTYPE, \
658 PARDESC, group_name, PARVALUE); \
659 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, PARNAME); \
660 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); \
661 cpl_parameterlist_append(parlist, p); \
662 cpl_free(par_name); \
668 while(pars_counter < npars) {
669 char *name = va_arg(ap,
char *);
670 char *desc = va_arg(ap,
char *);
671 char *type = va_arg(ap,
char *);
673 if(!strcmp(type,
"CPL_TYPE_INT")) {
674 int v1 = va_arg(ap,
int);
676 insert_par(name, desc, v1, CPL_TYPE_INT);
677 }
else if(!strcmp(type,
"CPL_TYPE_BOOL")) {
678 char *v2 = va_arg(ap,
char *);
680 if(!strcmp(v2,
"CPL_FALSE"))
681 insert_par(name, desc, CPL_FALSE, CPL_TYPE_BOOL);
682 if(!strcmp(v2,
"CPL_TRUE"))
683 insert_par(name, desc, CPL_TRUE, CPL_TYPE_BOOL);
684 }
else if(!strcmp(type,
"CPL_TYPE_STRING")) {
685 char *v2 = va_arg(ap,
char *);
687 insert_par(name, desc, v2, CPL_TYPE_STRING);
688 }
else if(!strcmp(type,
"CPL_TYPE_DOUBLE")) {
689 double v3 = va_arg(ap,
double);
690 insert_par(name, desc, v3, CPL_TYPE_DOUBLE);
698 cpl_free(group_name);
716 detmon_retrieve_par_int(
const char *parn,
717 const char *pipeline_name,
718 const char *recipe_name,
719 const cpl_parameterlist * parlist)
725 par_name = cpl_sprintf(
"%s.%s.%s", pipeline_name, recipe_name, parn);
726 assert(par_name != NULL);
727 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
728 value = cpl_parameter_get_int(par);
746 detmon_retrieve_par_double(
const char *parn,
747 const char *pipeline_name,
748 const char *recipe_name,
749 const cpl_parameterlist * parlist)
755 par_name = cpl_sprintf(
"%s.%s.%s", pipeline_name, recipe_name, parn);
756 assert(par_name != NULL);
757 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
758 value = cpl_parameter_get_double(par);
776 detmon_compare_dits(
const cpl_frame * frame1,
const cpl_frame * frame2)
779 cpl_propertylist *plist1;
780 cpl_propertylist *plist2;
784 if(frame1 == NULL || frame2 == NULL)
788 if((plist1 = cpl_propertylist_load(cpl_frame_get_filename(frame1),
790 cpl_msg_error(cpl_func,
"getting header from reference frame");
793 if((plist2 = cpl_propertylist_load(cpl_frame_get_filename(frame2),
795 cpl_msg_error(cpl_func,
"getting header from reference frame");
796 cpl_propertylist_delete(plist1);
801 if(cpl_error_get_code()) {
802 cpl_propertylist_delete(plist1);
803 cpl_propertylist_delete(plist2);
809 dval1 = irplib_pfits_get_exptime(plist1);
810 dval2 = irplib_pfits_get_exptime(plist2);
811 if(cpl_error_get_code()) {
812 cpl_msg_error(cpl_func,
"cannot get exposure time");
813 cpl_propertylist_delete(plist1);
814 cpl_propertylist_delete(plist2);
817 if(fabs(dval1 - dval2) > 1e-3)
821 cpl_propertylist_delete(plist1);
822 cpl_propertylist_delete(plist2);
837 irplib_pfits_get_exptime(
const cpl_propertylist * plist)
841 exptime = cpl_propertylist_get_double(plist,
"EXPTIME");
858 static cpl_error_code
859 detmon_ronbias_retrieve_parlist(
const char *pipeline_name,
860 const char *recipe_name,
861 const cpl_parameterlist * parlist,
872 par_name = cpl_sprintf(
"%s.%s.method", pipeline_name, recipe_name);
873 assert(par_name != NULL);
874 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
875 detmon_ronbias_config.method = cpl_parameter_get_string(par);
878 detmon_ronbias_config.method_bitmask = 0;
880 sscanf(detmon_ronbias_config.method,
"%s %s %s", m1, m2, m3);
882 if(!strcmp(m1,
"RANDOM") || !strcmp(m2,
"RANDOM")
883 || !strcmp(m3,
"RANDOM"))
884 detmon_ronbias_config.method_bitmask += RANDOM;
886 if(!strcmp(m1,
"HISTO") || !strcmp(m2,
"HISTO") || !strcmp(m3,
"HISTO"))
887 detmon_ronbias_config.method_bitmask += HISTO;
889 if(!strcmp(m1,
"PREOVERSCAN") || !strcmp(m2,
"PREOVERSCAN")
890 || !strcmp(m3,
"PREOVERSCAN")) {
891 if (opt_nir == NIR) {
895 cpl_msg_warning(cpl_func,
"PREOVERSCAN is not appliable for NIR");
897 detmon_ronbias_config.method_bitmask += PREOVERSCAN;
900 if(!strcmp(m1,
"REGION") || !strcmp(m2,
"REGION")
901 || !strcmp(m3,
"REGION"))
902 detmon_ronbias_config.method_bitmask += REGION;
904 if(!strcmp(m1,
"ALL")) {
905 if (opt_nir == OPT) {
906 detmon_ronbias_config.method_bitmask =
907 RANDOM | HISTO | PREOVERSCAN | REGION;
909 detmon_ronbias_config.method_bitmask =
910 RANDOM | HISTO | REGION;
915 par_name = cpl_sprintf(
"%s.%s.pmethod", pipeline_name, recipe_name);
916 assert(par_name != NULL);
917 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
918 detmon_ronbias_config.pmethod = cpl_parameter_get_string(par);
922 detmon_ronbias_config.preoverscan_degree =
923 detmon_retrieve_par_int(
"preoverscan.degree", pipeline_name,
924 recipe_name, parlist);
927 detmon_ronbias_config.random_nsamples =
928 detmon_retrieve_par_int(
"random.nsamples", pipeline_name,
929 recipe_name, parlist);
932 detmon_ronbias_config.random_sizex =
933 detmon_retrieve_par_int(
"random.sizex", pipeline_name,
934 recipe_name, parlist);
937 detmon_ronbias_config.random_sizey =
938 detmon_retrieve_par_int(
"random.sizey", pipeline_name,
939 recipe_name, parlist);
942 detmon_ronbias_config.criteria =
943 detmon_retrieve_par_int(
"criteria", pipeline_name, recipe_name,
947 detmon_ronbias_config.ref_llx =
948 detmon_retrieve_par_int(
"ref.llx", pipeline_name, recipe_name,
951 detmon_ronbias_config.ref_lly =
952 detmon_retrieve_par_int(
"ref.lly", pipeline_name, recipe_name,
955 detmon_ronbias_config.ref_urx =
956 detmon_retrieve_par_int(
"ref.urx", pipeline_name, recipe_name,
959 detmon_ronbias_config.ref_ury =
960 detmon_retrieve_par_int(
"ref.ury", pipeline_name, recipe_name,
965 cpl_sprintf(
"%s.%s.stacking.method", pipeline_name, recipe_name);
966 assert(par_name != NULL);
967 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
968 detmon_ronbias_config.stacking_method = cpl_parameter_get_string(par);
972 detmon_ronbias_config.stacking_ks_low =
973 detmon_retrieve_par_int(
"stacking.ks.low", pipeline_name,
974 recipe_name, parlist);
976 detmon_ronbias_config.stacking_ks_high =
977 detmon_retrieve_par_int(
"stacking.ks.high", pipeline_name,
978 recipe_name, parlist);
980 detmon_ronbias_config.stacking_ks_iter =
981 detmon_retrieve_par_int(
"stacking.ks.iter", pipeline_name,
982 recipe_name, parlist);
984 detmon_ronbias_config.master_shift_x =
985 detmon_retrieve_par_int(
"master.shift.x", pipeline_name,
986 recipe_name, parlist);
988 detmon_ronbias_config.master_shift_y =
989 detmon_retrieve_par_int(
"master.shift.y", pipeline_name,
990 recipe_name, parlist);
992 detmon_ronbias_config.ron_llx =
993 detmon_retrieve_par_int(
"ron.llx", pipeline_name, recipe_name,
996 detmon_ronbias_config.ron_lly =
997 detmon_retrieve_par_int(
"ron.lly", pipeline_name, recipe_name,
1000 detmon_ronbias_config.ron_urx =
1001 detmon_retrieve_par_int(
"ron.urx", pipeline_name, recipe_name,
1004 detmon_ronbias_config.ron_ury =
1005 detmon_retrieve_par_int(
"ron.ury", pipeline_name, recipe_name,
1008 detmon_ronbias_config.exts =
1009 detmon_retrieve_par_int(
"exts", pipeline_name, recipe_name,
1012 if(cpl_error_get_code()) {
1013 cpl_msg_error(cpl_func,
"Failed to retrieve the input parameters");
1014 cpl_ensure_code(0, CPL_ERROR_DATA_NOT_FOUND);
1018 return CPL_ERROR_NONE;
1032 detmon_ronbias_check_defaults(
const cpl_frameset *
set,
1035 const cpl_frame * fr = cpl_frameset_get_first_const(
set);
1037 cpl_propertylist * plist =
1038 cpl_propertylist_load(cpl_frame_get_filename(fr), whichext);
1040 const int naxis1 = cpl_propertylist_get_int(plist,
"NAXIS1");
1041 const int naxis2 = cpl_propertylist_get_int(plist,
"NAXIS2");
1043 if(detmon_ronbias_config.method_bitmask & PREOVERSCAN)
1045 const int nx = cpl_propertylist_get_int(plist,
"ESO DET OUT1 NX");
1046 const int ny = cpl_propertylist_get_int(plist,
"ESO DET OUT1 NY");
1054 cpl_propertylist_get_int(plist,
"ESO DET OUT1 PRSCX");
1056 cpl_propertylist_get_int(plist,
"ESO DET OUT1 OVSCX");
1058 cpl_error_ensure(cpl_error_get_code() == CPL_ERROR_NONE, cpl_error_get_code(),
goto cleanup,
"error");
1060 detmon_ronbias_config.prescan_llx = 1;
1061 detmon_ronbias_config.prescan_lly = 1;
1062 detmon_ronbias_config.prescan_urx = prscsize;
1063 detmon_ronbias_config.prescan_ury = naxis2;
1064 detmon_ronbias_config.overscan_llx = naxis1 - ovscsize;
1065 detmon_ronbias_config.overscan_lly = 1;
1066 detmon_ronbias_config.overscan_urx = naxis1;
1067 detmon_ronbias_config.overscan_ury = naxis2;
1068 }
else if (naxis2 != ny)
1071 cpl_propertylist_get_int(plist,
"ESO DET OUT1 PRSCY");
1073 cpl_propertylist_get_int(plist,
"ESO DET OUT1 OVSCY");
1074 cpl_error_ensure(cpl_error_get_code() == CPL_ERROR_NONE, cpl_error_get_code(),
goto cleanup,
"error");
1076 detmon_ronbias_config.prescan_llx = 1;
1077 detmon_ronbias_config.prescan_lly = 1;
1078 detmon_ronbias_config.prescan_urx = naxis1;
1079 detmon_ronbias_config.prescan_ury = prscsize;
1080 detmon_ronbias_config.overscan_llx = 1;
1081 detmon_ronbias_config.overscan_lly = naxis2 - ovscsize;
1082 detmon_ronbias_config.overscan_urx = naxis1;
1083 detmon_ronbias_config.overscan_ury = naxis2;
1086 cpl_msg_error(cpl_func,
1087 "No PREOVERSCAN areas found");
1088 cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
1093 if(detmon_ronbias_config.ref_llx == -1)
1094 detmon_ronbias_config.ref_llx = naxis1 / 8;
1095 if(detmon_ronbias_config.ref_lly == -1)
1096 detmon_ronbias_config.ref_lly = naxis2 / 8;
1097 if(detmon_ronbias_config.ref_urx == -1)
1098 detmon_ronbias_config.ref_urx = naxis1 * 7 / 8;
1099 if(detmon_ronbias_config.ref_ury == -1)
1100 detmon_ronbias_config.ref_ury = naxis2 * 7 / 8;
1102 if(detmon_ronbias_config.ron_llx == -1)
1103 detmon_ronbias_config.ron_llx = 1;
1104 if(detmon_ronbias_config.ron_lly == -1)
1105 detmon_ronbias_config.ron_lly = 1;
1106 if(detmon_ronbias_config.ron_urx == -1)
1107 detmon_ronbias_config.ron_urx = naxis1;
1108 if(detmon_ronbias_config.ron_ury == -1)
1109 detmon_ronbias_config.ron_ury = naxis2;
1112 cpl_propertylist_delete(plist);
1113 return cpl_error_get_code();
1129 detmon_ronbias(cpl_frameset * frameset,
1130 const cpl_parameterlist * parlist,
1132 const char *recipe_name,
1133 const char *pipeline_name,
1134 const char *pafregexp,
1135 const cpl_propertylist * pro_master,
1136 const cpl_propertylist * pro_xstr,
1137 const cpl_propertylist * pro_ystr,
1138 const cpl_propertylist * pro_synth,
1139 const cpl_propertylist * pro_bpmhot,
1140 const cpl_propertylist * pro_bpmcold,
1141 const cpl_propertylist * pro_bpmdev,
1142 const char *package,
1143 int (*compare) (
const cpl_frame *,
const cpl_frame *),
1144 cpl_boolean opt_nir)
1150 cpl_size * selection = NULL;
1151 cpl_frameset * cur_fset = NULL;
1152 cpl_propertylist * qclist = NULL;
1153 cpl_image * synthetic = NULL;
1154 cpl_image * masterbias = NULL;
1155 cpl_imagelist * rawbiases = NULL;
1156 cpl_mask * bpmhot = NULL;
1157 cpl_mask * bpmcold = NULL;
1158 cpl_mask * bpmdev = NULL;
1161 cpl_ensure_code(frameset != NULL, CPL_ERROR_NULL_INPUT);
1162 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
1163 cpl_ensure_code(tag != NULL, CPL_ERROR_NULL_INPUT);
1164 cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
1165 cpl_ensure_code(pipeline_name != NULL, CPL_ERROR_NULL_INPUT);
1166 cpl_ensure_code(pro_master != NULL, CPL_ERROR_NULL_INPUT);
1167 cpl_ensure_code(pro_bpmhot != NULL, CPL_ERROR_NULL_INPUT);
1168 cpl_ensure_code(pro_bpmcold != NULL, CPL_ERROR_NULL_INPUT);
1169 cpl_ensure_code(pro_bpmdev != NULL, CPL_ERROR_NULL_INPUT);
1170 cpl_ensure_code(package != NULL, CPL_ERROR_NULL_INPUT);
1172 if(detmon_ronbias_dfs_set_groups(frameset, tag)) {
1173 cpl_msg_error(cpl_func,
"Cannot identify RAW and CALIB frames");
1189 detmon_ronbias_retrieve_parlist(pipeline_name,
1190 recipe_name, parlist, opt_nir);
1193 if(detmon_ronbias_config.method_bitmask & PREOVERSCAN)
1194 cpl_ensure_code(pro_synth != NULL, CPL_ERROR_NULL_INPUT);
1201 cpl_msg_info(cpl_func,
"Identify the different settings");
1202 selection = cpl_frameset_labelise(frameset, compare, &nsets);
1203 if(selection == NULL)
1204 cpl_msg_error(cpl_func,
"Cannot labelise input frames");
1208 for(i = 0; i < nsets; i++) {
1213 detmon_ronbias_config.nb_extensions = 1;
1216 cpl_msg_info(cpl_func,
"Reduce data set nb %d out of %" CPL_SIZE_FORMAT
"",
1219 cur_fset = nsets == 1 ?
1220 cpl_frameset_duplicate(frameset) :
1221 cpl_frameset_extract(frameset, selection, i);
1222 skip_if(cur_fset == NULL);
1224 if(detmon_ronbias_config.exts > 0) {
1225 first_ext = detmon_ronbias_config.exts;
1226 last_ext = first_ext + 1;
1227 }
else if(detmon_ronbias_config.exts < 0) {
1228 const cpl_frame *cur_frame =
1229 cpl_frameset_get_first_const(cur_fset);
1231 detmon_ronbias_config.nb_extensions =
1232 cpl_frame_get_nextensions(cur_frame);
1234 last_ext = detmon_ronbias_config.nb_extensions + 1;
1237 if (last_ext - first_ext > 1) {
1238 skip_if(detmon_ronbias_save(parlist, frameset,
1240 pipeline_name, pafregexp,
1241 pro_master, pro_xstr,
1242 pro_ystr, pro_synth,
1244 pro_bpmcold, pro_bpmdev,
1245 package, NULL, NULL, NULL,
1247 0, 0, cur_fset, 0));
1250 for(j = first_ext; j < last_ext; j++) {
1253 qclist = cpl_propertylist_new();
1256 = cpl_imagelist_load_frameset(cur_fset,
1257 CPL_TYPE_FLOAT, 1, j);
1258 skip_if(rawbiases == NULL);
1260 skip_if(detmon_ronbias_check_defaults(cur_fset, j));
1262 skip_if(detmon_ronbias_dutycycl(cur_fset, qclist));
1264 masterbias = detmon_ronbias_master(rawbiases,
1267 skip_if(masterbias == NULL);
1274 if(detmon_ronbias_config.method_bitmask & RANDOM) {
1275 skip_if(detmon_ronbias_random(rawbiases, masterbias,
1279 if(detmon_ronbias_config.method_bitmask & HISTO) {
1280 skip_if(detmon_ronbias_histo(rawbiases, masterbias,
1284 if(detmon_ronbias_config.method_bitmask & PREOVERSCAN) {
1285 skip_if(detmon_ronbias_preoverscan(rawbiases,
1287 qclist, &synthetic));
1290 if(detmon_ronbias_config.method_bitmask & REGION) {
1291 skip_if(detmon_ronbias_region(rawbiases, masterbias,
1301 detmon_ronbias_check(qclist);
1307 whichext = first_ext > 1 ? 0 : j;
1309 skip_if(detmon_ronbias_save(parlist, frameset,
1311 pipeline_name, pafregexp,
1312 pro_master, pro_xstr,
1313 pro_ystr, pro_synth,
1315 pro_bpmcold, pro_bpmdev,
1316 package, masterbias, synthetic,
1317 bpmhot, bpmcold, bpmdev,
1318 qclist, 0, 0, cur_fset,
1321 cpl_image_delete(synthetic);
1322 cpl_image_delete(masterbias);
1323 cpl_mask_delete(bpmhot);
1324 cpl_mask_delete(bpmcold);
1325 cpl_mask_delete(bpmdev);
1326 cpl_imagelist_delete(rawbiases);
1327 cpl_propertylist_delete(qclist);
1338 cpl_frameset_delete(cur_fset);
1345 cpl_free(selection);
1347 cpl_frameset_delete(cur_fset);
1349 cpl_image_delete(synthetic);
1350 cpl_image_delete(masterbias);
1351 cpl_mask_delete(bpmhot);
1352 cpl_mask_delete(bpmcold);
1353 cpl_mask_delete(bpmdev);
1354 cpl_imagelist_delete(rawbiases);
1355 cpl_propertylist_delete(qclist);
1357 return cpl_error_get_code();
1371 static cpl_error_code
1372 detmon_ronbias_random(
const cpl_imagelist * rawbiases,
1373 const cpl_image * masterbias,
1374 cpl_propertylist * qclist)
1376 int nraws = cpl_imagelist_get_size(rawbiases);
1378 double bias = DBL_MAX;
1383 (
double *) cpl_malloc(
sizeof(
double) * nraws);
1387 cpl_error_code error = CPL_ERROR_NONE;
1391 if(!strcmp(detmon_ronbias_config.pmethod,
"DIF"))
1396 for(i = 0; i < nraws; i++)
1398 const cpl_image *c1_raw =
1399 cpl_imagelist_get_const(rawbiases, i);
1400 const cpl_image *c2_raw =
1401 cpl_imagelist_get_const(rawbiases, i + 1);
1403 const cpl_image *c_raw = cpl_image_subtract_create(c1_raw,
1405 error = cpl_flux_get_noise_window(c_raw, NULL,
1406 detmon_ronbias_config.random_sizex / 2,
1407 detmon_ronbias_config.random_nsamples,
1408 ron + i, &ron_error);
1409 cpl_image_delete((cpl_image*)c_raw);
1410 if (error != CPL_ERROR_NONE)
1417 for(i = 0; i < nraws; i++)
1419 const cpl_image *c_raw = cpl_imagelist_get_const(rawbiases, i);
1420 skip_if(cpl_flux_get_noise_window(c_raw, NULL,
1421 detmon_ronbias_config.random_sizex / 2,
1422 detmon_ronbias_config.random_nsamples,
1423 ron + i, &ron_error));
1429 if (error == CPL_ERROR_NONE)
1431 irplib_flux_get_bias_window(masterbias, NULL,
1432 detmon_ronbias_config.random_sizex / 2,
1433 detmon_ronbias_config.random_nsamples,
1434 &bias, &bias_error);
1436 v = cpl_vector_wrap(nraws, ron);
1437 stdev = cpl_vector_get_median_const(v);
1438 cpl_vector_unwrap(v);
1441 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_RANDOM_VAL, bias));
1442 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_RANDOM_VAL,
1443 DETMON_QC_BIAS_RANDOM_VAL_C));
1445 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_RANDOM_RON, stdev));
1446 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_RANDOM_RON,
1447 DETMON_QC_BIAS_RANDOM_RON_C));
1450 irplib_flux_get_bias_window(masterbias, NULL,
1451 detmon_ronbias_config.random_sizex / 2,
1452 detmon_ronbias_config.random_nsamples,
1453 &bias, &bias_error);
1455 v = cpl_vector_wrap(nraws, ron);
1458 stdev = cpl_vector_get_median_const(v);
1459 cpl_vector_unwrap(v);
1462 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_RANDOM_VAL, bias);
1463 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_RANDOM_VAL,
1464 DETMON_QC_BIAS_RANDOM_VAL_C);
1467 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_RANDOM_RON, stdev);
1468 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_RANDOM_RON,
1469 DETMON_QC_BIAS_RANDOM_RON_C);
1474 return cpl_error_get_code();
1477 static cpl_error_code
1478 detmon_ronbias_histo(
const cpl_imagelist * rawbiases,
1479 const cpl_image * masterbias,
1480 cpl_propertylist * qclist)
1482 int nraws = cpl_imagelist_get_size(rawbiases);
1485 double mbias = DBL_MAX;
1486 double mfwhm = DBL_MAX;
1487 double mmax = DBL_MAX;
1492 double mean_fwhm = DBL_MAX;
1494 if(!strcmp(detmon_ronbias_config.pmethod,
"DIF")) nraws--;
1496 fwhms = cpl_vector_new(nraws);
1497 maxs = cpl_vector_new(nraws);
1499 for(i = 0; i < nraws; i++) {
1501 const cpl_image * c_raw;
1502 double bias = DBL_MAX;
1503 double fwhm = DBL_MAX;
1504 double max = DBL_MAX;
1506 if(strcmp(detmon_ronbias_config.pmethod,
"DIF")) {
1507 c_raw = cpl_imagelist_get_const(rawbiases, i);
1509 const cpl_image *c1_raw = cpl_imagelist_get_const(rawbiases, i);
1510 const cpl_image * c2_raw = cpl_imagelist_get_const(rawbiases, i+1);
1511 c_raw = cpl_image_subtract_create(c1_raw, c2_raw);
1514 skip_if(detmon_ronbias_histo_reduce(c_raw, &bias, &fwhm, &max));
1516 skip_if(bias == DBL_MAX || fwhm == DBL_MAX || max == DBL_MAX);
1518 if(!strcmp(detmon_ronbias_config.pmethod,
"DIF"))
1519 cpl_image_delete((cpl_image *)c_raw);
1521 skip_if(cpl_vector_set(maxs, i, max));
1522 skip_if(cpl_vector_set(fwhms, i, fwhm));
1527 skip_if(cpl_vector_divide_scalar(fwhms, HIST_FACT));
1529 detmon_ronbias_histo_reduce(masterbias, &mbias, &mfwhm, &mmax);
1531 skip_if(mbias == DBL_MAX || mfwhm == DBL_MAX || mmax == DBL_MAX);
1533 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_HISTO_VAL,
1535 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_HISTO_VAL,
1536 DETMON_QC_BIAS_HISTO_VAL_C));
1537 mean_fwhm = cpl_vector_get_mean(fwhms);
1539 skip_if(mean_fwhm == DBL_MAX);
1540 skip_if(cpl_error_get_code());
1542 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_HISTO_RON,
1544 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_HISTO_RON,
1545 DETMON_QC_BIAS_HISTO_RON_C));
1549 cpl_vector_delete(fwhms);
1550 cpl_vector_delete(maxs);
1552 return cpl_error_get_code();
1556 detmon_ronbias_histo_reduce(
const cpl_image * c_raw,
1563 unsigned long maxwhere = 0;
1566 unsigned long x1a = 1;
1567 unsigned long x2a = 1;
1572 double maxwhere_interp;
1575 cpl_matrix * coeffs =cpl_matrix_new(3, 3);
1576 cpl_matrix * rhs =cpl_matrix_new(3, 1);
1578 cpl_matrix * result = NULL;
1580 dupi = cpl_image_duplicate(c_raw);
1585 hist = irplib_hist_new();
1586 irplib_hist_fill(hist, dupi);
1588 cpl_image_delete(dupi);
1590 irplib_hist_get_max(hist, &maxwhere);
1592 for( p = 0; p< 3; p++){
1593 unsigned long bi = irplib_hist_get_value(hist, maxwhere-1+p);
1594 cpl_matrix_set(rhs, p, 0, bi);
1595 for( q= 0; q< 3; q++) {
1596 cpl_matrix_set(coeffs, p,q,pow((maxwhere-1+p),q));
1600 result = cpl_matrix_solve(coeffs, rhs);
1602 a = cpl_matrix_get(result, 2, 0);
1603 b = cpl_matrix_get(result, 1, 0);
1604 c = cpl_matrix_get(result, 0, 0);
1606 maxwhere_interp = -0.5 * b / (2 * a);
1607 max_interp = -1 * b * b / (4 * a) + c;
1609 cpl_matrix_delete(coeffs);
1610 cpl_matrix_delete(rhs);
1611 cpl_matrix_delete(result);
1614 for(uj = 0; uj < maxwhere; uj++) {
1615 if(irplib_hist_get_value(hist, uj) <= max_interp / 2 &&
1616 irplib_hist_get_value(hist, uj + 1) > max_interp / 2) {
1620 for(uj = maxwhere; uj < irplib_hist_get_nbins(hist)-1; uj++) {
1621 if(irplib_hist_get_value(hist, uj) >= max_interp / 2 &&
1622 irplib_hist_get_value(hist, uj + 1) < max_interp / 2) {
1627 x1 = (max_interp / 2 - irplib_hist_get_value(hist, x1a)) /
1628 (irplib_hist_get_value(hist, x1a + 1) -
1629 irplib_hist_get_value(hist, x1a)) + x1a;
1630 x2 = (max_interp / 2 - irplib_hist_get_value(hist, x2a)) /
1631 (irplib_hist_get_value(hist, x2a + 1) -
1632 irplib_hist_get_value(hist, x2a)) + x2a;
1634 *fwhm = (x2 - x1) * irplib_hist_get_bin_size(hist);
1638 *bias = maxwhere_interp * irplib_hist_get_bin_size(hist) +
1639 irplib_hist_get_start(hist);
1641 irplib_hist_delete(hist);
1643 return cpl_error_get_code();
1656 static cpl_error_code
1657 detmon_ronbias_preoverscan(
const cpl_imagelist * rawbiases,
1658 cpl_propertylist * qclist,
1659 cpl_image ** synthetic)
1665 cpl_vector *meanspre;
1666 cpl_vector *medspre;
1667 cpl_vector *rmsspre;
1668 cpl_vector *meansover;
1669 cpl_vector *medsover;
1670 cpl_vector *rmssover;
1672 cpl_error_code error;
1674 nraws = cpl_imagelist_get_size(rawbiases);
1675 cpl_ensure_code(nraws != -1, CPL_ERROR_ILLEGAL_INPUT);
1677 nx = cpl_image_get_size_x(cpl_imagelist_get_const(rawbiases, 0));
1678 ny = cpl_image_get_size_y(cpl_imagelist_get_const(rawbiases, 0));
1679 cpl_ensure_code(nx != -1 && ny != -1, CPL_ERROR_ILLEGAL_INPUT);
1681 if(nx < detmon_ronbias_config.prescan_urx ||
1682 nx < detmon_ronbias_config.overscan_urx ||
1683 ny < detmon_ronbias_config.prescan_ury ||
1684 ny < detmon_ronbias_config.overscan_ury) {
1685 cpl_msg_warning(cpl_func,
"PREOVERSCAN method not applied. Given "
1686 "limits of prescan and overscan area "
1687 "exceed image size. Please check and rerun.");
1688 return CPL_ERROR_NONE;
1691 meanspre = cpl_vector_new(nraws);
1692 medspre = cpl_vector_new(nraws);
1693 rmsspre = cpl_vector_new(nraws);
1694 meansover = cpl_vector_new(nraws);
1695 medsover = cpl_vector_new(nraws);
1696 rmssover = cpl_vector_new(nraws);
1698 for(i = 0; i < nraws; i++) {
1702 cpl_image *prescan = NULL;
1703 cpl_image *overscan = NULL;
1705 const cpl_image *c_raw = cpl_imagelist_get_const(rawbiases, i);
1707 cpl_ensure_code(c_raw != NULL, CPL_ERROR_ILLEGAL_INPUT);
1710 cpl_image_extract(c_raw,
1711 detmon_ronbias_config.prescan_llx,
1712 detmon_ronbias_config.prescan_lly,
1713 detmon_ronbias_config.prescan_urx,
1714 detmon_ronbias_config.prescan_ury);
1715 cpl_ensure_code(prescan != NULL, CPL_ERROR_ILLEGAL_INPUT);
1717 cpl_image_extract(c_raw,
1718 detmon_ronbias_config.overscan_llx,
1719 detmon_ronbias_config.overscan_lly,
1720 detmon_ronbias_config.overscan_urx,
1721 detmon_ronbias_config.overscan_ury);
1722 cpl_ensure_code(overscan != NULL, CPL_ERROR_ILLEGAL_INPUT);
1725 *synthetic = detmon_build_synthetic(prescan, overscan);
1726 cpl_msg_info(cpl_func,
"Creating SYNTHETIC frame");
1727 if(*synthetic == NULL) {
1728 cpl_msg_error(cpl_func,
"Error creating SYNTHETIC frame");
1729 return CPL_ERROR_UNSPECIFIED;
1733 error = irplib_ksigma_clip(c_raw,
1734 detmon_ronbias_config.
1736 detmon_ronbias_config.
1738 detmon_ronbias_config.
1740 detmon_ronbias_config.
1742 (
double) detmon_ronbias_config.
1744 detmon_ronbias_config.
1745 stacking_ks_iter, 1e-5,
1747 cpl_ensure_code(!error, error);
1749 cpl_ensure_code(mean != 0 && stdev != 0, CPL_ERROR_UNSPECIFIED);
1751 error = cpl_vector_set(medspre, i, cpl_image_get_median(prescan));
1752 cpl_ensure_code(!error, error);
1754 error = cpl_vector_set(meanspre, i, mean);
1755 cpl_ensure_code(!error, error);
1756 error = cpl_vector_set(rmsspre, i, stdev);
1757 cpl_ensure_code(!error, error);
1758 error = irplib_ksigma_clip(c_raw,
1759 detmon_ronbias_config.
1761 detmon_ronbias_config.
1763 detmon_ronbias_config.
1765 detmon_ronbias_config.
1767 (
double) detmon_ronbias_config.
1769 detmon_ronbias_config.
1770 stacking_ks_iter, 1e-5,
1772 cpl_ensure_code(!error, error);
1774 cpl_ensure_code(mean != 0 && stdev != 0, CPL_ERROR_UNSPECIFIED);
1776 error = cpl_vector_set(medsover, i, cpl_image_get_median(overscan));
1777 cpl_ensure_code(!error, error);
1779 error = cpl_vector_set(meansover, i, mean);
1780 cpl_ensure_code(!error, error);
1781 error = cpl_vector_set(rmssover, i, stdev);
1782 cpl_ensure_code(!error, error);
1784 cpl_image_delete(prescan);
1785 cpl_image_delete(overscan);
1788 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_PRESCAN_MEAN,
1789 cpl_vector_get_mean(meanspre));
1791 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_PRESCAN_MEAN,
1792 DETMON_QC_BIAS_PRESCAN_MEAN_C);
1794 cpl_ensure_code(!error, error);
1795 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_PRESCAN_MED,
1796 cpl_vector_get_mean(medspre));
1797 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_PRESCAN_MED,
1798 DETMON_QC_BIAS_PRESCAN_MED_C);
1800 cpl_ensure_code(!error, error);
1801 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_PRESCAN_RON,
1802 cpl_vector_get_mean(rmsspre));
1804 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_PRESCAN_RON,
1805 DETMON_QC_BIAS_PRESCAN_RON_C);
1806 cpl_ensure_code(!error, error);
1809 cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_OVERSCAN_MEAN,
1810 cpl_vector_get_mean(meansover));
1811 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_OVERSCAN_MEAN,
1812 DETMON_QC_BIAS_OVERSCAN_MEAN_C);
1813 cpl_ensure_code(!error, error);
1814 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_OVERSCAN_MED,
1815 cpl_vector_get_mean(medsover));
1816 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_OVERSCAN_MED,
1817 DETMON_QC_BIAS_OVERSCAN_MED_C);
1818 cpl_ensure_code(!error, error);
1819 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_OVERSCAN_RON,
1820 cpl_vector_get_mean(rmssover));
1821 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_OVERSCAN_RON,
1822 DETMON_QC_BIAS_OVERSCAN_RON_C);
1823 cpl_ensure_code(!error, error);
1861 cpl_vector_delete(meanspre);
1862 cpl_vector_delete(medspre);
1863 cpl_vector_delete(rmsspre);
1864 cpl_vector_delete(meansover);
1865 cpl_vector_delete(medsover);
1866 cpl_vector_delete(rmssover);
1868 return CPL_ERROR_NONE;
1882 static cpl_error_code
1883 detmon_ronbias_region(
const cpl_imagelist * rawbiases,
1884 const cpl_image * masterbias,
1885 cpl_propertylist * qclist)
1888 int nraws = cpl_imagelist_get_size(rawbiases);
1892 cpl_image_get_size_x(cpl_imagelist_get_const(rawbiases, 0));
1894 cpl_image_get_size_y(cpl_imagelist_get_const(rawbiases, 0));
1896 cpl_vector *rmssreg;
1897 cpl_error_code error;
1899 const cpl_image * c_raw;
1900 double median, mbias, mstdev;
1902 if(!strcmp(detmon_ronbias_config.pmethod,
"DIF")) nraws--;
1904 rmssreg = cpl_vector_new(nraws);
1906 if(nx < detmon_ronbias_config.ref_urx ||
1907 ny < detmon_ronbias_config.ref_ury) {
1908 cpl_msg_warning(cpl_func,
"REGION method not applied. Given "
1909 "limits of prescan and overscan area "
1910 "exceed image size. Please check and rerun.");
1911 return CPL_ERROR_NONE;
1914 for(i = 0; i < nraws; i++) {
1917 if(strcmp(detmon_ronbias_config.pmethod,
"DIF")) {
1918 c_raw = cpl_imagelist_get_const(rawbiases, i);
1920 const cpl_image *c1_raw = cpl_imagelist_get_const(rawbiases, i);
1921 const cpl_image * c2_raw = cpl_imagelist_get_const(rawbiases, i+1);
1922 c_raw = cpl_image_subtract_create(c1_raw, c2_raw);
1924 error = irplib_ksigma_clip(c_raw,
1925 detmon_ronbias_config.ref_llx,
1926 detmon_ronbias_config.ref_lly,
1927 detmon_ronbias_config.ref_urx,
1928 detmon_ronbias_config.ref_ury,
1929 (
double) detmon_ronbias_config.
1931 detmon_ronbias_config.
1932 stacking_ks_iter, 1e-5,
1934 cpl_ensure_code(!error, error);
1941 error = cpl_vector_set(rmssreg, i, stdev);
1942 cpl_ensure_code(!error, error);
1943 if(!strcmp(detmon_ronbias_config.pmethod,
"DIF")) cpl_image_delete((cpl_image *)c_raw);
1946 median = cpl_image_get_median_window(masterbias,
1947 detmon_ronbias_config.ref_llx,
1948 detmon_ronbias_config.ref_lly,
1949 detmon_ronbias_config.ref_urx,
1950 detmon_ronbias_config.ref_ury);
1951 error = irplib_ksigma_clip(masterbias,
1952 detmon_ronbias_config.ref_llx,
1953 detmon_ronbias_config.ref_lly,
1954 detmon_ronbias_config.ref_urx,
1955 detmon_ronbias_config.ref_ury,
1956 (
double) detmon_ronbias_config.
1958 detmon_ronbias_config.
1959 stacking_ks_iter, 1e-5,
1962 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_REGION_MED,
1964 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_REGION_MED,
1965 DETMON_QC_BIAS_REGION_MED_C);
1966 cpl_ensure_code(!error, error);
1968 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_REGION_VAL,
1970 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_REGION_VAL,
1971 DETMON_QC_BIAS_REGION_VAL_C);
1972 cpl_ensure_code(!error, error);
1973 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_REGION_RON,
1974 cpl_vector_get_mean(rmssreg));
1975 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_REGION_RON,
1976 DETMON_QC_BIAS_REGION_RON_C);
1977 cpl_ensure_code(!error, error);
1984 cpl_vector_delete(rmssreg);
1986 return cpl_error_get_code();
2001 detmon_ronbias_master(
const cpl_imagelist * rawbiases,
2002 cpl_mask ** bpmhot, cpl_mask ** bpmcold,
2003 cpl_mask ** bpmdev, cpl_propertylist * qclist)
2007 cpl_image *masterbias = NULL;
2008 double dark_med, stdev_med,lower, upper;
2009 int hotpix_nb, coldpix_nb, devpix_nb;
2010 cpl_image * stdev_im = NULL;
2012 if(!strcmp(detmon_ronbias_config.stacking_method,
"MEAN"))
2013 masterbias = cpl_imagelist_collapse_create(rawbiases);
2014 if(!strcmp(detmon_ronbias_config.stacking_method,
"MINMAX"))
2016 cpl_imagelist_collapse_minmax_create(rawbiases, 0, 10000);
2017 if(!strcmp(detmon_ronbias_config.stacking_method,
"KSIGMA"))
2019 cpl_imagelist_collapse_sigclip_create(rawbiases, 3.0, 3.0, 0.9,
2020 CPL_COLLAPSE_MEAN, NULL);
2021 if(!strcmp(detmon_ronbias_config.stacking_method,
"MEDIAN"))
2022 masterbias = cpl_imagelist_collapse_median_create(rawbiases);
2024 skip_if(masterbias == NULL);
2026 skip_if(irplib_ksigma_clip(masterbias, 1, 1,
2027 cpl_image_get_size_x(masterbias),
2028 cpl_image_get_size_y(masterbias),
2029 (
double) detmon_ronbias_config.
2031 detmon_ronbias_config.
2032 stacking_ks_iter, 1e-5,
2035 if(irplib_isnan(mean))
2036 cpl_msg_error(cpl_func,
"We have an error in mean");
2037 if(irplib_isnan(stdev))
2038 cpl_msg_error(cpl_func,
"We have an error in stdev");
2040 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_MASTER_MEAN,
2042 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_MASTER_MEAN,
2043 DETMON_QC_MASTER_MEAN_C));
2045 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_MASTER_RMS,
2047 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_MASTER_RMS,
2048 DETMON_QC_MASTER_RMS_C));
2051 dark_med = cpl_image_get_median(masterbias);
2053 lower = dark_med - stdev * detmon_ronbias_config.stacking_ks_low;
2054 upper = dark_med + stdev * detmon_ronbias_config.stacking_ks_high;
2057 cpl_mask_delete(*bpmhot);
2058 irplib_check(*bpmhot = cpl_mask_threshold_image_create(masterbias,
2060 "Cannot compute the hot pixel map");
2061 hotpix_nb = cpl_mask_count(*bpmhot);
2065 cpl_mask_delete(*bpmcold);
2066 irplib_check(*bpmcold = cpl_mask_threshold_image_create(masterbias,
2068 "Cannot compute the cold pixel map");
2069 coldpix_nb = cpl_mask_count(*bpmcold);
2073 stdev_im = irplib_imagelist_collapse_stdev_create(rawbiases);
2074 stdev_med = cpl_image_get_median(stdev_im);
2076 skip_if(irplib_ksigma_clip(stdev_im, 1, 1,
2077 cpl_image_get_size_x(stdev_im),
2078 cpl_image_get_size_y(stdev_im),
2079 (
double) detmon_ronbias_config.
2081 detmon_ronbias_config.
2082 stacking_ks_iter, 1e-5,
2085 lower = stdev_med - stdev * detmon_ronbias_config.stacking_ks_low;
2086 upper = stdev_med + stdev * detmon_ronbias_config.stacking_ks_high;
2088 cpl_mask_delete(*bpmdev);
2089 irplib_check(*bpmdev = cpl_mask_threshold_image_create(stdev_im,
2091 "Cannot compute the cold pixel map");
2092 cpl_mask_not(*bpmdev);
2093 devpix_nb = cpl_mask_count(*bpmdev);
2097 skip_if(cpl_propertylist_append_int(qclist,DETMON_QC_NBCOLDPIX,coldpix_nb));
2098 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_NBCOLDPIX,
2099 DETMON_QC_NBCOLDPIX_C));
2101 skip_if(cpl_propertylist_append_int(qclist,DETMON_QC_NBHOTPIX, hotpix_nb));
2102 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_NBHOTPIX,
2103 DETMON_QC_NBHOTPIX_C));
2105 skip_if(cpl_propertylist_append_int(qclist,DETMON_QC_NBDEVPIX, devpix_nb));
2106 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_NBDEVPIX,
2107 DETMON_QC_NBDEVPIX_C));
2111 cpl_image_delete(stdev_im);
2113 if (cpl_error_get_code()) {
2114 cpl_image_delete(masterbias);
2132 static cpl_error_code
2133 detmon_ronbias_save(
const cpl_parameterlist * parlist,
2134 cpl_frameset * frameset,
2135 const char *recipe_name,
2136 const char *pipeline_name,
2137 const char *pafregexp,
2138 const cpl_propertylist * pro_master,
2139 const cpl_propertylist * pro_xstr,
2140 const cpl_propertylist * pro_ystr,
2141 const cpl_propertylist * pro_synth,
2142 const cpl_propertylist * pro_bpmhot,
2143 const cpl_propertylist * pro_bpmcold,
2144 const cpl_propertylist * pro_bpmdev,
2145 const char *package,
2146 const cpl_image * masterbias,
2147 const cpl_image * synthetic,
2148 const cpl_mask * bpmhot,
2149 const cpl_mask * bpmcold,
2150 const cpl_mask * bpmdev,
2151 cpl_propertylist * qclist,
2152 const int flag_sets,
2153 const int which_set,
2154 cpl_frameset * usedframes,
2158 cpl_frame *ref_frame;
2159 cpl_propertylist *plist = NULL;
2160 char *name_o = NULL;
2162 cpl_propertylist * paflist = NULL;
2163 cpl_propertylist * mainplist = NULL;
2164 cpl_propertylist * xplist = NULL;
2165 cpl_image * image = NULL;
2167 cpl_propertylist * mypro_master =
2168 cpl_propertylist_duplicate(pro_master);
2170 cpl_propertylist * mypro_synth = NULL;
2171 cpl_propertylist * mypro_bpmhot =
2172 cpl_propertylist_duplicate(pro_bpmhot);
2173 cpl_propertylist * mypro_bpmcold =
2174 cpl_propertylist_duplicate(pro_bpmcold);
2175 cpl_propertylist * mypro_bpmdev =
2176 cpl_propertylist_duplicate(pro_bpmdev);
2178 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
2179 cpl_ensure_code(frameset != NULL, CPL_ERROR_NULL_INPUT);
2180 cpl_ensure_code(pafregexp != NULL, CPL_ERROR_NULL_INPUT);
2181 cpl_ensure_code(package != NULL, CPL_ERROR_NULL_INPUT);
2182 cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
2183 cpl_ensure_code(pipeline_name != NULL, CPL_ERROR_NULL_INPUT);
2184 cpl_ensure_code(usedframes != NULL, CPL_ERROR_NULL_INPUT);
2187 mypro_synth = cpl_propertylist_duplicate(pro_synth);
2190 cpl_ensure_code(pro_xstr == NULL && pro_ystr == NULL,
2191 CPL_ERROR_UNSUPPORTED_MODE);
2194 if (detmon_ronbias_config.exts < 0) {
2195 const char * filename =
2196 cpl_frame_get_filename(cpl_frameset_get_first(frameset));
2199 xplist = cpl_propertylist_load_regexp(filename, whichext,
2201 skip_if(cpl_propertylist_append(xplist, qclist));
2204 cpl_msg_info(cpl_func,
"dealing with extention %d",whichext);
2208 ref_frame = cpl_frameset_get_first(frameset);
2209 skip_if(ref_frame == NULL);
2211 skip_if((mainplist =
2212 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
2221 name_o = cpl_sprintf(
"%s_masterbias.fits", recipe_name);
2222 assert(name_o != NULL);
2225 cpl_sprintf(
"%s_masterbias_set%02d.fits", recipe_name,
2227 assert(name_o != NULL);
2230 if (whichext == 0) {
2231 cpl_propertylist_append(mypro_master, qclist);
2233 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,
2234 masterbias, CPL_BPP_IEEE_FLOAT, recipe_name,
2235 mypro_master, NULL, package, name_o));
2237 skip_if(cpl_image_save(masterbias,
2238 name_o, CPL_BPP_IEEE_FLOAT, xplist,
2251 name_o = cpl_sprintf(
"%s_hotpixmap.fits", recipe_name);
2252 assert(name_o != NULL);
2255 cpl_sprintf(
"%s_hotpixmap_set%02d.fits", recipe_name,
2257 assert(name_o != NULL);
2261 image = cpl_image_new_from_mask(bpmhot);
2264 if (whichext == 0) {
2265 cpl_propertylist_append(mypro_bpmhot, qclist);
2267 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,
2268 image, CPL_BPP_IEEE_FLOAT, recipe_name,
2269 mypro_bpmhot, NULL, package, name_o));
2271 skip_if(cpl_image_save(image,
2272 name_o, CPL_BPP_IEEE_FLOAT, xplist,
2277 cpl_image_delete(image);
2287 name_o = cpl_sprintf(
"%s_coldpixmap.fits", recipe_name);
2288 assert(name_o != NULL);
2291 cpl_sprintf(
"%s_coldpixmap_set%02d.fits", recipe_name,
2293 assert(name_o != NULL);
2297 image = cpl_image_new_from_mask(bpmcold);
2300 if (whichext == 0) {
2301 cpl_propertylist_append(mypro_bpmcold, qclist);
2303 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,
2304 image, CPL_BPP_IEEE_FLOAT, recipe_name,
2305 mypro_bpmcold, NULL, package, name_o));
2307 skip_if(cpl_image_save(image,
2308 name_o, CPL_BPP_IEEE_FLOAT, xplist,
2313 cpl_image_delete(image);
2323 name_o = cpl_sprintf(
"%s_devpixmap.fits", recipe_name);
2324 assert(name_o != NULL);
2327 cpl_sprintf(
"%s_devpixmap_set%02d.fits", recipe_name,
2329 assert(name_o != NULL);
2333 image = cpl_image_new_from_mask(bpmdev);
2336 if (whichext == 0) {
2337 cpl_propertylist_append(mypro_bpmdev, qclist);
2339 skip_if(cpl_dfs_save_image(frameset, NULL,parlist, usedframes, NULL,
2340 image, CPL_BPP_IEEE_FLOAT, recipe_name,
2341 mypro_bpmdev, NULL, package, name_o));
2343 skip_if(cpl_image_save(image,
2344 name_o, CPL_BPP_IEEE_FLOAT, xplist,
2349 cpl_image_delete(image);
2356 if(detmon_ronbias_config.method_bitmask & PREOVERSCAN) {
2359 name_o = cpl_sprintf(
"%s_synthetic.fits", recipe_name);
2360 assert(name_o != NULL);
2363 cpl_sprintf(
"%s_synthetic_set%02d.fits", recipe_name,
2365 assert(name_o != NULL);
2368 if (whichext == 0) {
2370 cpl_propertylist_append(mypro_synth, qclist);
2372 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes,
2373 NULL,synthetic, CPL_BPP_IEEE_DOUBLE,
2374 recipe_name, mypro_synth, NULL,
2377 skip_if(cpl_image_save(synthetic, name_o, CPL_BPP_IEEE_FLOAT,
2378 xplist, CPL_IO_EXTEND));
2389 paflist = cpl_propertylist_new();
2392 if(detmon_ronbias_config.exts >= 0) {
2394 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
2395 detmon_ronbias_config.exts)) == NULL);
2398 name_o = cpl_sprintf(
"%s.paf", recipe_name);
2399 assert(name_o != NULL);
2401 name_o = cpl_sprintf(
"%s_set%02d.paf",
2402 recipe_name, which_set);
2403 assert(name_o != NULL);
2407 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
2408 whichext)) == NULL);
2412 name_o = cpl_sprintf(
"%s_ext%02d.paf",
2413 recipe_name, whichext);
2414 assert(name_o != NULL);
2416 name_o = cpl_sprintf(
"%s_set%02d_ext%02d.paf",
2418 which_set, whichext);
2419 assert(name_o != NULL);
2424 skip_if(cpl_propertylist_copy_property_regexp(paflist, plist,
2426 skip_if(cpl_propertylist_copy_property_regexp(paflist, mainplist,
2429 skip_if(cpl_propertylist_append(paflist, qclist));
2432 skip_if(cpl_dfs_save_paf(pipeline_name, recipe_name, paflist, name_o));
2438 cpl_propertylist_delete(plist);
2439 cpl_propertylist_delete(paflist);
2440 cpl_propertylist_delete(mainplist);
2441 cpl_propertylist_delete(xplist);
2443 cpl_image_delete(image);
2445 cpl_propertylist_delete(mypro_master);
2446 cpl_propertylist_delete(mypro_synth);
2447 cpl_propertylist_delete(mypro_bpmhot);
2448 cpl_propertylist_delete(mypro_bpmcold);
2449 cpl_propertylist_delete(mypro_bpmdev);
2451 return cpl_error_get_code();
2455 detmon_fill_prolist(
const char * procatg,
2456 const char * protype,
2457 const char * protech,
2458 cpl_boolean proscience)
2460 cpl_propertylist * prolist = cpl_propertylist_new();
2462 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procatg);
2463 cpl_propertylist_append_bool(prolist, CPL_DFS_PRO_SCIENCE, proscience);
2465 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_TYPE, protype);
2467 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_TECH, protech);
2484 detmon_ronbias_dfs_set_groups(cpl_frameset *
set,
const char *tag)
2486 cpl_frame *cur_frame;
2487 const char *cur_tag;
2496 nframes = cpl_frameset_get_size(
set);
2499 for(i = 0; i < nframes; i++) {
2500 cur_frame = cpl_frameset_get_frame(
set, i);
2501 cur_tag = cpl_frame_get_tag(cur_frame);
2504 if(!strcmp(cur_tag, tag))
2505 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW);
2527 detmon_build_synthetic(cpl_image * prescan, cpl_image * overscan)
2531 int distance = detmon_ronbias_config.overscan_urx -
2532 detmon_ronbias_config.prescan_llx + 1;
2534 double * mean_x = (
double *) cpl_malloc(
sizeof(
double) * distance);
2536 double * xvalues = (
double *) cpl_malloc(
sizeof(
double) * distance);
2538 cpl_vector *x = NULL;
2539 cpl_vector *y = NULL;
2541 cpl_polynomial *poly = NULL;
2542 cpl_polynomial *poly2 = NULL;
2544 cpl_matrix * samppos;
2546 cpl_size pows[2] = { 0, 0 };
2548 cpl_image * synthetic = NULL;
2553 for(j = 0; j < distance; j++) {
2558 for(j = 0; j < cpl_image_get_size_x(prescan); j++) {
2560 cpl_image_get_mean_window(prescan, j + 1, 1, j + 1,
2561 cpl_image_get_size_y(prescan));
2564 for(j = 0; j < cpl_image_get_size_x(overscan); j++) {
2565 *(mean_x + distance - cpl_image_get_size_x(overscan) + j) =
2566 cpl_image_get_mean_window(overscan, j + 1, 1, j + 1,
2567 cpl_image_get_size_y(overscan));
2570 x = cpl_vector_wrap(distance, xvalues);
2571 y = cpl_vector_wrap(distance, mean_x);
2573 poly = cpl_polynomial_new(1);
2575 cpl_matrix_wrap(1, cpl_vector_get_size(x), cpl_vector_get_data(x));
2577 cpl_polynomial_fit(poly, samppos, NULL, y, NULL,
2578 CPL_FALSE, NULL, &detmon_ronbias_config.preoverscan_degree);
2580 cpl_matrix_unwrap(samppos);
2582 cpl_vector_unwrap(x);
2583 cpl_vector_unwrap(y);
2590 poly2 = cpl_polynomial_new(2);
2593 cpl_polynomial_set_coeff(poly2, pows, cpl_polynomial_get_coeff(poly, &j));
2597 cpl_polynomial_set_coeff(poly2, pows, cpl_polynomial_get_coeff(poly, &j));
2599 cpl_polynomial_delete(poly);
2602 cpl_image_new(distance, cpl_image_get_size_y(prescan),
2605 if(cpl_image_fill_polynomial(synthetic, poly2, initial, 1, 1, 1)) {
2606 cpl_msg_error(cpl_func,
"Error creating the synthetic frame");
2607 cpl_polynomial_delete(poly2);
2611 cpl_polynomial_delete(poly2);
2627 static cpl_error_code
2628 detmon_ronbias_dutycycl(
const cpl_frameset * frameset,
2629 cpl_propertylist * qclist)
2631 const cpl_frame *first = 0;
2632 cpl_propertylist *plistfirst = 0;
2635 const cpl_frame *last = 0;
2636 cpl_propertylist *plistlast = 0;
2639 cpl_error_code error;
2641 first = cpl_frameset_get_first_const(frameset);
2642 plistfirst = cpl_propertylist_load(cpl_frame_get_filename(first), 0);
2643 tfirst = cpl_propertylist_get_double(plistfirst,
"MJD-OBS");
2644 nraws = cpl_frameset_get_size(frameset);
2645 last = cpl_frameset_get_frame_const(frameset, nraws - 1);
2646 plistlast = cpl_propertylist_load(cpl_frame_get_filename(last), 0);
2647 tlast = cpl_propertylist_get_double(plistlast,
"MJD-OBS");
2648 dutycycl = (tlast - tfirst) / (nraws - 1);
2650 error = cpl_error_get_code();
2651 if (error != CPL_ERROR_NONE)
2655 cpl_propertylist_append_double(qclist,DETMON_QC_DUTYCYCL, dutycycl);
2656 error = cpl_propertylist_set_comment(qclist,DETMON_QC_DUTYCYCL,
2657 DETMON_QC_DUTYCYCL_C);
2661 cpl_propertylist_delete(plistfirst);
2662 cpl_propertylist_delete(plistlast);
2681 #define HORIZONTAL TRUE
2684 detmon_pernoise_reduce(cpl_image * image)
2686 int nsamples, nffts;
2690 float * hanning = 0;
2692 cpl_image * power_im = 0;
2693 cpl_image * output = 0;
2694 cpl_image * pos_spec = 0;
2695 cpl_table * table = 0;
2696 cpl_image* fourier_im = 0;
2698 cpl_error_code error = CPL_ERROR_NONE;
2699 cpl_image * sub_image = 0;
2703 if(detmon_pernoise_config.direction == HORIZONTAL) {
2704 error = cpl_image_flip(image, 1);
2705 cpl_ensure(!error, error, NULL);
2708 nsamples = cpl_image_get_size_x(image);
2709 nffts = cpl_image_get_size_y(image);
2720 error = detmon_pernoise_rm_bg(image, nsamples, nffts);
2721 cpl_ensure(!error, error, NULL);
2723 sub_image = cpl_image_extract(image, nsamples/8 + 1, nffts/8+1,
2724 nsamples*7/8, nffts*7/8);
2726 nsamples = cpl_image_get_size_x(sub_image);
2727 nffts = cpl_image_get_size_y(sub_image);
2740 hanning = cpl_malloc(
sizeof(
float) * nsamples);
2742 for(i = 0; i < nsamples; i++) {
2743 *(hanning + i) = 0.5 - 0.5 * cos(2 * CPL_MATH_PI * (
float) i / nsamples);
2744 for(j = 0; j < nffts; j++) {
2746 cpl_image_get(sub_image, i + 1, j + 1, &status);
2747 error = cpl_image_set(sub_image, i + 1, j + 1, (*(hanning + i)) * value);
2752 if (error != CPL_ERROR_NONE)
2757 power = (
float *) cpl_calloc(
sizeof(
float), nsamples * nffts);
2760 fourier_im = cpl_image_new(nsamples,nffts, CPL_TYPE_FLOAT_COMPLEX);
2761 error = cpl_fft_image(fourier_im, sub_image, CPL_FFT_FORWARD);
2763 for(i = 1; i <= nffts; i++) {
2764 for(j = 1; j <= nsamples; j++) {
2766 double complex cvalue = cpl_image_get_complex(fourier_im,j, i, &rej );
2767 double value = cabs(cvalue);
2772 cpl_image_set(power_im, j, i, value);
2776 cpl_image_delete(fourier_im);
2778 output = cpl_image_collapse_create(power_im, 0);
2779 pos_spec = cpl_image_extract(output, 1, 1, nsamples/2, 1);
2781 cpl_image_delete(power_im);
2784 cpl_image_delete(output);
2786 table = cpl_table_new(nsamples/2);
2787 cpl_table_new_column(table,
"FREQ", CPL_TYPE_DOUBLE);
2788 cpl_table_new_column(table,
"POW", CPL_TYPE_DOUBLE);
2790 freq = detmon_pernoise_config.speed*1000/nffts_old;
2792 for(i = 0; i < nsamples/2; i++) {
2793 error = cpl_table_set(table,
"FREQ", i, freq/(nsamples/2)*i);
2794 error = cpl_table_set(table,
"POW", i, cpl_image_get(pos_spec, i+1, 1, &status));
2797 for(i= 0; i < 5; i++) {
2798 error = cpl_table_set(table,
"POW", i, 0.0);
2803 cpl_image_delete(pos_spec);
2805 cpl_image_delete(sub_image);
2806 if (error != CPL_ERROR_NONE)
2808 cpl_table_delete(table);
2831 detmon_rm_bpixs(cpl_image ** image,
2832 const double kappa,
int nffts,
int nsamples)
2836 float *data = cpl_image_get_data_float(*image);
2838 for(i = 0; i < nffts; i++) {
2839 for(j = 0; j < nsamples; j++) {
2840 float neighbours = 0;
2850 neighbours += *(data + (i - 1) * nsamples + j);
2854 neighbours += *(data + (i + 1) * nsamples + j);
2858 neighbours += *(data + i * nsamples + (j - 1));
2861 if(j < nsamples - 1) {
2862 neighbours += *(data + i * nsamples + (j + 1));
2865 average = neighbours / nneighs;
2867 if(*(data + i * nsamples + j) < average * (-1 * kappa) ||
2868 *(data + i * nsamples + j) > average * (kappa)) {
2870 *(data + i * nsamples + j) = average;
2874 if(*(data + i * nsamples + j) > average * (-1 * kappa) ||
2875 *(data + i * nsamples + j) < average * (kappa)) {
2877 *(data + i * nsamples + j) = average;
2885 return cpl_error_get_code();
2891 #define RECT_RON_HS 4
2892 #define RECT_RON_SAMPLES 100
2906 irplib_flux_get_bias_window(
const cpl_image * diff,
2907 const int *zone_def,
2909 int ron_nsamp,
double *bias,
double *error)
2911 const int hsize = ron_hsize < 0 ? RECT_RON_HS : ron_hsize;
2912 const int nsamples =
2913 ron_nsamp < 0 ? RECT_RON_SAMPLES : ron_nsamp;
2914 cpl_bivector *sample_reg;
2915 cpl_vector *rms_list;
2924 cpl_ensure_code(diff && bias, CPL_ERROR_NULL_INPUT);
2927 if(zone_def != NULL) {
2928 rect[0] = zone_def[0] + hsize + 1;
2929 rect[1] = zone_def[1] - hsize - 1;
2930 rect[2] = zone_def[2] + hsize + 1;
2931 rect[3] = zone_def[3] - hsize - 1;
2933 rect[0] = hsize + 1;
2934 rect[1] = cpl_image_get_size_x(diff) - hsize - 1;
2935 rect[2] = hsize + 1;
2936 rect[3] = cpl_image_get_size_y(diff) - hsize - 1;
2939 cpl_ensure_code(rect[0] < rect[1] && rect[2] < rect[3],
2940 CPL_ERROR_ILLEGAL_INPUT);
2945 irplib_bivector_gen_rect_poisson(rect, nsamples + 1, nsamples + 1);
2946 cpl_ensure(sample_reg != NULL, CPL_ERROR_ILLEGAL_INPUT,
2947 CPL_ERROR_ILLEGAL_INPUT);
2949 px = cpl_bivector_get_x_data(sample_reg);
2950 py = cpl_bivector_get_y_data(sample_reg);
2954 rms_list = cpl_vector_new(nsamples);
2955 cpl_ensure(rms_list != NULL, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
2956 pr = cpl_vector_get_data(rms_list);
2958 for(i = 0; i < nsamples; i++) {
2959 zone[0] = (int) px[i + 1] - hsize;
2960 zone[1] = (int) px[i + 1] + hsize;
2961 zone[2] = (int) py[i + 1] - hsize;
2962 zone[3] = (int) py[i + 1] + hsize;
2963 pr[i] = cpl_image_get_mean_window(diff,
2964 zone[0], zone[2], zone[1], zone[3]);
2966 cpl_bivector_delete(sample_reg);
2970 *error = cpl_vector_get_stdev(rms_list);
2974 *bias = cpl_vector_get_median(rms_list);
2976 cpl_vector_delete(rms_list);
2978 return CPL_ERROR_NONE;
2982 #undef RECT_RON_SAMPLES
2995 static cpl_bivector *
2996 irplib_bivector_gen_rect_poisson(
const int *r,
const int np,
const int homog)
3002 double cand_x, cand_y;
3005 int xmin, xmax, ymin, ymax;
3008 const int homogc = 0 < homog && homog < np ? homog : np;
3013 cpl_ensure(r, CPL_ERROR_NULL_INPUT, NULL);
3014 cpl_ensure(np > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
3016 list = cpl_bivector_new(np);
3017 cpl_ensure(list, CPL_ERROR_NULL_INPUT, NULL);
3018 px = cpl_bivector_get_x_data(list);
3019 py = cpl_bivector_get_y_data(list);
3027 CPL_MATH_SQRT1_2 * ((xmax - xmin) * (ymax - ymin) / (double) (homogc + 1));
3033 while(gnp < homogc) {
3035 cand_x = cpl_drand() * (xmax - xmin) + xmin;
3036 cand_y = cpl_drand() * (ymax - ymin) + ymin;
3040 for(i = 0; i < gnp; i++) {
3041 if(pdist(cand_x, cand_y, px[i], py[i]) < min_dist) {
3060 cand_x = cpl_drand() * (xmax - xmin) + xmin;
3061 cand_y = cpl_drand() * (ymax - ymin) + ymin;
3065 for(i = 0; i < homogc; i++) {
3068 px[start_ndx + i], py[start_ndx + i]) < min_dist) {
3087 cand_x = cpl_drand() * (xmax - xmin) + xmin;
3088 cand_y = cpl_drand() * (ymax - ymin) + ymin;
3092 for(i = 0; i < homogc; i++) {
3095 px[start_ndx + i], py[start_ndx + i]) < min_dist) {
3126 detmon_pernoise(cpl_frameset * frameset,
3127 const cpl_parameterlist * parlist,
3129 const char * recipe_name,
3130 const char * pipeline_name,
3131 const char * procatg_tbl,
3132 const char * package,
3133 int (*compare)(
const cpl_frame *,
3137 cpl_size *selection = NULL;
3139 cpl_error_code error;
3141 if(detmon_pernoise_dfs_set_groups(frameset, tag)) {
3142 cpl_msg_error(cpl_func,
"Cannot identify RAW and CALIB frames");
3150 error = detmon_pernoise_retrieve_parlist(pipeline_name,
3151 recipe_name, parlist);
3152 cpl_ensure_code(!error, error);
3158 cpl_msg_info(cpl_func,
"Identify the different settings");
3159 selection = cpl_frameset_labelise(frameset, compare, &nsets);
3160 if(selection == NULL)
3161 cpl_msg_error(cpl_func,
"Cannot labelise input frames");
3164 detmon_pernoise_config.nb_extensions = 1;
3165 if(detmon_pernoise_config.exts < 0) {
3166 const cpl_frame *cur_frame =
3167 cpl_frameset_get_first_const(frameset);
3169 detmon_pernoise_config.nb_extensions =
3170 cpl_frame_get_nextensions(cur_frame);
3174 for(i = 0; i < nsets; i++)
3177 cpl_table ** freq_table;
3178 cpl_propertylist ** qclist =
3179 (cpl_propertylist **)
3180 cpl_malloc(detmon_pernoise_config.nb_extensions *
3181 sizeof(cpl_propertylist *));
3183 cpl_imagelist ** raws = (cpl_imagelist **) cpl_malloc(detmon_pernoise_config.nb_extensions *
sizeof(cpl_imagelist *));
3184 cpl_image ** input = (cpl_image **) cpl_malloc(detmon_pernoise_config.nb_extensions *
sizeof(cpl_image *));
3187 if(detmon_pernoise_config.mode == 1)
3190 (cpl_table **) cpl_malloc(detmon_pernoise_config.nb_extensions *
3191 4 *
sizeof(cpl_table *));
3195 (cpl_table **) cpl_malloc(detmon_pernoise_config.nb_extensions *
3196 sizeof(cpl_table *));
3199 if(detmon_pernoise_config.exts >= 0)
3202 cpl_imagelist_load_frameset(frameset, CPL_TYPE_FLOAT, 1,
3203 detmon_pernoise_config.exts);
3204 *input = cpl_image_subtract_create(cpl_imagelist_get(*raws,0),
3205 cpl_imagelist_get(*raws,1));
3208 cpl_imagelist *raws_all_exts =
3209 cpl_imagelist_load_frameset(frameset, CPL_TYPE_FLOAT, 1,
3211 for(j = 0; j < detmon_pernoise_config.nb_extensions; j++)
3213 int nframes = cpl_frameset_get_size(frameset);
3215 for(k = 0; k < nframes; k++)
3218 cpl_imagelist_unset(raws_all_exts,
3219 (detmon_pernoise_config.
3220 nb_extensions - 1 - j) * k);
3221 cpl_imagelist_set(raws[j], image, k);
3224 cpl_image_subtract_create(cpl_imagelist_get(raws[j],0),
3225 cpl_imagelist_get(raws[j],1));
3229 for(j = 0; j < detmon_pernoise_config.nb_extensions; j++) {
3230 cpl_msg_info(cpl_func,
"Starting reduction");
3231 qclist[j] = cpl_propertylist_new();
3232 if(detmon_pernoise_config.mode == 1)
3234 int nx = cpl_image_get_size_x(input[j]);
3235 int ny = cpl_image_get_size_y(input[j]);
3239 quad[0] = cpl_image_extract(input[j], 1, 1, nx/2, ny/2);
3240 quad[1] = cpl_image_extract(input[j], 1, ny/2+1, nx/2, ny);
3241 quad[2] = cpl_image_extract(input[j], nx/2+1, 1, nx, ny/2);
3242 quad[3] = cpl_image_extract(input[j], nx/2+1, ny/2+1, nx, ny);
3244 for (k = 0; k < 4; k++)
3246 freq_table[j * 4 + k] = detmon_pernoise_reduce(quad[k]);
3248 for(k = 0; k < 4; k++)
3250 error = detmon_pernoise_qc(qclist[j], freq_table[j + k], k+1);
3251 if (error != CPL_ERROR_NONE)
3254 for (k = 0; k < 4; k++)
3256 cpl_image_delete(quad[k]);
3260 freq_table[j] = detmon_pernoise_reduce(input[j]);
3261 if(freq_table[j] != NULL)
3263 error = detmon_pernoise_qc(qclist[j], freq_table[j], 0);
3266 if (error != CPL_ERROR_NONE)
3271 if (error == CPL_ERROR_NONE)
3273 error = detmon_pernoise_save(parlist, frameset, recipe_name,
3274 pipeline_name, procatg_tbl,
3275 package, freq_table, qclist, 0,
3279 for(j = 0; j < detmon_pernoise_config.nb_extensions; j++)
3281 cpl_propertylist_delete(qclist[j]);
3282 cpl_imagelist_delete(raws[j]);
3283 cpl_image_delete(input[j]);
3288 if(detmon_pernoise_config.mode == 1)
3290 for(j= 0; j < detmon_pernoise_config.nb_extensions * 4; j++) {
3291 cpl_table_delete(freq_table[j]);
3294 for(j= 0; j < detmon_pernoise_config.nb_extensions; j++) {
3295 cpl_table_delete(freq_table[j]);
3298 cpl_free(freq_table);
3299 if (error != CPL_ERROR_NONE)
3305 return cpl_error_get_code();
3320 detmon_pernoise_dfs_set_groups(cpl_frameset *
set,
const char *tag)
3322 cpl_frame *cur_frame;
3323 const char *cur_tag;
3332 nframes = cpl_frameset_get_size(
set);
3335 for(i = 0; i < nframes; i++) {
3336 cur_frame = cpl_frameset_get_frame(
set, i);
3337 cur_tag = cpl_frame_get_tag(cur_frame);
3340 if(!strcmp(cur_tag, tag))
3341 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW);
3363 detmon_fill_pernoise_params(cpl_parameterlist * parlist,
3364 const char *recipe_name,
3365 const char *pipeline_name,
3367 const char * direction,
3376 detmon_fill_parlist(parlist, recipe_name, pipeline_name, 9,
3380 "CPL_TYPE_INT", mode,
3383 "Readout direction",
3384 "CPL_TYPE_BOOL", direction,
3388 "CPL_TYPE_DOUBLE", speed,
3391 "(yet unsupported) x coordinate of the lower-left "
3392 "point of the region of interest. If not modified, default value will be 1.",
3393 "CPL_TYPE_INT", llx,
3395 "(yet unsupported) y coordinate of the lower-left "
3396 "point of the region of interest. If not modified, default value will be 1.",
3397 "CPL_TYPE_INT", lly,
3399 "(yet unsupported) x coordinate of the upper-right "
3400 "point of the region of interest. If not modified, default value will be X dimension of the input image.",
3401 "CPL_TYPE_INT", urx,
3403 "(yet unsupported) y coordinate of the upper-right "
3404 "point of the region of interest. If not modified, default value will be Y dimension of the input image.",
3405 "CPL_TYPE_INT", ury,
3408 "Kappa used for determining threshold of bad (hot, cold) pixels",
3409 "CPL_TYPE_DOUBLE", kappa,
3412 "Activate the multi-exts option",
3413 "CPL_TYPE_INT", exts);
3430 detmon_fill_pernoise_params_default(cpl_parameterlist * parlist,
3431 const char *recipe_name,
3432 const char *pipeline_name)
3434 detmon_fill_pernoise_params(parlist, recipe_name, pipeline_name,
3450 static cpl_error_code
3451 detmon_pernoise_retrieve_parlist(
const char *pipeline_name,
3452 const char *recipe_name,
3453 const cpl_parameterlist * parlist)
3459 detmon_pernoise_config.mode =
3460 detmon_retrieve_par_int(
"mode", pipeline_name, recipe_name,
3464 par_name = cpl_sprintf(
"%s.%s.direction", pipeline_name, recipe_name);
3465 assert(par_name != NULL);
3466 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
3467 detmon_pernoise_config.direction = cpl_parameter_get_bool(par);
3471 par_name = cpl_sprintf(
"%s.%s.speed", pipeline_name, recipe_name);
3472 assert(par_name != NULL);
3473 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
3474 detmon_pernoise_config.speed = cpl_parameter_get_double(par);
3478 detmon_pernoise_config.llx =
3479 detmon_retrieve_par_int(
"llx", pipeline_name, recipe_name,
3483 detmon_pernoise_config.lly =
3484 detmon_retrieve_par_int(
"lly", pipeline_name, recipe_name,
3487 detmon_pernoise_config.urx =
3488 detmon_retrieve_par_int(
"urx", pipeline_name, recipe_name,
3491 detmon_pernoise_config.ury =
3492 detmon_retrieve_par_int(
"ury", pipeline_name, recipe_name,
3495 detmon_pernoise_config.kappa =
3496 detmon_retrieve_par_double(
"kappa", pipeline_name, recipe_name,
3500 detmon_pernoise_config.exts =
3501 detmon_retrieve_par_int(
"exts", pipeline_name, recipe_name,
3504 if(cpl_error_get_code()) {
3505 cpl_msg_error(cpl_func,
"Failed to retrieve the input parameters");
3506 cpl_ensure_code(0, CPL_ERROR_DATA_NOT_FOUND);
3509 return cpl_error_get_code();
3523 static cpl_error_code
3524 detmon_pernoise_save(
const cpl_parameterlist * parlist,
3525 cpl_frameset * frameset,
3526 const char *recipe_name,
3527 const char *pipeline_name,
3528 const char *procatg_tbl,
3529 const char *package,
3530 cpl_table ** freq_table,
3531 cpl_propertylist ** qclist,
3532 const int flag_sets,
3533 const int which_set,
3534 const cpl_frameset * usedframes)
3537 cpl_frame *ref_frame;
3538 cpl_propertylist *plist;
3539 char *name_o = NULL;
3541 cpl_propertylist *paflist;
3542 cpl_error_code error;
3544 cpl_propertylist * pro_tbl = cpl_propertylist_new();
3546 cpl_propertylist_append_string(pro_tbl,
3547 CPL_DFS_PRO_CATG, procatg_tbl);
3549 cpl_propertylist_append(pro_tbl, qclist[0]);
3556 if(detmon_pernoise_config.mode != 1) {
3559 name_o = cpl_sprintf(
"%s_freq_table.fits", recipe_name);
3560 assert(name_o != NULL);
3563 cpl_sprintf(
"%s_freq_table_set%02d.fits", recipe_name,
3565 assert(name_o != NULL);
3569 if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL, freq_table[0],
3570 NULL, recipe_name, pro_tbl, NULL,
3572 cpl_msg_error(cpl_func,
"Cannot save the product: %s", name_o);
3574 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
3577 if(detmon_pernoise_config.exts < 0) {
3579 for(i = 1; i < detmon_pernoise_config.nb_extensions; i++) {
3581 cpl_table_save(freq_table[i], NULL, qclist[i], name_o,
3583 cpl_ensure_code(!error, error);
3591 for (j = 1; j <= 4; j++) {
3594 name_o = cpl_sprintf(
"%s_freq_table_quad%02d.fits",
3596 assert(name_o != NULL);
3599 cpl_sprintf(
"%s_freq_table_quad%02d_set%02d.fits",
3600 recipe_name, j, which_set);
3601 assert(name_o != NULL);
3605 if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL,
3607 NULL, recipe_name, pro_tbl, NULL,
3609 cpl_msg_error(cpl_func,
"Cannot save the product: %s", name_o);
3611 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
3614 if(detmon_pernoise_config.exts < 0) {
3615 for(i = 1; i < detmon_pernoise_config.nb_extensions; i++) {
3616 error = cpl_table_save(freq_table[(j-1) + 4 * i],
3617 NULL, qclist[i], name_o,
3619 cpl_ensure_code(!error, error);
3633 ref_frame = cpl_frameset_get_first(frameset);
3634 if((plist = cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
3636 cpl_msg_error(cpl_func,
"getting header from reference frame");
3637 cpl_ensure_code(0, cpl_error_get_code());
3641 paflist = cpl_propertylist_new();
3642 cpl_propertylist_copy_property_regexp(paflist, plist,
3643 "^(ARCFILE|MJD-OBS|ESO TPL ID|"
3644 "DATE-OBS|ESO DET DIT|ESO DET NDIT|"
3646 "ESO DET MODE NAME)$", 0);
3648 for(i = 0; i < detmon_pernoise_config.nb_extensions; i++) {
3649 cpl_propertylist * c_paflist = cpl_propertylist_duplicate(paflist);
3650 error = cpl_propertylist_append(c_paflist, qclist[i]);
3651 cpl_ensure_code(!error, error);
3654 if(detmon_pernoise_config.exts >= 0) {
3656 name_o = cpl_sprintf(
"%s.paf", recipe_name);
3657 assert(name_o != NULL);
3659 name_o = cpl_sprintf(
"%s_set%02d.paf", recipe_name, which_set);
3660 assert(name_o != NULL);
3664 name_o = cpl_sprintf(
"%s_ext%02d.paf", recipe_name, i+1);
3665 assert(name_o != NULL);
3667 name_o = cpl_sprintf(
"%s_set%02d_ext%02d.paf", recipe_name, which_set, i+1);
3668 assert(name_o != NULL);
3672 if(cpl_dfs_save_paf(pipeline_name, recipe_name, c_paflist, name_o)) {
3673 cpl_msg_error(cpl_func,
"Cannot save the product: %s", name_o);
3675 cpl_propertylist_delete(paflist);
3676 cpl_propertylist_delete(plist);
3678 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
3680 cpl_propertylist_delete(c_paflist);
3684 cpl_propertylist_delete(plist);
3685 cpl_propertylist_delete(paflist);
3686 cpl_propertylist_delete(pro_tbl);
3687 return cpl_error_get_code();
3690 static cpl_error_code
3691 detmon_pernoise_qc(cpl_propertylist * qclist,
3695 cpl_error_code error;
3698 double freqs[3] = {0, 0, 0};
3699 double pows[3] = {0, 0, 0};
3708 int nrows = cpl_table_get_nrow(table);
3711 double * all_freqs = cpl_table_get_data_double(table,
"FREQ");
3712 double * all_pows = cpl_table_get_data_double(table,
"POW");
3714 for ( i= 1; i< nrows-1; i++){
3715 if (all_pows[i] > pows[0]) {
3716 if(all_pows[i-1] < all_pows[i] && all_pows[i] > all_pows[i+1]){
3719 pows[0]=all_pows[i];
3723 freqs[0]=all_freqs[i];
3725 }
else if (all_pows[i] > pows[1]) {
3726 if(all_pows[i-1] < all_pows[i] && all_pows[i] > all_pows[i+1]){
3728 pows[1]=all_pows[i];
3731 freqs[1]=all_freqs[i];
3734 }
else if(all_pows[i] > pows[2]) {
3735 if(all_pows[i-1] < all_pows[i] && all_pows[i] > all_pows[i+1]){
3736 pows[2]=all_pows[i];
3738 freqs[2]=all_freqs[i];
3744 if (detmon_pernoise_config.mode == 1) {
3745 propname = cpl_sprintf(
"ESO QC FREQ1 %d", iquad);
3746 assert(propname != NULL);
3748 propname = cpl_sprintf(
"ESO QC FREQ1");
3751 error = cpl_propertylist_append_double(qclist, propname, freqs[0]);
3752 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_FREQ_C);
3753 cpl_ensure_code(!error, error);
3757 if (detmon_pernoise_config.mode == 1) {
3758 propname = cpl_sprintf(
"ESO QC FREQ2 %d", iquad);
3759 assert(propname != NULL);
3761 propname = cpl_sprintf(
"ESO QC FREQ2");
3764 error = cpl_propertylist_append_double(qclist, propname, freqs[1]);
3765 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_FREQ_C);
3766 cpl_ensure_code(!error, error);
3770 if (detmon_pernoise_config.mode == 1) {
3771 propname = cpl_sprintf(
"ESO QC FREQ3 %d", iquad);
3772 assert(propname != NULL);
3774 propname = cpl_sprintf(
"ESO QC FREQ3");
3777 error = cpl_propertylist_append_double(qclist, propname, freqs[2]);
3778 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_FREQ_C);
3779 cpl_ensure_code(!error, error);
3783 if (detmon_pernoise_config.mode == 1) {
3784 propname = cpl_sprintf(
"ESO QC POW1 %d", iquad);
3785 assert(propname != NULL);
3787 propname = cpl_sprintf(
"ESO QC POW1");
3790 error = cpl_propertylist_append_double(qclist, propname, pows[0]);
3791 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_POW_C);
3792 cpl_ensure_code(!error, error);
3796 if (detmon_pernoise_config.mode == 1) {
3797 propname = cpl_sprintf(
"ESO QC POW2 %d", iquad);
3798 assert(propname != NULL);
3800 propname = cpl_sprintf(
"ESO QC POW2");
3803 error = cpl_propertylist_append_double(qclist, propname, pows[1]);
3804 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_POW_C);
3805 cpl_ensure_code(!error, error);
3809 if (detmon_pernoise_config.mode == 1) {
3810 propname = cpl_sprintf(
"ESO QC POW3 %d", iquad);
3811 assert(propname != NULL);
3813 propname = cpl_sprintf(
"ESO QC POW3");
3816 error = cpl_propertylist_append_double(qclist, propname, pows[2]);
3817 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_POW_C);
3818 cpl_ensure_code(!error, error);
3823 return cpl_error_get_code();
3838 detmon_pernoise_rm_bg(cpl_image * image,
int nsamples,
int nffts)
3840 cpl_vector *values = cpl_vector_new(nsamples * nffts);
3844 cpl_vector *xy_pos = cpl_vector_new(nsamples * nffts * 2);
3845 cpl_polynomial * poly_2d = 0;
3846 cpl_image * poly_ima = 0;
3847 cpl_size degree = 3;
3848 cpl_error_code error = CPL_ERROR_NONE;
3849 cpl_matrix * samppos = 0;
3851 for(i = 1; i <= nffts; i++) {
3852 for(j = 1; j <= nsamples; j++) {
3853 cpl_vector_set(xy_pos, (i - 1) * nsamples + (j - 1), j);
3854 cpl_vector_set(xy_pos, (i - 1) * nsamples + (j - 1) + nsamples * nffts, i);
3855 cpl_vector_set(values, (i - 1) * nsamples + (j - 1),
3856 cpl_image_get(image, j, i, &rejected));
3857 error = cpl_error_get_code();
3858 if (error != CPL_ERROR_NONE)
3863 if (error != CPL_ERROR_NONE)
3868 if (error != CPL_ERROR_NONE)
3873 poly_2d = cpl_polynomial_new(2);
3875 cpl_matrix_wrap(2, nsamples * nffts, cpl_vector_get_data(xy_pos));
3877 cpl_polynomial_fit(poly_2d, samppos, NULL, values, NULL,
3878 CPL_FALSE, NULL, °ree);
3880 cpl_matrix_unwrap(samppos);
3882 poly_ima = cpl_image_new(nsamples, nffts, CPL_TYPE_FLOAT);
3884 cpl_image_fill_polynomial(poly_ima, poly_2d, 1, 1, 1, 1);
3886 cpl_image_subtract(image, poly_ima);
3889 cpl_polynomial_delete(poly_2d);
3890 cpl_image_delete(poly_ima);
3891 cpl_vector_delete(xy_pos);
3892 cpl_vector_delete(values);
3894 return cpl_error_get_code();
3909 detmon_dark(cpl_frameset * frameset,
3910 const cpl_parameterlist * parlist,
3912 const char * recipe_name,
3913 const char * pipeline_name,
3914 const char * procatg_master,
3915 const char * procatg_dsnu,
3916 const char * procatg_tbl,
3917 const char * package,
3918 int (*compare)(
const cpl_frame *,
3922 cpl_size *selection = NULL;
3924 cpl_error_code error;
3926 if(detmon_dark_dfs_set_groups(frameset, tag)) {
3927 cpl_msg_error(cpl_func,
"Cannot identify RAW and CALIB frames");
3935 error = detmon_retrieve_dark_params(pipeline_name,
3936 recipe_name, parlist);
3937 cpl_ensure_code(!error, error);
3943 cpl_msg_info(cpl_func,
"Identify the different settings");
3944 selection = cpl_frameset_labelise(frameset, compare, &nsets);
3945 if(selection == NULL)
3946 cpl_msg_error(cpl_func,
"Cannot labelise input frames");
3949 detmon_dark_config.nb_extensions = 1;
3950 if(detmon_dark_config.exts < 0) {
3951 const cpl_frame *cur_frame =
3952 cpl_frameset_get_first_const(frameset);
3954 detmon_dark_config.nb_extensions =
3955 cpl_frame_get_nextensions(cur_frame);
3959 for(i = 0; i < nsets; i++) {
3960 cpl_size *select_dits = NULL;
3961 cpl_frameset *cur_fset =
3962 nsets == 1 ? cpl_frameset_duplicate(frameset) :
3963 cpl_frameset_extract(frameset, selection, i);
3967 cpl_table ** dsnu_table = NULL;
3968 cpl_imagelist ** dsnu = NULL;
3970 cpl_propertylist ** qclist =
3971 (cpl_propertylist **)
3972 cpl_malloc(detmon_dark_config.nb_extensions *
3973 sizeof(cpl_propertylist *));
3976 cpl_imagelist ** masters =
3978 cpl_malloc(detmon_dark_config.nb_extensions *
3979 sizeof(cpl_imagelist *));
3982 if(detmon_dark_config.opt_nir == OPT) {
3984 (cpl_table **) cpl_malloc(detmon_dark_config.nb_extensions *
3985 sizeof(cpl_table *));
3988 cpl_malloc(detmon_dark_config.nb_extensions *
3989 sizeof(cpl_imagelist *));
3992 select_dits = cpl_frameset_labelise(cur_fset,
3993 detmon_compare_dits,
3996 if(detmon_dark_config.exts >= 0) {
3997 *masters = cpl_imagelist_new();
3998 if(detmon_dark_config.opt_nir == OPT) {
3999 *dsnu = cpl_imagelist_new();
4000 *dsnu_table = cpl_table_new(ndits);
4002 *qclist = cpl_propertylist_new();
4003 cpl_table_new_column(*dsnu_table,
"DIT", CPL_TYPE_DOUBLE);
4004 cpl_table_new_column(*dsnu_table,
"STDEV", CPL_TYPE_DOUBLE);
4006 for ( j = 0; j < detmon_dark_config.nb_extensions; j ++) {
4007 masters[j] = cpl_imagelist_new();
4008 if(detmon_dark_config.opt_nir == OPT) {
4009 dsnu[j] = cpl_imagelist_new();
4010 dsnu_table[j] = cpl_table_new(ndits);
4012 qclist[j] = cpl_propertylist_new();
4013 cpl_table_new_column(dsnu_table[j],
"DIT", CPL_TYPE_DOUBLE);
4014 cpl_table_new_column(dsnu_table[j],
"STDEV", CPL_TYPE_DOUBLE);
4018 for(j = 0; j < ndits; j++) {
4019 cpl_frameset * cur_fdit = cpl_frameset_extract(cur_fset,
4021 cpl_imagelist ** raws =
4023 cpl_malloc(detmon_dark_config.nb_extensions *
4024 sizeof(cpl_imagelist *));
4026 if(detmon_dark_config.exts >= 0) {
4027 cpl_image * collapsed;
4029 cpl_imagelist_load_frameset(cur_fdit, CPL_TYPE_FLOAT, 1,
4030 detmon_dark_config.exts);
4031 collapsed = cpl_imagelist_collapse_create(*raws);
4032 cpl_imagelist_set(*masters, collapsed, j);
4033 if(detmon_dark_config.opt_nir == OPT) {
4034 detmon_dark_dsnu(cur_fdit, *dsnu, *dsnu_table,
4037 detmon_dark_qc(*qclist, collapsed);
4039 cpl_imagelist *raws_all_exts =
4040 cpl_imagelist_load_frameset(cur_fdit, CPL_TYPE_FLOAT, 1,
4042 for(k = 0; k < detmon_dark_config.nb_extensions; k++) {
4043 int nframes = cpl_frameset_get_size(cur_fdit);
4045 cpl_image * collapsed;
4046 for(h = 0; h < nframes; h++) {
4048 cpl_imagelist_unset(raws_all_exts,
4049 (detmon_dark_config.
4050 nb_extensions - 1 - k) * h);
4051 cpl_imagelist_set(raws[k], image, h);
4053 collapsed = cpl_imagelist_collapse_create(raws[k]);
4054 cpl_imagelist_set(masters[k],collapsed, j);
4055 if(detmon_dark_config.opt_nir == OPT) {
4056 detmon_dark_dsnu(cur_fdit, dsnu[k],
4057 dsnu_table[j], collapsed, j);
4059 detmon_dark_qc(qclist[k], collapsed);
4063 cpl_frameset_delete(cur_fdit);
4064 for(k = 0; k < detmon_dark_config.nb_extensions; k++) {
4065 cpl_imagelist_delete(raws[k]);
4070 cpl_frameset_delete(cur_fset);
4072 detmon_dark_save(parlist, frameset, recipe_name, pipeline_name,
4073 procatg_master, procatg_tbl, procatg_dsnu,
4074 package, masters, dsnu_table, dsnu, qclist,
4077 if(detmon_dark_config.opt_nir == OPT) {
4078 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
4079 cpl_table_delete(dsnu_table[j]);
4080 cpl_imagelist_delete(dsnu[j]);
4082 cpl_free(dsnu_table);
4086 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
4087 cpl_propertylist_delete(qclist[j]);
4088 cpl_imagelist_delete(masters[j]);
4092 cpl_free(select_dits);
4096 cpl_free(selection);
4098 return cpl_error_get_code();
4114 detmon_dark_dfs_set_groups(cpl_frameset *
set,
const char *tag)
4116 cpl_frame *cur_frame;
4117 const char *cur_tag;
4126 nframes = cpl_frameset_get_size(
set);
4129 for(i = 0; i < nframes; i++) {
4130 cur_frame = cpl_frameset_get_frame(
set, i);
4131 cur_tag = cpl_frame_get_tag(cur_frame);
4134 if(!strcmp(cur_tag, tag))
4135 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW);
4156 static cpl_error_code
4157 detmon_retrieve_dark_params(
const char *pipeline_name,
4158 const char *recipe_name,
4159 const cpl_parameterlist * parlist)
4165 par_name = cpl_sprintf(
"%s.%s.ron.method", pipeline_name, recipe_name);
4166 assert(par_name != NULL);
4167 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
4168 detmon_dark_config.ron_method = cpl_parameter_get_string(par);
4172 par_name = cpl_sprintf(
"%s.%s.dsnu.method", pipeline_name, recipe_name);
4173 assert(par_name != NULL);
4174 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
4175 detmon_dark_config.dsnu_method = cpl_parameter_get_string(par);
4179 par_name = cpl_sprintf(
"%s.%s.opt_nir", pipeline_name, recipe_name);
4180 assert(par_name != NULL);
4181 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
4182 detmon_dark_config.opt_nir = cpl_parameter_get_bool(par);
4186 detmon_dark_config.exts =
4187 detmon_retrieve_par_int(
"exts", pipeline_name, recipe_name,
4190 if(cpl_error_get_code()) {
4191 cpl_msg_error(cpl_func,
"Failed to retrieve the input parameters");
4192 cpl_ensure_code(0, CPL_ERROR_DATA_NOT_FOUND);
4196 return CPL_ERROR_NONE;
4212 detmon_fill_dark_params(cpl_parameterlist * parlist,
4213 const char *recipe_name,
4214 const char *pipeline_name,
4215 const char * ron_method,
4216 const char * dsnu_method,
4217 const char * opt_nir,
4220 detmon_fill_parlist(parlist, recipe_name, pipeline_name, 4,
4223 "Method used to compute RON. Currently no "
4224 "change is possible, RMS computed",
4225 "CPL_TYPE_STRING", ron_method,
4228 "Method used to compute DSNU map. Currently no "
4229 "change is possible. Method used STDEV",
4230 "CPL_TYPE_STRING", dsnu_method,
4233 "Boolean, OPT (FALSE) or NIR(TRUE)",
4234 "CPL_TYPE_BOOL", opt_nir,
4237 "Activate the multi-exts option. Default 0"
4238 "(primary unit), -1 (all exts)",
4239 "CPL_TYPE_INT", exts);
4241 return cpl_error_get_code();
4256 detmon_fill_dark_params_default(cpl_parameterlist * parlist,
4257 const char *recipe_name,
4258 const char *pipeline_name)
4260 detmon_fill_dark_params(parlist, recipe_name, pipeline_name,
4265 return cpl_error_get_code();
4280 detmon_dark_dsnu(cpl_frameset * cur_fdit,
4281 cpl_imagelist * dsnu,
4282 cpl_table * dsnu_table,
4283 cpl_image * collapsed,
4286 cpl_frame * first = cpl_frameset_get_first(cur_fdit);
4287 cpl_propertylist * plist =
4288 cpl_propertylist_load(cpl_frame_get_filename(first), 0);
4289 double dit = irplib_pfits_get_exptime(plist);
4290 double mean = cpl_image_get_mean(collapsed);
4292 cpl_image * dsnu_map =
4293 cpl_image_subtract_scalar_create(collapsed, mean);
4295 cpl_image_divide_scalar(dsnu_map, mean);
4296 stdev = cpl_image_get_stdev(dsnu_map);
4298 cpl_imagelist_set(dsnu, dsnu_map, pos);
4300 cpl_table_set(dsnu_table,
"DIT", pos, dit);
4301 cpl_table_set(dsnu_table,
"STDEV", pos, stdev);
4303 cpl_propertylist_delete(plist);
4305 return cpl_error_get_code();
4320 static cpl_error_code
4321 detmon_dark_save(
const cpl_parameterlist * parlist,
4322 cpl_frameset * frameset,
4323 const char *recipe_name,
4324 const char *pipeline_name,
4325 const char *procatg_master,
4326 const char *procatg_tbl,
4327 const char *procatg_dsnu,
4328 const char *package,
4329 cpl_imagelist ** masters,
4330 cpl_table ** dsnu_table,
4331 cpl_imagelist ** dsnu,
4332 cpl_propertylist ** qclist,
4333 const int flag_sets,
4334 const int which_set,
4335 const cpl_frameset * usedframes)
4338 cpl_frame *ref_frame;
4339 cpl_propertylist *plist;
4340 char *name_o = NULL;
4342 cpl_propertylist *paflist;
4343 cpl_error_code error;
4350 nb_images = cpl_imagelist_get_size(masters[0]);
4351 cpl_ensure_code(nb_images > 0, CPL_ERROR_DATA_NOT_FOUND);
4354 for(i = 0; i < nb_images; i++) {
4358 cpl_sprintf(
"%s_master_dit_%d.fits", recipe_name, i+1);
4359 assert(name_o != NULL);
4362 cpl_sprintf(
"%s_master_dit_%d_set%02d.fits",
4363 recipe_name, i, which_set);
4364 assert(name_o != NULL);
4369 if(detmon_dark_config.exts >= 0) {
4370 cpl_propertylist * pro_master = cpl_propertylist_new();
4372 cpl_propertylist_append_string(pro_master,
4373 CPL_DFS_PRO_CATG, procatg_master);
4375 cpl_propertylist_append(pro_master, qclist[0]);
4377 if(cpl_dfs_save_image
4378 (frameset, NULL, parlist, usedframes, NULL,
4379 cpl_imagelist_get(*masters, i), CPL_BPP_IEEE_FLOAT,
4380 recipe_name, pro_master, NULL, package,
4382 cpl_msg_error(cpl_func,
"Cannot save the product: %s",
4385 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
4389 cpl_propertylist_delete(pro_master);
4391 cpl_propertylist * pro_master = cpl_propertylist_new();
4393 cpl_propertylist_append_string(pro_master,
4394 CPL_DFS_PRO_CATG, procatg_master);
4396 cpl_propertylist_append(pro_master, qclist[0]);
4398 if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,
4399 NULL, CPL_BPP_IEEE_FLOAT, recipe_name,
4402 cpl_msg_error(cpl_func,
"Cannot save the product: %s",
4405 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
4408 cpl_propertylist_delete(pro_master);
4409 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
4411 cpl_image_save(cpl_imagelist_get(masters[j], i),
4412 name_o, CPL_BPP_IEEE_FLOAT, qclist[j],
4414 cpl_ensure_code(!error, error);
4420 if (detmon_dark_config.opt_nir == OPT) {
4421 cpl_propertylist * pro_tbl = cpl_propertylist_new();
4423 cpl_propertylist_append_string(pro_tbl,
4424 CPL_DFS_PRO_CATG, procatg_tbl);
4426 cpl_propertylist_append(pro_tbl, qclist[0]);
4433 name_o = cpl_sprintf(
"%s_dsnu_table.fits", recipe_name);
4434 assert(name_o != NULL);
4437 cpl_sprintf(
"%s_dsnu_table_set%02d.fits", recipe_name,
4439 assert(name_o != NULL);
4442 if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL,
4443 dsnu_table[0], NULL, recipe_name, pro_tbl, NULL,
4445 cpl_msg_error(cpl_func,
"Cannot save the product: %s", name_o);
4447 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
4450 cpl_propertylist_delete(pro_tbl);
4452 if(detmon_dark_config.exts < 0) {
4454 for(i = 1; i < detmon_dark_config.nb_extensions; i++) {
4456 cpl_table_save(dsnu_table[i], NULL, qclist[i], name_o,
4458 cpl_ensure_code(!error, error);
4469 for(i = 0; i < nb_images; i++) {
4473 cpl_sprintf(
"%s_dsnu_map_dit_%d.fits", recipe_name, i+1);
4474 assert(name_o != NULL);
4477 cpl_sprintf(
"%s_dsnu_map_dit_%d_set%02d.fits",
4478 recipe_name, i, which_set);
4479 assert(name_o != NULL);
4484 if(detmon_dark_config.exts >= 0) {
4485 cpl_propertylist * pro_dsnu = cpl_propertylist_new();
4487 cpl_propertylist_append_string(pro_dsnu,
4488 CPL_DFS_PRO_CATG, procatg_dsnu);
4490 cpl_propertylist_append(pro_dsnu, qclist[0]);
4492 if(cpl_dfs_save_image
4493 (frameset, NULL, parlist, usedframes, NULL,
4494 cpl_imagelist_get(*dsnu, i), CPL_BPP_IEEE_FLOAT,
4495 recipe_name, pro_dsnu, NULL, package,
4497 cpl_msg_error(cpl_func,
"Cannot save the product: %s",
4500 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
4504 cpl_propertylist_delete(pro_dsnu);
4506 cpl_propertylist * pro_dsnu = cpl_propertylist_new();
4508 cpl_propertylist_append_string(pro_dsnu,
4509 CPL_DFS_PRO_CATG, procatg_dsnu);
4511 cpl_propertylist_append(pro_dsnu, qclist[0]);
4513 if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes,
4515 CPL_BPP_IEEE_FLOAT, recipe_name,
4518 cpl_msg_error(cpl_func,
"Cannot save the product: %s",
4521 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
4524 cpl_propertylist_delete(pro_dsnu);
4525 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
4527 cpl_image_save(cpl_imagelist_get(dsnu[j], i),
4528 name_o, CPL_BPP_IEEE_FLOAT, qclist[j],
4530 cpl_ensure_code(!error, error);
4545 ref_frame = cpl_frameset_get_first(frameset);
4546 if((plist = cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
4548 cpl_msg_error(cpl_func,
"getting header from reference frame");
4549 cpl_ensure_code(0, cpl_error_get_code());
4553 paflist = cpl_propertylist_new();
4554 cpl_propertylist_copy_property_regexp(paflist, plist,
4555 "^(ARCFILE|MJD-OBS|ESO TPL ID|"
4556 "DATE-OBS|ESO DET DIT|ESO DET NDIT|"
4558 "ESO DET MODE NAME)$", 0);
4560 for(i = 0; i < detmon_dark_config.nb_extensions; i++) {
4561 cpl_propertylist * c_paflist = cpl_propertylist_duplicate(paflist);
4562 error = cpl_propertylist_append(c_paflist, qclist[i]);
4563 cpl_ensure_code(!error, error);
4566 if(detmon_dark_config.exts >= 0) {
4568 name_o = cpl_sprintf(
"%s.paf", recipe_name);
4569 assert(name_o != NULL);
4571 name_o = cpl_sprintf(
"%s_set%02d.paf", recipe_name, which_set);
4572 assert(name_o != NULL);
4576 name_o = cpl_sprintf(
"%s_ext%02d.paf", recipe_name, i+1);
4577 assert(name_o != NULL);
4579 name_o = cpl_sprintf(
"%s_set%02d_ext%02d.paf", recipe_name, which_set, i+1);
4580 assert(name_o != NULL);
4584 if(cpl_dfs_save_paf(pipeline_name, recipe_name, c_paflist, name_o)) {
4585 cpl_msg_error(cpl_func,
"Cannot save the product: %s", name_o);
4587 cpl_propertylist_delete(paflist);
4588 cpl_propertylist_delete(plist);
4590 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
4592 cpl_propertylist_delete(c_paflist);
4596 cpl_propertylist_delete(plist);
4597 cpl_propertylist_delete(paflist);
4599 return cpl_error_get_code();
4603 detmon_dark_qc(cpl_propertylist * qclist,
4604 cpl_image * collapsed)
4606 double mean = cpl_image_get_mean(collapsed);
4607 double stdev = cpl_image_get_stdev(collapsed);
4609 cpl_error_code error;
4611 error = cpl_propertylist_append_double(qclist,DETMON_QC_DARK, mean);
4612 error = cpl_propertylist_set_comment(qclist,DETMON_QC_DARK,
4614 cpl_ensure_code(!error, error);
4616 error = cpl_propertylist_append_double(qclist,DETMON_QC_DARK_STDEV, stdev);
4617 error = cpl_propertylist_set_comment(qclist,DETMON_QC_DARK_STDEV,
4618 DETMON_QC_DARK_STDEV_C);
4619 cpl_ensure_code(!error, error);
4621 return cpl_error_get_code();
4644 irplib_imagelist_collapse_stdev_create(
const cpl_imagelist * imlist)
4648 cpl_image * sq_delta;
4654 cpl_ensure(imlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
4655 cpl_ensure(cpl_imagelist_is_uniform(imlist) == 0, CPL_ERROR_ILLEGAL_INPUT,
4659 mean = cpl_image_duplicate(cpl_imagelist_get_const(imlist, 0));
4660 cpl_image_fill_rejected(mean, 0.0);
4661 cpl_image_accept_all(mean);
4663 stdev = cpl_image_new(cpl_image_get_size_x(mean),
4664 cpl_image_get_size_y(mean),
4667 for (i = 1; i < cpl_imagelist_get_size(imlist); i++) {
4668 delta = cpl_image_subtract_create(cpl_imagelist_get_const(imlist, i),
4670 cpl_image_fill_rejected(delta, 0.0);
4671 cpl_image_accept_all(delta);
4673 sq_delta = cpl_image_multiply_create(delta, delta);
4675 cpl_image_multiply_scalar(sq_delta, ((
double) i / (
double)(i+1)));
4676 cpl_image_add(stdev, sq_delta);
4678 cpl_image_divide_scalar(delta, i + 1);
4679 cpl_image_add(mean, delta);
4681 cpl_image_delete(delta);
4682 cpl_image_delete(sq_delta);
4685 cpl_image_divide_scalar(stdev, cpl_imagelist_get_size(imlist) - 1);
4686 cpl_image_power(stdev, 0.5);
4688 cpl_image_delete(mean);