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 }
00520 }
00521
00522 cx_free(raw_bias_list);
00523
00524 giraffe_stacking_config_destroy(stack_config);
00525 stack_config = NULL;
00526
00527 return -1;
00528
00529 }
00530 else {
00531 curr_frame = cpl_frameset_find(set, NULL);
00532 }
00533 }
00534
00535 if (mbias_config.correctbadpixels == TRUE) {
00536
00537
00538
00539 bad_pixel_frame = cpl_frameset_find(set, GIFRAME_BADPIXEL_MAP);
00540
00541 cpl_msg_info(fctid, "Bad Pixel Frame is : %s.",
00542 cpl_frame_get_filename(bad_pixel_frame));
00543
00544 bad_pixels = giraffe_image_new(CPL_TYPE_INT);
00545
00546 e_code = giraffe_image_load(bad_pixels,
00547 cpl_frame_get_filename(bad_pixel_frame),
00548 GIMASTERBIAS_BAD_PIXEL_EXTENSION);
00549
00550 if (e_code !=0 ) {
00551 cpl_msg_error(fctid, "Could not load Bad Pixel Image [%s], "
00552 "aborting...",
00553 cpl_frame_get_filename(bad_pixel_frame));
00554
00555 for (j = 0; j < raw_bias_count; j++) {
00556 if (raw_bias_list[j] != NULL) {
00557 giraffe_image_delete(raw_bias_list[j]);
00558 }
00559 }
00560
00561 cx_free(raw_bias_list);
00562
00563 giraffe_stacking_config_destroy(stack_config);
00564 stack_config = NULL;
00565
00566 return -1;
00567 }
00568 }
00569
00570
00571
00572
00573
00574
00575 master_bias = giraffe_stacking_stack_images(raw_bias_list, stack_config);
00576
00577 if (master_bias == NULL) {
00578 cpl_msg_error(fctid,"Stacking of raw bias frames failed! "
00579 "No master bias was created, aborting...");
00580
00581 for (j = 0; j < raw_bias_count; j++) {
00582 if (raw_bias_list[j] != NULL) {
00583 giraffe_image_delete(raw_bias_list[j]);
00584 }
00585 }
00586
00587 cx_free(raw_bias_list);
00588
00589 if (bad_pixels != NULL) {
00590 giraffe_image_delete(bad_pixels);
00591 }
00592
00593 giraffe_stacking_config_destroy(stack_config);
00594 stack_config = NULL;
00595
00596 return -1;
00597
00598 }
00599
00600 properties = giraffe_image_get_properties(raw_bias_list[0]);
00601 e_code = giraffe_image_set_properties(master_bias, properties);
00602
00603 giraffe_stacking_config_destroy(stack_config);
00604 stack_config = NULL;
00605
00606
00607
00608
00609
00610
00611 if (mbias_config.correctbadpixels == TRUE) {
00612
00613 cpl_msg_info(fctid, "Cleaning bad pixels on created "
00614 "master bias image.");
00615
00616 if (gimasterbias_remove_badpixels(master_bias, bad_pixels) != 0) {
00617
00618 cpl_msg_error(fctid, "Bad pixel cleaning failed, aborting...");
00619
00620 for (j = 0; j < raw_bias_count; j++) {
00621 if (raw_bias_list[j] != NULL) {
00622 giraffe_image_delete(raw_bias_list[j]);
00623 }
00624 }
00625
00626 cx_free(raw_bias_list);
00627
00628 if (bad_pixels != NULL) {
00629 giraffe_image_delete(bad_pixels);
00630 }
00631
00632 if (master_bias != NULL) {
00633 giraffe_image_delete(master_bias);
00634 }
00635
00636 return -1;
00637
00638 }
00639 }
00640
00641
00642
00643
00644
00645 if (mbias_config.removeoverscan == TRUE) {
00646
00647 cpl_msg_info(fctid, "Removing overscan areas from "
00648 "master bias image");
00649
00650 if (giraffe_trim_raw_areas(master_bias) != 0) {
00651
00652 cpl_msg_error(fctid, "Removing overscan areas from master "
00653 "bias failed, aborting...");
00654
00655 for (j = 0; j < raw_bias_count; j++) {
00656 if (raw_bias_list[j] != NULL) {
00657 giraffe_image_delete(raw_bias_list[j]);
00658 }
00659 }
00660
00661 cx_free(raw_bias_list);
00662
00663 if (bad_pixels != NULL) {
00664 giraffe_image_delete(bad_pixels);
00665 }
00666
00667 if (master_bias != NULL) {
00668 giraffe_image_delete(master_bias);
00669 }
00670
00671 return -1;
00672 }
00673
00674 }
00675
00676
00677
00678
00679
00680
00681
00682 cpl_msg_info(fctid, "Writing master bias image ...");
00683
00684 properties = giraffe_image_get_properties(master_bias);
00685 cx_assert(properties != NULL);
00686
00687 cpl_propertylist_update_double(properties, GIALIAS_CRPIX1, 1.);
00688
00689 cpl_propertylist_update_double(properties, GIALIAS_EXPTTOT, 0.0);
00690 cpl_propertylist_update_int(properties, GIALIAS_DATANCOM, raw_bias_count);
00691 cpl_propertylist_update_double(properties, GIALIAS_BZERO, 0.0);
00692
00693 cpl_propertylist_update_double(properties, GIALIAS_BIASVALUE,
00694 cpl_image_get_mean(giraffe_image_get(master_bias)));
00695 cpl_propertylist_update_double(properties, GIALIAS_BIASSIGMA,
00696 cpl_image_get_stdev(giraffe_image_get(master_bias)));
00697
00698 cpl_propertylist_erase(properties, GIALIAS_EXPTIME);
00699 cpl_propertylist_erase(properties, GIALIAS_TPLEXPNO);
00700
00701
00702
00703
00704
00705
00706 for (j = 0; j < raw_bias_count; j++) {
00707 if (raw_bias_list[j] != NULL) {
00708 giraffe_image_delete(raw_bias_list[j]);
00709 }
00710 }
00711
00712 cx_free(raw_bias_list);
00713 raw_bias_list = NULL;
00714
00715 if (bad_pixels != NULL) {
00716 giraffe_image_delete(bad_pixels);
00717 bad_pixels = NULL;
00718 }
00719
00720
00721 giraffe_image_add_info(master_bias, &info, set);
00722
00723 product_frame = giraffe_frame_create_image(master_bias,
00724 GIFRAME_BIAS_MASTER,
00725 CPL_FRAME_LEVEL_FINAL,
00726 TRUE, TRUE);
00727
00728 if (product_frame == NULL) {
00729
00730 cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
00731
00732 if (master_bias != NULL) {
00733 giraffe_image_delete(master_bias);
00734 }
00735
00736 return -1;
00737
00738 }
00739
00740 cpl_frameset_insert(set, product_frame);
00741
00742
00743
00744
00745
00746
00747
00748 if ((mbias_config.bpm.create == TRUE) && (master_bias != NULL)
00749 && (bad_pixel_count == 0)) {
00750
00751 const cpl_image* _master_bias = giraffe_image_get(master_bias);
00752
00753 const cxdouble* pd_mbias =
00754 cpl_image_get_data_double_const(_master_bias);
00755
00756
00757 cxint e_code2 = 0;
00758 cxint row_min = 0;
00759 cxint row_max = 0;
00760 cxint ncol = cpl_image_get_size_x(_master_bias);
00761 cxint nrow = cpl_image_get_size_y(_master_bias);
00762 cxint* pi_bpm = NULL;
00763
00764 cxlong npix = ncol * nrow;
00765 cxlong nbpx = 0L;
00766 cxlong nbpx_max = (cxlong)(mbias_config.bpm.fraction * npix + 0.5);
00767
00768 cxdouble median = 0.;
00769 cxdouble median_max = CX_MINDOUBLE;
00770 cxdouble median_min = CX_MAXDOUBLE;
00771 cxdouble ron = 0.;
00772 cxdouble tlow = 0.;
00773 cxdouble thigh = 0.;
00774
00775 GiImage* bpixel = giraffe_image_create(CPL_TYPE_INT, ncol, nrow);
00776
00777
00778 cpl_msg_info(fctid, "Creating bad pixel map from master bias "
00779 "frame ...");
00780
00781
00782
00783
00784
00785
00786
00787 e_code2 = giraffe_image_set_properties(bpixel, properties);
00788 properties = giraffe_image_get_properties(bpixel);
00789
00790
00791
00792
00793
00794
00795 pi_bpm = cpl_image_get_data_int(giraffe_image_get(bpixel));
00796
00797
00798
00799
00800
00801
00802 if ((cpl_propertylist_has(properties, GIALIAS_PRSCX) == TRUE) ||
00803 (cpl_propertylist_has(properties, GIALIAS_OVSCX) == TRUE)) {
00804
00805 cxint nvalues = 0;
00806
00807 if (cpl_propertylist_has(properties, GIALIAS_PRSCX) == TRUE) {
00808
00809 cxint xsz = cpl_propertylist_get_int(properties,
00810 GIALIAS_PRSCX);
00811
00812 cxdouble sdev = 0.;
00813
00814
00815 for (i = 0; i < nrow; ++i) {
00816
00817 register cxint stride = i * ncol;
00818
00819 cxdouble scx_mean = giraffe_array_mean(pd_mbias + stride,
00820 xsz);
00821
00822 for (j = 0; j < xsz; ++j) {
00823 sdev += (pd_mbias[stride + j] - scx_mean) *
00824 (pd_mbias[stride + j] - scx_mean);
00825 }
00826
00827 }
00828
00829 ron = sqrt(sdev / (cxdouble)(nrow * xsz - 1));
00830 ++nvalues;
00831
00832 }
00833
00834 if (cpl_propertylist_has(properties, GIALIAS_OVSCX) == TRUE) {
00835
00836 cxint xsz = cpl_propertylist_get_int(properties,
00837 GIALIAS_OVSCX);
00838
00839 cxdouble sdev = 0.;
00840
00841
00842 for (i = 0; i < nrow; ++i) {
00843
00844 register cxint stride = (i + 1) * ncol - xsz;
00845
00846 cxdouble scx_mean = giraffe_array_mean(pd_mbias + stride,
00847 xsz);
00848
00849 for (j = 0; j < xsz; ++j) {
00850 sdev += (pd_mbias[stride + j] - scx_mean) *
00851 (pd_mbias[stride + j] - scx_mean);
00852 }
00853
00854 }
00855
00856 ron += sqrt(sdev / (cxdouble)(nrow * xsz - 1));
00857 ++nvalues;
00858
00859 }
00860
00861 ron /= (cxdouble)nvalues;
00862
00863 }
00864 else {
00865
00866 if (cpl_propertylist_has(properties, GIALIAS_RON)) {
00867
00868 ron = cpl_propertylist_get_double(properties, GIALIAS_RON);
00869
00870 if (cpl_propertylist_has(properties, GIALIAS_CONAD)) {
00871
00872 cxdouble conad = cpl_propertylist_get_double(properties,
00873 GIALIAS_CONAD);
00874
00875 if (conad <= 0.) {
00876
00877 cpl_msg_error(fctid, "Invalid conversion factor "
00878 "property (%s): %.2g!", GIALIAS_CONAD,
00879 conad);
00880
00881 giraffe_image_delete(bpixel);
00882 bpixel = NULL;
00883
00884 giraffe_image_delete(master_bias);
00885 master_bias = NULL;
00886
00887 return -1;
00888 }
00889 else {
00890 ron /= conad;
00891 }
00892 }
00893 else {
00894 cpl_msg_error(fctid, "Missing conversion factor property "
00895 "(%s)!", GIALIAS_CONAD);
00896
00897 giraffe_image_delete(bpixel);
00898 bpixel = NULL;
00899
00900 giraffe_image_delete(master_bias);
00901 master_bias = NULL;
00902
00903 return -1;
00904 }
00905 }
00906 else {
00907 ron = cpl_image_get_stdev(giraffe_image_get(master_bias));
00908 }
00909
00910 }
00911
00912 cpl_msg_info(fctid, "Using local median +/- %.4f [ADU] as "
00913 "valid pixel value range", ron);
00914
00915
00916 for (i = 0; i < nrow; ++i) {
00917
00918 register cxint stride = i * ncol;
00919 register cxint* bpx_row = pi_bpm + stride;
00920
00921 register const cxdouble* bias_row = pd_mbias + stride;
00922
00923 register cxdouble sdev = 0.;
00924
00925 median = giraffe_array_median(bias_row, ncol);
00926
00927 for (j = 0; j < ncol; ++j) {
00928 sdev += (bias_row[j] - median) * (bias_row[j] - median);
00929 }
00930 sdev = sqrt(sdev / (cxdouble)(ncol - 1));
00931
00932 if (median < median_min) {
00933 median_min = median;
00934 row_min = i;
00935 }
00936
00937 if (median > median_max) {
00938 median_max = median;
00939 row_max = i;
00940 }
00941
00942 tlow = median - mbias_config.bpm.factor * ron;
00943 thigh = median + mbias_config.bpm.factor * ron;
00944
00945 for (j = 0; j < ncol; ++j) {
00946
00947 if ((bias_row[j] < tlow) || (bias_row[j] > thigh)) {
00948 bpx_row[j] = 1;
00949 ++nbpx;
00950 }
00951 else {
00952 bpx_row[j] = 0;
00953 }
00954
00955 }
00956
00957 }
00958
00959
00960 if (nbpx > nbpx_max) {
00961 cpl_msg_warning(fctid, "Number of bad pixels found (%ld) exceeds "
00962 "maximum number of bad pixels expected (%ld)!", nbpx,
00963 nbpx_max);
00964 }
00965
00966 properties = giraffe_image_get_properties(bpixel);
00967
00968 cpl_propertylist_update_double(properties, GIALIAS_BZERO, 0.);
00969
00970 cpl_propertylist_update_double(properties,
00971 GIALIAS_BPM_FRACTION, mbias_config.bpm.fraction);
00972 cpl_propertylist_set_comment(properties, GIALIAS_BPM_FRACTION,
00973 "Maximum fraction of bad pixels allowed.");
00974
00975 cpl_propertylist_update_int(properties,
00976 GIALIAS_BPM_NPIX, nbpx);
00977 cpl_propertylist_set_comment(properties, GIALIAS_BPM_NPIX,
00978 "Number of pixels flagged as bad.");
00979
00980 cpl_propertylist_update_double(properties,
00981 GIALIAS_BPM_MEDIAN_MIN, median_min);
00982 cpl_propertylist_set_comment(properties, GIALIAS_BPM_MEDIAN_MIN,
00983 "Minimum median pixel value used for bad pixel detection.");
00984
00985 cpl_propertylist_update_double(properties,
00986 GIALIAS_BPM_MEDIAN_MAX, median_max);
00987 cpl_propertylist_set_comment(properties, GIALIAS_BPM_MEDIAN_MAX,
00988 "Maximum median pixel value used for bad pixel detection.");
00989
00990 cpl_propertylist_update_double(properties,
00991 GIALIAS_BPM_FACTOR, mbias_config.bpm.factor);
00992 cpl_propertylist_set_comment(properties, GIALIAS_BPM_FACTOR,
00993 "Noise multiplier defining thresholds for bad pixel "
00994 "detection.");
00995
00996 cpl_propertylist_update_double(properties,
00997 GIALIAS_BPM_NOISE, ron);
00998 cpl_propertylist_set_comment(properties, GIALIAS_BPM_NOISE,
00999 "Bias noise value [ADU] used for bad pixel detection.");
01000
01001 giraffe_image_add_info(bpixel, &info, set);
01002
01003 product_frame = giraffe_frame_create_image(bpixel,
01004 GIFRAME_BADPIXEL_MAP,
01005 CPL_FRAME_LEVEL_FINAL,
01006 TRUE, TRUE);
01007
01008 if (product_frame == NULL) {
01009
01010 cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
01011
01012 if (master_bias != NULL) {
01013 giraffe_image_delete(master_bias);
01014 }
01015
01016 if (bpixel != NULL) {
01017 giraffe_image_delete(bpixel);
01018 }
01019
01020 return -1;
01021
01022 }
01023
01024 cpl_frameset_insert(set, product_frame);
01025
01026
01027
01028
01029
01030
01031 if (bpixel != NULL) {
01032 giraffe_image_delete(bpixel);
01033 }
01034
01035 }
01036
01037 if (master_bias != NULL) {
01038 giraffe_image_delete(master_bias);
01039 }
01040
01041 return 0;
01042
01043 }
01044
01045
01046
01047
01048
01049
01050 static cxint
01051 giqcmasterbias(cpl_frameset* set)
01052 {
01053
01054 const cxchar* const fctid = "giqcmasterbias";
01055
01056
01057 const cxint wstart = 50;
01058 const cxint wsize = 100;
01059
01060 cxint i;
01061 cxint j;
01062 cxint k;
01063 cxint nx = 0;
01064 cxint ny = 0;
01065 cxint nvalid = 0;
01066 cxint status = 0;
01067 cxint nsigma = 5;
01068
01069 const cxdouble low = 100.;
01070 const cxdouble high = 300.;
01071 const cxdouble sthreshold = 2.;
01072
01073 cxdouble mean = 0.;
01074 cxdouble median = 0.;
01075 cxdouble smean = 0.;
01076 cxdouble sum = 0.;
01077 cxdouble* _mbdata = NULL;
01078 cxdouble* _tdata = NULL;
01079 cxdouble sigma[nsigma];
01080
01081 cpl_propertylist* properties = NULL;
01082 cpl_propertylist* qclog = NULL;
01083
01084 cpl_vector* _sigma = NULL;
01085
01086 cpl_image* _mbias = NULL;
01087 cpl_image* _smbias = NULL;
01088 cpl_image* _test = NULL;
01089
01090 cpl_frame* rframe = NULL;
01091 cpl_frame* pframe = NULL;
01092
01093 GiPaf* qc = NULL;
01094
01095 GiImage* mbias = NULL;
01096 GiImage* bias = NULL;
01097
01098 GiWindow w;
01099
01100
01101 cpl_msg_info(fctid, "Computing QC1 parameters ...");
01102
01103 qc = giraffe_qclog_open(0);
01104
01105 if (qc == NULL) {
01106 cpl_msg_error(fctid, "Cannot create QC1 log!");
01107 return 1;
01108 }
01109
01110 qclog = giraffe_paf_get_properties(qc);
01111 cx_assert(qclog != NULL);
01112
01113
01114
01115
01116
01117
01118 pframe = giraffe_get_frame(set, GIFRAME_BIAS_MASTER,
01119 CPL_FRAME_GROUP_PRODUCT);
01120
01121 if (pframe == NULL) {
01122 cpl_msg_error(fctid, "Missing product frame (%s)",
01123 GIFRAME_BIAS_MASTER);
01124
01125 giraffe_paf_delete(qc);
01126 qc = NULL;
01127
01128 return 1;
01129 }
01130
01131 cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
01132 cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
01133
01134 mbias = giraffe_image_new(CPL_TYPE_DOUBLE);
01135 status = giraffe_image_load(mbias, cpl_frame_get_filename(pframe), 0);
01136
01137 if (status != 0) {
01138 cpl_msg_error(fctid, "Could not load master bias '%s'! Aborting ...",
01139 cpl_frame_get_filename(pframe));
01140
01141 giraffe_image_delete(mbias);
01142 mbias = NULL;
01143
01144 giraffe_paf_delete(qc);
01145 qc = NULL;
01146
01147 return 1;
01148 }
01149
01150
01151
01152
01153
01154
01155 rframe = cpl_frameset_find(set, GIFRAME_BIAS);
01156
01157 if (rframe == NULL) {
01158 cpl_msg_error(fctid, "Missing raw frame (%s)", GIFRAME_BIAS);
01159
01160 giraffe_image_delete(mbias);
01161 mbias = NULL;
01162
01163 giraffe_paf_delete(qc);
01164 qc = NULL;
01165
01166 return 1;
01167 }
01168
01169 bias = giraffe_image_new(CPL_TYPE_DOUBLE);
01170 status = giraffe_image_load(bias, cpl_frame_get_filename(rframe), 0);
01171
01172 if (status != 0) {
01173 cpl_msg_error(fctid, "Could not load bias '%s'!",
01174 cpl_frame_get_filename(rframe));
01175
01176 giraffe_image_delete(bias);
01177 bias = NULL;
01178
01179 giraffe_image_delete(mbias);
01180 mbias = NULL;
01181
01182 giraffe_paf_delete(qc);
01183 qc = NULL;
01184
01185 return 1;
01186
01187 }
01188
01189 properties = giraffe_image_get_properties(bias);
01190 cx_assert(properties != NULL);
01191
01192 giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
01193 giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
01194
01195 cpl_propertylist_update_string(qclog, "PRO.CATG",
01196 cpl_frame_get_tag(pframe));
01197 cpl_propertylist_set_comment(qclog, "PRO.CATG",
01198 "Pipeline product category");
01199
01200 properties = giraffe_image_get_properties(mbias);
01201 cx_assert(properties != NULL);
01202
01203 giraffe_propertylist_copy(qclog, "PRO.DATAAVG",
01204 properties, GIALIAS_DATAMEAN);
01205 giraffe_propertylist_copy(qclog, "PRO.DATARMS",
01206 properties, GIALIAS_DATASIG);
01207 giraffe_propertylist_copy(qclog, "PRO.DATAMED",
01208 properties, GIALIAS_DATAMEDI);
01209 giraffe_propertylist_copy(qclog, "PRO.DATANCOM",
01210 properties, GIALIAS_DATANCOM);
01211
01212
01213
01214
01215
01216
01217 _mbias = giraffe_image_get(mbias);
01218 _mbdata = cpl_image_get_data(_mbias);
01219
01220 nx = cpl_image_get_size_x(_mbias);
01221 ny = cpl_image_get_size_y(_mbias);
01222
01223 nvalid = 0;
01224
01225 for (i = 0; i < nx * ny; i++) {
01226
01227 if (_mbdata[i] >= low && _mbdata[i] < high) {
01228 ++nvalid;
01229 }
01230
01231 }
01232
01233 _test = cpl_image_new(nvalid, 1, CPL_TYPE_DOUBLE);
01234 _tdata = cpl_image_get_data(_test);
01235
01236 j = 0;
01237
01238 for (i = 0; i < nx * ny; i++) {
01239
01240 if (_mbdata[i] >= low && _mbdata[i] < high) {
01241 _tdata[j++] = _mbdata[i];
01242 }
01243
01244 }
01245
01246 cpl_propertylist_update_double(properties, GIALIAS_QCMBIASMED,
01247 cpl_image_get_median(_test));
01248 cpl_propertylist_set_comment(properties, GIALIAS_QCMBIASMED,
01249 "Median master bias level (ADU)");
01250
01251 cpl_propertylist_update_double(properties, GIALIAS_QCMBIASAVG,
01252 cpl_image_get_mean(_test));
01253 cpl_propertylist_set_comment(properties, GIALIAS_QCMBIASAVG,
01254 "Mean master bias level (ADU)");
01255
01256 cpl_propertylist_update_double(properties, GIALIAS_QCMBIASRMS,
01257 cpl_image_get_stdev(_test));
01258 cpl_propertylist_set_comment(properties, GIALIAS_QCMBIASRMS,
01259 "RMS of master bias level (ADU)");
01260
01261 cpl_image_delete(_test);
01262 _test = NULL;
01263
01264 giraffe_propertylist_copy(qclog, "QC.BIAS.MASTER.MEDIAN",
01265 properties, GIALIAS_QCMBIASMED);
01266 giraffe_propertylist_copy(qclog, "QC.BIAS.MASTER.MEAN",
01267 properties, GIALIAS_QCMBIASAVG);
01268 giraffe_propertylist_copy(qclog, "QC.BIAS.MASTER.RMS",
01269 properties, GIALIAS_QCMBIASRMS);
01270
01271
01272
01273
01274
01275
01276
01277 if (cpl_frameset_count_tags(set, GIFRAME_BIAS) > 1) {
01278
01279 cpl_frame* _frame = NULL;
01280
01281 cpl_image* diff = NULL;
01282
01283 GiImage* _bias;
01284
01285
01286 nsigma = 5;
01287 memset(sigma, 0, nsigma * sizeof(cxdouble));
01288
01289 _frame = cpl_frameset_find(set, GIFRAME_BIAS);
01290 _frame = cpl_frameset_find(set, NULL);
01291
01292 _bias = giraffe_image_new(CPL_TYPE_DOUBLE);
01293 status = giraffe_image_load(_bias, cpl_frame_get_filename(_frame), 0);
01294
01295 if (status != 0) {
01296 cpl_msg_error(fctid, "Could not load bias '%s'! Aborting ...",
01297 cpl_frame_get_filename(_frame));
01298
01299 giraffe_image_delete(_bias);
01300 _bias = NULL;
01301
01302 giraffe_image_delete(mbias);
01303 mbias = NULL;
01304
01305 giraffe_image_delete(bias);
01306 bias = NULL;
01307
01308 giraffe_paf_delete(qc);
01309 qc = NULL;
01310
01311 return 1;
01312 }
01313
01314 diff = cpl_image_duplicate(giraffe_image_get(bias));
01315
01316 if (diff == NULL) {
01317 cpl_msg_error(fctid, "Cannot compute bias difference image! "
01318 "Aborting ...");
01319
01320 giraffe_image_delete(_bias);
01321 _bias = NULL;
01322
01323 giraffe_image_delete(mbias);
01324 mbias = NULL;
01325
01326 giraffe_image_delete(bias);
01327 bias = NULL;
01328
01329 giraffe_paf_delete(qc);
01330 qc = NULL;
01331
01332 return 1;
01333 }
01334
01335 cpl_image_subtract(diff, giraffe_image_get(_bias));
01336
01337 giraffe_image_delete(_bias);
01338
01339
01340 i = 0;
01341
01342
01343
01344 w.x0 = wstart;
01345 w.y0 = wstart;
01346 w.x1 = w.x0 + wsize;
01347 w.y1 = w.y0 + wsize;
01348
01349 giraffe_error_push();
01350
01351 sigma[i++] = cpl_image_get_stdev_window(diff, w.x0, w.y0, w.x1, w.y1);
01352
01353 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01354 --nsigma;
01355 }
01356
01357 giraffe_error_pop();
01358
01359
01360
01361
01362 w.x0 = cpl_image_get_size_x(diff) - wstart - wsize;
01363 w.x1 = w.x0 + wsize;
01364
01365 giraffe_error_push();
01366
01367 sigma[i++] = cpl_image_get_stdev_window(diff, w.x0, w.y0, w.x1, w.y1);
01368
01369 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01370 --nsigma;
01371 }
01372
01373 giraffe_error_pop();
01374
01375
01376
01377
01378 w.y0 = cpl_image_get_size_y(diff) - wstart - wsize;
01379 w.y1 = w.y0 + wsize;
01380
01381 giraffe_error_push();
01382
01383 sigma[i++] = cpl_image_get_stdev_window(diff, w.x0, w.y0, w.x1, w.y1);
01384
01385 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01386 --nsigma;
01387 }
01388
01389 giraffe_error_pop();
01390
01391
01392
01393
01394 w.x0 = wstart;
01395 w.x1 = w.x0 + wsize;
01396
01397 giraffe_error_push();
01398
01399 sigma[i++] = cpl_image_get_stdev_window(diff, w.x0, w.y0, w.x1, w.y1);
01400
01401 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01402 --nsigma;
01403 }
01404
01405 giraffe_error_pop();
01406
01407
01408
01409
01410 w.x0 = 1024;
01411 w.y0 = 1998;
01412 w.x1 = 1124;
01413 w.y1 = 2098;
01414
01415 giraffe_error_push();
01416
01417 sigma[i++] = cpl_image_get_stdev_window(diff, w.x0, w.y0, w.x1, w.y1);
01418
01419 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01420 --nsigma;
01421 }
01422
01423 giraffe_error_pop();
01424
01425
01426 for (i = 0; i < nsigma; i++) {
01427 sigma[i] /= sqrt(2.);
01428 }
01429
01430 if (nsigma < 1) {
01431 cpl_msg_error(fctid, "Could not compute image statistics in any "
01432 "window! Aborting ...");
01433
01434 cpl_image_delete(diff);
01435 diff = NULL;
01436
01437 giraffe_image_delete(mbias);
01438 mbias = NULL;
01439
01440 giraffe_image_delete(bias);
01441 bias = NULL;
01442
01443 giraffe_paf_delete(qc);
01444 qc = NULL;
01445
01446 return 1;
01447 }
01448
01449
01450 _sigma = cpl_vector_wrap(nsigma, sigma);
01451
01452 median = cpl_vector_get_median(_sigma);
01453
01454 cpl_vector_unwrap(_sigma);
01455 _sigma = NULL;
01456
01457 cpl_image_delete(diff);
01458 diff = NULL;
01459
01460
01461 cpl_propertylist_update_double(properties, GIALIAS_QCRON, median);
01462 cpl_propertylist_set_comment(properties, GIALIAS_QCRON,
01463 "Readout noise (raw)");
01464
01465 giraffe_propertylist_copy(qclog, "QC.OUT1.RON.RAW", properties,
01466 GIALIAS_QCRON);
01467 }
01468
01469 giraffe_image_delete(bias);
01470 bias = NULL;
01471
01472
01473
01474
01475
01476
01477 k = 0;
01478 nsigma = 5;
01479 memset(sigma, 0, nsigma * sizeof(cxdouble));
01480
01481
01482
01483
01484 w.x0 = wstart;
01485 w.y0 = wstart;
01486 w.x1 = w.x0 + wsize;
01487 w.y1 = w.y0 + wsize;
01488
01489 _smbias = cpl_image_extract(_mbias, w.x0, w.y0, w.x1, w.y1);
01490 _mbdata = cpl_image_get_data(_smbias);
01491
01492 nvalid = 0;
01493
01494 for (i = 0; i < wsize * wsize; i++) {
01495
01496 if (_mbdata[i] >= low && _mbdata[i] < high) {
01497 ++nvalid;
01498 }
01499
01500 }
01501
01502 _test = cpl_image_new(nvalid, 1, CPL_TYPE_DOUBLE);
01503 _tdata = cpl_image_get_data(_test);
01504
01505 j = 0;
01506
01507 for (i = 0; i < wsize * wsize; i++) {
01508
01509 if (_mbdata[i] >= low && _mbdata[i] < high) {
01510 _tdata[j++] = _mbdata[i];
01511 }
01512
01513 }
01514
01515 giraffe_error_push();
01516
01517 sigma[k++] = cpl_image_get_stdev(_test);
01518
01519 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01520 --nsigma;
01521 }
01522
01523 giraffe_error_pop();
01524
01525 cpl_image_delete(_smbias);
01526 _smbias = NULL;
01527
01528 cpl_image_delete(_test);
01529 _test = NULL;
01530
01531
01532
01533 w.x0 = cpl_image_get_size_x(_mbias) - wstart - wsize;
01534 w.x1 = w.x0 + wsize;
01535
01536 _smbias = cpl_image_extract(_mbias, w.x0, w.y0, w.x1, w.y1);
01537 _mbdata = cpl_image_get_data(_smbias);
01538
01539 nvalid = 0;
01540
01541 for (i = 0; i < wsize * wsize; i++) {
01542
01543 if (_mbdata[i] >= low && _mbdata[i] < high) {
01544 ++nvalid;
01545 }
01546
01547 }
01548
01549 _test = cpl_image_new(nvalid, 1, CPL_TYPE_DOUBLE);
01550 _tdata = cpl_image_get_data(_test);
01551
01552 j = 0;
01553
01554 for (i = 0; i < wsize * wsize; i++) {
01555
01556 if (_mbdata[i] >= low && _mbdata[i] < high) {
01557 _tdata[j++] = _mbdata[i];
01558 }
01559
01560 }
01561
01562 giraffe_error_push();
01563
01564 sigma[k++] = cpl_image_get_stdev(_test);
01565
01566 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01567 --nsigma;
01568 }
01569
01570 giraffe_error_pop();
01571
01572 cpl_image_delete(_smbias);
01573 _smbias = NULL;
01574
01575 cpl_image_delete(_test);
01576 _test = NULL;
01577
01578
01579
01580 w.y0 = cpl_image_get_size_y(_mbias) - wstart - wsize;
01581 w.y1 = w.y0 + wsize;
01582
01583 _smbias = cpl_image_extract(_mbias, w.x0, w.y0, w.x1, w.y1);
01584 _mbdata = cpl_image_get_data(_smbias);
01585
01586 nvalid = 0;
01587
01588 for (i = 0; i < wsize * wsize; i++) {
01589
01590 if (_mbdata[i] >= low && _mbdata[i] < high) {
01591 ++nvalid;
01592 }
01593
01594 }
01595
01596 _test = cpl_image_new(nvalid, 1, CPL_TYPE_DOUBLE);
01597 _tdata = cpl_image_get_data(_test);
01598
01599 j = 0;
01600
01601 for (i = 0; i < wsize * wsize; i++) {
01602
01603 if (_mbdata[i] >= low && _mbdata[i] < high) {
01604 _tdata[j++] = _mbdata[i];
01605 }
01606
01607 }
01608
01609 giraffe_error_push();
01610
01611 sigma[k++] = cpl_image_get_stdev(_test);
01612
01613 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01614 --nsigma;
01615 }
01616
01617 giraffe_error_pop();
01618
01619 cpl_image_delete(_smbias);
01620 _smbias = NULL;
01621
01622 cpl_image_delete(_test);
01623 _test = NULL;
01624
01625
01626
01627 w.x0 = wstart;
01628 w.x1 = w.x0 + wsize;
01629
01630 _smbias = cpl_image_extract(_mbias, w.x0, w.y0, w.x1, w.y1);
01631 _mbdata = cpl_image_get_data(_smbias);
01632
01633 nvalid = 0;
01634
01635 for (i = 0; i < wsize * wsize; i++) {
01636
01637 if (_mbdata[i] >= low && _mbdata[i] < high) {
01638 ++nvalid;
01639 }
01640
01641 }
01642
01643 _test = cpl_image_new(nvalid, 1, CPL_TYPE_DOUBLE);
01644 _tdata = cpl_image_get_data(_test);
01645
01646 j = 0;
01647
01648 for (i = 0; i < wsize * wsize; i++) {
01649
01650 if (_mbdata[i] >= low && _mbdata[i] < high) {
01651 _tdata[j++] = _mbdata[i];
01652 }
01653
01654 }
01655
01656 giraffe_error_push();
01657
01658 sigma[k++] = cpl_image_get_stdev(_test);
01659
01660 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01661 --nsigma;
01662 }
01663
01664 giraffe_error_pop();
01665
01666 cpl_image_delete(_smbias);
01667 _smbias = NULL;
01668
01669 cpl_image_delete(_test);
01670 _test = NULL;
01671
01672
01673
01674 w.x0 = 1024;
01675 w.y0 = 1998;
01676 w.x1 = 1124;
01677 w.y1 = 2098;
01678
01679 _smbias = cpl_image_extract(_mbias, w.x0, w.y0, w.x1, w.y1);
01680 _mbdata = cpl_image_get_data(_smbias);
01681
01682 nvalid = 0;
01683
01684 for (i = 0; i < wsize * wsize; i++) {
01685
01686 if (_mbdata[i] >= low && _mbdata[i] < high) {
01687 ++nvalid;
01688 }
01689
01690 }
01691
01692 _test = cpl_image_new(nvalid, 1, CPL_TYPE_DOUBLE);
01693 _tdata = cpl_image_get_data(_test);
01694
01695 j = 0;
01696
01697 for (i = 0; i < wsize * wsize; i++) {
01698
01699 if (_mbdata[i] >= low && _mbdata[i] < high) {
01700 _tdata[j++] = _mbdata[i];
01701 }
01702
01703 }
01704
01705 giraffe_error_push();
01706
01707 sigma[k++] = cpl_image_get_stdev(_test);
01708
01709 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01710 --nsigma;
01711 }
01712
01713 giraffe_error_pop();
01714
01715 cpl_image_delete(_smbias);
01716 _smbias = NULL;
01717
01718 cpl_image_delete(_test);
01719 _test = NULL;
01720
01721 if (nsigma < 1) {
01722 cpl_msg_error(fctid, "Could not compute image statistics in any "
01723 "window! Aborting ...");
01724
01725 giraffe_image_delete(mbias);
01726 mbias = NULL;
01727
01728 giraffe_paf_delete(qc);
01729 qc = NULL;
01730
01731 return 1;
01732 }
01733
01734 _sigma = cpl_vector_wrap(nsigma, sigma);
01735
01736 median = cpl_vector_get_median(_sigma);
01737
01738 cpl_vector_unwrap(_sigma);
01739 _sigma = NULL;
01740
01741 cpl_propertylist_update_double(properties, GIALIAS_QCMRON, median);
01742 cpl_propertylist_set_comment(properties, GIALIAS_QCMRON, "Readout noise "
01743 "(master)");
01744
01745 giraffe_propertylist_copy(qclog, "QC.OUT1.RON.MASTER", properties,
01746 GIALIAS_QCMRON);
01747
01748
01749
01750
01751
01752
01753 _test = cpl_image_collapse_create(_mbias, 0);
01754 cpl_image_divide_scalar(_test, cpl_image_get_size_y(_mbias));
01755
01756 mean = cpl_image_get_mean(_test);
01757
01758
01759
01760
01761
01762
01763 nvalid = 0;
01764 sum = 0.;
01765
01766 _tdata = cpl_image_get_data(_test);
01767
01768 for (i = 0; i < cpl_image_get_size_x(_test); i++) {
01769
01770 if ((_tdata[i] > mean - sthreshold) &&
01771 (_tdata[i] < mean + sthreshold)) {
01772 sum += _tdata[i];
01773 ++nvalid;
01774 }
01775
01776 }
01777
01778 smean = sum / nvalid;
01779
01780
01781
01782
01783
01784
01785 nvalid = 0;
01786 sum = 0.;
01787
01788 for (i = 0; i < cpl_image_get_size_x(_test); i++) {
01789
01790 if ((_tdata[i] > mean - sthreshold) &&
01791 (_tdata[i] < mean + sthreshold)) {
01792 sum += pow(_tdata[i] - smean, 2.);
01793 ++nvalid;
01794 }
01795
01796 }
01797
01798 sum = sqrt(sum / (nvalid - 1));
01799
01800 cpl_propertylist_update_double(properties, GIALIAS_QCSTRUCTX, sum);
01801 cpl_propertylist_set_comment(properties, GIALIAS_QCSTRUCTX,
01802 "Structure along the x axis");
01803
01804 giraffe_propertylist_copy(qclog, "QC.OUT1.STRUCT.X", properties,
01805 GIALIAS_QCSTRUCTX);
01806
01807 cpl_image_delete(_test);
01808 _test = NULL;
01809
01810
01811 _test = cpl_image_collapse_create(_mbias, 1);
01812 cpl_image_divide_scalar(_test, cpl_image_get_size_x(_mbias));
01813
01814 mean = cpl_image_get_mean(_test);
01815
01816
01817
01818
01819
01820
01821 nvalid = 0;
01822 sum = 0.;
01823
01824 _tdata = cpl_image_get_data(_test);
01825
01826 for (i = 0; i < cpl_image_get_size_y(_test); i++) {
01827
01828 if ((_tdata[i] > mean - sthreshold) &&
01829 (_tdata[i] < mean + sthreshold)) {
01830 sum += _tdata[i];
01831 ++nvalid;
01832 }
01833
01834 }
01835
01836 smean = sum / nvalid;
01837
01838
01839
01840
01841
01842
01843 nvalid = 0;
01844 sum = 0.;
01845
01846 _tdata = cpl_image_get_data(_test);
01847
01848 for (i = 0; i < cpl_image_get_size_y(_test); i++) {
01849
01850 if ((_tdata[i] > mean - sthreshold) &&
01851 (_tdata[i] < mean + sthreshold)) {
01852 sum += pow(_tdata[i] - smean, 2.);
01853 ++nvalid;
01854 }
01855
01856 }
01857
01858 sum = sqrt(sum / (nvalid - 1));
01859
01860 cpl_propertylist_update_double(properties, GIALIAS_QCSTRUCTY, sum);
01861 cpl_propertylist_set_comment(properties, GIALIAS_QCSTRUCTY,
01862 "Structure along the y axis");
01863
01864 giraffe_propertylist_copy(qclog, "QC.OUT1.STRUCT.Y", properties,
01865 GIALIAS_QCSTRUCTY);
01866
01867 cpl_image_delete(_test);
01868 _test = NULL;
01869
01870
01871
01872
01873
01874
01875 giraffe_image_save(mbias, cpl_frame_get_filename(pframe));
01876
01877 giraffe_image_delete(mbias);
01878 mbias = NULL;
01879
01880 giraffe_qclog_close(qc);
01881 qc = NULL;
01882
01883 return 0;
01884
01885 }
01886
01887
01888
01889
01890
01891
01892
01893 int
01894 cpl_plugin_get_info(cpl_pluginlist* list)
01895 {
01896
01897 cpl_recipe* recipe = cx_calloc(1, sizeof *recipe);
01898 cpl_plugin* plugin = &recipe->interface;
01899
01900
01901 cpl_plugin_init(plugin,
01902 CPL_PLUGIN_API,
01903 GIRAFFE_BINARY_VERSION,
01904 CPL_PLUGIN_TYPE_RECIPE,
01905 "gimasterbias",
01906 "Creates a master bias image from a set of raw biases.",
01907 "For detailed information please refer to the "
01908 "GIRAFFE pipeline user manual.\nIt is available at "
01909 "http://www.eso.org/pipelines.",
01910 "Giraffe Pipeline",
01911 PACKAGE_BUGREPORT,
01912 giraffe_get_license(),
01913 gimasterbias_create,
01914 gimasterbias_exec,
01915 gimasterbias_destroy);
01916
01917 cpl_pluginlist_append(list, plugin);
01918
01919 return 0;
01920
01921 }