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