37 #include "detmon_lg.h"
38 #include "irplib_plugin.h"
47 #include <sys/types.h>
50 #define RECIPE_NAME "detmon_opt_lg_mr"
58 detmon_lg_dfs_set_groups(cpl_frameset *
set,
59 const char *tag_on,
const char *tag_off);
61 CPL_RECIPE_DEFINE(detmon_opt_lg_mr, DETMON_BINARY_VERSION,
62 detmon_lg_fill_parlist_opt_default_mr(recipe->parameters,
63 "detmon_opt_lg_mr",
"detmon"),
64 "Julian Taylor",
"jtaylor@partner.eso.org",
"2013",
65 "Linearity/Gain recipe for the optical domain, multi "
67 detmon_lg_get_description(
"detmon_opt_lg_mr",
"DETMON",
69 DETMON_LG_OFF_RAW_NEW,
71 DETMON_LG_OFF_RAW_OLD));
75 int compare_tags(
const cpl_frame * a,
const cpl_frame * b)
77 return strcmp(cpl_frame_get_tag(a), cpl_frame_get_tag(b)) == 0;
93 static cpl_error_code merge_keys(cpl_propertylist * mplist,
94 const cpl_propertylist * plist_,
96 const char * rmregexp)
100 cpl_propertylist * plist = cpl_propertylist_duplicate(plist_);
103 cpl_propertylist_erase_regexp(plist, rmregexp, 0);
104 cpl_propertylist_erase_regexp(mplist, rmregexp, 0);
107 for (cpl_size i = 0; i < cpl_propertylist_get_size(plist); i++) {
108 cpl_property * p = cpl_propertylist_get(plist, i);
109 const char * key = cpl_property_get_name(p);
111 if (!strncmp(key,
"ESO QC ", 7)) {
112 sprintf(buffer,
"ESO QC REG%d %s", pos, key + 7);
113 cpl_msg_debug(cpl_func,
"merging %s to %s", key, buffer);
114 if (cpl_property_get_type(p) == CPL_TYPE_INT) {
115 int val = cpl_property_get_int(p);
116 cpl_propertylist_append_int(mplist, buffer, val);
117 }
else if (cpl_property_get_type(p) == CPL_TYPE_DOUBLE) {
118 double val = cpl_property_get_double(p);
119 cpl_propertylist_append_double(mplist, buffer, val);
120 }
else if (cpl_property_get_type(p) == CPL_TYPE_STRING) {
121 const char * val = cpl_property_get_string(p);
122 cpl_propertylist_append_string(mplist, buffer, val);
126 const char * com = cpl_property_get_comment(p);
127 cpl_propertylist_set_comment(mplist, buffer, com);
130 if (cpl_propertylist_has(mplist, key))
131 cpl_propertylist_erase(mplist, key);
137 cpl_propertylist_delete(plist);
139 return cpl_error_get_code();
152 static cpl_error_code
153 merge_images(cpl_imagelist * mimgl,
const cpl_imagelist * img)
155 cpl_ensure_code(cpl_imagelist_get_size(img) ==
156 cpl_imagelist_get_size(mimgl), CPL_ERROR_ILLEGAL_INPUT);
157 for (
int i = 0; i < cpl_imagelist_get_size(img); i++) {
158 cpl_image * mimg = cpl_imagelist_get(mimgl, i);
159 const cpl_image * part = cpl_imagelist_get_const(img, i);
160 cpl_image_add(mimg, part);
163 return cpl_error_get_code();
176 static cpl_error_code
177 merge_table(cpl_table * mtab, cpl_table * tab,
const int pos)
179 cpl_table_new_column(tab,
"REGION", CPL_TYPE_INT);
180 cpl_table_fill_column_window(tab,
"REGION", 0, cpl_table_get_nrow(tab), pos);
181 skip_if(cpl_table_insert(mtab, tab, cpl_table_get_nrow(mtab)));
185 return cpl_error_get_code();
189 static cpl_error_code
190 parse_token(
const char * token, cpl_size * llx, cpl_size * lly,
191 cpl_size * urx, cpl_size * ury)
193 assert(
sizeof(*llx) == 8);
194 if (sscanf(token,
" %lld , %lld , %lld , %lld ", llx, lly, urx, ury) == 4) {
195 return CPL_ERROR_NONE;
197 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
198 "Data not formated correctly: %s; "
199 "expecting: name,llx,lly,urx,ury",
218 static cpl_error_code
219 read_regions_file(
const char * filename, cpl_size ** rllx,
220 cpl_size ** rlly, cpl_size ** rurx, cpl_size ** rury,
223 FILE * f = fopen(filename,
"r");
228 return cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO,
229 "Could not open file %s: %s", filename,
232 cpl_msg_info(cpl_func,
"Reading %s", filename);
235 *rllx = cpl_malloc(
sizeof(**rllx) * nmax);
236 *rlly = cpl_malloc(
sizeof(**rllx) * nmax);
237 *rurx = cpl_malloc(
sizeof(**rllx) * nmax);
238 *rury = cpl_malloc(
sizeof(**rllx) * nmax);
240 while (fgets(line, 1024, f) != NULL) {
241 const size_t nline = strlen(line);
242 if (line[nline - 1] !=
'\n') {
243 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO,
244 "File %s contained too long line",
252 skip_if(parse_token(line, &(*rllx)[i], &(*rlly)[i],
253 &(*rurx)[i], &(*rury)[i]));
257 *rllx = cpl_realloc(*rllx,
sizeof(**rllx) * nmax);
258 *rlly = cpl_realloc(*rlly,
sizeof(**rllx) * nmax);
259 *rurx = cpl_realloc(*rurx,
sizeof(**rllx) * nmax);
260 *rury = cpl_realloc(*rury,
sizeof(**rllx) * nmax);
268 return CPL_ERROR_NONE;
286 static cpl_error_code
287 read_regions_str(
const char * istr, cpl_size ** rllx,
288 cpl_size ** rlly, cpl_size ** rurx, cpl_size ** rury,
292 char * str_ = cpl_strdup(istr);
295 *rllx = cpl_malloc(
sizeof(**rllx) * nmax);
296 *rlly = cpl_malloc(
sizeof(**rllx) * nmax);
297 *rurx = cpl_malloc(
sizeof(**rllx) * nmax);
298 *rury = cpl_malloc(
sizeof(**rllx) * nmax);
300 for (
int i = 0; ;i++) {
301 char * token = strtok(str,
":");
305 skip_if(parse_token(token, &(*rllx)[i], &(*rlly)[i],
306 &(*rurx)[i], &(*rury)[i]));
310 *rllx = cpl_realloc(*rllx,
sizeof(**rllx) * nmax);
311 *rlly = cpl_realloc(*rlly,
sizeof(**rllx) * nmax);
312 *rurx = cpl_realloc(*rurx,
sizeof(**rllx) * nmax);
313 *rury = cpl_realloc(*rury,
sizeof(**rllx) * nmax);
322 return CPL_ERROR_NONE;
340 static cpl_error_code
341 merge_lingain(cpl_propertylist * mplist[], cpl_table * mtab[],
342 const char * fn,
const cpl_size next,
343 const char * rmregexp,
int pos)
345 cpl_errorstate cleanstate = cpl_errorstate_get();
348 cpl_propertylist * plist = cpl_propertylist_load(fn, 0);
349 skip_if(plist == NULL);
350 if (mplist[0] == NULL) {
352 merge_keys(mplist[0], plist, pos, rmregexp);
355 merge_keys(mplist[0], plist, pos, rmregexp);
356 cpl_propertylist_delete(plist);
361 for (
int e = 1; e < next + 1; e++) {
362 cpl_propertylist * plist = cpl_propertylist_load(fn, e);
363 cpl_table * tab = cpl_table_load(fn, e, 0);
366 cpl_errorstate_set(cleanstate);
367 cpl_propertylist_delete(plist);
370 skip_if(plist == NULL);
372 if (mplist[e] == NULL) {
373 merge_keys(plist, plist, pos, rmregexp);
374 cpl_table_new_column(tab,
"REGION", CPL_TYPE_INT);
375 cpl_table_fill_column_window(tab,
"REGION", 0,
376 cpl_table_get_nrow(tab), 1);
382 merge_keys(mplist[e], plist, pos, rmregexp);
383 merge_table(mtab[e], tab, pos);
385 cpl_propertylist_delete(plist);
386 cpl_table_delete(tab);
393 return cpl_error_get_code();
411 static cpl_error_code
412 merge_bpmcoeff(cpl_propertylist * mplist[], cpl_imagelist * mimg[],
413 const char * fn,
const cpl_size next,
414 const char * rmregexp,
int pos)
416 cpl_errorstate cleanstate = cpl_errorstate_get();
418 for (
int e = 0; e < next + 1; e++) {
419 cpl_propertylist * plist = cpl_propertylist_load(fn, e);
420 cpl_imagelist * img = cpl_imagelist_load(fn, CPL_TYPE_UNSPECIFIED, e);
423 cpl_errorstate_set(cleanstate);
424 cpl_propertylist_delete(plist);
427 skip_if(plist == NULL);
429 if (mimg[e] == NULL) {
430 merge_keys(plist, plist, pos, rmregexp);
435 merge_keys(mplist[e], plist, pos, rmregexp);
436 merge_images(mimg[e], img);
438 cpl_propertylist_delete(plist);
439 cpl_imagelist_delete(img);
446 return cpl_error_get_code();
450 DETMON_BP_MAP_NL_IDX = 0,
451 DETMON_LIN_INFO_IDX = 1,
452 DETMON_GAIN_INFO_IDX = 2,
454 DETMON_COEFF_IDX = 4,
458 static cpl_error_code disable_contamination(cpl_parameterlist * parlist)
462 for (
int i = 1; i < 6; i++) {
464 sprintf(buffer,
"detmon.detmon_opt_lg_mr.llx%d", i);
465 par = cpl_parameterlist_find(parlist, buffer);
466 cpl_parameter_set_int(par, 1);
467 sprintf(buffer,
"detmon.detmon_opt_lg_mr.lly%d", i);
468 par = cpl_parameterlist_find(parlist, buffer);
469 cpl_parameter_set_int(par, 1);
470 sprintf(buffer,
"detmon.detmon_opt_lg_mr.urx%d", i);
471 par = cpl_parameterlist_find(parlist, buffer);
472 cpl_parameter_set_int(par, 2);
473 sprintf(buffer,
"detmon.detmon_opt_lg_mr.ury%d", i);
474 par = cpl_parameterlist_find(parlist, buffer);
475 cpl_parameter_set_int(par, 2);
478 return cpl_error_get_code();
490 static int detmon_opt_lg_mr(cpl_frameset * frameset,
491 const cpl_parameterlist * parlist_)
493 const char * tag_on=NULL;
494 const char * tag_off=NULL;
495 IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
496 cpl_parameterlist * parlist = (cpl_parameterlist *)parlist_;
497 IRPLIB_DIAG_PRAGMA_POP;
498 cpl_propertylist ** mplist[DETMON_MAX_IDX] = {NULL};
499 cpl_imagelist ** mimg[DETMON_MAX_IDX] = {NULL};
500 cpl_table ** mtab[DETMON_MAX_IDX] = {NULL};
501 cpl_size next[DETMON_MAX_IDX] = {0};
502 char * outname[DETMON_MAX_IDX] = {NULL};
503 char * outtag[DETMON_MAX_IDX] = {NULL};
505 cpl_frameset * frameset_copy = NULL;
507 cpl_propertylist * lintbl =
508 detmon_fill_prolist(
"DET_LIN_INFO",
"REDUCED",
"TECH", CPL_FALSE);
510 cpl_propertylist * gaintbl =
511 detmon_fill_prolist(
"GAIN_INFO",
"REDUCED",
"TECH", CPL_FALSE);
513 cpl_propertylist * coeffscube =
514 detmon_fill_prolist(
"COEFFS_CUBE",
"REDUCED",
"TECH", CPL_FALSE);
516 cpl_propertylist * bpm =
517 detmon_fill_prolist(
"BP_MAP_NL",
"REDUCED",
"TECH", CPL_FALSE);
519 cpl_propertylist * corr =
520 detmon_fill_prolist(
"AUTOCORR",
"REDUCED",
"TECH", CPL_FALSE);
522 cpl_propertylist * diff_flat =
523 detmon_fill_prolist(
"DIFF_FLAT",
"REDUCED",
"TECH", CPL_FALSE);
524 const char * regions_file = NULL;
525 const char * regions_str = NULL;
526 cpl_error_code error = CPL_ERROR_NONE;
527 cpl_size * llx = NULL, * lly = NULL, * urx = NULL, * ury = NULL;
528 const cpl_parameter * p =
529 cpl_parameterlist_find_const(parlist,
"detmon.detmon_opt_lg_mr.regions-file");
531 regions_file = cpl_parameter_get_string(p);
532 if (strlen(regions_file) == 0)
535 p = cpl_parameterlist_find_const(parlist,
536 "detmon.detmon_opt_lg_mr.regions");
538 regions_str = cpl_parameter_get_string(p);
539 if (strlen(regions_str) == 0)
543 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
544 "Please only provide either "
546 "--regions-file, not both");
551 p = cpl_parameterlist_find_const(parlist,
552 "detmon.detmon_opt_lg_mr.intermediate");
554 error_if(cpl_parameter_get_bool(p), CPL_ERROR_UNSUPPORTED_MODE,
555 "--intermediate not supported by multi region recipe");
558 skip_if (detmon_lg_set_tag(frameset, &tag_on, &tag_off));
559 skip_if (detmon_lg_dfs_set_groups(frameset, tag_on, tag_off));
561 cpl_size nregions = 0;
563 read_regions_file(regions_file, &llx, &lly, &urx, &ury,
566 else if (regions_str) {
567 read_regions_str(regions_str, &llx, &lly, &urx, &ury,
571 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
572 "Empty value in --regions or "
578 skip_if(disable_contamination(parlist));
583 for (
int i = 0; i < nregions; i++) {
585 par = cpl_parameterlist_find(parlist,
"detmon.detmon_opt_lg_mr.llx");
586 cpl_parameter_set_int(par, llx[i]);
587 par = cpl_parameterlist_find(parlist,
"detmon.detmon_opt_lg_mr.lly");
588 cpl_parameter_set_int(par, lly[i]);
589 par = cpl_parameterlist_find(parlist,
"detmon.detmon_opt_lg_mr.urx");
590 cpl_parameter_set_int(par, urx[i]);
591 par = cpl_parameterlist_find(parlist,
"detmon.detmon_opt_lg_mr.ury");
592 cpl_parameter_set_int(par, ury[i]);
593 cpl_msg_info(cpl_func,
"working on region %d/%d: %lld %lld, "
594 "%lld %lld", i + 1, (
int)nregions,
595 llx[i], lly[i], urx[i], ury[i]);
599 cpl_frameset_delete(frameset_copy);
600 frameset_copy = cpl_frameset_duplicate(frameset);
601 error = detmon_lg(frameset_copy,
608 lintbl, gaintbl, coeffscube,
609 bpm, corr, diff_flat,
610 PACKAGE
"/" PACKAGE_VERSION,
615 cpl_size * selection = cpl_frameset_labelise(frameset_copy,
616 compare_tags, &nlabels);
618 for (cpl_size j = 0; j < nlabels; j++) {
619 cpl_frameset * a = cpl_frameset_extract(frameset_copy, selection, j);
620 cpl_frame * frm = cpl_frameset_get_first(a);
621 const char * fn = cpl_frame_get_filename(frm);
624 if (strcmp(cpl_frame_get_tag(frm),
"DET_LIN_INFO") == 0)
625 idx = DETMON_LIN_INFO_IDX;
626 else if (strcmp(cpl_frame_get_tag(frm),
"GAIN_INFO") == 0)
627 idx = DETMON_GAIN_INFO_IDX;
628 else if (strcmp(cpl_frame_get_tag(frm),
"BP_MAP_NL") == 0)
629 idx = DETMON_BPM_IDX;
630 else if (strcmp(cpl_frame_get_tag(frm),
"COEFFS_CUBE") == 0)
631 idx = DETMON_COEFF_IDX;
633 cpl_frameset_delete(a);
638 if (mplist[idx] == NULL) {
639 next[idx] = cpl_frame_get_nextensions(frm);
640 outname[idx] = cpl_strdup(cpl_frame_get_filename(frm));
641 outtag[idx] = cpl_strdup(cpl_frame_get_tag(frm));
642 mplist[idx] = cpl_calloc(
sizeof(cpl_propertylist*), next[idx] + 1);
643 mimg[idx] = cpl_calloc(
sizeof(cpl_imagelist*), next[idx] + 1);
644 mtab[idx] = cpl_calloc(
sizeof(cpl_table*), next[idx] + 1);
647 if (idx == DETMON_LIN_INFO_IDX) {
648 const char * rmregexp =
"ESO QC CONTAM.*";
649 merge_lingain(mplist[idx], mtab[idx], fn, next[idx],
652 else if (idx == DETMON_GAIN_INFO_IDX) {
653 merge_lingain(mplist[idx], mtab[idx], fn, next[idx],
656 else if (idx == DETMON_BPM_IDX) {
657 merge_bpmcoeff(mplist[idx], mimg[idx], fn, next[idx],
660 else if (idx == DETMON_COEFF_IDX) {
661 merge_bpmcoeff(mplist[idx], mimg[idx], fn, next[idx],
666 for (
int e = 0; e < next[idx] + 1; e++) {
668 cpl_propertylist * copy_plist;
674 copy_plist = cpl_propertylist_duplicate(mplist[idx][e]);
675 cpl_propertylist_erase_regexp(copy_plist,
"ESO QC.*", 1);
676 len = cpl_propertylist_get_size(copy_plist);
677 cpl_propertylist_delete(copy_plist);
682 sprintf(buffer,
"ESO QC REG%d LLX", i + 1);
683 cpl_propertylist_append_int(mplist[idx][e], buffer, llx[i]);
684 cpl_propertylist_set_comment(mplist[idx][e], buffer,
685 "Lower left X of region");
686 sprintf(buffer,
"ESO QC REG%d LLY", i + 1);
687 cpl_propertylist_append_int(mplist[idx][e], buffer, lly[i]);
688 cpl_propertylist_set_comment(mplist[idx][e], buffer,
689 "Lower left Y of region");
690 sprintf(buffer,
"ESO QC REG%d URX", i + 1);
691 cpl_propertylist_append_int(mplist[idx][e], buffer, urx[i]);
692 cpl_propertylist_set_comment(mplist[idx][e], buffer,
693 "Upper right X of region");
694 sprintf(buffer,
"ESO QC REG%d URY", i + 1);
695 cpl_propertylist_append_int(mplist[idx][e], buffer, ury[i]);
696 cpl_propertylist_set_comment(mplist[idx][e], buffer,
697 "Upper right Y of region");
700 cpl_frameset_delete(a);
707 cpl_frameset * usedframes = cpl_frameset_new();
709 for (cpl_frame *frm = cpl_frameset_get_first(frameset); frm != NULL;
710 frm = cpl_frameset_get_next(frameset)) {
711 if (cpl_frame_get_group(frm) == CPL_FRAME_GROUP_RAW ||
712 cpl_frame_get_group(frm) == CPL_FRAME_GROUP_CALIB) {
713 cpl_frameset_insert(usedframes, cpl_frame_duplicate(frm));
716 for (
int idx = 0; idx < DETMON_MAX_IDX; idx++) {
719 if (idx == DETMON_LIN_INFO_IDX || idx == DETMON_GAIN_INFO_IDX) {
721 RECIPE_NAME, outtag[idx],
722 mplist[idx][0], NULL, PACKAGE
"/"
723 PACKAGE_VERSION, outname[idx]);
725 for (cpl_size e = 1; e < next[idx] + 1; e++) {
727 cpl_table_save(mtab[idx][e], NULL, mplist[idx][e],
728 outname[idx], CPL_IO_EXTEND);
731 cpl_propertylist_save(mplist[idx][e], outname[idx],
737 else if (idx == DETMON_BPM_IDX) {
740 RECIPE_NAME, outtag[idx],
741 mplist[idx][0], NULL, PACKAGE
747 cpl_imagelist_get(mimg[idx][0], 0),
748 CPL_TYPE_UNSPECIFIED, RECIPE_NAME,
749 outtag[idx], mplist[idx][0], NULL,
750 PACKAGE
"/" PACKAGE_VERSION,
752 cpl_imagelist_delete(mimg[idx][0]);
756 for (cpl_size e = 1; e < next[idx] + 1; e++) {
758 cpl_image * img = cpl_imagelist_get(mimg[idx][e], 0);
759 cpl_image_save(img, outname[idx], CPL_TYPE_UNSPECIFIED,
762 cpl_imagelist_delete(mimg[idx][e]);
766 cpl_propertylist_save(mplist[idx][e], outname[idx],
772 else if (idx == DETMON_COEFF_IDX) {
775 RECIPE_NAME, outtag[idx],
776 mplist[idx][0], NULL, PACKAGE
783 CPL_TYPE_UNSPECIFIED,
784 RECIPE_NAME, outtag[idx],
785 mplist[idx][0], NULL, PACKAGE
"/"
786 PACKAGE_VERSION, outname[idx]);
787 cpl_imagelist_delete(mimg[idx][0]);
791 for (cpl_size e = 1; e < next[idx] + 1; e++) {
793 cpl_imagelist_save(mimg[idx][e], outname[idx],
794 CPL_TYPE_UNSPECIFIED,
795 mplist[idx][e], CPL_IO_EXTEND);
796 cpl_imagelist_delete(mimg[idx][e]);
800 cpl_propertylist_save(mplist[idx][e], outname[idx],
808 cpl_frameset_delete(usedframes);
813 cpl_frameset_delete(frameset_copy);
814 cpl_propertylist_delete(lintbl);
815 cpl_propertylist_delete(gaintbl);
816 cpl_propertylist_delete(coeffscube);
817 cpl_propertylist_delete(bpm);
818 cpl_propertylist_delete(corr);
819 cpl_propertylist_delete(diff_flat);
820 for (
int i = 0; i < DETMON_MAX_IDX; i++) {
821 for (
int e = 0; e < next[i] + 1; e++) {
823 cpl_propertylist_delete(mplist[i][e]);
825 cpl_imagelist_delete(mimg[i][e]);
827 cpl_table_delete(mtab[i][e]);
832 cpl_free(outname[i]);
840 return cpl_error_get_code();