34 #include <cxmessages.h>
37 #include <cpl_recipe.h>
38 #include <cpl_plugininfo.h>
39 #include <cpl_parameterlist.h>
40 #include <cpl_frameset.h>
41 #include <cpl_propertylist.h>
42 #include <cpl_vector.h>
54 #include "gistacking.h"
59 #define GIMASTERBIAS_BIAS_EXTENSION_IMG 0
60 #define GIMASTERBIAS_BIAS_EXTENSION_PL 0
61 #define GIMASTERBIAS_BAD_PIXEL_EXTENSION 0
64 struct GiMasterbiasConfig {
66 cxbool removeoverscan;
67 cxbool correctbadpixels;
77 typedef struct GiMasterbiasConfig GiMasterbiasConfig;
79 static cxint gimasterbias(cpl_parameterlist*, cpl_frameset*);
80 static cxint giqcmasterbias(cpl_frameset*);
87 static cxdouble max_bpx_fraction = 0.15;
96 gimasterbias_create(cpl_plugin* plugin)
99 cpl_recipe* recipe = (cpl_recipe*)plugin;
104 giraffe_error_init();
113 recipe->parameters = cpl_parameterlist_new();
114 cx_assert(recipe->parameters != NULL);
126 p = cpl_parameter_new_value(
"giraffe.masterbias.overscan.remove",
128 "Remove pre- and over-scan regions from "
129 "the created master bias image.",
130 "giraffe.masterbias.overscan",
132 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"mbias-oscremove");
133 cpl_parameterlist_append(recipe->parameters, p);
135 p = cpl_parameter_new_value(
"giraffe.masterbias.badpixel.clean",
137 "Correct master bias image for bad pixels",
138 "giraffe.masterbias.badpixel",
140 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"mbias-bpxclean");
141 cpl_parameterlist_append(recipe->parameters, p);
143 p = cpl_parameter_new_value(
"giraffe.masterbias.bpm.create",
145 "Create bad pixel map using a simple "
146 "thresholding algorithm. (temporary!)",
147 "giraffe.masterbias.bpm",
149 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"bpm-create");
150 cpl_parameterlist_append(recipe->parameters, p);
152 p = cpl_parameter_new_value(
"giraffe.masterbias.bpm.factor",
154 "Readout noise multiplier defining the "
155 "valid range of pixel values for searching "
157 "giraffe.masterbias.bpm",
159 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"bpm-factor");
160 cpl_parameterlist_append(recipe->parameters, p);
162 p = cpl_parameter_new_value(
"giraffe.masterbias.bpm.fraction",
164 "Maximum fraction of pixels which may be "
165 "flagged as 'bad. If more pixels are "
166 "found to be 'bad a warning is issued.",
167 "giraffe.masterbias.bpm",
169 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"bpm-frac");
170 cpl_parameterlist_append(recipe->parameters, p);
181 gimasterbias_exec(cpl_plugin* plugin)
184 cpl_recipe* recipe = (cpl_recipe*)plugin;
189 if (recipe->parameters == NULL || recipe->frames == NULL) {
193 status = gimasterbias(recipe->parameters, recipe->frames);
199 status = giqcmasterbias(recipe->frames);
211 gimasterbias_destroy(cpl_plugin* plugin)
214 cpl_recipe* recipe = (cpl_recipe*)plugin;
223 cpl_parameterlist_delete(recipe->parameters);
225 giraffe_error_clear();
236 gimasterbias_remove_badpixels(GiImage* img, GiImage* img_badpixels)
239 const cxchar*
const fctid =
"gimasterbias_remove_badpixels";
246 register cxint nr_pairs;
256 cxint search_horizon = 100;
260 cxint sx[] = { 0, 1, 1, 1 };
261 cxint sy[] = { 1,-1, 0, 1 };
264 cxlong nr_bad_pixels = 0L;
270 cxdouble* pd_img = NULL;
272 cxdouble estimate[4];
277 cpl_msg_error(fctid,
"NULL Image as input, aborting..." );
281 if (!img_badpixels) {
282 cpl_msg_error(fctid,
"NULL Bad Pixel Image as input, aborting..." );
288 npix_bp = ncol_bp * nrow_bp;
293 for (n=0; n<npix_bp; n++) {
298 if (((cxdouble)nr_bad_pixels / (cxdouble)npix_bp) >= max_bpx_fraction) {
299 cpl_msg_error(fctid,
"Too many bad pixels, aborting..." );
307 for (badx=0; badx<ncol_bp; badx++) {
308 for (bady=0; bady<nrow_bp; bady++) {
309 if (pi_bp[badx + bady * ncol_bp]==1) {
311 for (j=0; j<4; j++) {
312 estimate[nr_pairs] = 0.0;
315 for (k=0; k<2; k++) {
323 if (cx<0 || cx>=ncol_bp || cy<0 || cy>=nrow_bp)
326 }
while (pi_bp[cx+cy*ncol_bp] && (d<search_horizon));
328 if (cx>=0 && cx<ncol_bp && cy>=0 && cy<nrow_bp &&
331 save = pd_img[cx+cy*ncol_bp];
332 estimate[nr_pairs] += save / d;
333 sumd += 1.0 / (cxdouble) d;
335 estimate[nr_pairs] /= sumd;
343 estimate[nr_pairs] = save;
347 cpl_vector* _estimate =
348 cpl_vector_wrap(nr_pairs,
351 pd_img[badx+bady*ncol_bp] =
352 cpl_vector_get_median(_estimate);
354 cpl_vector_unwrap(_estimate);
357 }
else if (nr_pairs==2) {
358 pd_img[badx+bady*ncol_bp] =
359 (estimate[0]+estimate[1]) * 0.5;
360 }
else if (nr_pairs==1) {
361 pd_img[badx+bady*ncol_bp] =
366 "Can't correct badpixel [%d,%d]",
391 gimasterbias(cpl_parameterlist* config, cpl_frameset*
set)
394 const cxchar*
const fctid =
"gimasterbias";
397 cxint raw_bias_count = 0;
398 cxint bad_pixel_count = 0;
404 cpl_propertylist* properties = NULL;
406 cpl_frame* curr_frame = NULL;
407 cpl_frame* bad_pixel_frame = NULL;
408 cpl_frame* product_frame = NULL;
410 cpl_parameter* p = NULL;
412 GiImage** raw_bias_list = NULL;
413 GiImage* bad_pixels = NULL;
414 GiImage* master_bias = NULL;
416 GiMasterbiasConfig mbias_config;
418 GiStackingConfig* stack_config = NULL;
420 GiRecipeInfo info = {(cxchar*)fctid, 1, NULL};
422 GiGroupInfo groups[] = {
423 {GIFRAME_BIAS, CPL_FRAME_GROUP_RAW},
424 {GIFRAME_BADPIXEL_MAP, CPL_FRAME_GROUP_CALIB},
425 {NULL, CPL_FRAME_GROUP_NONE}
433 p = cpl_parameterlist_find(config,
"giraffe.masterbias.overscan.remove");
434 mbias_config.removeoverscan = cpl_parameter_get_bool(p);
436 p = cpl_parameterlist_find(config,
"giraffe.masterbias.badpixel.clean");
437 mbias_config.correctbadpixels = cpl_parameter_get_bool(p);
439 p = cpl_parameterlist_find(config,
"giraffe.masterbias.bpm.create");
440 mbias_config.bpm.create = cpl_parameter_get_bool(p);
442 p = cpl_parameterlist_find(config,
"giraffe.masterbias.bpm.factor");
443 mbias_config.bpm.factor = cpl_parameter_get_double(p);
445 p = cpl_parameterlist_find(config,
"giraffe.masterbias.bpm.fraction");
446 mbias_config.bpm.fraction = cpl_parameter_get_double(p);
449 e_code = giraffe_frameset_set_groups(
set, groups);
452 cpl_msg_error(fctid,
"Setting frame group information failed!");
464 raw_bias_count = cpl_frameset_count_tags(
set, GIFRAME_BIAS);
466 if (raw_bias_count < stack_config->min_nr_frames) {
467 cpl_msg_error(fctid,
"Not enough raw bias Images [%d, need %d], "
468 "aborting...", raw_bias_count,
469 stack_config->min_nr_frames);
477 bad_pixel_count = cpl_frameset_count_tags(
set, GIFRAME_BADPIXEL_MAP);
479 if (mbias_config.correctbadpixels == TRUE) {
480 if (bad_pixel_count != 1) {
481 cpl_msg_error(fctid,
"Invalid number of bad pixel Images "
482 "[%d instead of 1], aborting...", bad_pixel_count);
491 cpl_msg_info(fctid,
"Creating master bias from %d bias frames ...",
497 raw_bias_list = (GiImage**)cx_calloc(raw_bias_count + 1,
sizeof(GiImage*));
499 raw_bias_list[raw_bias_count] = NULL;
501 curr_frame = cpl_frameset_find(
set, GIFRAME_BIAS);
503 for (i = 0; i < raw_bias_count; ++i) {
508 cpl_frame_get_filename(curr_frame),
509 GIMASTERBIAS_BIAS_EXTENSION_IMG);
513 cpl_msg_error(fctid,
"Could not load raw Bias Image [%s], "
514 "aborting...", cpl_frame_get_filename(curr_frame));
516 for (j = 0; j <= i; ++j) {
517 if (raw_bias_list[j] != NULL) {
519 raw_bias_list[j] = NULL;
523 cx_free(raw_bias_list);
532 curr_frame = cpl_frameset_find(
set, NULL);
536 if (mbias_config.correctbadpixels == TRUE) {
540 bad_pixel_frame = cpl_frameset_find(
set, GIFRAME_BADPIXEL_MAP);
542 cpl_msg_info(fctid,
"Bad Pixel Frame is : %s.",
543 cpl_frame_get_filename(bad_pixel_frame));
548 cpl_frame_get_filename(bad_pixel_frame),
549 GIMASTERBIAS_BAD_PIXEL_EXTENSION);
552 cpl_msg_error(fctid,
"Could not load Bad Pixel Image [%s], "
554 cpl_frame_get_filename(bad_pixel_frame));
556 for (j = 0; j < raw_bias_count; j++) {
557 if (raw_bias_list[j] != NULL) {
562 cx_free(raw_bias_list);
578 if (master_bias == NULL) {
579 cpl_msg_error(fctid,
"Stacking of raw bias frames failed! "
580 "No master bias was created, aborting...");
582 for (j = 0; j < raw_bias_count; j++) {
583 if (raw_bias_list[j] != NULL) {
588 cx_free(raw_bias_list);
590 if (bad_pixels != NULL) {
612 if (mbias_config.correctbadpixels == TRUE) {
614 cpl_msg_info(fctid,
"Cleaning bad pixels on created "
615 "master bias image.");
617 if (gimasterbias_remove_badpixels(master_bias, bad_pixels) != 0) {
619 cpl_msg_error(fctid,
"Bad pixel cleaning failed, aborting...");
621 for (j = 0; j < raw_bias_count; j++) {
622 if (raw_bias_list[j] != NULL) {
627 cx_free(raw_bias_list);
629 if (bad_pixels != NULL) {
633 if (master_bias != NULL) {
646 if (mbias_config.removeoverscan == TRUE) {
648 cpl_msg_info(fctid,
"Removing overscan areas from "
649 "master bias image");
653 cpl_msg_error(fctid,
"Removing overscan areas from master "
654 "bias failed, aborting...");
656 for (j = 0; j < raw_bias_count; j++) {
657 if (raw_bias_list[j] != NULL) {
662 cx_free(raw_bias_list);
664 if (bad_pixels != NULL) {
668 if (master_bias != NULL) {
683 cpl_msg_info(fctid,
"Writing master bias image ...");
686 cx_assert(properties != NULL);
688 cpl_propertylist_update_double(properties, GIALIAS_CRPIX1, 1.);
690 cpl_propertylist_update_double(properties, GIALIAS_EXPTTOT, 0.0);
691 cpl_propertylist_update_int(properties, GIALIAS_DATANCOM, raw_bias_count);
692 cpl_propertylist_update_double(properties, GIALIAS_BZERO, 0.0);
694 cpl_propertylist_update_double(properties, GIALIAS_BIASVALUE,
696 cpl_propertylist_update_double(properties, GIALIAS_BIASSIGMA,
699 cpl_propertylist_erase(properties, GIALIAS_EXPTIME);
700 cpl_propertylist_erase(properties, GIALIAS_TPLEXPNO);
707 for (j = 0; j < raw_bias_count; j++) {
708 if (raw_bias_list[j] != NULL) {
713 cx_free(raw_bias_list);
714 raw_bias_list = NULL;
716 if (bad_pixels != NULL) {
726 CPL_FRAME_LEVEL_FINAL,
729 if (product_frame == NULL) {
731 cpl_msg_error(fctid,
"Cannot create local file! Aborting ...");
733 if (master_bias != NULL) {
741 cpl_frameset_insert(
set, product_frame);
749 if ((mbias_config.bpm.create == TRUE) && (master_bias != NULL)
750 && (bad_pixel_count == 0)) {
754 const cxdouble* pd_mbias =
755 cpl_image_get_data_double_const(_master_bias);
761 cxint ncol = cpl_image_get_size_x(_master_bias);
762 cxint nrow = cpl_image_get_size_y(_master_bias);
763 cxint* pi_bpm = NULL;
765 cxlong npix = ncol * nrow;
767 cxlong nbpx_max = (cxlong)(mbias_config.bpm.fraction * npix + 0.5);
769 cxdouble median = 0.;
770 cxdouble median_max = CX_MINDOUBLE;
771 cxdouble median_min = CX_MAXDOUBLE;
779 cpl_msg_info(fctid,
"Creating bad pixel map from master bias "
803 if ((cpl_propertylist_has(properties, GIALIAS_PRSCX) == TRUE) ||
804 (cpl_propertylist_has(properties, GIALIAS_OVSCX) == TRUE)) {
808 if (cpl_propertylist_has(properties, GIALIAS_PRSCX) == TRUE) {
810 cxint xsz = cpl_propertylist_get_int(properties,
816 for (i = 0; i < nrow; ++i) {
818 register cxint stride = i * ncol;
820 cxdouble scx_mean = giraffe_array_mean(pd_mbias + stride,
823 for (j = 0; j < xsz; ++j) {
824 sdev += (pd_mbias[stride + j] - scx_mean) *
825 (pd_mbias[stride + j] - scx_mean);
830 ron = sqrt(sdev / (cxdouble)(nrow * xsz - 1));
835 if (cpl_propertylist_has(properties, GIALIAS_OVSCX) == TRUE) {
837 cxint xsz = cpl_propertylist_get_int(properties,
843 for (i = 0; i < nrow; ++i) {
845 register cxint stride = (i + 1) * ncol - xsz;
847 cxdouble scx_mean = giraffe_array_mean(pd_mbias + stride,
850 for (j = 0; j < xsz; ++j) {
851 sdev += (pd_mbias[stride + j] - scx_mean) *
852 (pd_mbias[stride + j] - scx_mean);
857 ron += sqrt(sdev / (cxdouble)(nrow * xsz - 1));
862 ron /= (cxdouble)nvalues;
867 if (cpl_propertylist_has(properties, GIALIAS_RON)) {
869 ron = cpl_propertylist_get_double(properties, GIALIAS_RON);
871 if (cpl_propertylist_has(properties, GIALIAS_CONAD)) {
873 cxdouble conad = cpl_propertylist_get_double(properties,
878 cpl_msg_error(fctid,
"Invalid conversion factor "
879 "property (%s): %.2g!", GIALIAS_CONAD,
895 cpl_msg_error(fctid,
"Missing conversion factor property "
896 "(%s)!", GIALIAS_CONAD);
913 cpl_msg_info(fctid,
"Using local median +/- %.4f [ADU] as "
914 "valid pixel value range", ron);
917 for (i = 0; i < nrow; ++i) {
919 register cxint stride = i * ncol;
920 register cxint* bpx_row = pi_bpm + stride;
922 register const cxdouble* bias_row = pd_mbias + stride;
924 register cxdouble sdev = 0.;
926 median = giraffe_array_median(bias_row, ncol);
928 for (j = 0; j < ncol; ++j) {
929 sdev += (bias_row[j] - median) * (bias_row[j] - median);
931 sdev = sqrt(sdev / (cxdouble)(ncol - 1));
933 if (median < median_min) {
938 if (median > median_max) {
943 tlow = median - mbias_config.bpm.factor * ron;
944 thigh = median + mbias_config.bpm.factor * ron;
946 for (j = 0; j < ncol; ++j) {
948 if ((bias_row[j] < tlow) || (bias_row[j] > thigh)) {
961 if (nbpx > nbpx_max) {
962 cpl_msg_warning(fctid,
"Number of bad pixels found (%ld) exceeds "
963 "maximum number of bad pixels expected (%ld)!", nbpx,
969 cpl_propertylist_update_double(properties, GIALIAS_BZERO, 0.);
971 cpl_propertylist_update_double(properties,
972 GIALIAS_BPM_FRACTION, mbias_config.bpm.fraction);
973 cpl_propertylist_set_comment(properties, GIALIAS_BPM_FRACTION,
974 "Maximum fraction of bad pixels allowed.");
976 cpl_propertylist_update_int(properties,
977 GIALIAS_BPM_NPIX, nbpx);
978 cpl_propertylist_set_comment(properties, GIALIAS_BPM_NPIX,
979 "Number of pixels flagged as bad.");
981 cpl_propertylist_update_double(properties,
982 GIALIAS_BPM_MEDIAN_MIN, median_min);
983 cpl_propertylist_set_comment(properties, GIALIAS_BPM_MEDIAN_MIN,
984 "Minimum median pixel value used for bad pixel detection.");
986 cpl_propertylist_update_double(properties,
987 GIALIAS_BPM_MEDIAN_MAX, median_max);
988 cpl_propertylist_set_comment(properties, GIALIAS_BPM_MEDIAN_MAX,
989 "Maximum median pixel value used for bad pixel detection.");
991 cpl_propertylist_update_double(properties,
992 GIALIAS_BPM_FACTOR, mbias_config.bpm.factor);
993 cpl_propertylist_set_comment(properties, GIALIAS_BPM_FACTOR,
994 "Noise multiplier defining thresholds for bad pixel "
997 cpl_propertylist_update_double(properties,
998 GIALIAS_BPM_NOISE, ron);
999 cpl_propertylist_set_comment(properties, GIALIAS_BPM_NOISE,
1000 "Bias noise value [ADU] used for bad pixel detection.");
1005 GIFRAME_BADPIXEL_MAP,
1006 CPL_FRAME_LEVEL_FINAL,
1009 if (product_frame == NULL) {
1011 cpl_msg_error(fctid,
"Cannot create local file! Aborting ...");
1013 if (master_bias != NULL) {
1017 if (bpixel != NULL) {
1025 cpl_frameset_insert(
set, product_frame);
1032 if (bpixel != NULL) {
1038 if (master_bias != NULL) {
1052 giqcmasterbias(cpl_frameset*
set)
1055 const cxchar*
const fctid =
"giqcmasterbias";
1058 const cxint wstart = 50;
1059 const cxint wsize = 100;
1070 const cxdouble low = 100.;
1071 const cxdouble high = 300.;
1072 const cxdouble sthreshold = 2.;
1075 cxdouble median = 0.;
1076 cxdouble smean = 0.;
1078 cxdouble* _mbdata = NULL;
1079 cxdouble* _tdata = NULL;
1080 cxdouble sigma[nsigma];
1082 cpl_propertylist* properties = NULL;
1083 cpl_propertylist* qclog = NULL;
1085 cpl_vector* _sigma = NULL;
1087 cpl_image* _mbias = NULL;
1088 cpl_image* _smbias = NULL;
1089 cpl_image* _test = NULL;
1091 cpl_frame* rframe = NULL;
1092 cpl_frame* pframe = NULL;
1096 GiImage* mbias = NULL;
1097 GiImage* bias = NULL;
1102 cpl_msg_info(fctid,
"Computing QC1 parameters ...");
1104 qc = giraffe_qclog_open(0);
1107 cpl_msg_error(fctid,
"Cannot create QC1 log!");
1111 qclog = giraffe_paf_get_properties(qc);
1112 cx_assert(qclog != NULL);
1120 CPL_FRAME_GROUP_PRODUCT);
1122 if (pframe == NULL) {
1123 cpl_msg_error(fctid,
"Missing product frame (%s)",
1124 GIFRAME_BIAS_MASTER);
1126 giraffe_paf_delete(qc);
1132 cpl_msg_info(fctid,
"Processing product frame '%s' (%s)",
1133 cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
1139 cpl_msg_error(fctid,
"Could not load master bias '%s'! Aborting ...",
1140 cpl_frame_get_filename(pframe));
1145 giraffe_paf_delete(qc);
1156 rframe = cpl_frameset_find(
set, GIFRAME_BIAS);
1158 if (rframe == NULL) {
1159 cpl_msg_error(fctid,
"Missing raw frame (%s)", GIFRAME_BIAS);
1164 giraffe_paf_delete(qc);
1174 cpl_msg_error(fctid,
"Could not load bias '%s'!",
1175 cpl_frame_get_filename(rframe));
1183 giraffe_paf_delete(qc);
1191 cx_assert(properties != NULL);
1196 cpl_propertylist_update_string(qclog,
"PRO.CATG",
1197 cpl_frame_get_tag(pframe));
1198 cpl_propertylist_set_comment(qclog,
"PRO.CATG",
1199 "Pipeline product category");
1202 cx_assert(properties != NULL);
1205 properties, GIALIAS_DATAMEAN);
1207 properties, GIALIAS_DATASIG);
1209 properties, GIALIAS_DATAMEDI);
1211 properties, GIALIAS_DATANCOM);
1219 _mbdata = cpl_image_get_data(_mbias);
1221 nx = cpl_image_get_size_x(_mbias);
1222 ny = cpl_image_get_size_y(_mbias);
1226 for (i = 0; i < nx * ny; i++) {
1228 if (_mbdata[i] >= low && _mbdata[i] < high) {
1234 _test = cpl_image_new(nvalid, 1, CPL_TYPE_DOUBLE);
1235 _tdata = cpl_image_get_data(_test);
1239 for (i = 0; i < nx * ny; i++) {
1241 if (_mbdata[i] >= low && _mbdata[i] < high) {
1242 _tdata[j++] = _mbdata[i];
1247 cpl_propertylist_update_double(properties, GIALIAS_QCMBIASMED,
1248 cpl_image_get_median(_test));
1249 cpl_propertylist_set_comment(properties, GIALIAS_QCMBIASMED,
1250 "Median master bias level (ADU)");
1252 cpl_propertylist_update_double(properties, GIALIAS_QCMBIASAVG,
1253 cpl_image_get_mean(_test));
1254 cpl_propertylist_set_comment(properties, GIALIAS_QCMBIASAVG,
1255 "Mean master bias level (ADU)");
1257 cpl_propertylist_update_double(properties, GIALIAS_QCMBIASRMS,
1258 cpl_image_get_stdev(_test));
1259 cpl_propertylist_set_comment(properties, GIALIAS_QCMBIASRMS,
1260 "RMS of master bias level (ADU)");
1262 cpl_image_delete(_test);
1266 properties, GIALIAS_QCMBIASMED);
1268 properties, GIALIAS_QCMBIASAVG);
1270 properties, GIALIAS_QCMBIASRMS);
1278 if (cpl_frameset_count_tags(
set, GIFRAME_BIAS) > 1) {
1280 cpl_frame* _frame = NULL;
1282 cpl_image* diff = NULL;
1288 memset(sigma, 0, nsigma *
sizeof(cxdouble));
1290 _frame = cpl_frameset_find(
set, GIFRAME_BIAS);
1291 _frame = cpl_frameset_find(
set, NULL);
1297 cpl_msg_error(fctid,
"Could not load bias '%s'! Aborting ...",
1298 cpl_frame_get_filename(_frame));
1309 giraffe_paf_delete(qc);
1318 cpl_msg_error(fctid,
"Cannot compute bias difference image! "
1330 giraffe_paf_delete(qc);
1347 w.x1 = w.x0 + wsize;
1348 w.y1 = w.y0 + wsize;
1350 giraffe_error_push();
1352 sigma[i++] = cpl_image_get_stdev_window(diff, w.x0, w.y0, w.x1, w.y1);
1354 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1358 giraffe_error_pop();
1363 w.x0 = cpl_image_get_size_x(diff) - wstart - wsize;
1364 w.x1 = w.x0 + wsize;
1366 giraffe_error_push();
1368 sigma[i++] = cpl_image_get_stdev_window(diff, w.x0, w.y0, w.x1, w.y1);
1370 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1374 giraffe_error_pop();
1379 w.y0 = cpl_image_get_size_y(diff) - wstart - wsize;
1380 w.y1 = w.y0 + wsize;
1382 giraffe_error_push();
1384 sigma[i++] = cpl_image_get_stdev_window(diff, w.x0, w.y0, w.x1, w.y1);
1386 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1390 giraffe_error_pop();
1396 w.x1 = w.x0 + wsize;
1398 giraffe_error_push();
1400 sigma[i++] = cpl_image_get_stdev_window(diff, w.x0, w.y0, w.x1, w.y1);
1402 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1406 giraffe_error_pop();
1416 giraffe_error_push();
1418 sigma[i++] = cpl_image_get_stdev_window(diff, w.x0, w.y0, w.x1, w.y1);
1420 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1424 giraffe_error_pop();
1427 for (i = 0; i < nsigma; i++) {
1428 sigma[i] /= sqrt(2.);
1432 cpl_msg_error(fctid,
"Could not compute image statistics in any "
1433 "window! Aborting ...");
1435 cpl_image_delete(diff);
1444 giraffe_paf_delete(qc);
1451 _sigma = cpl_vector_wrap(nsigma, sigma);
1453 median = cpl_vector_get_median(_sigma);
1455 cpl_vector_unwrap(_sigma);
1458 cpl_image_delete(diff);
1462 cpl_propertylist_update_double(properties, GIALIAS_QCRON, median);
1463 cpl_propertylist_set_comment(properties, GIALIAS_QCRON,
1464 "Readout noise (raw)");
1480 memset(sigma, 0, nsigma *
sizeof(cxdouble));
1487 w.x1 = w.x0 + wsize;
1488 w.y1 = w.y0 + wsize;
1490 _smbias = cpl_image_extract(_mbias, w.x0, w.y0, w.x1, w.y1);
1491 _mbdata = cpl_image_get_data(_smbias);
1495 for (i = 0; i < wsize * wsize; i++) {
1497 if (_mbdata[i] >= low && _mbdata[i] < high) {
1503 _test = cpl_image_new(nvalid, 1, CPL_TYPE_DOUBLE);
1504 _tdata = cpl_image_get_data(_test);
1508 for (i = 0; i < wsize * wsize; i++) {
1510 if (_mbdata[i] >= low && _mbdata[i] < high) {
1511 _tdata[j++] = _mbdata[i];
1516 giraffe_error_push();
1518 sigma[k++] = cpl_image_get_stdev(_test);
1520 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1524 giraffe_error_pop();
1526 cpl_image_delete(_smbias);
1529 cpl_image_delete(_test);
1534 w.x0 = cpl_image_get_size_x(_mbias) - wstart - wsize;
1535 w.x1 = w.x0 + wsize;
1537 _smbias = cpl_image_extract(_mbias, w.x0, w.y0, w.x1, w.y1);
1538 _mbdata = cpl_image_get_data(_smbias);
1542 for (i = 0; i < wsize * wsize; i++) {
1544 if (_mbdata[i] >= low && _mbdata[i] < high) {
1550 _test = cpl_image_new(nvalid, 1, CPL_TYPE_DOUBLE);
1551 _tdata = cpl_image_get_data(_test);
1555 for (i = 0; i < wsize * wsize; i++) {
1557 if (_mbdata[i] >= low && _mbdata[i] < high) {
1558 _tdata[j++] = _mbdata[i];
1563 giraffe_error_push();
1565 sigma[k++] = cpl_image_get_stdev(_test);
1567 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1571 giraffe_error_pop();
1573 cpl_image_delete(_smbias);
1576 cpl_image_delete(_test);
1581 w.y0 = cpl_image_get_size_y(_mbias) - wstart - wsize;
1582 w.y1 = w.y0 + wsize;
1584 _smbias = cpl_image_extract(_mbias, w.x0, w.y0, w.x1, w.y1);
1585 _mbdata = cpl_image_get_data(_smbias);
1589 for (i = 0; i < wsize * wsize; i++) {
1591 if (_mbdata[i] >= low && _mbdata[i] < high) {
1597 _test = cpl_image_new(nvalid, 1, CPL_TYPE_DOUBLE);
1598 _tdata = cpl_image_get_data(_test);
1602 for (i = 0; i < wsize * wsize; i++) {
1604 if (_mbdata[i] >= low && _mbdata[i] < high) {
1605 _tdata[j++] = _mbdata[i];
1610 giraffe_error_push();
1612 sigma[k++] = cpl_image_get_stdev(_test);
1614 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1618 giraffe_error_pop();
1620 cpl_image_delete(_smbias);
1623 cpl_image_delete(_test);
1629 w.x1 = w.x0 + wsize;
1631 _smbias = cpl_image_extract(_mbias, w.x0, w.y0, w.x1, w.y1);
1632 _mbdata = cpl_image_get_data(_smbias);
1636 for (i = 0; i < wsize * wsize; i++) {
1638 if (_mbdata[i] >= low && _mbdata[i] < high) {
1644 _test = cpl_image_new(nvalid, 1, CPL_TYPE_DOUBLE);
1645 _tdata = cpl_image_get_data(_test);
1649 for (i = 0; i < wsize * wsize; i++) {
1651 if (_mbdata[i] >= low && _mbdata[i] < high) {
1652 _tdata[j++] = _mbdata[i];
1657 giraffe_error_push();
1659 sigma[k++] = cpl_image_get_stdev(_test);
1661 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1665 giraffe_error_pop();
1667 cpl_image_delete(_smbias);
1670 cpl_image_delete(_test);
1680 _smbias = cpl_image_extract(_mbias, w.x0, w.y0, w.x1, w.y1);
1681 _mbdata = cpl_image_get_data(_smbias);
1685 for (i = 0; i < wsize * wsize; i++) {
1687 if (_mbdata[i] >= low && _mbdata[i] < high) {
1693 _test = cpl_image_new(nvalid, 1, CPL_TYPE_DOUBLE);
1694 _tdata = cpl_image_get_data(_test);
1698 for (i = 0; i < wsize * wsize; i++) {
1700 if (_mbdata[i] >= low && _mbdata[i] < high) {
1701 _tdata[j++] = _mbdata[i];
1706 giraffe_error_push();
1708 sigma[k++] = cpl_image_get_stdev(_test);
1710 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1714 giraffe_error_pop();
1716 cpl_image_delete(_smbias);
1719 cpl_image_delete(_test);
1723 cpl_msg_error(fctid,
"Could not compute image statistics in any "
1724 "window! Aborting ...");
1729 giraffe_paf_delete(qc);
1735 _sigma = cpl_vector_wrap(nsigma, sigma);
1737 median = cpl_vector_get_median(_sigma);
1739 cpl_vector_unwrap(_sigma);
1742 cpl_propertylist_update_double(properties, GIALIAS_QCMRON, median);
1743 cpl_propertylist_set_comment(properties, GIALIAS_QCMRON,
"Readout noise "
1754 _test = cpl_image_collapse_create(_mbias, 0);
1755 cpl_image_divide_scalar(_test, cpl_image_get_size_y(_mbias));
1757 mean = cpl_image_get_mean(_test);
1767 _tdata = cpl_image_get_data(_test);
1769 for (i = 0; i < cpl_image_get_size_x(_test); i++) {
1771 if ((_tdata[i] > mean - sthreshold) &&
1772 (_tdata[i] < mean + sthreshold)) {
1779 smean = sum / nvalid;
1789 for (i = 0; i < cpl_image_get_size_x(_test); i++) {
1791 if ((_tdata[i] > mean - sthreshold) &&
1792 (_tdata[i] < mean + sthreshold)) {
1793 sum += pow(_tdata[i] - smean, 2.);
1799 sum = sqrt(sum / (nvalid - 1));
1801 cpl_propertylist_update_double(properties, GIALIAS_QCSTRUCTX, sum);
1802 cpl_propertylist_set_comment(properties, GIALIAS_QCSTRUCTX,
1803 "Structure along the x axis");
1808 cpl_image_delete(_test);
1812 _test = cpl_image_collapse_create(_mbias, 1);
1813 cpl_image_divide_scalar(_test, cpl_image_get_size_x(_mbias));
1815 mean = cpl_image_get_mean(_test);
1825 _tdata = cpl_image_get_data(_test);
1827 for (i = 0; i < cpl_image_get_size_y(_test); i++) {
1829 if ((_tdata[i] > mean - sthreshold) &&
1830 (_tdata[i] < mean + sthreshold)) {
1837 smean = sum / nvalid;
1847 _tdata = cpl_image_get_data(_test);
1849 for (i = 0; i < cpl_image_get_size_y(_test); i++) {
1851 if ((_tdata[i] > mean - sthreshold) &&
1852 (_tdata[i] < mean + sthreshold)) {
1853 sum += pow(_tdata[i] - smean, 2.);
1859 sum = sqrt(sum / (nvalid - 1));
1861 cpl_propertylist_update_double(properties, GIALIAS_QCSTRUCTY, sum);
1862 cpl_propertylist_set_comment(properties, GIALIAS_QCSTRUCTY,
1863 "Structure along the y axis");
1868 cpl_image_delete(_test);
1881 giraffe_qclog_close(qc);
1895 cpl_plugin_get_info(cpl_pluginlist* list)
1898 cpl_recipe* recipe = cx_calloc(1,
sizeof *recipe);
1899 cpl_plugin* plugin = &recipe->interface;
1902 cpl_plugin_init(plugin,
1904 GIRAFFE_BINARY_VERSION,
1905 CPL_PLUGIN_TYPE_RECIPE,
1907 "Creates a master bias image from a set of raw biases.",
1908 "For detailed information please refer to the "
1909 "GIRAFFE pipeline user manual.\nIt is available at "
1910 "http://www.eso.org/pipelines.",
1914 gimasterbias_create,
1916 gimasterbias_destroy);
1918 cpl_pluginlist_append(list, plugin);