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 #ifdef HAVE_CONFIG_H
00027 #include <config.h>
00028 #endif
00029
00030
00038
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include <xsh_error.h>
00050
00051 #include <xsh_utils.h>
00052 #include <xsh_utils_image.h>
00053 #include <xsh_msg.h>
00054
00055 #include <xsh_dfs.h>
00056
00057 #include <xsh_drl.h>
00058
00059 #include <xsh_pfits.h>
00060
00061 #include <cpl.h>
00062
00063 #include <xsh_drl_check.h>
00064 #include <xsh_model_arm_constants.h>
00065 #include <xsh_badpixelmap.h>
00066
00067
00068
00069
00070
00071 #define RECIPE_ID "xsh_mdark"
00072 #define RECIPE_AUTHOR "P.Goldoni, L.Guglielmi, R. Haigron, F. Royer, D. Bramich, A. Modigliani"
00073 #define RECIPE_CONTACT "amodigli@eso.org"
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 static int xsh_mdark_create(cpl_plugin *);
00084 static int xsh_mdark_exec(cpl_plugin *);
00085 static int xsh_mdark_destroy(cpl_plugin *);
00086
00087
00088 static void xsh_mdark(cpl_parameterlist *, cpl_frameset *);
00089
00090
00091
00092
00093 static char xsh_mdark_description_short[] =
00094 "Create the master dark frame";
00095
00096 static char xsh_mdark_description[] =
00097 "This recipe creates a master dark frame\n\
00098 Input Frames : \n\
00099 - A set of n RAW frames (Format=RAW, n >=3, Tag = DARK_arm)\n\
00100 - [UVB,VIS] A master bias frame (Format=PRE, Tag = MASTER_BIAS_arm)\n\
00101 - [OPTIONAL] A map of non linear bad pixels (Format=QUP, Tag = BP_MAP_NL_arm)\n\
00102 - [OPTIONAL] A map of reference bad pixels (Format = QUP,RAW, Tag = BP_MAP_RP_arm)\n\
00103 Products : \n\
00104 - A master dark frame (Format=PRE, PRO.CATG = MASTER_DARK_arm)\n\
00105 A dark frame, (Format=PRE, PRO.CATG = DARK_arm)\n";
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00126
00127
00128 int cpl_plugin_get_info(cpl_pluginlist *list) {
00129 cpl_recipe *recipe = NULL;
00130 cpl_plugin *plugin = NULL;
00131
00132 recipe = cpl_calloc(1, sizeof(*recipe));
00133 if ( recipe == NULL ){
00134 return -1;
00135 }
00136
00137 plugin = &recipe->interface ;
00138
00139 cpl_plugin_init(plugin,
00140 CPL_PLUGIN_API,
00141 XSH_BINARY_VERSION,
00142 CPL_PLUGIN_TYPE_RECIPE,
00143 RECIPE_ID,
00144 xsh_mdark_description_short,
00145 xsh_mdark_description,
00146 RECIPE_AUTHOR,
00147 RECIPE_CONTACT,
00148 xsh_get_license(),
00149 xsh_mdark_create,
00150 xsh_mdark_exec,
00151 xsh_mdark_destroy);
00152
00153 cpl_pluginlist_append(list, plugin);
00154
00155 return (cpl_error_get_code() != CPL_ERROR_NONE);
00156 }
00157
00158
00168
00169
00170 static int xsh_mdark_create(cpl_plugin *plugin){
00171 cpl_recipe *recipe = NULL;
00172 xsh_clipping_param crh_clip_param = {-1.0, 3, 0.7, 0, 0.3};
00173 xsh_clipping_param noise_clip_param = {9.0, 5, 0.7, 0, 0.3};
00174 xsh_fpn_param fpn_param = {-1,-1,-1,-1,2,1000};
00175 xsh_ref_param ref_param = {-1,-1,-1,-1};
00176 xsh_ron_dark_param ron_param = {-1,-1,-1,-1,4,100};
00177 xsh_stack_param stack_param = {"median",5.,5.};
00178 int ival=DECODE_BP_FLAG_DEF;
00179
00180 xsh_init();
00181
00182
00183 assure( plugin != NULL, CPL_ERROR_NULL_INPUT, "Null plugin");
00184
00185
00186 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
00187 CPL_ERROR_TYPE_MISMATCH,
00188 "Plugin is not a recipe");
00189
00190 recipe = (cpl_recipe *)plugin;
00191
00192
00193 recipe->parameters = cpl_parameterlist_new();
00194 assure( recipe->parameters != NULL,
00195 CPL_ERROR_ILLEGAL_OUTPUT,
00196 "Memory allocation failed!");
00197
00198
00199 check( xsh_parameters_generic( RECIPE_ID, recipe->parameters ) ) ;
00200 xsh_parameters_decode_bp(RECIPE_ID,recipe->parameters,ival);
00201 check( xsh_parameters_pre_overscan( RECIPE_ID, recipe->parameters ) ) ;
00202 check(xsh_parameters_stack_create(RECIPE_ID,recipe->parameters,stack_param));
00203
00204
00205 check(xsh_parameters_new_boolean( recipe->parameters, RECIPE_ID,
00206 "bp-output", false,
00207 "Flag indicating whether the noise bad pixel map is to be computed"));
00208
00209
00210 check(xsh_parameters_clipping_crh_create(RECIPE_ID,recipe->parameters,
00211 crh_clip_param));
00212
00213
00214 check(xsh_parameters_clipping_noise_create(RECIPE_ID,
00215 recipe->parameters,
00216 noise_clip_param));
00217
00218 check(xsh_parameters_new_double( recipe->parameters,RECIPE_ID,
00219 "noise-lower-rejection", 10.,
00220 "Lower rejection percentile to flag bad pixels via noise"));
00221
00222 check(xsh_parameters_new_double( recipe->parameters, RECIPE_ID,
00223 "noise-higher-rejection", 10.,
00224 "Upper rejection percentile to flag bad pixels via noise"));
00225
00226
00227 check(xsh_parameters_ref1_create(RECIPE_ID,recipe->parameters,
00228 ref_param));
00229
00230
00231 check(xsh_parameters_ron_dark_create(RECIPE_ID,recipe->parameters,
00232 ron_param));
00233
00234 check(xsh_parameters_fpn_create(RECIPE_ID,recipe->parameters,
00235 fpn_param));
00236
00237
00238
00239 cleanup:
00240 if ( cpl_error_get_code() != CPL_ERROR_NONE ){
00241 xsh_error_dump(CPL_MSG_ERROR);
00242 return 1;
00243 }
00244 else {
00245 return 0;
00246 }
00247 }
00248
00249
00255
00256
00257 static int xsh_mdark_exec(cpl_plugin *plugin) {
00258 cpl_recipe *recipe = NULL;
00259
00260
00261
00262 assure( plugin != NULL, CPL_ERROR_NULL_INPUT, "Null plugin" );
00263
00264
00265 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
00266 CPL_ERROR_TYPE_MISMATCH, "Plugin is not a recipe");
00267
00268 recipe = (cpl_recipe *)plugin;
00269
00270
00271 xsh_mdark(recipe->parameters, recipe->frames);
00272
00273 cleanup:
00274 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
00275 xsh_error_dump(CPL_MSG_ERROR);
00276 xsh_error_reset();
00277 return 1;
00278 }
00279 else {
00280 return 0;
00281 }
00282 }
00283
00284
00290
00291 static int xsh_mdark_destroy(cpl_plugin *plugin)
00292 {
00293 cpl_recipe *recipe = NULL;
00294
00295
00296 xsh_error_reset();
00297
00298 assure( plugin != NULL, CPL_ERROR_NULL_INPUT, "Null plugin" );
00299
00300
00301 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
00302 CPL_ERROR_TYPE_MISMATCH, "Plugin is not a recipe");
00303 recipe = (cpl_recipe *)plugin;
00304
00305 xsh_free_parameterlist(&recipe->parameters);
00306
00307 cleanup:
00308 if (cpl_error_get_code() != CPL_ERROR_NONE)
00309 {
00310 return 1;
00311 }
00312 else
00313 {
00314 return 0;
00315 }
00316 }
00317
00318 static cpl_error_code
00319 xsh_params_set_defaults(cpl_parameterlist* pars,
00320 xsh_instrument* inst)
00321 {
00322 cpl_parameter* p=NULL;
00323
00324 check(p=xsh_parameters_find(pars,RECIPE_ID,"crh-clip-kappa"));
00325 if(cpl_parameter_get_double(p) <= 0) {
00326 if (xsh_instrument_get_arm(inst) == XSH_ARM_NIR){
00327 cpl_parameter_set_double(p,11.);
00328 } else {
00329 cpl_parameter_set_double(p,9.);
00330 }
00331 }
00332
00333 cleanup:
00334
00335 return cpl_error_get_code();
00336
00337 }
00338
00339
00340
00341 static cpl_frame*
00342 xsh_get_master_dark_nir_via_noise(cpl_imagelist* dataList, cpl_frame* medFrame,
00343 cpl_parameterlist* parameters, xsh_clipping_param* noise_clipping,
00344 xsh_instrument* instrument,cpl_frame** noisyFrame) {
00345 cpl_frame* nirFrame = NULL;
00346
00347 cpl_parameter* p = NULL;
00348 int llx = 0;
00349 int lly = 0;
00350 int urx = 0;
00351 int ury = 0;
00352 int iter = 0;
00353 int low_rej = 0;
00354 int high_rej = 0;
00355 cpl_image* noise_image = NULL;
00356 cpl_mask* bp_map_noise = NULL;
00357 cpl_propertylist* plist = NULL;
00358 const char* bp_map_noise_pro_catg = NULL;
00359 char bp_map_noise_name[256];
00360
00361
00362 xsh_msg_dbg_low(
00363 "Noise parameters: Sigma %lf, Niteration %d, \
00364 Fraction %lf, Diff %lf", noise_clipping->sigma, noise_clipping->niter, noise_clipping->frac, noise_clipping->diff);
00365
00366 nirFrame = xsh_compute_noise_map(dataList, medFrame, noise_clipping,
00367 instrument,noisyFrame);
00368
00369
00370 p = cpl_parameterlist_find(parameters, "xsh.xsh_mdark.ref1_llx");
00371 llx = cpl_parameter_get_int(p);
00372 p = cpl_parameterlist_find(parameters, "xsh.xsh_mdark.ref1_lly");
00373 lly = cpl_parameter_get_int(p);
00374 p = cpl_parameterlist_find(parameters, "xsh.xsh_mdark.ref1_urx");
00375 urx = cpl_parameter_get_int(p);
00376 p = cpl_parameterlist_find(parameters, "xsh.xsh_mdark.ref1_ury");
00377 ury = cpl_parameter_get_int(p);
00378 p = cpl_parameterlist_find(parameters, "xsh.xsh_mdark.noise-clip-niter");
00379 iter = cpl_parameter_get_int(p);
00380 p = cpl_parameterlist_find(parameters, "xsh.xsh_mdark.noise-lower-rejection");
00381 low_rej = cpl_parameter_get_double(p);
00382 p = cpl_parameterlist_find(parameters, "xsh.xsh_mdark.noise-higher-rejection");
00383 high_rej = cpl_parameter_get_double(p);
00384
00385 noise_image = xsh_image_search_bad_pixels_via_noise(dataList, iter, low_rej,
00386 high_rej, llx, lly, urx, ury);
00387 bp_map_noise = cpl_mask_threshold_image_create(noise_image,
00388 QFLAG_HOT_PIXEL - 1, QFLAG_HOT_PIXEL + 1);
00389 xsh_free_image(&noise_image);
00390 noise_image = cpl_image_new_from_mask(bp_map_noise);
00391 cpl_mask_not(bp_map_noise);
00392 xsh_bpmap_mask_bad_pixel(noise_image, bp_map_noise, QFLAG_HOT_PIXEL);
00393
00394
00395
00396 cpl_image_threshold(noise_image, 1.1, DBL_MAX, 0, DBL_MAX);
00397
00398 plist = cpl_propertylist_new();
00399 bp_map_noise_pro_catg = XSH_GET_TAG_FROM_ARM(XSH_BP_MAP_NP, instrument);
00400 sprintf(bp_map_noise_name, "%s.fits", bp_map_noise_pro_catg);
00401 xsh_pfits_set_pcatg(plist, bp_map_noise_pro_catg);
00402 check(cpl_image_save(noise_image,bp_map_noise_name,CPL_BPP_IEEE_FLOAT, plist,CPL_IO_DEFAULT));
00403 xsh_add_temporary_file(bp_map_noise_name);
00404
00405
00406 cleanup:
00407 xsh_free_mask(&bp_map_noise);
00408 xsh_free_propertylist(&plist);
00409 xsh_free_image(&noise_image);
00410 return nirFrame;
00411
00412 }
00413
00414 static cpl_frame*
00415 xsh_get_master_dark_opt(cpl_frame* medFrame, cpl_frame* master_bias,
00416 cpl_parameterlist* parameters,
00417 cpl_frame* crh_frm, cpl_frame* bp_map_noise_frm, xsh_instrument* instrument,
00418 const int pre_overscan_corr) {
00419 cpl_frame* resFrame = NULL;
00420 cpl_frame* rmbias = NULL;
00421 if (master_bias != NULL) {
00422 xsh_msg("Subtract bias");
00423 check(
00424 rmbias = xsh_subtract_bias(medFrame,master_bias,instrument,"DARK_",pre_overscan_corr,0));
00425
00426 xsh_msg( "Generates master dark");
00427 check_msg(
00428 resFrame=xsh_create_master_dark(rmbias, instrument,parameters, crh_frm,bp_map_noise_frm),
00429 "Error in create master dark");
00430 } else {
00431 check(resFrame=cpl_frame_duplicate(medFrame));
00432 }
00433
00434 cleanup:
00435
00436 return resFrame;
00437 }
00438
00439 static cpl_frame*
00440 xsh_get_crh_frame(cpl_image* crh_ima, xsh_instrument* instrument) {
00441 char* crh_name = NULL;
00442 char* crh_pro_catg = NULL;
00443 cpl_frame* crh_frm = NULL;
00444 char *prefix = NULL;
00445
00446 crh_name = cpl_sprintf("%s_%s.fits", XSH_CRH_MAP,
00447 xsh_instrument_arm_tostring(instrument));
00448
00449 if (crh_ima != NULL) {
00450
00451 crh_pro_catg = XSH_GET_TAG_FROM_ARM(XSH_CRH_MAP,instrument);
00452 crh_frm = xsh_frame_product(crh_name, crh_pro_catg, CPL_FRAME_TYPE_IMAGE,
00453 CPL_FRAME_GROUP_PRODUCT, CPL_FRAME_LEVEL_FINAL);
00454
00455 XSH_PREFIX(prefix, "CRH_MAP", instrument);
00456 cpl_image_save(crh_ima, crh_name, CPL_BPP_32_SIGNED, NULL, CPL_IO_DEFAULT);
00457 xsh_add_temporary_file(crh_name);
00458
00459 }
00460 cleanup:
00461 XSH_FREE(crh_name);
00462 XSH_FREE(prefix);
00463 return crh_frm;
00464 }
00465
00466
00467
00475
00476 static void xsh_mdark(cpl_parameterlist* parameters, cpl_frameset* frameset) {
00477
00478 const char* recipe_tags[1] = { XSH_DARK };
00479 int recipe_tags_size = 1;
00480
00481 cpl_frameset* raws = NULL;
00482 cpl_frameset* calib = NULL;
00483 cpl_frame* bpmap = NULL;
00484 cpl_frame* master_bias = NULL;
00485 cpl_frame* rmbias = NULL;
00486 xsh_instrument* instrument = NULL;
00487 xsh_clipping_param* crh_clipping = NULL;
00488 xsh_clipping_param* noise_clipping = NULL;
00489 cpl_imagelist * dataList = NULL;
00490
00491
00492 cpl_frame * medFrame = NULL;
00493 cpl_frame * nirFrame = NULL;
00494 cpl_frame * noisyFrame = NULL;
00495
00496
00497 cpl_frame * resFrame = NULL;
00498
00499 cpl_image* crh_ima = NULL;
00500 const int mode_or=1;
00501
00502 cpl_frame* crh_frm = NULL;
00503 xsh_pre* pre=NULL;
00504 char name[256];
00505
00506 cpl_propertylist* plist = NULL;
00507 char med_frame_tag[256];
00508
00509
00510 cpl_frame* dark_on = NULL;
00511 cpl_frame* dark_qc = NULL;
00512
00513 int pre_overscan_corr = 0;
00514 xsh_stack_param* stack_par = NULL;
00515
00516 char pcatg[256];
00517 cpl_propertylist* qc_log = NULL;
00518 int nraws;
00519 int sz=0;
00520
00521
00522
00523
00524 check( xsh_begin( frameset, parameters, &instrument, &raws, &calib,
00525 recipe_tags, recipe_tags_size,
00526 RECIPE_ID, XSH_BINARY_VERSION,
00527 xsh_mdark_description_short ) );
00528
00529 check(xsh_recipe_params_check(parameters,instrument,RECIPE_ID));
00530
00531
00532
00533
00534 XSH_ASSURE_NOT_ILLEGAL((nraws=cpl_frameset_get_size(raws)) >= 1);
00535 check(bpmap=xsh_check_load_master_bpmap(calib,instrument,RECIPE_ID));
00536
00537
00538
00539 if (xsh_instrument_get_arm(instrument) != XSH_ARM_NIR) {
00540 master_bias = xsh_find_frame_with_tag(calib, XSH_MASTER_BIAS,instrument);
00541 }
00542
00543 sprintf(med_frame_tag, "DARK_REMOVE_CRH_%s",
00544 xsh_instrument_arm_tostring(instrument));
00545
00546
00547
00548
00549 check(xsh_params_set_defaults(parameters,instrument));
00550 check(
00551 pre_overscan_corr = xsh_parameters_get_int( parameters, RECIPE_ID, "pre-overscan-corr"));
00552 stack_par = xsh_stack_frames_get(RECIPE_ID, parameters);
00553
00554 crh_clipping = xsh_parameters_clipping_crh_get(RECIPE_ID, parameters);
00555 noise_clipping = xsh_parameters_clipping_noise_get(RECIPE_ID, parameters);
00556
00557
00558
00559
00560
00561
00562 check(xsh_prepare(raws, bpmap, master_bias, XSH_DARK, instrument,pre_overscan_corr,CPL_TRUE));
00563
00564 check(xsh_frameset_check_uniform_exptime(raws,instrument));
00565
00566
00567 xsh_msg( "Calling xsh_remove_crh_multiple" );
00568 check_msg( medFrame = xsh_remove_crh_multiple( raws,med_frame_tag,stack_par,crh_clipping,
00569 instrument,&dataList,&crh_ima,1 ),"Error in xsh_remove_crh" );
00570
00571 check(crh_frm=xsh_get_crh_frame(crh_ima,instrument));
00572
00573
00574 if (xsh_instrument_get_arm(instrument) == XSH_ARM_NIR) {
00575 check(nirFrame=xsh_get_master_dark_nir_via_noise(dataList,medFrame,parameters,noise_clipping,instrument,&noisyFrame));
00576 xsh_msg( "Create master dark");
00577
00578 check_msg(
00579 resFrame=xsh_create_master_dark(nirFrame,instrument,parameters,crh_frm,bpmap ),
00580 "Error in create master dark");
00581 } else {
00582
00583 check(
00584 resFrame=xsh_get_master_dark_opt(medFrame,master_bias,parameters,crh_frm,bpmap, instrument,pre_overscan_corr));
00585 }
00586
00587
00588
00589
00590
00591 qc_log = xsh_frame_head_extract_qc(resFrame);
00592
00593
00594
00595
00596
00597 xsh_free_frame(&resFrame);
00598 check(resFrame=xsh_create_master_dark2(raws,stack_par,parameters,qc_log,instrument));
00599
00600
00601 if (xsh_instrument_get_arm(instrument) == XSH_ARM_NIR) {
00602
00603
00604 if(noisyFrame != NULL) {
00605 cpl_frame* frm=NULL;
00606 cpl_image* bpm=cpl_image_load(cpl_frame_get_filename(noisyFrame),
00607 CPL_TYPE_INT,0,0);
00608 pre=xsh_pre_load(resFrame,instrument);
00609 xsh_badpixelmap_image_coadd(&(pre->qual),bpm,mode_or);
00610 frm=xsh_pre_save( pre, cpl_frame_get_filename(resFrame),cpl_frame_get_tag(resFrame), 0);
00611 xsh_free_image(&bpm);
00612 xsh_pre_free(&pre);
00613 xsh_free_frame(&frm);
00614 }
00615 }
00616
00617 check(xsh_badpixelmap_fill_bp_pattern_holes(resFrame));
00618
00619 xsh_msg( "Save products" );
00620 check(xsh_add_product_image( resFrame, frameset, parameters,RECIPE_ID, instrument,NULL));
00621
00622
00623
00624
00625 dark_on = cpl_frameset_get_frame(raws, 0);
00626 sprintf(pcatg, "DARK_ON");
00627 sprintf(name, "%s.fits", pcatg);
00628 xsh_add_product_image(dark_on,frameset,parameters,RECIPE_ID,instrument,pcatg);
00629
00630
00631
00632 sz=cpl_frameset_get_size(raws);
00633 dark_qc = cpl_frameset_get_frame(raws, sz-1);
00634 sprintf(pcatg, "DARK_QC");
00635 sprintf(name, "%s.fits", pcatg);
00636 xsh_add_product_image(dark_qc,frameset,parameters,RECIPE_ID,instrument,pcatg);
00637
00638
00639 cleanup: xsh_end(RECIPE_ID, frameset, parameters);
00640 XSH_FREE(crh_clipping);
00641 XSH_FREE(noise_clipping);
00642 XSH_FREE(stack_par);
00643 xsh_instrument_free(&instrument);
00644 xsh_free_frameset(&raws);
00645 xsh_free_frameset(&calib);
00646
00647 xsh_free_imagelist(&dataList);
00648 xsh_free_frame(&medFrame);
00649 xsh_free_frame(&nirFrame);
00650 xsh_free_frame(&resFrame);
00651 xsh_free_frame(&rmbias);
00652 xsh_free_frame(&crh_frm);
00653 xsh_free_frame(&noisyFrame);
00654 xsh_free_image(&crh_ima);
00655 xsh_free_propertylist(&plist);
00656 xsh_free_propertylist(&qc_log);
00657
00658 return;
00659 }
00660