00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 # include <config.h>
00030 #endif
00031
00032 #include <math.h>
00033
00034 #include <cxmessages.h>
00035 #include <cxmemory.h>
00036
00037 #include <cpl_recipe.h>
00038 #include <cpl_plugininfo.h>
00039 #include <cpl_parameterlist.h>
00040 #include <cpl_frameset.h>
00041 #include <cpl_propertylist.h>
00042 #include <cpl_vector.h>
00043 #include <cpl_msg.h>
00044
00045 #include "gialias.h"
00046 #include "gierror.h"
00047 #include "giarray.h"
00048 #include "giframe.h"
00049 #include "giimage.h"
00050 #include "giwindow.h"
00051 #include "gifibers.h"
00052 #include "gibias.h"
00053 #include "gimath.h"
00054 #include "gistacking.h"
00055 #include "giqclog.h"
00056 #include "giutils.h"
00057
00058
00059 #define GIMASTERBIAS_BIAS_EXTENSION_IMG 0
00060 #define GIMASTERBIAS_BIAS_EXTENSION_PL 0
00061 #define GIMASTERBIAS_BAD_PIXEL_EXTENSION 0
00062
00063
00064 struct GiMasterbiasConfig {
00065
00066 cxbool removeoverscan;
00067 cxbool correctbadpixels;
00068
00069 struct {
00070 cxbool create;
00071 cxdouble factor;
00072 cxdouble fraction;
00073 } bpm;
00074 cxbool crebadpixmap;
00075 };
00076
00077 typedef struct GiMasterbiasConfig GiMasterbiasConfig;
00078
00079 static cxint gimasterbias(cpl_parameterlist*, cpl_frameset*);
00080 static cxint giqcmasterbias(cpl_frameset*);
00081
00082
00083
00084
00085
00086
00087 static cxdouble max_bpx_fraction = 0.15;
00088
00089
00090
00091
00092
00093
00094
00095 static cxint
00096 gimasterbias_create(cpl_plugin* plugin)
00097 {
00098
00099 cpl_recipe* recipe = (cpl_recipe*)plugin;
00100
00101 cpl_parameter* p;
00102
00103
00104 giraffe_error_init();
00105
00106
00107
00108
00109
00110
00111
00112
00113 recipe->parameters = cpl_parameterlist_new();
00114 cx_assert(recipe->parameters != NULL);
00115
00116
00117
00118
00119
00120
00121
00122 giraffe_stacking_config_add(recipe->parameters);
00123
00124
00125
00126 p = cpl_parameter_new_value("giraffe.masterbias.overscan.remove",
00127 CPL_TYPE_BOOL,
00128 "Remove pre- and over-scan regions from "
00129 "the created master bias image.",
00130 "giraffe.masterbias.overscan",
00131 FALSE);
00132 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "mbias-oscremove");
00133 cpl_parameterlist_append(recipe->parameters, p);
00134
00135 p = cpl_parameter_new_value("giraffe.masterbias.badpixel.clean",
00136 CPL_TYPE_BOOL,
00137 "Correct master bias image for bad pixels",
00138 "giraffe.masterbias.badpixel",
00139 FALSE);
00140 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "mbias-bpxclean");
00141 cpl_parameterlist_append(recipe->parameters, p);
00142
00143 p = cpl_parameter_new_value("giraffe.masterbias.bpm.create",
00144 CPL_TYPE_BOOL,
00145 "Create bad pixel map using a simple "
00146 "thresholding algorithm. (temporary!)",
00147 "giraffe.masterbias.bpm",
00148 TRUE);
00149 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bpm-create");
00150 cpl_parameterlist_append(recipe->parameters, p);
00151
00152 p = cpl_parameter_new_value("giraffe.masterbias.bpm.factor",
00153 CPL_TYPE_DOUBLE,
00154 "Readout noise multiplier defining the "
00155 "valid range of pixel values for searching "
00156 "bad pixels.",
00157 "giraffe.masterbias.bpm",
00158 5.0);
00159 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bpm-factor");
00160 cpl_parameterlist_append(recipe->parameters, p);
00161
00162 p = cpl_parameter_new_value("giraffe.masterbias.bpm.fraction",
00163 CPL_TYPE_DOUBLE,
00164 "Maximum fraction of pixels which may be "
00165 "flagged as 'bad. If more pixels are "
00166 "found to be 'bad a warning is issued.",
00167 "giraffe.masterbias.bpm",
00168 max_bpx_fraction);
00169 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bpm-frac");
00170 cpl_parameterlist_append(recipe->parameters, p);
00171
00172 return 0;
00173
00174 }
00175
00176
00177
00178
00179
00180 static cxint
00181 gimasterbias_exec(cpl_plugin* plugin)
00182 {
00183
00184 cpl_recipe* recipe = (cpl_recipe*)plugin;
00185
00186 cxint status = 0;
00187
00188
00189 if (recipe->parameters == NULL || recipe->frames == NULL) {
00190 return 1;
00191 }
00192
00193 status = gimasterbias(recipe->parameters, recipe->frames);
00194
00195 if (status != 0) {
00196 return 1;
00197 }
00198
00199 status = giqcmasterbias(recipe->frames);
00200
00201 if (status != 0) {
00202 return 1;
00203 }
00204
00205 return 0;
00206
00207 }
00208
00209
00210 static cxint
00211 gimasterbias_destroy(cpl_plugin* plugin)
00212 {
00213
00214 cpl_recipe* recipe = (cpl_recipe*)plugin;
00215
00216
00217
00218
00219
00220
00221
00222
00223 cpl_parameterlist_delete(recipe->parameters);
00224
00225 giraffe_error_clear();
00226
00227 return 0;
00228
00229 }
00230
00231
00232
00233
00234
00235 static cxint
00236 gimasterbias_remove_badpixels(GiImage* img, GiImage* img_badpixels)
00237 {
00238
00239 const cxchar* const fctid = "gimasterbias_remove_badpixels";
00240
00241
00242 cxbool found_first;
00243
00244 register cxint j;
00245 register cxint k;
00246 register cxint nr_pairs;
00247 register cxint d;
00248 register cxint sign;
00249
00250 cxint ncol_bp;
00251 cxint nrow_bp;
00252 cxint badx;
00253 cxint bady;
00254 cxint cx;
00255 cxint cy;
00256 cxint search_horizon = 100;
00257
00258 cxint* pi_bp = NULL;
00259
00260 cxint sx[] = { 0, 1, 1, 1 };
00261 cxint sy[] = { 1,-1, 0, 1 };
00262
00263 cxlong npix_bp;
00264 cxlong nr_bad_pixels = 0L;
00265 cxlong n;
00266
00267 cxdouble sumd;
00268 cxdouble save = 0.;
00269
00270 cxdouble* pd_img = NULL;
00271
00272 cxdouble estimate[4];
00273
00274
00275
00276 if (!img) {
00277 cpl_msg_error(fctid, "NULL Image as input, aborting..." );
00278 return -1;
00279 }
00280
00281 if (!img_badpixels) {
00282 cpl_msg_error(fctid, "NULL Bad Pixel Image as input, aborting..." );
00283 return -1;
00284 }
00285
00286 ncol_bp = cpl_image_get_size_x(giraffe_image_get(img_badpixels));
00287 nrow_bp = cpl_image_get_size_y(giraffe_image_get(img_badpixels));
00288 npix_bp = ncol_bp * nrow_bp;
00289 pi_bp = cpl_image_get_data_int(giraffe_image_get(img_badpixels));
00290
00291 pd_img = cpl_image_get_data_double(giraffe_image_get(img));
00292
00293 for (n=0; n<npix_bp; n++) {
00294 if (pi_bp[n]!=0)
00295 nr_bad_pixels++;
00296 }
00297
00298 if (((cxdouble)nr_bad_pixels / (cxdouble)npix_bp) >= max_bpx_fraction) {
00299 cpl_msg_error(fctid, "Too many bad pixels, aborting..." );
00300 return -1;
00301 }
00302
00303
00304
00305
00306
00307 for (badx=0; badx<ncol_bp; badx++) {
00308 for (bady=0; bady<nrow_bp; bady++) {
00309 if (pi_bp[badx + bady * ncol_bp]==1) {
00310 nr_pairs = 0;
00311 for (j=0; j<4; j++) {
00312 estimate[nr_pairs] = 0.0;
00313 sumd = 0.0;
00314 found_first = FALSE;
00315 for (k=0; k<2; k++) {
00316 sign = 2 * k - 1;
00317 d = 0;
00318 cx = badx;
00319 cy = bady;
00320 do {
00321 cx += sign * sx[j];
00322 cy += sign * sy[j];
00323 if (cx<0 || cx>=ncol_bp || cy<0 || cy>=nrow_bp)
00324 break;
00325 d++;
00326 } while (pi_bp[cx+cy*ncol_bp] && (d<search_horizon));
00327
00328 if (cx>=0 && cx<ncol_bp && cy>=0 && cy<nrow_bp &&
00329 (d<search_horizon) )
00330 {
00331 save = pd_img[cx+cy*ncol_bp];
00332 estimate[nr_pairs] += save / d;
00333 sumd += 1.0 / (cxdouble) d;
00334 if (k) {
00335 estimate[nr_pairs] /= sumd;
00336 nr_pairs++;
00337 } else {
00338 found_first = TRUE;
00339 }
00340 } else {
00341 if (k) {
00342 if (found_first) {
00343 estimate[nr_pairs] = save;
00344 nr_pairs++;
00345 if (nr_pairs>2) {
00346
00347 cpl_vector* _estimate =
00348 cpl_vector_wrap(nr_pairs,
00349 estimate);
00350
00351 pd_img[badx+bady*ncol_bp] =
00352 cpl_vector_get_median(_estimate);
00353
00354 cpl_vector_unwrap(_estimate);
00355 _estimate = NULL;
00356
00357 } else if (nr_pairs==2) {
00358 pd_img[badx+bady*ncol_bp] =
00359 (estimate[0]+estimate[1]) * 0.5;
00360 } else if (nr_pairs==1) {
00361 pd_img[badx+bady*ncol_bp] =
00362 estimate[0];
00363 } else {
00364 cpl_msg_warning(
00365 fctid,
00366 "Can't correct badpixel [%d,%d]",
00367 badx,
00368 bady
00369 );
00370 }
00371 }
00372 }
00373 }
00374 }
00375
00376 }
00377 }
00378 }
00379 }
00380
00381 return 0;
00382
00383 }
00384
00385
00386
00387
00388
00389
00390 static cxint
00391 gimasterbias(cpl_parameterlist* config, cpl_frameset* set)
00392 {
00393
00394 const cxchar* const fctid = "gimasterbias";
00395
00396
00397 cxint raw_bias_count = 0;
00398 cxint bad_pixel_count = 0;
00399 cxint e_code = 0;
00400
00401 cxlong i = 0;
00402 cxlong j = 0;
00403
00404 cpl_propertylist* properties = NULL;
00405
00406 cpl_frame* curr_frame = NULL;
00407 cpl_frame* bad_pixel_frame = NULL;
00408 cpl_frame* product_frame = NULL;
00409
00410 cpl_parameter* p = NULL;
00411
00412 GiImage** raw_bias_list = NULL;
00413 GiImage* bad_pixels = NULL;
00414 GiImage* master_bias = NULL;
00415
00416 GiMasterbiasConfig mbias_config;
00417
00418 GiStackingConfig* stack_config = NULL;
00419
00420 GiRecipeInfo info = {(cxchar*)fctid, 1, NULL};
00421
00422 GiGroupInfo groups[] = {
00423 {GIFRAME_BIAS, CPL_FRAME_GROUP_RAW},
00424 {GIFRAME_BADPIXEL_MAP, CPL_FRAME_GROUP_CALIB},
00425 {NULL, CPL_FRAME_GROUP_NONE}
00426 };
00427
00428
00429
00430
00431
00432
00433 p = cpl_parameterlist_find(config, "giraffe.masterbias.overscan.remove");
00434 mbias_config.removeoverscan = cpl_parameter_get_bool(p);
00435
00436 p = cpl_parameterlist_find(config, "giraffe.masterbias.badpixel.clean");
00437 mbias_config.correctbadpixels = cpl_parameter_get_bool(p);
00438
00439 p = cpl_parameterlist_find(config, "giraffe.masterbias.bpm.create");
00440 mbias_config.bpm.create = cpl_parameter_get_bool(p);
00441
00442 p = cpl_parameterlist_find(config, "giraffe.masterbias.bpm.factor");
00443 mbias_config.bpm.factor = cpl_parameter_get_double(p);
00444
00445 p = cpl_parameterlist_find(config, "giraffe.masterbias.bpm.fraction");
00446 mbias_config.bpm.fraction = cpl_parameter_get_double(p);
00447
00448
00449 e_code = giraffe_frameset_set_groups(set, groups);
00450
00451 if (e_code != 0) {
00452 cpl_msg_error(fctid, "Setting frame group information failed!");
00453 return 1;
00454 }
00455
00456
00457
00458
00459
00460
00461 stack_config = giraffe_stacking_config_create(config);
00462
00463
00464 raw_bias_count = cpl_frameset_count_tags(set, GIFRAME_BIAS);
00465
00466 if (raw_bias_count < stack_config->min_nr_frames) {
00467 cpl_msg_error(fctid, "Not enough raw bias Images [%d, need %d], "
00468 "aborting...", raw_bias_count,
00469 stack_config->min_nr_frames);
00470
00471 giraffe_stacking_config_destroy(stack_config);
00472 stack_config = NULL;
00473
00474 return -1;
00475 }
00476
00477 bad_pixel_count = cpl_frameset_count_tags(set, GIFRAME_BADPIXEL_MAP);
00478
00479 if (mbias_config.correctbadpixels == TRUE) {
00480 if (bad_pixel_count != 1) {
00481 cpl_msg_error(fctid, "Invalid number of bad pixel Images "
00482 "[%d instead of 1], aborting...", bad_pixel_count);
00483
00484 giraffe_stacking_config_destroy(stack_config);
00485 stack_config = NULL;
00486
00487 return -1;
00488 }
00489 }
00490
00491 cpl_msg_info(fctid, "Creating master bias from %d bias frames ...",
00492 raw_bias_count);
00493
00494
00495
00496
00497 raw_bias_list = (GiImage**)cx_calloc(raw_bias_count + 1, sizeof(GiImage*));
00498
00499 raw_bias_list[raw_bias_count] = NULL;
00500
00501 curr_frame = cpl_frameset_find(set, GIFRAME_BIAS);
00502
00503 for (i = 0; i < raw_bias_count; ++i) {
00504
00505 raw_bias_list[i] = giraffe_image_new(CPL_TYPE_DOUBLE);
00506
00507 e_code = giraffe_image_load(raw_bias_list[i],
00508 cpl_frame_get_filename(curr_frame),
00509 GIMASTERBIAS_BIAS_EXTENSION_IMG);
00510
00511 if (e_code != 0) {
00512
00513 cpl_msg_error(fctid, "Could not load raw Bias Image [%s], "
00514 "aborting...", cpl_frame_get_filename(curr_frame));
00515
00516 for (j = 0; j <= i; ++j) {
00517 if (raw_bias_list[j] != NULL) {
00518 giraffe_image_delete(raw_bias_list[j]);
00519 raw_bias_list[j] = NULL;
00520 }
00521 }
00522
00523 cx_free(raw_bias_list);
00524
00525 giraffe_stacking_config_destroy(stack_config);
00526 stack_config = NULL;
00527
00528 return -1;
00529
00530 }
00531 else {
00532 curr_frame = cpl_frameset_find(set, NULL);
00533 }
00534 }
00535
00536 if (mbias_config.correctbadpixels == TRUE) {
00537
00538
00539
00540 bad_pixel_frame = cpl_frameset_find(set, GIFRAME_BADPIXEL_MAP);
00541
00542 cpl_msg_info(fctid, "Bad Pixel Frame is : %s.",
00543 cpl_frame_get_filename(bad_pixel_frame));
00544
00545 bad_pixels = giraffe_image_new(CPL_TYPE_INT);
00546
00547 e_code = giraffe_image_load(bad_pixels,
00548 cpl_frame_get_filename(bad_pixel_frame),
00549 GIMASTERBIAS_BAD_PIXEL_EXTENSION);
00550
00551 if (e_code !=0 ) {
00552 cpl_msg_error(fctid, "Could not load Bad Pixel Image [%s], "
00553 "aborting...",
00554 cpl_frame_get_filename(bad_pixel_frame));
00555
00556 for (j = 0; j < raw_bias_count; j++) {
00557 if (raw_bias_list[j] != NULL) {
00558 giraffe_image_delete(raw_bias_list[j]);
00559 }
00560 }
00561
00562 cx_free(raw_bias_list);
00563
00564 giraffe_stacking_config_destroy(stack_config);
00565 stack_config = NULL;
00566
00567 return -1;
00568 }
00569 }
00570
00571
00572
00573
00574
00575
00576 master_bias = giraffe_stacking_stack_images(raw_bias_list, stack_config);
00577
00578 if (master_bias == NULL) {
00579 cpl_msg_error(fctid,"Stacking of raw bias frames failed! "
00580 "No master bias was created, aborting...");
00581
00582 for (j = 0; j < raw_bias_count; j++) {
00583 if (raw_bias_list[j] != NULL) {
00584 giraffe_image_delete(raw_bias_list[j]);
00585 }
00586 }
00587
00588 cx_free(raw_bias_list);
00589
00590 if (bad_pixels != NULL) {
00591 giraffe_image_delete(bad_pixels);
00592 }
00593
00594 giraffe_stacking_config_destroy(stack_config);
00595 stack_config = NULL;
00596
00597 return -1;
00598
00599 }
00600
00601 properties = giraffe_image_get_properties(raw_bias_list[0]);
00602 e_code = giraffe_image_set_properties(master_bias, properties);
00603
00604 giraffe_stacking_config_destroy(stack_config);
00605 stack_config = NULL;
00606
00607
00608
00609
00610
00611
00612 if (mbias_config.correctbadpixels == TRUE) {
00613
00614 cpl_msg_info(fctid, "Cleaning bad pixels on created "
00615 "master bias image.");
00616
00617 if (gimasterbias_remove_badpixels(master_bias, bad_pixels) != 0) {
00618
00619 cpl_msg_error(fctid, "Bad pixel cleaning failed, aborting...");
00620
00621 for (j = 0; j < raw_bias_count; j++) {
00622 if (raw_bias_list[j] != NULL) {
00623 giraffe_image_delete(raw_bias_list[j]);
00624 }
00625 }
00626
00627 cx_free(raw_bias_list);
00628
00629 if (bad_pixels != NULL) {
00630 giraffe_image_delete(bad_pixels);
00631 }
00632
00633 if (master_bias != NULL) {
00634 giraffe_image_delete(master_bias);
00635 }
00636
00637 return -1;
00638
00639 }
00640 }
00641
00642
00643
00644
00645
00646 if (mbias_config.removeoverscan == TRUE) {
00647
00648 cpl_msg_info(fctid, "Removing overscan areas from "
00649 "master bias image");
00650
00651 if (giraffe_trim_raw_areas(master_bias) != 0) {
00652
00653 cpl_msg_error(fctid, "Removing overscan areas from master "
00654 "bias failed, aborting...");
00655
00656 for (j = 0; j < raw_bias_count; j++) {
00657 if (raw_bias_list[j] != NULL) {
00658 giraffe_image_delete(raw_bias_list[j]);
00659 }
00660 }
00661
00662 cx_free(raw_bias_list);
00663
00664 if (bad_pixels != NULL) {
00665 giraffe_image_delete(bad_pixels);
00666 }
00667
00668 if (master_bias != NULL) {
00669 giraffe_image_delete(master_bias);
00670 }
00671
00672 return -1;
00673 }
00674
00675 }
00676
00677
00678
00679
00680
00681
00682
00683 cpl_msg_info(fctid, "Writing master bias image ...");
00684
00685 properties = giraffe_image_get_properties(master_bias);
00686 cx_assert(properties != NULL);
00687
00688 cpl_propertylist_update_double(properties, GIALIAS_CRPIX1, 1.);
00689
00690 cpl_propertylist_update_double(properties, GIALIAS_EXPTTOT, 0.0);
00691 cpl_propertylist_update_int(properties, GIALIAS_DATANCOM, raw_bias_count);
00692 cpl_propertylist_update_double(properties, GIALIAS_BZERO, 0.0);
00693
00694 cpl_propertylist_update_double(properties, GIALIAS_BIASVALUE,
00695 cpl_image_get_mean(giraffe_image_get(master_bias)));
00696 cpl_propertylist_update_double(properties, GIALIAS_BIASSIGMA,
00697 cpl_image_get_stdev(giraffe_image_get(master_bias)));
00698
00699 cpl_propertylist_erase(properties, GIALIAS_EXPTIME);
00700 cpl_propertylist_erase(properties, GIALIAS_TPLEXPNO);
00701
00702
00703
00704
00705
00706
00707 for (j = 0; j < raw_bias_count; j++) {
00708 if (raw_bias_list[j] != NULL) {
00709 giraffe_image_delete(raw_bias_list[j]);
00710 }
00711 }
00712
00713 cx_free(raw_bias_list);
00714 raw_bias_list = NULL;
00715
00716 if (bad_pixels != NULL) {
00717 giraffe_image_delete(bad_pixels);
00718 bad_pixels = NULL;
00719 }
00720
00721
00722 giraffe_image_add_info(master_bias, &info, set);
00723
00724 product_frame = giraffe_frame_create_image(master_bias,
00725 GIFRAME_BIAS_MASTER,
00726 CPL_FRAME_LEVEL_FINAL,
00727 TRUE, TRUE);
00728
00729 if (product_frame == NULL) {
00730
00731 cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
00732
00733 if (master_bias != NULL) {
00734 giraffe_image_delete(master_bias);
00735 }
00736
00737 return -1;
00738
00739 }
00740
00741 cpl_frameset_insert(set, product_frame);
00742
00743
00744
00745
00746
00747
00748
00749 if ((mbias_config.bpm.create == TRUE) && (master_bias != NULL)
00750 && (bad_pixel_count == 0)) {
00751
00752 const cpl_image* _master_bias = giraffe_image_get(master_bias);
00753
00754 const cxdouble* pd_mbias =
00755 cpl_image_get_data_double_const(_master_bias);
00756
00757
00758 cxint e_code2 = 0;
00759 cxint row_min = 0;
00760 cxint row_max = 0;
00761 cxint ncol = cpl_image_get_size_x(_master_bias);
00762 cxint nrow = cpl_image_get_size_y(_master_bias);
00763 cxint* pi_bpm = NULL;
00764
00765 cxlong npix = ncol * nrow;
00766 cxlong nbpx = 0L;
00767 cxlong nbpx_max = (cxlong)(mbias_config.bpm.fraction * npix + 0.5);
00768
00769 cxdouble median = 0.;
00770 cxdouble median_max = CX_MINDOUBLE;
00771 cxdouble median_min = CX_MAXDOUBLE;
00772 cxdouble ron = 0.;
00773 cxdouble tlow = 0.;
00774 cxdouble thigh = 0.;
00775
00776 GiImage* bpixel = giraffe_image_create(CPL_TYPE_INT, ncol, nrow);
00777
00778
00779 cpl_msg_info(fctid, "Creating bad pixel map from master bias "
00780 "frame ...");
00781
00782
00783
00784
00785
00786
00787
00788 e_code2 = giraffe_image_set_properties(bpixel, properties);
00789 properties = giraffe_image_get_properties(bpixel);
00790
00791
00792
00793
00794
00795
00796 pi_bpm = cpl_image_get_data_int(giraffe_image_get(bpixel));
00797
00798
00799
00800
00801
00802
00803 if ((cpl_propertylist_has(properties, GIALIAS_PRSCX) == TRUE) ||
00804 (cpl_propertylist_has(properties, GIALIAS_OVSCX) == TRUE)) {
00805
00806 cxint nvalues = 0;
00807
00808 if (cpl_propertylist_has(properties, GIALIAS_PRSCX) == TRUE) {
00809
00810 cxint xsz = cpl_propertylist_get_int(properties,
00811 GIALIAS_PRSCX);
00812
00813 cxdouble sdev = 0.;
00814
00815
00816 for (i = 0; i < nrow; ++i) {
00817
00818 register cxint stride = i * ncol;
00819
00820 cxdouble scx_mean = giraffe_array_mean(pd_mbias + stride,
00821 xsz);
00822
00823 for (j = 0; j < xsz; ++j) {
00824 sdev += (pd_mbias[stride + j] - scx_mean) *
00825 (pd_mbias[stride + j] - scx_mean);
00826 }
00827
00828 }
00829
00830 ron = sqrt(sdev / (cxdouble)(nrow * xsz - 1));
00831 ++nvalues;
00832
00833 }
00834
00835 if (cpl_propertylist_has(properties, GIALIAS_OVSCX) == TRUE) {
00836
00837 cxint xsz = cpl_propertylist_get_int(properties,
00838 GIALIAS_OVSCX);
00839
00840 cxdouble sdev = 0.;
00841
00842
00843 for (i = 0; i < nrow; ++i) {
00844
00845 register cxint stride = (i + 1) * ncol - xsz;
00846
00847 cxdouble scx_mean = giraffe_array_mean(pd_mbias + stride,
00848 xsz);
00849
00850 for (j = 0; j < xsz; ++j) {
00851 sdev += (pd_mbias[stride + j] - scx_mean) *
00852 (pd_mbias[stride + j] - scx_mean);
00853 }
00854
00855 }
00856
00857 ron += sqrt(sdev / (cxdouble)(nrow * xsz - 1));
00858 ++nvalues;
00859
00860 }
00861
00862 ron /= (cxdouble)nvalues;
00863
00864 }
00865 else {
00866
00867 if (cpl_propertylist_has(properties, GIALIAS_RON)) {
00868
00869 ron = cpl_propertylist_get_double(properties, GIALIAS_RON);
00870
00871 if (cpl_propertylist_has(properties, GIALIAS_CONAD)) {
00872
00873 cxdouble conad = cpl_propertylist_get_double(properties,
00874 GIALIAS_CONAD);
00875
00876 if (conad <= 0.) {
00877
00878 cpl_msg_error(fctid, "Invalid conversion factor "
00879 "property (%s): %.2g!", GIALIAS_CONAD,
00880 conad);
00881
00882 giraffe_image_delete(bpixel);
00883 bpixel = NULL;
00884
00885 giraffe_image_delete(master_bias);
00886 master_bias = NULL;
00887
00888 return -1;
00889 }
00890 else {
00891 ron /= conad;
00892 }
00893 }
00894 else {
00895 cpl_msg_error(fctid, "Missing conversion factor property "
00896 "(%s)!", GIALIAS_CONAD);
00897
00898 giraffe_image_delete(bpixel);
00899 bpixel = NULL;
00900
00901 giraffe_image_delete(master_bias);
00902 master_bias = NULL;
00903
00904 return -1;
00905 }
00906 }
00907 else {
00908 ron = cpl_image_get_stdev(giraffe_image_get(master_bias));
00909 }
00910
00911 }
00912
00913 cpl_msg_info(fctid, "Using local median +/- %.4f [ADU] as "
00914 "valid pixel value range", ron);
00915
00916
00917 for (i = 0; i < nrow; ++i) {
00918
00919 register cxint stride = i * ncol;
00920 register cxint* bpx_row = pi_bpm + stride;
00921
00922 register const cxdouble* bias_row = pd_mbias + stride;
00923
00924 register cxdouble sdev = 0.;
00925
00926 median = giraffe_array_median(bias_row, ncol);
00927
00928 for (j = 0; j < ncol; ++j) {
00929 sdev += (bias_row[j] - median) * (bias_row[j] - median);
00930 }
00931 sdev = sqrt(sdev / (cxdouble)(ncol - 1));
00932
00933 if (median < median_min) {
00934 median_min = median;
00935 row_min = i;
00936 }
00937
00938 if (median > median_max) {
00939 median_max = median;
00940 row_max = i;
00941 }
00942
00943 tlow = median - mbias_config.bpm.factor * ron;
00944 thigh = median + mbias_config.bpm.factor * ron;
00945
00946 for (j = 0; j < ncol; ++j) {
00947
00948 if ((bias_row[j] < tlow) || (bias_row[j] > thigh)) {
00949 bpx_row[j] = 1;
00950 ++nbpx;
00951 }
00952 else {
00953 bpx_row[j] = 0;
00954 }
00955
00956 }
00957
00958 }
00959
00960
00961 if (nbpx > nbpx_max) {
00962 cpl_msg_warning(fctid, "Number of bad pixels found (%ld) exceeds "
00963 "maximum number of bad pixels expected (%ld)!", nbpx,
00964 nbpx_max);
00965 }
00966
00967 properties = giraffe_image_get_properties(bpixel);
00968
00969 cpl_propertylist_update_double(properties, GIALIAS_BZERO, 0.);
00970
00971 cpl_propertylist_update_double(properties,
00972 GIALIAS_BPM_FRACTION, mbias_config.bpm.fraction);
00973 cpl_propertylist_set_comment(properties, GIALIAS_BPM_FRACTION,
00974 "Maximum fraction of bad pixels allowed.");
00975
00976 cpl_propertylist_update_int(properties,
00977 GIALIAS_BPM_NPIX, nbpx);
00978 cpl_propertylist_set_comment(properties, GIALIAS_BPM_NPIX,
00979 "Number of pixels flagged as bad.");
00980
00981 cpl_propertylist_update_double(properties,
00982 GIALIAS_BPM_MEDIAN_MIN, median_min);
00983 cpl_propertylist_set_comment(properties, GIALIAS_BPM_MEDIAN_MIN,
00984 "Minimum median pixel value used for bad pixel detection.");
00985
00986 cpl_propertylist_update_double(properties,
00987 GIALIAS_BPM_MEDIAN_MAX, median_max);
00988 cpl_propertylist_set_comment(properties, GIALIAS_BPM_MEDIAN_MAX,
00989 "Maximum median pixel value used for bad pixel detection.");
00990
00991 cpl_propertylist_update_double(properties,
00992 GIALIAS_BPM_FACTOR, mbias_config.bpm.factor);
00993 cpl_propertylist_set_comment(properties, GIALIAS_BPM_FACTOR,
00994 "Noise multiplier defining thresholds for bad pixel "
00995 "detection.");
00996
00997 cpl_propertylist_update_double(properties,
00998 GIALIAS_BPM_NOISE, ron);
00999 cpl_propertylist_set_comment(properties, GIALIAS_BPM_NOISE,
01000 "Bias noise value [ADU] used for bad pixel detection.");
01001
01002 giraffe_image_add_info(bpixel, &info, set);
01003
01004 product_frame = giraffe_frame_create_image(bpixel,
01005 GIFRAME_BADPIXEL_MAP,
01006 CPL_FRAME_LEVEL_FINAL,
01007 TRUE, TRUE);
01008
01009 if (product_frame == NULL) {
01010
01011 cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
01012
01013 if (master_bias != NULL) {
01014 giraffe_image_delete(master_bias);
01015 }
01016
01017 if (bpixel != NULL) {
01018 giraffe_image_delete(bpixel);
01019 }
01020
01021 return -1;
01022
01023 }
01024
01025 cpl_frameset_insert(set, product_frame);
01026
01027
01028
01029
01030
01031
01032 if (bpixel != NULL) {
01033 giraffe_image_delete(bpixel);
01034 }
01035
01036 }
01037
01038 if (master_bias != NULL) {
01039 giraffe_image_delete(master_bias);
01040 }
01041
01042 return 0;
01043
01044 }
01045
01046
01047
01048
01049
01050
01051 static cxint
01052 giqcmasterbias(cpl_frameset* set)
01053 {
01054
01055 const cxchar* const fctid = "giqcmasterbias";
01056
01057
01058 const cxint wstart = 50;
01059 const cxint wsize = 100;
01060
01061 cxint i;
01062 cxint j;
01063 cxint k;
01064 cxint nx = 0;
01065 cxint ny = 0;
01066 cxint nvalid = 0;
01067 cxint status = 0;
01068 cxint nsigma = 5;
01069
01070 const cxdouble low = 100.;
01071 const cxdouble high = 300.;
01072 const cxdouble sthreshold = 2.;
01073
01074 cxdouble mean = 0.;
01075 cxdouble median = 0.;
01076 cxdouble smean = 0.;
01077 cxdouble sum = 0.;
01078 cxdouble* _mbdata = NULL;
01079 cxdouble* _tdata = NULL;
01080 cxdouble sigma[nsigma];
01081
01082 cpl_propertylist* properties = NULL;
01083 cpl_propertylist* qclog = NULL;
01084
01085 cpl_vector* _sigma = NULL;
01086
01087 cpl_image* _mbias = NULL;
01088 cpl_image* _smbias = NULL;
01089 cpl_image* _test = NULL;
01090
01091 cpl_frame* rframe = NULL;
01092 cpl_frame* pframe = NULL;
01093
01094 GiPaf* qc = NULL;
01095
01096 GiImage* mbias = NULL;
01097 GiImage* bias = NULL;
01098
01099 GiWindow w;
01100
01101
01102 cpl_msg_info(fctid, "Computing QC1 parameters ...");
01103
01104 qc = giraffe_qclog_open(0);
01105
01106 if (qc == NULL) {
01107 cpl_msg_error(fctid, "Cannot create QC1 log!");
01108 return 1;
01109 }
01110
01111 qclog = giraffe_paf_get_properties(qc);
01112 cx_assert(qclog != NULL);
01113
01114
01115
01116
01117
01118
01119 pframe = giraffe_get_frame(set, GIFRAME_BIAS_MASTER,
01120 CPL_FRAME_GROUP_PRODUCT);
01121
01122 if (pframe == NULL) {
01123 cpl_msg_error(fctid, "Missing product frame (%s)",
01124 GIFRAME_BIAS_MASTER);
01125
01126 giraffe_paf_delete(qc);
01127 qc = NULL;
01128
01129 return 1;
01130 }
01131
01132 cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
01133 cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
01134
01135 mbias = giraffe_image_new(CPL_TYPE_DOUBLE);
01136 status = giraffe_image_load(mbias, cpl_frame_get_filename(pframe), 0);
01137
01138 if (status != 0) {
01139 cpl_msg_error(fctid, "Could not load master bias '%s'! Aborting ...",
01140 cpl_frame_get_filename(pframe));
01141
01142 giraffe_image_delete(mbias);
01143 mbias = NULL;
01144
01145 giraffe_paf_delete(qc);
01146 qc = NULL;
01147
01148 return 1;
01149 }
01150
01151
01152
01153
01154
01155
01156 rframe = cpl_frameset_find(set, GIFRAME_BIAS);
01157
01158 if (rframe == NULL) {
01159 cpl_msg_error(fctid, "Missing raw frame (%s)", GIFRAME_BIAS);
01160
01161 giraffe_image_delete(mbias);
01162 mbias = NULL;
01163
01164 giraffe_paf_delete(qc);
01165 qc = NULL;
01166
01167 return 1;
01168 }
01169
01170 bias = giraffe_image_new(CPL_TYPE_DOUBLE);
01171 status = giraffe_image_load(bias, cpl_frame_get_filename(rframe), 0);
01172
01173 if (status != 0) {
01174 cpl_msg_error(fctid, "Could not load bias '%s'!",
01175 cpl_frame_get_filename(rframe));
01176
01177 giraffe_image_delete(bias);
01178 bias = NULL;
01179
01180 giraffe_image_delete(mbias);
01181 mbias = NULL;
01182
01183 giraffe_paf_delete(qc);
01184 qc = NULL;
01185
01186 return 1;
01187
01188 }
01189
01190 properties = giraffe_image_get_properties(bias);
01191 cx_assert(properties != NULL);
01192
01193 giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
01194 giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
01195
01196 cpl_propertylist_update_string(qclog, "PRO.CATG",
01197 cpl_frame_get_tag(pframe));
01198 cpl_propertylist_set_comment(qclog, "PRO.CATG",
01199 "Pipeline product category");
01200
01201 properties = giraffe_image_get_properties(mbias);
01202 cx_assert(properties != NULL);
01203
01204 giraffe_propertylist_copy(qclog, "PRO.DATAAVG",
01205 properties, GIALIAS_DATAMEAN);
01206 giraffe_propertylist_copy(qclog, "PRO.DATARMS",
01207 properties, GIALIAS_DATASIG);
01208 giraffe_propertylist_copy(qclog, "PRO.DATAMED",
01209 properties, GIALIAS_DATAMEDI);
01210 giraffe_propertylist_copy(qclog, "PRO.DATANCOM",
01211 properties, GIALIAS_DATANCOM);
01212
01213
01214
01215
01216
01217
01218 _mbias = giraffe_image_get(mbias);
01219 _mbdata = cpl_image_get_data(_mbias);
01220
01221 nx = cpl_image_get_size_x(_mbias);
01222 ny = cpl_image_get_size_y(_mbias);
01223
01224 nvalid = 0;
01225
01226 for (i = 0; i < nx * ny; i++) {
01227
01228 if (_mbdata[i] >= low && _mbdata[i] < high) {
01229 ++nvalid;
01230 }
01231
01232 }
01233
01234 _test = cpl_image_new(nvalid, 1, CPL_TYPE_DOUBLE);
01235 _tdata = cpl_image_get_data(_test);
01236
01237 j = 0;
01238
01239 for (i = 0; i < nx * ny; i++) {
01240
01241 if (_mbdata[i] >= low && _mbdata[i] < high) {
01242 _tdata[j++] = _mbdata[i];
01243 }
01244
01245 }
01246
01247 cpl_propertylist_update_double(properties, GIALIAS_QCMBIASMED,
01248 cpl_image_get_median(_test));
01249 cpl_propertylist_set_comment(properties, GIALIAS_QCMBIASMED,
01250 "Median master bias level (ADU)");
01251
01252 cpl_propertylist_update_double(properties, GIALIAS_QCMBIASAVG,
01253 cpl_image_get_mean(_test));
01254 cpl_propertylist_set_comment(properties, GIALIAS_QCMBIASAVG,
01255 "Mean master bias level (ADU)");
01256
01257 cpl_propertylist_update_double(properties, GIALIAS_QCMBIASRMS,
01258 cpl_image_get_stdev(_test));
01259 cpl_propertylist_set_comment(properties, GIALIAS_QCMBIASRMS,
01260 "RMS of master bias level (ADU)");
01261
01262 cpl_image_delete(_test);
01263 _test = NULL;
01264
01265 giraffe_propertylist_copy(qclog, "QC.BIAS.MASTER.MEDIAN",
01266 properties, GIALIAS_QCMBIASMED);
01267 giraffe_propertylist_copy(qclog, "QC.BIAS.MASTER.MEAN",
01268 properties, GIALIAS_QCMBIASAVG);
01269 giraffe_propertylist_copy(qclog, "QC.BIAS.MASTER.RMS",
01270 properties, GIALIAS_QCMBIASRMS);
01271
01272
01273
01274
01275
01276
01277
01278 if (cpl_frameset_count_tags(set, GIFRAME_BIAS) > 1) {
01279
01280 cpl_frame* _frame = NULL;
01281
01282 cpl_image* diff = NULL;
01283
01284 GiImage* _bias;
01285
01286
01287 nsigma = 5;
01288 memset(sigma, 0, nsigma * sizeof(cxdouble));
01289
01290 _frame = cpl_frameset_find(set, GIFRAME_BIAS);
01291 _frame = cpl_frameset_find(set, NULL);
01292
01293 _bias = giraffe_image_new(CPL_TYPE_DOUBLE);
01294 status = giraffe_image_load(_bias, cpl_frame_get_filename(_frame), 0);
01295
01296 if (status != 0) {
01297 cpl_msg_error(fctid, "Could not load bias '%s'! Aborting ...",
01298 cpl_frame_get_filename(_frame));
01299
01300 giraffe_image_delete(_bias);
01301 _bias = NULL;
01302
01303 giraffe_image_delete(mbias);
01304 mbias = NULL;
01305
01306 giraffe_image_delete(bias);
01307 bias = NULL;
01308
01309 giraffe_paf_delete(qc);
01310 qc = NULL;
01311
01312 return 1;
01313 }
01314
01315 diff = cpl_image_duplicate(giraffe_image_get(bias));
01316
01317 if (diff == NULL) {
01318 cpl_msg_error(fctid, "Cannot compute bias difference image! "
01319 "Aborting ...");
01320
01321 giraffe_image_delete(_bias);
01322 _bias = NULL;
01323
01324 giraffe_image_delete(mbias);
01325 mbias = NULL;
01326
01327 giraffe_image_delete(bias);
01328 bias = NULL;
01329
01330 giraffe_paf_delete(qc);
01331 qc = NULL;
01332
01333 return 1;
01334 }
01335
01336 cpl_image_subtract(diff, giraffe_image_get(_bias));
01337
01338 giraffe_image_delete(_bias);
01339
01340
01341 i = 0;
01342
01343
01344
01345 w.x0 = wstart;
01346 w.y0 = wstart;
01347 w.x1 = w.x0 + wsize;
01348 w.y1 = w.y0 + wsize;
01349
01350 giraffe_error_push();
01351
01352 sigma[i++] = cpl_image_get_stdev_window(diff, w.x0, w.y0, w.x1, w.y1);
01353
01354 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01355 --nsigma;
01356 }
01357
01358 giraffe_error_pop();
01359
01360
01361
01362
01363 w.x0 = cpl_image_get_size_x(diff) - wstart - wsize;
01364 w.x1 = w.x0 + wsize;
01365
01366 giraffe_error_push();
01367
01368 sigma[i++] = cpl_image_get_stdev_window(diff, w.x0, w.y0, w.x1, w.y1);
01369
01370 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01371 --nsigma;
01372 }
01373
01374 giraffe_error_pop();
01375
01376
01377
01378
01379 w.y0 = cpl_image_get_size_y(diff) - wstart - wsize;
01380 w.y1 = w.y0 + wsize;
01381
01382 giraffe_error_push();
01383
01384 sigma[i++] = cpl_image_get_stdev_window(diff, w.x0, w.y0, w.x1, w.y1);
01385
01386 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01387 --nsigma;
01388 }
01389
01390 giraffe_error_pop();
01391
01392
01393
01394
01395 w.x0 = wstart;
01396 w.x1 = w.x0 + wsize;
01397
01398 giraffe_error_push();
01399
01400 sigma[i++] = cpl_image_get_stdev_window(diff, w.x0, w.y0, w.x1, w.y1);
01401
01402 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01403 --nsigma;
01404 }
01405
01406 giraffe_error_pop();
01407
01408
01409
01410
01411 w.x0 = 1024;
01412 w.y0 = 1998;
01413 w.x1 = 1124;
01414 w.y1 = 2098;
01415
01416 giraffe_error_push();
01417
01418 sigma[i++] = cpl_image_get_stdev_window(diff, w.x0, w.y0, w.x1, w.y1);
01419
01420 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01421 --nsigma;
01422 }
01423
01424 giraffe_error_pop();
01425
01426
01427 for (i = 0; i < nsigma; i++) {
01428 sigma[i] /= sqrt(2.);
01429 }
01430
01431 if (nsigma < 1) {
01432 cpl_msg_error(fctid, "Could not compute image statistics in any "
01433 "window! Aborting ...");
01434
01435 cpl_image_delete(diff);
01436 diff = NULL;
01437
01438 giraffe_image_delete(mbias);
01439 mbias = NULL;
01440
01441 giraffe_image_delete(bias);
01442 bias = NULL;
01443
01444 giraffe_paf_delete(qc);
01445 qc = NULL;
01446
01447 return 1;
01448 }
01449
01450
01451 _sigma = cpl_vector_wrap(nsigma, sigma);
01452
01453 median = cpl_vector_get_median(_sigma);
01454
01455 cpl_vector_unwrap(_sigma);
01456 _sigma = NULL;
01457
01458 cpl_image_delete(diff);
01459 diff = NULL;
01460
01461
01462 cpl_propertylist_update_double(properties, GIALIAS_QCRON, median);
01463 cpl_propertylist_set_comment(properties, GIALIAS_QCRON,
01464 "Readout noise (raw)");
01465
01466 giraffe_propertylist_copy(qclog, "QC.OUT1.RON.RAW", properties,
01467 GIALIAS_QCRON);
01468 }
01469
01470 giraffe_image_delete(bias);
01471 bias = NULL;
01472
01473
01474
01475
01476
01477
01478 k = 0;
01479 nsigma = 5;
01480 memset(sigma, 0, nsigma * sizeof(cxdouble));
01481
01482
01483
01484
01485 w.x0 = wstart;
01486 w.y0 = wstart;
01487 w.x1 = w.x0 + wsize;
01488 w.y1 = w.y0 + wsize;
01489
01490 _smbias = cpl_image_extract(_mbias, w.x0, w.y0, w.x1, w.y1);
01491 _mbdata = cpl_image_get_data(_smbias);
01492
01493 nvalid = 0;
01494
01495 for (i = 0; i < wsize * wsize; i++) {
01496
01497 if (_mbdata[i] >= low && _mbdata[i] < high) {
01498 ++nvalid;
01499 }
01500
01501 }
01502
01503 _test = cpl_image_new(nvalid, 1, CPL_TYPE_DOUBLE);
01504 _tdata = cpl_image_get_data(_test);
01505
01506 j = 0;
01507
01508 for (i = 0; i < wsize * wsize; i++) {
01509
01510 if (_mbdata[i] >= low && _mbdata[i] < high) {
01511 _tdata[j++] = _mbdata[i];
01512 }
01513
01514 }
01515
01516 giraffe_error_push();
01517
01518 sigma[k++] = cpl_image_get_stdev(_test);
01519
01520 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01521 --nsigma;
01522 }
01523
01524 giraffe_error_pop();
01525
01526 cpl_image_delete(_smbias);
01527 _smbias = NULL;
01528
01529 cpl_image_delete(_test);
01530 _test = NULL;
01531
01532
01533
01534 w.x0 = cpl_image_get_size_x(_mbias) - wstart - wsize;
01535 w.x1 = w.x0 + wsize;
01536
01537 _smbias = cpl_image_extract(_mbias, w.x0, w.y0, w.x1, w.y1);
01538 _mbdata = cpl_image_get_data(_smbias);
01539
01540 nvalid = 0;
01541
01542 for (i = 0; i < wsize * wsize; i++) {
01543
01544 if (_mbdata[i] >= low && _mbdata[i] < high) {
01545 ++nvalid;
01546 }
01547
01548 }
01549
01550 _test = cpl_image_new(nvalid, 1, CPL_TYPE_DOUBLE);
01551 _tdata = cpl_image_get_data(_test);
01552
01553 j = 0;
01554
01555 for (i = 0; i < wsize * wsize; i++) {
01556
01557 if (_mbdata[i] >= low && _mbdata[i] < high) {
01558 _tdata[j++] = _mbdata[i];
01559 }
01560
01561 }
01562
01563 giraffe_error_push();
01564
01565 sigma[k++] = cpl_image_get_stdev(_test);
01566
01567 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01568 --nsigma;
01569 }
01570
01571 giraffe_error_pop();
01572
01573 cpl_image_delete(_smbias);
01574 _smbias = NULL;
01575
01576 cpl_image_delete(_test);
01577 _test = NULL;
01578
01579
01580
01581 w.y0 = cpl_image_get_size_y(_mbias) - wstart - wsize;
01582 w.y1 = w.y0 + wsize;
01583
01584 _smbias = cpl_image_extract(_mbias, w.x0, w.y0, w.x1, w.y1);
01585 _mbdata = cpl_image_get_data(_smbias);
01586
01587 nvalid = 0;
01588
01589 for (i = 0; i < wsize * wsize; i++) {
01590
01591 if (_mbdata[i] >= low && _mbdata[i] < high) {
01592 ++nvalid;
01593 }
01594
01595 }
01596
01597 _test = cpl_image_new(nvalid, 1, CPL_TYPE_DOUBLE);
01598 _tdata = cpl_image_get_data(_test);
01599
01600 j = 0;
01601
01602 for (i = 0; i < wsize * wsize; i++) {
01603
01604 if (_mbdata[i] >= low && _mbdata[i] < high) {
01605 _tdata[j++] = _mbdata[i];
01606 }
01607
01608 }
01609
01610 giraffe_error_push();
01611
01612 sigma[k++] = cpl_image_get_stdev(_test);
01613
01614 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01615 --nsigma;
01616 }
01617
01618 giraffe_error_pop();
01619
01620 cpl_image_delete(_smbias);
01621 _smbias = NULL;
01622
01623 cpl_image_delete(_test);
01624 _test = NULL;
01625
01626
01627
01628 w.x0 = wstart;
01629 w.x1 = w.x0 + wsize;
01630
01631 _smbias = cpl_image_extract(_mbias, w.x0, w.y0, w.x1, w.y1);
01632 _mbdata = cpl_image_get_data(_smbias);
01633
01634 nvalid = 0;
01635
01636 for (i = 0; i < wsize * wsize; i++) {
01637
01638 if (_mbdata[i] >= low && _mbdata[i] < high) {
01639 ++nvalid;
01640 }
01641
01642 }
01643
01644 _test = cpl_image_new(nvalid, 1, CPL_TYPE_DOUBLE);
01645 _tdata = cpl_image_get_data(_test);
01646
01647 j = 0;
01648
01649 for (i = 0; i < wsize * wsize; i++) {
01650
01651 if (_mbdata[i] >= low && _mbdata[i] < high) {
01652 _tdata[j++] = _mbdata[i];
01653 }
01654
01655 }
01656
01657 giraffe_error_push();
01658
01659 sigma[k++] = cpl_image_get_stdev(_test);
01660
01661 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01662 --nsigma;
01663 }
01664
01665 giraffe_error_pop();
01666
01667 cpl_image_delete(_smbias);
01668 _smbias = NULL;
01669
01670 cpl_image_delete(_test);
01671 _test = NULL;
01672
01673
01674
01675 w.x0 = 1024;
01676 w.y0 = 1998;
01677 w.x1 = 1124;
01678 w.y1 = 2098;
01679
01680 _smbias = cpl_image_extract(_mbias, w.x0, w.y0, w.x1, w.y1);
01681 _mbdata = cpl_image_get_data(_smbias);
01682
01683 nvalid = 0;
01684
01685 for (i = 0; i < wsize * wsize; i++) {
01686
01687 if (_mbdata[i] >= low && _mbdata[i] < high) {
01688 ++nvalid;
01689 }
01690
01691 }
01692
01693 _test = cpl_image_new(nvalid, 1, CPL_TYPE_DOUBLE);
01694 _tdata = cpl_image_get_data(_test);
01695
01696 j = 0;
01697
01698 for (i = 0; i < wsize * wsize; i++) {
01699
01700 if (_mbdata[i] >= low && _mbdata[i] < high) {
01701 _tdata[j++] = _mbdata[i];
01702 }
01703
01704 }
01705
01706 giraffe_error_push();
01707
01708 sigma[k++] = cpl_image_get_stdev(_test);
01709
01710 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01711 --nsigma;
01712 }
01713
01714 giraffe_error_pop();
01715
01716 cpl_image_delete(_smbias);
01717 _smbias = NULL;
01718
01719 cpl_image_delete(_test);
01720 _test = NULL;
01721
01722 if (nsigma < 1) {
01723 cpl_msg_error(fctid, "Could not compute image statistics in any "
01724 "window! Aborting ...");
01725
01726 giraffe_image_delete(mbias);
01727 mbias = NULL;
01728
01729 giraffe_paf_delete(qc);
01730 qc = NULL;
01731
01732 return 1;
01733 }
01734
01735 _sigma = cpl_vector_wrap(nsigma, sigma);
01736
01737 median = cpl_vector_get_median(_sigma);
01738
01739 cpl_vector_unwrap(_sigma);
01740 _sigma = NULL;
01741
01742 cpl_propertylist_update_double(properties, GIALIAS_QCMRON, median);
01743 cpl_propertylist_set_comment(properties, GIALIAS_QCMRON, "Readout noise "
01744 "(master)");
01745
01746 giraffe_propertylist_copy(qclog, "QC.OUT1.RON.MASTER", properties,
01747 GIALIAS_QCMRON);
01748
01749
01750
01751
01752
01753
01754 _test = cpl_image_collapse_create(_mbias, 0);
01755 cpl_image_divide_scalar(_test, cpl_image_get_size_y(_mbias));
01756
01757 mean = cpl_image_get_mean(_test);
01758
01759
01760
01761
01762
01763
01764 nvalid = 0;
01765 sum = 0.;
01766
01767 _tdata = cpl_image_get_data(_test);
01768
01769 for (i = 0; i < cpl_image_get_size_x(_test); i++) {
01770
01771 if ((_tdata[i] > mean - sthreshold) &&
01772 (_tdata[i] < mean + sthreshold)) {
01773 sum += _tdata[i];
01774 ++nvalid;
01775 }
01776
01777 }
01778
01779 smean = sum / nvalid;
01780
01781
01782
01783
01784
01785
01786 nvalid = 0;
01787 sum = 0.;
01788
01789 for (i = 0; i < cpl_image_get_size_x(_test); i++) {
01790
01791 if ((_tdata[i] > mean - sthreshold) &&
01792 (_tdata[i] < mean + sthreshold)) {
01793 sum += pow(_tdata[i] - smean, 2.);
01794 ++nvalid;
01795 }
01796
01797 }
01798
01799 sum = sqrt(sum / (nvalid - 1));
01800
01801 cpl_propertylist_update_double(properties, GIALIAS_QCSTRUCTX, sum);
01802 cpl_propertylist_set_comment(properties, GIALIAS_QCSTRUCTX,
01803 "Structure along the x axis");
01804
01805 giraffe_propertylist_copy(qclog, "QC.OUT1.STRUCT.X", properties,
01806 GIALIAS_QCSTRUCTX);
01807
01808 cpl_image_delete(_test);
01809 _test = NULL;
01810
01811
01812 _test = cpl_image_collapse_create(_mbias, 1);
01813 cpl_image_divide_scalar(_test, cpl_image_get_size_x(_mbias));
01814
01815 mean = cpl_image_get_mean(_test);
01816
01817
01818
01819
01820
01821
01822 nvalid = 0;
01823 sum = 0.;
01824
01825 _tdata = cpl_image_get_data(_test);
01826
01827 for (i = 0; i < cpl_image_get_size_y(_test); i++) {
01828
01829 if ((_tdata[i] > mean - sthreshold) &&
01830 (_tdata[i] < mean + sthreshold)) {
01831 sum += _tdata[i];
01832 ++nvalid;
01833 }
01834
01835 }
01836
01837 smean = sum / nvalid;
01838
01839
01840
01841
01842
01843
01844 nvalid = 0;
01845 sum = 0.;
01846
01847 _tdata = cpl_image_get_data(_test);
01848
01849 for (i = 0; i < cpl_image_get_size_y(_test); i++) {
01850
01851 if ((_tdata[i] > mean - sthreshold) &&
01852 (_tdata[i] < mean + sthreshold)) {
01853 sum += pow(_tdata[i] - smean, 2.);
01854 ++nvalid;
01855 }
01856
01857 }
01858
01859 sum = sqrt(sum / (nvalid - 1));
01860
01861 cpl_propertylist_update_double(properties, GIALIAS_QCSTRUCTY, sum);
01862 cpl_propertylist_set_comment(properties, GIALIAS_QCSTRUCTY,
01863 "Structure along the y axis");
01864
01865 giraffe_propertylist_copy(qclog, "QC.OUT1.STRUCT.Y", properties,
01866 GIALIAS_QCSTRUCTY);
01867
01868 cpl_image_delete(_test);
01869 _test = NULL;
01870
01871
01872
01873
01874
01875
01876 giraffe_image_save(mbias, cpl_frame_get_filename(pframe));
01877
01878 giraffe_image_delete(mbias);
01879 mbias = NULL;
01880
01881 giraffe_qclog_close(qc);
01882 qc = NULL;
01883
01884 return 0;
01885
01886 }
01887
01888
01889
01890
01891
01892
01893
01894 int
01895 cpl_plugin_get_info(cpl_pluginlist* list)
01896 {
01897
01898 cpl_recipe* recipe = cx_calloc(1, sizeof *recipe);
01899 cpl_plugin* plugin = &recipe->interface;
01900
01901
01902 cpl_plugin_init(plugin,
01903 CPL_PLUGIN_API,
01904 GIRAFFE_BINARY_VERSION,
01905 CPL_PLUGIN_TYPE_RECIPE,
01906 "gimasterbias",
01907 "Creates a master bias image from a set of raw biases.",
01908 "For detailed information please refer to the "
01909 "GIRAFFE pipeline user manual.\nIt is available at "
01910 "http://www.eso.org/pipelines.",
01911 "Giraffe Pipeline",
01912 PACKAGE_BUGREPORT,
01913 giraffe_get_license(),
01914 gimasterbias_create,
01915 gimasterbias_exec,
01916 gimasterbias_destroy);
01917
01918 cpl_pluginlist_append(list, plugin);
01919
01920 return 0;
01921
01922 }