36 #include "detmon_lg.h"
37 #include "irplib_plugin.h"
46 #include <sys/types.h>
53 detmon_lg_dfs_set_groups(cpl_frameset * set,
54 const char *tag_on,
const char *tag_off);
58 static const cpl_parameter *
59 get_parameter_const(
const cpl_parameterlist * parlist,
60 const char * recipe,
const char * name)
62 char * parname = cpl_sprintf(
"detmon.%s.%s", recipe, name);
63 const cpl_parameter * p = cpl_parameterlist_find_const(parlist, parname);
68 static cpl_parameter *
69 get_parameter(cpl_parameterlist * parlist,
70 const char * recipe,
const char * name)
72 char * parname = cpl_sprintf(
"detmon.%s.%s", recipe, name);
73 cpl_parameter * p = cpl_parameterlist_find(parlist, parname);
78 int compare_tags(
const cpl_frame * a,
const cpl_frame * b)
80 return strcmp(cpl_frame_get_tag(a), cpl_frame_get_tag(b)) == 0;
96 static cpl_error_code merge_keys(cpl_propertylist * mplist,
97 const cpl_propertylist * plist_,
99 const char * rmregexp)
103 cpl_propertylist * plist = cpl_propertylist_duplicate(plist_);
106 cpl_propertylist_erase_regexp(plist, rmregexp, 0);
107 cpl_propertylist_erase_regexp(mplist, rmregexp, 0);
110 for (cpl_size i = 0; i < cpl_propertylist_get_size(plist); i++) {
111 cpl_property * p = cpl_propertylist_get(plist, i);
112 const char * key = cpl_property_get_name(p);
114 if (!strncmp(key,
"ESO QC ", 7)) {
115 sprintf(buffer,
"ESO QC REG%d %s", pos, key + 7);
116 cpl_msg_debug(cpl_func,
"merging %s to %s", key, buffer);
117 if (cpl_property_get_type(p) == CPL_TYPE_INT) {
118 int val = cpl_property_get_int(p);
119 cpl_propertylist_append_int(mplist, buffer, val);
120 }
else if (cpl_property_get_type(p) == CPL_TYPE_DOUBLE) {
121 double val = cpl_property_get_double(p);
122 cpl_propertylist_append_double(mplist, buffer, val);
123 }
else if (cpl_property_get_type(p) == CPL_TYPE_STRING) {
124 const char * val = cpl_property_get_string(p);
125 cpl_propertylist_append_string(mplist, buffer, val);
129 const char * com = cpl_property_get_comment(p);
130 cpl_propertylist_set_comment(mplist, buffer, com);
133 if (cpl_propertylist_has(mplist, key))
134 cpl_propertylist_erase(mplist, key);
140 cpl_propertylist_delete(plist);
142 return cpl_error_get_code();
155 static cpl_error_code
156 merge_images(cpl_imagelist * mimgl,
const cpl_imagelist * img)
158 cpl_ensure_code(cpl_imagelist_get_size(img) ==
159 cpl_imagelist_get_size(mimgl), CPL_ERROR_ILLEGAL_INPUT);
160 for (
int i = 0; i < cpl_imagelist_get_size(img); i++) {
161 cpl_image * mimg = cpl_imagelist_get(mimgl, i);
162 const cpl_image * part = cpl_imagelist_get_const(img, i);
163 cpl_image_add(mimg, part);
166 return cpl_error_get_code();
179 static cpl_error_code
180 merge_table(cpl_table * mtab, cpl_table * tab,
const int pos)
182 cpl_table_new_column(tab,
"REGION", CPL_TYPE_INT);
183 cpl_table_fill_column_window(tab,
"REGION", 0, cpl_table_get_nrow(tab), pos);
184 skip_if(cpl_table_insert(mtab, tab, cpl_table_get_nrow(mtab)));
188 return cpl_error_get_code();
192 static cpl_error_code
193 parse_token(
const char * token, cpl_size * llx, cpl_size * lly,
194 cpl_size * urx, cpl_size * ury)
196 assert(
sizeof(*llx) == 8);
197 if (sscanf(token,
" %lld , %lld , %lld , %lld ", llx, lly, urx, ury) == 4) {
198 return CPL_ERROR_NONE;
200 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
201 "Data not formated correctly: %s; "
202 "expecting: name,llx,lly,urx,ury",
221 static cpl_error_code
222 read_regions_file(
const char * filename, cpl_size ** rllx,
223 cpl_size ** rlly, cpl_size ** rurx, cpl_size ** rury,
226 FILE * f = fopen(filename,
"r");
231 return cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO,
232 "Could not open file %s: %s", filename,
235 cpl_msg_info(cpl_func,
"Reading %s", filename);
238 *rllx = cpl_malloc(
sizeof(**rllx) * nmax);
239 *rlly = cpl_malloc(
sizeof(**rllx) * nmax);
240 *rurx = cpl_malloc(
sizeof(**rllx) * nmax);
241 *rury = cpl_malloc(
sizeof(**rllx) * nmax);
243 while (fgets(line, 1024, f) != NULL) {
244 const size_t nline = strlen(line);
245 if (line[nline - 1] !=
'\n') {
246 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO,
247 "File %s contained too long line",
255 skip_if(parse_token(line, &(*rllx)[i], &(*rlly)[i],
256 &(*rurx)[i], &(*rury)[i]));
260 *rllx = cpl_realloc(*rllx,
sizeof(**rllx) * nmax);
261 *rlly = cpl_realloc(*rlly,
sizeof(**rllx) * nmax);
262 *rurx = cpl_realloc(*rurx,
sizeof(**rllx) * nmax);
263 *rury = cpl_realloc(*rury,
sizeof(**rllx) * nmax);
271 return CPL_ERROR_NONE;
289 static cpl_error_code
290 read_regions_str(
const char * istr, cpl_size ** rllx,
291 cpl_size ** rlly, cpl_size ** rurx, cpl_size ** rury,
295 char * str_ = cpl_strdup(istr);
298 *rllx = cpl_malloc(
sizeof(**rllx) * nmax);
299 *rlly = cpl_malloc(
sizeof(**rllx) * nmax);
300 *rurx = cpl_malloc(
sizeof(**rllx) * nmax);
301 *rury = cpl_malloc(
sizeof(**rllx) * nmax);
303 for (
int i = 0; ;i++) {
304 char * token = strtok(str,
":");
308 skip_if(parse_token(token, &(*rllx)[i], &(*rlly)[i],
309 &(*rurx)[i], &(*rury)[i]));
313 *rllx = cpl_realloc(*rllx,
sizeof(**rllx) * nmax);
314 *rlly = cpl_realloc(*rlly,
sizeof(**rllx) * nmax);
315 *rurx = cpl_realloc(*rurx,
sizeof(**rllx) * nmax);
316 *rury = cpl_realloc(*rury,
sizeof(**rllx) * nmax);
325 return CPL_ERROR_NONE;
328 static int check_regions(cpl_size * llx, cpl_size * lly,
329 cpl_size * urx, cpl_size * ury,
332 for (cpl_size i = 0; i < nregions; i++) {
333 if (llx[i] < 1 || lly < 1 ||
334 urx[i] < 1 || ury[i] < 1) {
335 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
336 "Region %lld (%lld,%lld,%lld,%lld) has entry smaller one",
337 i, llx[i], lly[i], urx[i], ury[i]);
339 if ((urx[i] - llx[i] < 1) || (ury[i] - lly[i] < 1)) {
340 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
341 "Region %lld (%lld,%lld,%lld,%lld) has size zero",
342 i, llx[i], lly[i], urx[i], ury[i]);
344 for (cpl_size j = i + 1; j < nregions; j++) {
345 if (!(llx[i] > urx[j] || urx[i] < llx[j] ||
346 lly[i] > ury[j] || ury[i] < lly[j])) {
347 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
348 "Regions %lld (%lld,%lld,%lld,%lld) and "
349 "%lld (%lld,%lld,%lld,%lld) overlap (llx,lly,urx,ury)",
350 i, llx[i], lly[i], urx[i], ury[i],
351 j, llx[j], lly[j], urx[j], ury[j]);
356 return CPL_ERROR_NONE;
374 static cpl_error_code
375 merge_lingain(cpl_propertylist * mplist[], cpl_table * mtab[],
376 const char * fn,
const cpl_size next,
377 const char * rmregexp,
int pos)
379 cpl_errorstate cleanstate = cpl_errorstate_get();
382 cpl_propertylist * plist = cpl_propertylist_load(fn, 0);
383 skip_if(plist == NULL);
384 if (mplist[0] == NULL) {
386 merge_keys(mplist[0], plist, pos, rmregexp);
389 merge_keys(mplist[0], plist, pos, rmregexp);
390 cpl_propertylist_delete(plist);
395 for (
int e = 1; e < next + 1; e++) {
396 cpl_propertylist * plist = cpl_propertylist_load(fn, e);
397 cpl_table * tab = cpl_table_load(fn, e, 0);
400 cpl_errorstate_set(cleanstate);
401 cpl_propertylist_delete(plist);
404 skip_if(plist == NULL);
406 if (mplist[e] == NULL) {
407 merge_keys(plist, plist, pos, rmregexp);
408 cpl_table_new_column(tab,
"REGION", CPL_TYPE_INT);
409 cpl_table_fill_column_window(tab,
"REGION", 0,
410 cpl_table_get_nrow(tab), 1);
416 merge_keys(mplist[e], plist, pos, rmregexp);
417 merge_table(mtab[e], tab, pos);
419 cpl_propertylist_delete(plist);
420 cpl_table_delete(tab);
427 return cpl_error_get_code();
445 static cpl_error_code
446 merge_bpmcoeff(cpl_propertylist * mplist[], cpl_imagelist * mimg[],
447 const char * fn,
const cpl_size next,
448 const char * rmregexp,
int pos)
450 cpl_errorstate cleanstate = cpl_errorstate_get();
452 for (
int e = 0; e < next + 1; e++) {
453 cpl_propertylist * plist = cpl_propertylist_load(fn, e);
454 cpl_imagelist * img = cpl_imagelist_load(fn, CPL_TYPE_UNSPECIFIED, e);
457 cpl_errorstate_set(cleanstate);
458 cpl_propertylist_delete(plist);
461 skip_if(plist == NULL);
463 if (mimg[e] == NULL) {
464 merge_keys(plist, plist, pos, rmregexp);
469 merge_keys(mplist[e], plist, pos, rmregexp);
470 merge_images(mimg[e], img);
472 cpl_propertylist_delete(plist);
473 cpl_imagelist_delete(img);
480 return cpl_error_get_code();
484 DETMON_BP_MAP_NL_IDX = 0,
485 DETMON_LIN_INFO_IDX = 1,
486 DETMON_GAIN_INFO_IDX = 2,
488 DETMON_COEFF_IDX = 4,
492 static cpl_error_code disable_contamination(cpl_parameterlist * parlist,
497 for (
int i = 1; i < 6; i++) {
499 sprintf(buffer,
"detmon.%s.llx%d", recipe, i);
500 par = cpl_parameterlist_find(parlist, buffer);
501 cpl_parameter_set_int(par, 1);
502 sprintf(buffer,
"detmon.%s.lly%d", recipe, i);
503 par = cpl_parameterlist_find(parlist, buffer);
504 cpl_parameter_set_int(par, 1);
505 sprintf(buffer,
"detmon.%s.urx%d", recipe, i);
506 par = cpl_parameterlist_find(parlist, buffer);
507 cpl_parameter_set_int(par, 2);
508 sprintf(buffer,
"detmon.%s.ury%d", recipe, i);
509 par = cpl_parameterlist_find(parlist, buffer);
510 cpl_parameter_set_int(par, 2);
513 return cpl_error_get_code();
527 int detmon_lg_mr(cpl_frameset * frameset,
528 const cpl_parameterlist * parlist_,
532 const char * tag_on=NULL;
533 const char * tag_off=NULL;
534 IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
535 cpl_parameterlist * parlist = (cpl_parameterlist *)parlist_;
536 IRPLIB_DIAG_PRAGMA_POP;
537 cpl_propertylist ** mplist[DETMON_MAX_IDX] = {NULL};
538 cpl_imagelist ** mimg[DETMON_MAX_IDX] = {NULL};
539 cpl_table ** mtab[DETMON_MAX_IDX] = {NULL};
540 cpl_size next[DETMON_MAX_IDX] = {0};
541 char * outname[DETMON_MAX_IDX] = {NULL};
542 char * outtag[DETMON_MAX_IDX] = {NULL};
544 cpl_frameset * frameset_copy = NULL;
546 cpl_propertylist * lintbl =
547 detmon_fill_prolist(
"DET_LIN_INFO",
"REDUCED",
"TECH", CPL_FALSE);
549 cpl_propertylist * gaintbl =
550 detmon_fill_prolist(
"GAIN_INFO",
"REDUCED",
"TECH", CPL_FALSE);
552 cpl_propertylist * coeffscube =
553 detmon_fill_prolist(
"COEFFS_CUBE",
"REDUCED",
"TECH", CPL_FALSE);
555 cpl_propertylist * bpm =
556 detmon_fill_prolist(
"BP_MAP_NL",
"REDUCED",
"TECH", CPL_FALSE);
558 cpl_propertylist * corr =
559 detmon_fill_prolist(
"AUTOCORR",
"REDUCED",
"TECH", CPL_FALSE);
561 cpl_propertylist * diff_flat =
562 detmon_fill_prolist(
"DIFF_FLAT",
"REDUCED",
"TECH", CPL_FALSE);
563 const char * regions_file = NULL;
564 const char * regions_str = NULL;
565 cpl_error_code error = CPL_ERROR_NONE;
566 cpl_size * llx = NULL, * lly = NULL, * urx = NULL, * ury = NULL;
567 const cpl_parameter * p =
568 get_parameter_const(parlist, recipe,
"regions-file");
570 regions_file = cpl_parameter_get_string(p);
571 if (strlen(regions_file) == 0)
575 p = get_parameter_const(parlist, recipe,
"regions");
577 regions_str = cpl_parameter_get_string(p);
578 if (strlen(regions_str) == 0)
582 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
583 "Please only provide either "
585 "--regions-file, not both");
590 p = get_parameter(parlist, recipe,
"intermediate");
592 error_if(cpl_parameter_get_bool(p), CPL_ERROR_UNSUPPORTED_MODE,
593 "--intermediate not supported by multi region recipe");
596 skip_if (detmon_lg_set_tag(frameset, &tag_on, &tag_off));
597 skip_if (detmon_lg_dfs_set_groups(frameset, tag_on, tag_off));
599 cpl_size nregions = 0;
601 read_regions_file(regions_file, &llx, &lly, &urx, &ury,
604 else if (regions_str) {
605 read_regions_str(regions_str, &llx, &lly, &urx, &ury,
609 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
610 "Empty value in --regions or "
615 skip_if(check_regions(llx, lly, urx, ury, nregions));
619 skip_if(disable_contamination(parlist, recipe));
625 for (
int i = 0; i < nregions; i++) {
627 par = get_parameter(parlist, recipe,
"llx");
628 cpl_parameter_set_int(par, llx[i]);
629 par = get_parameter(parlist, recipe,
"lly");
630 cpl_parameter_set_int(par, lly[i]);
631 par = get_parameter(parlist, recipe,
"urx");
632 cpl_parameter_set_int(par, urx[i]);
633 par = get_parameter(parlist, recipe,
"ury");
634 cpl_parameter_set_int(par, ury[i]);
635 cpl_msg_info(cpl_func,
"working on region %d/%d: %lld %lld, "
636 "%lld %lld", i + 1, (
int)nregions,
637 llx[i], lly[i], urx[i], ury[i]);
641 cpl_frameset_delete(frameset_copy);
642 frameset_copy = cpl_frameset_duplicate(frameset);
643 error = detmon_lg(frameset_copy,
650 lintbl, gaintbl, coeffscube,
651 bpm, corr, diff_flat,
652 PACKAGE
"/" PACKAGE_VERSION,
657 cpl_size * selection = cpl_frameset_labelise(frameset_copy,
658 compare_tags, &nlabels);
660 for (cpl_size j = 0; j < nlabels; j++) {
661 cpl_frameset * a = cpl_frameset_extract(frameset_copy, selection, j);
662 cpl_frame * frm = cpl_frameset_get_first(a);
663 const char * fn = cpl_frame_get_filename(frm);
666 if (strcmp(cpl_frame_get_tag(frm),
"DET_LIN_INFO") == 0)
667 idx = DETMON_LIN_INFO_IDX;
668 else if (strcmp(cpl_frame_get_tag(frm),
"GAIN_INFO") == 0)
669 idx = DETMON_GAIN_INFO_IDX;
670 else if (strcmp(cpl_frame_get_tag(frm),
"BP_MAP_NL") == 0)
671 idx = DETMON_BPM_IDX;
672 else if (strcmp(cpl_frame_get_tag(frm),
"COEFFS_CUBE") == 0)
673 idx = DETMON_COEFF_IDX;
675 cpl_frameset_delete(a);
680 if (mplist[idx] == NULL) {
681 next[idx] = cpl_frame_get_nextensions(frm);
682 outname[idx] = cpl_strdup(cpl_frame_get_filename(frm));
683 outtag[idx] = cpl_strdup(cpl_frame_get_tag(frm));
684 mplist[idx] = cpl_calloc(
sizeof(cpl_propertylist*), next[idx] + 1);
685 mimg[idx] = cpl_calloc(
sizeof(cpl_imagelist*), next[idx] + 1);
686 mtab[idx] = cpl_calloc(
sizeof(cpl_table*), next[idx] + 1);
689 if (idx == DETMON_LIN_INFO_IDX) {
690 const char * rmregexp =
"ESO QC CONTAM.*";
691 merge_lingain(mplist[idx], mtab[idx], fn, next[idx],
694 else if (idx == DETMON_GAIN_INFO_IDX) {
695 merge_lingain(mplist[idx], mtab[idx], fn, next[idx],
698 else if (idx == DETMON_BPM_IDX) {
699 merge_bpmcoeff(mplist[idx], mimg[idx], fn, next[idx],
702 else if (idx == DETMON_COEFF_IDX) {
703 merge_bpmcoeff(mplist[idx], mimg[idx], fn, next[idx],
708 for (
int e = 0; e < next[idx] + 1; e++) {
710 cpl_propertylist * copy_plist;
716 copy_plist = cpl_propertylist_duplicate(mplist[idx][e]);
717 cpl_propertylist_erase_regexp(copy_plist,
"ESO QC.*", 1);
718 len = cpl_propertylist_get_size(copy_plist);
719 cpl_propertylist_delete(copy_plist);
724 sprintf(buffer,
"ESO QC REG%d LLX", i + 1);
725 cpl_propertylist_append_int(mplist[idx][e], buffer, llx[i]);
726 cpl_propertylist_set_comment(mplist[idx][e], buffer,
727 "Lower left X of region");
728 sprintf(buffer,
"ESO QC REG%d LLY", i + 1);
729 cpl_propertylist_append_int(mplist[idx][e], buffer, lly[i]);
730 cpl_propertylist_set_comment(mplist[idx][e], buffer,
731 "Lower left Y of region");
732 sprintf(buffer,
"ESO QC REG%d URX", i + 1);
733 cpl_propertylist_append_int(mplist[idx][e], buffer, urx[i]);
734 cpl_propertylist_set_comment(mplist[idx][e], buffer,
735 "Upper right X of region");
736 sprintf(buffer,
"ESO QC REG%d URY", i + 1);
737 cpl_propertylist_append_int(mplist[idx][e], buffer, ury[i]);
738 cpl_propertylist_set_comment(mplist[idx][e], buffer,
739 "Upper right Y of region");
742 cpl_frameset_delete(a);
749 cpl_frameset * usedframes = cpl_frameset_new();
751 for (cpl_frame *frm = cpl_frameset_get_first(frameset); frm != NULL;
752 frm = cpl_frameset_get_next(frameset)) {
753 if (cpl_frame_get_group(frm) == CPL_FRAME_GROUP_RAW ||
754 cpl_frame_get_group(frm) == CPL_FRAME_GROUP_CALIB) {
755 cpl_frameset_insert(usedframes, cpl_frame_duplicate(frm));
758 for (
int idx = 0; idx < DETMON_MAX_IDX; idx++) {
761 if (idx == DETMON_LIN_INFO_IDX || idx == DETMON_GAIN_INFO_IDX) {
764 mplist[idx][0], NULL, PACKAGE
"/"
765 PACKAGE_VERSION, outname[idx]);
767 for (cpl_size e = 1; e < next[idx] + 1; e++) {
769 cpl_table_save(mtab[idx][e], NULL, mplist[idx][e],
770 outname[idx], CPL_IO_EXTEND);
773 cpl_propertylist_save(mplist[idx][e], outname[idx],
779 else if (idx == DETMON_BPM_IDX) {
783 mplist[idx][0], NULL, PACKAGE
789 cpl_imagelist_get(mimg[idx][0], 0),
790 CPL_TYPE_UNSPECIFIED, recipe,
791 outtag[idx], mplist[idx][0], NULL,
792 PACKAGE
"/" PACKAGE_VERSION,
794 cpl_imagelist_delete(mimg[idx][0]);
798 for (cpl_size e = 1; e < next[idx] + 1; e++) {
800 cpl_image * img = cpl_imagelist_get(mimg[idx][e], 0);
801 cpl_image_save(img, outname[idx], CPL_TYPE_UNSPECIFIED,
804 cpl_imagelist_delete(mimg[idx][e]);
808 cpl_propertylist_save(mplist[idx][e], outname[idx],
814 else if (idx == DETMON_COEFF_IDX) {
818 mplist[idx][0], NULL, PACKAGE
825 CPL_TYPE_UNSPECIFIED,
827 mplist[idx][0], NULL, PACKAGE
"/"
828 PACKAGE_VERSION, outname[idx]);
829 cpl_imagelist_delete(mimg[idx][0]);
833 for (cpl_size e = 1; e < next[idx] + 1; e++) {
835 cpl_imagelist_save(mimg[idx][e], outname[idx],
836 CPL_TYPE_UNSPECIFIED,
837 mplist[idx][e], CPL_IO_EXTEND);
838 cpl_imagelist_delete(mimg[idx][e]);
842 cpl_propertylist_save(mplist[idx][e], outname[idx],
850 cpl_frameset_delete(usedframes);
855 cpl_frameset_delete(frameset_copy);
856 cpl_propertylist_delete(lintbl);
857 cpl_propertylist_delete(gaintbl);
858 cpl_propertylist_delete(coeffscube);
859 cpl_propertylist_delete(bpm);
860 cpl_propertylist_delete(corr);
861 cpl_propertylist_delete(diff_flat);
862 for (
int i = 0; i < DETMON_MAX_IDX; i++) {
863 for (
int e = 0; e < next[i] + 1; e++) {
865 cpl_propertylist_delete(mplist[i][e]);
867 cpl_imagelist_delete(mimg[i][e]);
869 cpl_table_delete(mtab[i][e]);
874 cpl_free(outname[i]);
882 return cpl_error_get_code();
cpl_error_code irplib_dfs_save_propertylist(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const char *recipe, const char *procat, const cpl_propertylist *applist, const char *remregexp, const char *pipe_id, const char *filename)
Save a propertylist as a DFS-compliant pipeline product.
cpl_error_code irplib_dfs_save_image(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const cpl_image *image, cpl_type_bpp bpp, const char *recipe, const char *procat, const cpl_propertylist *applist, const char *remregexp, const char *pipe_id, const char *filename)
Save an image as a DFS-compliant pipeline product.
cpl_error_code irplib_dfs_save_imagelist(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const cpl_imagelist *imagelist, cpl_type_bpp bpp, const char *recipe, const char *procat, const cpl_propertylist *applist, const char *remregexp, const char *pipe_id, const char *filename)
Save an imagelist as a DFS-compliant pipeline product.