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
00033
00034
00035
00036 #include "omega_recipe.h"
00037
00038 #include "omega_background.h"
00039 #include "omega_bpm.h"
00040 #include "omega_flats.h"
00041 #include <cpl_errorstate.h>
00042
00072
00073
00074
00075
00076 static int omega_mflat_create(cpl_plugin *) ;
00077 static int omega_mflat_exec(cpl_plugin *) ;
00078 static int omega_mflat_destroy(cpl_plugin *) ;
00079 static int omega_mflat(cpl_frameset *,cpl_parameterlist *);
00080
00081
00082
00083
00084 int omega_mflat_combine(cpl_parameterlist *pars, int xn);
00085 static void omega_mflat_init(void);
00086 static void omega_mflat_tidy(void);
00087
00088
00089
00090
00091
00092 static struct {
00093
00094 int extnum;
00095 int oc;
00096 int paf;
00097 double sigma;
00098
00099
00100 int bpm;
00101 double Mean;
00102 double Median;
00103 double Stdev;
00104 double RawMin;
00105 double RawMax;
00106 double RawMean;
00107 double RawMedian;
00108 double RawStdev;
00109
00110 }omega_mflat_config;
00111
00112
00113 static struct {
00114
00115
00116 const cpl_frame *cframe;
00117 const cpl_frame *hframe;
00118 const cpl_frame *mbframe;
00119 const cpl_frame *mdomefr;
00120 const cpl_frame *nskyfr;
00121 const cpl_frame *bpframe;
00122 cpl_size *labels;
00123 cpl_frameset *flatlist;
00124 cpl_propertylist *eh;
00125 cpl_stats *stats;
00126 omega_fits *firstflat;
00127
00128
00129 cpl_image *bpixels;
00130 cpl_image *mflat;
00131 cpl_image *mtwilight;
00132
00133 }ps;
00134
00135
00136
00137
00138
00139
00140 #define RECIPE "omega_mflat"
00141
00142 static int isfirst;
00143 static int dummy;
00144
00145
00154
00155
00156 int cpl_plugin_get_info(cpl_pluginlist * list)
00157 {
00158 cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe)) ;
00159 cpl_plugin * plugin = &recipe->interface ;
00160
00161 cpl_plugin_init(plugin,
00162 CPL_PLUGIN_API,
00163 OMEGA_BINARY_VERSION,
00164 CPL_PLUGIN_TYPE_RECIPE,
00165 "omega_mflat",
00166 "OMEGA - Create Master Twilight and Master Flat for each chip",
00167 "This recipe is used to derive a valid twilight flat frame (Calfile 543, 546) \n"
00168 "for one particular chip and filter. The recipe always takes as input \n"
00169 "a list of raw twilight flat frames, a master bias and an optional master \n"
00170 "dome flat to be used in creating a final Master Flat Field. In addition, a hot \n"
00171 "pixel map (and a cold pixel map can be provided, which will be used to create a \n"
00172 "bad pixels map. Optionally, an overscan correction mode \n"
00173 "can be set. The default is to apply no overscan correction.\n\n"
00174 "The raw twilight flats are trimmed and overscan corrected. The data are then \n"
00175 "normalized, averaged, and the result is normalized again. Image statistics \n"
00176 "are computed for the resulting frames.",
00177 "Sandra Castro",
00178 "scastro@eso.org",
00179 omega_get_license(),
00180 omega_mflat_create,
00181 omega_mflat_exec,
00182 omega_mflat_destroy) ;
00183
00184 cpl_pluginlist_append(list, plugin) ;
00185
00186 return 0;
00187 }
00188
00189
00190
00191
00192 static int omega_mflat_create(cpl_plugin * plugin)
00193 {
00194 cpl_recipe * recipe;
00195 cpl_parameter * p ;
00196 char *path = NULL;
00197
00198
00199 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00200 cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
00201 cpl_func, __LINE__, cpl_error_get_where());
00202 return (int)cpl_error_get_code();
00203 }
00204
00205 if (plugin == NULL) {
00206 cpl_msg_error(cpl_func, "Null plugin");
00207 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
00208 }
00209
00210
00211 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
00212 cpl_msg_error(cpl_func, "Plugin is not a recipe");
00213 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
00214 }
00215
00216
00217 recipe = (cpl_recipe *)plugin;
00218
00219
00220 recipe->parameters = cpl_parameterlist_new() ;
00221 if (recipe->parameters == NULL) {
00222 cpl_msg_error(cpl_func, "Parameter list allocation failed");
00223 cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
00224 }
00225
00226
00227
00228
00229
00230 p = cpl_parameter_new_value("omega.omega_mflat.ExtensionNumber",
00231 CPL_TYPE_INT,
00232 "FITS extension number to load (1 to 32). (-1 = all)",
00233 "omega_mflat",
00234 -1) ;
00235
00236 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"ext") ;
00237 cpl_parameterlist_append(recipe->parameters, p) ;
00238
00239
00240 p = cpl_parameter_new_range("omega.omega_mflat.OverscanMethod",
00241 CPL_TYPE_INT,
00242 "Overscan Correction Method",
00243 "omega_mflat",
00244 0, 0, 6);
00245
00246 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"oc-meth") ;
00247 cpl_parameterlist_append(recipe->parameters, p) ;
00248
00249 p = cpl_parameter_new_value("omega.omega_mflat.PAF",
00250 CPL_TYPE_BOOL,
00251 "Boolean value to create PAF files. 1(Yes), 0(No)",
00252 "omega_mflat",
00253 1) ;
00254
00255 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI, "paf") ;
00256 cpl_parameterlist_append(recipe->parameters, p) ;
00257
00258 p = cpl_parameter_new_value("omega.omega_mflat.SigmaClip",
00259 CPL_TYPE_DOUBLE,
00260 "Sigma Clipping Threshold",
00261 "omega_mflat",
00262 3.0) ;
00263
00264 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI, "sig-clip") ;
00265 cpl_parameterlist_append(recipe->parameters, p) ;
00266
00267
00268
00269
00270 path = cpl_sprintf("%s", OMEGA_BIN_PATH);
00271 p = cpl_parameter_new_value("omega.omega_mflat.BinPath",
00272 CPL_TYPE_STRING,
00273 "Path to any external executable program.",
00274 "omega.BinPath",
00275 path);
00276
00277 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI, "bin-path");
00278 cpl_parameterlist_append(recipe->parameters, p);
00279 cpl_free(path);
00280
00281 p = cpl_parameter_new_value("omega.omega_mflat.GaussianFiltSize",
00282 CPL_TYPE_DOUBLE,
00283 "Standard deviation of Gaussian Fourier filter size",
00284 "omega_mflat",
00285 9.0) ;
00286
00287 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI, "gau_filt_sz") ;
00288 cpl_parameterlist_append(recipe->parameters, p) ;
00289
00290 p = cpl_parameter_new_value("omega.omega_mflat.MirrorXpix",
00291 CPL_TYPE_INT,
00292 "Width of X region for mirroring edges (FFT continuity)",
00293 "omega_mflat",
00294 75) ;
00295
00296 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI, "mr_xpix") ;
00297 cpl_parameterlist_append(recipe->parameters, p) ;
00298
00299 p = cpl_parameter_new_value("omega.omega_mflat.MirrorYpix",
00300 CPL_TYPE_INT,
00301 "Width of Y region for mirroring edges (FFT continuity)",
00302 "omega_mflat",
00303 150) ;
00304
00305 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI, "mr_ypix") ;
00306 cpl_parameterlist_append(recipe->parameters, p) ;
00307
00308
00309 p = cpl_parameter_new_range("omega.omega_mflat.LowThre",
00310 CPL_TYPE_DOUBLE,
00311 "Low flagging threshold for cold pixels map",
00312 "omega_mflat",
00313 0.96, 0.90, 1.00) ;
00314
00315 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI, "low") ;
00316 cpl_parameterlist_append(recipe->parameters, p) ;
00317
00318 p = cpl_parameter_new_range("omega.omega_mflat.HighThre",
00319 CPL_TYPE_DOUBLE,
00320 "High flagging threshold for cold pixels map",
00321 "omega_flat",
00322 1.04, 1.00, 1.10) ;
00323
00324 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"high") ;
00325 cpl_parameterlist_append(recipe->parameters, p) ;
00326
00327 return 0;
00328 }
00329
00330
00331
00332
00333 static int omega_mflat_exec(cpl_plugin * plugin)
00334 {
00335 cpl_recipe * recipe;
00336 int recipe_status;
00337
00338
00339 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00340 cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
00341 cpl_func, __LINE__, cpl_error_get_where());
00342 return (int)cpl_error_get_code();
00343 }
00344
00345 if (plugin == NULL) {
00346 cpl_msg_error(cpl_func, "Null plugin");
00347 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
00348 }
00349
00350
00351 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
00352 cpl_msg_error(cpl_func, "Plugin is not a recipe");
00353 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
00354 }
00355
00356
00357 recipe = (cpl_recipe *)plugin;
00358
00359
00360 if (recipe->parameters == NULL) {
00361 cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
00362 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
00363 }
00364 if (recipe->frames == NULL) {
00365 cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
00366 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
00367 }
00368
00369
00370 recipe_status = omega_mflat(recipe->frames, recipe->parameters);
00371
00372
00373 if (cpl_dfs_update_product_header(recipe->frames)) {
00374 if (!recipe_status) recipe_status = (int)cpl_error_get_code();
00375 }
00376
00377 return recipe_status;
00378 }
00379
00380
00381
00382
00383 static int omega_mflat_destroy(cpl_plugin * plugin)
00384 {
00385 cpl_recipe * recipe;
00386
00387 if (plugin == NULL) {
00388 cpl_msg_error(cpl_func, "Null plugin");
00389 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
00390 }
00391
00392
00393 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
00394 cpl_msg_error(cpl_func, "Plugin is not a recipe");
00395 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
00396 }
00397
00398
00399 recipe = (cpl_recipe *)plugin;
00400
00401 cpl_parameterlist_delete(recipe->parameters) ;
00402
00403 return 0 ;
00404 }
00405
00406
00407
00408
00409 static int omega_mflat(cpl_frameset *set, cpl_parameterlist *pars)
00410 {
00411 int j,jst,jfn;
00412 cpl_size nlab;
00413 int nflats = 0;
00414 int oscan1 = 0;
00415 int status = 1;
00416
00417 float bias = BIAS;
00418
00419 const char *_id = "omega_mflat";
00420 char *outbpm = NULL;
00421 char *outtwilight = NULL;
00422 char *outmflat = NULL;
00423 const cpl_frame *firstframe;
00424 const cpl_frame *refframe;
00425 cpl_frame *prframe_twil = NULL;
00426 cpl_frame *prframe_mflat = NULL;
00427 cpl_frame *prframe_bpm = NULL;
00428 cpl_parameter *par;
00429 cpl_propertylist *qclist;
00430 cpl_propertylist *alist;
00431 cpl_stats *diffstats = NULL;
00432 cpl_errorstate prestate = cpl_errorstate_get();
00433
00434
00435
00436
00437 if (!pars) {
00438 cpl_msg_error (_id, "Parameters list not found");
00439 return -1;
00440 }
00441
00442 if (cpl_frameset_is_empty(set) == 1) {
00443 cpl_msg_error (_id, "Frameset not found");
00444 return -1;
00445 }
00446
00447
00448 par = cpl_parameterlist_find(pars, "omega.omega_mflat.ExtensionNumber") ;
00449 omega_mflat_config.extnum = cpl_parameter_get_int(par) ;
00450
00451 par = cpl_parameterlist_find(pars, "omega.omega_mflat.OverscanMethod") ;
00452 omega_mflat_config.oc = cpl_parameter_get_int(par) ;
00453
00454 par = cpl_parameterlist_find(pars, "omega.omega_mflat.SigmaClip") ;
00455 omega_mflat_config.sigma = cpl_parameter_get_double(par) ;
00456
00457 par = cpl_parameterlist_find(pars, "omega.omega_mflat.PAF") ;
00458 omega_mflat_config.paf = cpl_parameter_get_bool(par) ;
00459
00460
00461 if (oc_dfs_set_groups(set)) {
00462 cpl_msg_error(_id, "Cannot identify RAW and CALIB frames") ;
00463 return -1 ;
00464 }
00465
00466
00467 omega_mflat_init();
00468
00469
00470 if ((ps.labels = cpl_frameset_labelise(set,omega_compare_tags,
00471 &nlab)) == NULL) {
00472 cpl_msg_error(_id,"Cannot labelise the input frameset");
00473 omega_mflat_tidy();
00474 return -1;
00475 }
00476 if ((ps.flatlist = omega_frameset_subgroup(set,ps.labels,nlab,
00477 MTWIL_RAW)) == NULL) {
00478 cpl_msg_error(_id,"Cannot find twilight flats in input frameset");
00479 omega_mflat_tidy();
00480 return -1;
00481 }
00482 nflats = cpl_frameset_count_tags (ps.flatlist, MTWIL_RAW);
00483 if (nflats < 2) {
00484 cpl_msg_error (_id, "Need at least 2 (%s) frames to run "
00485 "this recipe", MTWIL_RAW);
00486 omega_mflat_tidy();
00487 return -1;
00488 }
00489
00490 cpl_msg_info (_id,"There are %d %s frames in frame set",nflats, MTWIL_RAW);
00491
00492
00493
00494 ps.mbframe = cpl_frameset_find_const(set, OMEGA_CALIB_BIAS);
00495 if (ps.mbframe == NULL) {
00496 cpl_msg_error(cpl_func,"Cannot find OMEGA_CALIB_BIAS input in frame set");
00497 omega_mflat_tidy();
00498 return -1;
00499 }
00500 cpl_msg_info(_id,"Using %s %s",OMEGA_CALIB_BIAS, cpl_frame_get_filename(ps.mbframe));
00501
00502
00503 ps.cframe = cpl_frameset_find_const(set, OMEGA_CALIB_CPM);
00504 if(ps.cframe == NULL){
00505 cpl_msg_error(cpl_func,"Cannot find %s input in frame set",OMEGA_CALIB_CPM);
00506 omega_mflat_tidy();
00507 return -1;
00508 }
00509 cpl_msg_info(_id,"Using %s %s",OMEGA_CALIB_CPM, cpl_frame_get_filename(ps.cframe));
00510
00511
00512 ps.hframe = cpl_frameset_find_const(set, OMEGA_CALIB_HPM);
00513 if(ps.hframe == NULL){
00514 cpl_msg_error(cpl_func,"Cannot find %s input in frame set",OMEGA_CALIB_HPM);
00515 omega_mflat_tidy();
00516 return -1;
00517 }
00518 cpl_msg_info(_id,"Using %s %s",OMEGA_CALIB_HPM, cpl_frame_get_filename(ps.hframe));
00519
00520
00521 ps.mdomefr = cpl_frameset_find_const(set, OMEGA_CALIB_DOME);
00522 if(ps.mdomefr != NULL) {
00523 cpl_msg_info(_id,"Using %s %s", OMEGA_CALIB_DOME, cpl_frame_get_filename(ps.mdomefr));
00524 }
00525
00526
00527 ps.nskyfr = cpl_frameset_find_const(set, OMEGA_CALIB_NSKY);
00528 if(ps.nskyfr != NULL) {
00529 cpl_msg_info(_id,"Using %s %s", OMEGA_CALIB_NSKY, cpl_frame_get_filename(ps.nskyfr));
00530 }
00531
00532
00533 refframe = cpl_frameset_find_const(set, REFMFLAT);
00534 if (refframe != NULL)
00535 cpl_msg_info(cpl_func,"Using %s for comparison",cpl_frame_get_filename(refframe));
00536
00537
00538
00539 firstframe = cpl_frameset_get_first(ps.flatlist);
00540
00541
00542 omega_extensions(firstframe,omega_mflat_config.extnum,&jst,&jfn);
00543 if(omega_mflat_config.extnum == 0){
00544 cpl_msg_error(cpl_func,"Unsupported extension request, %d",omega_mflat_config.extnum);
00545 omega_mflat_tidy();
00546 return -1;
00547 }
00548
00549 for (j = jst; j <= jfn; j++) {
00550
00551 isfirst = (j == jst);
00552 cpl_msg_info(_id,"Beginning work on extension %d",j);
00553
00554 omega_mflat_config.bpm = 0;
00555 omega_mflat_config.Mean = 0.0;
00556 omega_mflat_config.Median = 0.0;
00557 omega_mflat_config.Stdev = 0.0;
00558 omega_mflat_config.RawMin = 0.0;
00559 omega_mflat_config.RawMax = 0.0;
00560 omega_mflat_config.RawMean = 0.0;
00561 omega_mflat_config.RawMedian = 0.0;
00562 omega_mflat_config.RawStdev = 0.0;
00563
00564
00565 if(ps.mbframe != NULL){
00566 oscan1 = omega_pfits_get_overscan(ps.mbframe, j);
00567 if(oscan1 != omega_mflat_config.oc) {
00568 cpl_msg_warning (_id, "Overscan correction mode for Master Bias (oc = %d) differs from "
00569 "the one used here (oc = %d)", oscan1, omega_mflat_config.oc);
00570 }
00571 }
00572
00573
00574 ps.firstflat = omega_fits_load(firstframe,CPL_TYPE_FLOAT,j);
00575 ps.eh = omega_fits_get_ehu(ps.firstflat);
00576
00577
00578
00579 status = omega_mflat_combine(pars, j);
00580 if(status == 1){
00581 cpl_msg_warning(_id, "Image detector is not live");
00582
00583 freefits(ps.firstflat);
00584 ps.eh = NULL;
00585 continue;
00586 }
00587 else if(status == -1){
00588 cpl_msg_error(_id,"Cannot combine images");
00589 freespace(outbpm);
00590 freespace(outtwilight);
00591 freespace(outmflat);
00592 omega_mflat_tidy();
00593 return -1;
00594 }
00595
00596 status = 0;
00597
00598 qclist = cpl_propertylist_new();
00599
00600
00601
00602 if(refframe != NULL){
00603 if(omega_compare_reference(ps.mflat,refframe,j,&diffstats) == -1){
00604 cpl_msg_warning(cpl_func,"Cannot compare with reference frame");
00605 }
00606 else{
00607 cpl_propertylist_append_double(qclist,"ESO QC DIFF REFMFLAT MEAN",
00608 cpl_stats_get_mean(diffstats));
00609 cpl_propertylist_set_comment(qclist,"ESO QC DIFF REFMFLAT MEAN",
00610 "Mean of difference with reference");
00611 cpl_propertylist_append_double(qclist,"ESO QC DIFF REFMFLAT MEDIAN",
00612 cpl_stats_get_median(diffstats));
00613 cpl_propertylist_set_comment(qclist,"ESO QC DIFF REFMFLAT MEDIAN",
00614 "Median of difference with reference");
00615 cpl_propertylist_append_double(qclist,"ESO QC DIFF REFMFLAT STDEV",
00616 cpl_stats_get_stdev(diffstats));
00617 cpl_propertylist_set_comment(qclist,"ESO QC DIFF REFMFLAT STDEV",
00618 "Stdev of difference with reference");
00619
00620 freestats(diffstats);
00621 }
00622 }
00623
00624
00625
00626 ps.stats = cpl_stats_new_from_image(ps.mflat, CPL_STATS_ALL);
00627 if(ps.stats != NULL) {
00628 omega_mflat_config.Mean = cpl_stats_get_mean(ps.stats);
00629 omega_mflat_config.Median = cpl_stats_get_median(ps.stats);
00630 omega_mflat_config.Stdev = cpl_stats_get_stdev(ps.stats);
00631 freestats(ps.stats);
00632 }
00633
00634
00635 cpl_propertylist_append_double(qclist, "ESO QC MASTER FLAT MEAN",
00636 omega_mflat_config.Mean) ;
00637 cpl_propertylist_set_comment(qclist,"ESO QC MASTER FLAT MEAN",
00638 "Mean value of master flat");
00639 cpl_propertylist_append_double(qclist, "ESO QC MASTER FLAT MEDIAN",
00640 omega_mflat_config.Median) ;
00641 cpl_propertylist_set_comment(qclist,"ESO QC MASTER FLAT MEDIAN",
00642 "Median value of master flat");
00643 cpl_propertylist_append_double(qclist, "ESO QC MASTER FLAT STDEV",
00644 omega_mflat_config.Stdev) ;
00645 cpl_propertylist_set_comment(qclist,"ESO QC MASTER FLAT STDEV",
00646 "Standard deviation value of master flat");
00647
00648
00649 if(isfirst){
00650 outmflat = cpl_sprintf("%s_%s.fits", INSTRUME,MFLAT_PROCATG);
00651 prframe_mflat = omega_product_frame(outmflat, MFLAT_PROCATG, CPL_FRAME_TYPE_IMAGE);
00652 }
00653
00654
00655 alist = cpl_propertylist_new();
00656 cpl_propertylist_append_string(alist, "EXTNAME",
00657 cpl_propertylist_get_string(ps.eh, "EXTNAME"));
00658 cpl_propertylist_set_comment(alist,"EXTNAME", "Extension name");
00659
00660 cpl_propertylist_copy_property_regexp(alist, ps.eh, WCS_KEYS, 0);
00661
00662
00663 cpl_propertylist_update_int(alist, "ESO DRS OVERSCAN METHOD", omega_mflat_config.oc);
00664 cpl_propertylist_set_comment(alist, "ESO DRS OVERSCAN METHOD", "overscan correction method");
00665
00666 if(omega_save_image(ps.mflat,set,pars,alist,qclist,CPL_BPP_IEEE_FLOAT,outmflat,
00667 RECIPE,prframe_mflat,NULL,isfirst) == -1){
00668 cpl_msg_error(_id,"Cannot save product %s", MFLAT_PROCATG);
00669 freeplist(alist);
00670 freeplist(qclist);
00671 freespace(outmflat);
00672 freespace(outtwilight);
00673 freespace(outbpm);
00674 omega_mflat_tidy();
00675 return -1;;
00676 }
00677
00678
00679 freeplist(qclist);
00680 freeimage(ps.mflat);
00681 status = 0;
00682
00683
00684
00685 ps.stats = cpl_stats_new_from_image(ps.mtwilight, CPL_STATS_ALL);
00686 if(ps.stats != NULL) {
00687 omega_mflat_config.Mean = cpl_stats_get_mean(ps.stats);
00688 omega_mflat_config.Median = cpl_stats_get_median(ps.stats);
00689 omega_mflat_config.Stdev = cpl_stats_get_stdev(ps.stats);
00690 freestats(ps.stats);
00691 }
00692
00693
00694 qclist = cpl_propertylist_new();
00695 cpl_propertylist_append_double(qclist, "ESO QC MASTER TWILIGHT MEAN",
00696 omega_mflat_config.Mean) ;
00697 cpl_propertylist_set_comment(qclist,"ESO QC MASTER TWILIGHT MEAN",
00698 "Mean value of master twilight flat");
00699 cpl_propertylist_append_double(qclist, "ESO QC MASTER TWILIGHT MEDIAN",
00700 omega_mflat_config.Median) ;
00701 cpl_propertylist_set_comment(qclist,"ESO QC MASTER TWILIGHT MEDIAN",
00702 "Median value of master twilight flat");
00703 cpl_propertylist_append_double(qclist, "ESO QC MASTER TWILIGHT STDEV",
00704 omega_mflat_config.Stdev) ;
00705 cpl_propertylist_set_comment(qclist,"ESO QC MASTER TWILIGHT STDEV",
00706 "Standard deviation value of master twilight flat");
00707
00708 cpl_propertylist_append_double(qclist, "ESO QC RAW TWILIGHT MIN",
00709 omega_mflat_config.RawMin);
00710 cpl_propertylist_append_double(qclist, "ESO QC RAW TWILIGHT MAX",
00711 omega_mflat_config.RawMax);
00712 cpl_propertylist_append_double(qclist, "ESO QC RAW TWILIGHT MEAN",
00713 omega_mflat_config.RawMean);
00714 cpl_propertylist_append_double(qclist, "ESO QC RAW TWILIGHT MEDIAN",
00715 omega_mflat_config.RawMedian);
00716 cpl_propertylist_append_double(qclist, "ESO QC RAW TWILIGHT STDEV",
00717 omega_mflat_config.RawStdev);
00718
00719 cpl_propertylist_set_comment(qclist, "ESO QC RAW TWILIGHT MIN",
00720 "median value of the raw flat flat having the lowest flux");
00721 cpl_propertylist_set_comment(qclist, "ESO QC RAW TWILIGHT MAX",
00722 "median value of the raw flat flat having the highest flux");
00723 cpl_propertylist_set_comment(qclist, "ESO QC RAW TWILIGHT MEAN",
00724 "mean value of all input raw flat flats (ADU)");
00725 cpl_propertylist_set_comment(qclist, "ESO QC RAW TWILIGHT MEDIAN",
00726 "median value of all input raw flat flats (ADU)");
00727 cpl_propertylist_set_comment(qclist, "ESO QC RAW TWILIGHT STDEV",
00728 "standard deviation of all input raw flat flats (ADU)");
00729
00730
00731 if(isfirst){
00732 outtwilight = cpl_sprintf("%s_%s.fits", INSTRUME,MTWIL_PROCATG);
00733 prframe_twil = omega_product_frame(outtwilight, MTWIL_PROCATG, CPL_FRAME_TYPE_IMAGE);
00734 }
00735
00736 if(omega_save_image(ps.mtwilight,set,pars,alist,qclist,CPL_BPP_IEEE_FLOAT,outtwilight,
00737 RECIPE,prframe_twil,NULL,isfirst) == -1){
00738 cpl_msg_error(_id,"Cannot save product %s", MTWIL_PROCATG);
00739 freeplist(qclist);
00740 freeplist(alist);
00741 freespace(outtwilight);
00742 freespace(outbpm);
00743 freespace(outmflat);
00744 omega_mflat_tidy();
00745 return -1;;
00746 }
00747
00748 freeplist(qclist);
00749 freeimage(ps.mtwilight);
00750 status = 0;
00751
00752
00753
00754 qclist = cpl_propertylist_new();
00755 cpl_propertylist_append_int(qclist, "ESO QC NUMBER BAD PIXELS",omega_mflat_config.bpm);
00756 cpl_propertylist_set_comment(qclist,"ESO QC NUMBER BAD PIXELS",
00757 "Number of bad pixels");
00758
00759 if(isfirst){
00760 outbpm = cpl_sprintf("%s_%s.fits", INSTRUME,BPM_PROCATG);
00761 prframe_bpm = omega_product_frame(outbpm, BPM_PROCATG, CPL_FRAME_TYPE_IMAGE);
00762 }
00763
00764 if(omega_save_image(ps.bpixels,set,pars,alist,qclist,CPL_BPP_16_SIGNED,outbpm,
00765 RECIPE,prframe_bpm,NULL,isfirst) == -1){
00766 cpl_msg_error(_id,"Cannot save product %s", BPM_PROCATG);
00767 freeplist(alist);
00768 freeplist(qclist);
00769 freespace(outbpm);
00770 freespace(outtwilight);
00771 freespace(outmflat);
00772 omega_mflat_tidy();
00773 return -1;;
00774 }
00775
00776 freeplist(qclist);
00777 freeplist(alist);
00778 freeimage(ps.bpixels);
00779 freefits(ps.firstflat);
00780 ps.firstflat = NULL;
00781 ps.eh = NULL;
00782
00783 }
00784
00785
00786 freespace(outbpm);
00787 freespace(outtwilight);
00788 freespace(outmflat);
00789 omega_mflat_tidy();
00790
00791 if(!cpl_errorstate_is_equal(prestate)){
00792 cpl_errorstate_dump(prestate,CPL_FALSE,NULL);
00793 }
00794
00795 return 0;
00796
00797 }
00798
00799
00810 int omega_mflat_combine(cpl_parameterlist *pars, int xn)
00811 {
00812
00813 int i,nflats,live, naxis1, naxis2;
00814 float bias = BIAS;
00815 double gain = 0.0;
00816 double median = 1.0;
00817 double threshold = 0.0;
00818 double *data_scales;
00819 const char *_id = "omega_mflat_combine";
00820
00821 cpl_error_code code;
00822 const cpl_frame *flatfr;
00823 cpl_vector *scales;
00824 cpl_vector *median_vector = NULL;
00825 cpl_image *trim_raw,*dev,*good_float,*good_int,*median_all,*new_image;
00826 cpl_image *sum_data,*sum_good;
00827 cpl_image *mbias;
00828 cpl_image *mdome;
00829 cpl_image *nsky;
00830 cpl_mask *bpm_map;
00831 cpl_imagelist *ilist;
00832 cpl_mask *good;
00833
00834 nflats = cpl_frameset_get_size(ps.flatlist);
00835 flatfr = cpl_frameset_get_first_const(ps.flatlist);
00836
00837
00838 omega_pfits_get_detlive(ps.eh,&live);
00839 if (! live) {
00840 return 1;
00841 }
00842
00843
00844 if(ps.mbframe != NULL){
00845 mbias = cpl_image_load(cpl_frame_get_filename(ps.mbframe), CPL_TYPE_FLOAT,0,xn);
00846 if (mbias == NULL) {
00847 cpl_msg_warning(_id,"Cannot load image %s", OMEGA_CALIB_BIAS);
00848 }
00849 }
00850
00851
00852 bpm_map = makebpm(ps.hframe, ps.cframe, xn);
00853 if(bpm_map != NULL){
00854
00855 omega_mflat_config.bpm = cpl_mask_count(bpm_map);
00856 }
00857
00858 scales = cpl_vector_new(nflats);
00859 data_scales = cpl_vector_get_data(scales);
00860
00861 median_vector = cpl_vector_new (nflats);
00862 cpl_vector_fill(median_vector,0.0);
00863
00864 ilist = cpl_imagelist_new();
00865 cpl_msg_info (_id,"Doing trim and overscan correction on images");
00866
00867
00868 for (i=0; i< nflats; i++)
00869 {
00870
00871 trim_raw = TrimOscanCorrect(flatfr, omega_mflat_config.oc, xn);
00872 if(trim_raw == NULL){
00873 freevector(scales);
00874 freevector(median_vector);
00875 freeilist(ilist);
00876 freemask(bpm_map);
00877 freeimage(mbias);
00878 return -1;
00879 }
00880
00881 if (mbias != NULL)
00882 cpl_image_subtract(trim_raw, mbias);
00883 else
00884 cpl_image_subtract_scalar(trim_raw, bias);
00885
00886 if (bpm_map == NULL) {
00887 ps.stats = cpl_stats_new_from_image(trim_raw, CPL_STATS_ALL);
00888 median = cpl_stats_get_median(ps.stats);
00889 }
00890 else {
00891 cpl_image_reject_from_mask(trim_raw, bpm_map);
00892 ps.stats = cpl_stats_new_from_image(trim_raw, CPL_STATS_ALL);
00893 median = cpl_stats_get_median(ps.stats);
00894 }
00895
00896 cpl_vector_set(median_vector, i, median);
00897
00898 data_scales[i] = (double)1.0/median;
00899
00900 cpl_image_divide_scalar(trim_raw, median);
00901
00902 cpl_imagelist_set(ilist, trim_raw, i);
00903
00904
00905 flatfr = cpl_frameset_get_next_const(ps.flatlist);
00906 if (flatfr == NULL)
00907 break;
00908
00909 freestats(ps.stats);
00910
00911 }
00912
00913 omega_mflat_config.RawMin = cpl_vector_get_min(median_vector);
00914 omega_mflat_config.RawMax = cpl_vector_get_max(median_vector);
00915 omega_mflat_config.RawMean = cpl_vector_get_mean(median_vector);
00916 omega_mflat_config.RawMedian = cpl_vector_get_median(median_vector);
00917 omega_mflat_config.RawStdev = cpl_vector_get_stdev(median_vector);
00918
00919 freevector(median_vector);
00920
00921 freestats(ps.stats);
00922 freeimage(mbias);
00923
00924 if (ilist == NULL) {
00925 cpl_msg_error(_id,"Error in image list <%s>",cpl_error_get_message());
00926 freevector(scales);
00927 freeimage(trim_raw);
00928 freemask(bpm_map);
00929 return -1;
00930 }
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940 omega_pfits_get_conad(ps.eh, &gain);
00941
00942
00943 if (gain < 0.1){
00944 omega_pfits_get_gain(ps.eh, &gain);
00945
00946 if(gain < 0.1) {
00947 cpl_msg_info(_id,"Using default value for gain");
00948 gain = 2.0;
00949 }
00950 }
00951 else {
00952 cpl_msg_info(_id,"Gain value from images is %g", gain);
00953 }
00954
00955 cpl_msg_info (_id,"Computing the median of all images...");
00956 median_all = cpl_imagelist_collapse_median_create(ilist);
00957
00958 if (median_all == NULL) {
00959 cpl_msg_error (_id,"Cannot take median of imset <%s>",cpl_error_get_message());
00960 freevector(scales);
00961 freeilist(ilist);
00962 freemask(bpm_map);
00963 return -1;
00964 }
00965
00966 naxis1 = cpl_image_get_size_x(median_all);
00967 naxis2 = cpl_image_get_size_y(median_all);
00968
00969 sum_data = cpl_image_new(naxis1,naxis2,CPL_TYPE_FLOAT);
00970 sum_good = cpl_image_new(naxis1,naxis2,CPL_TYPE_FLOAT);
00971
00972
00973 for (i=0; i< nflats; i++)
00974 {
00975 trim_raw = cpl_imagelist_get(ilist, i);
00976 new_image = cpl_image_duplicate(trim_raw);
00977
00978
00979
00980
00981
00982 cpl_image_threshold(trim_raw, 0, FLT_MAX, 0, 2e20);
00983
00984 dev = cpl_image_subtract_create(median_all, trim_raw);
00985
00986 code = cpl_image_power(trim_raw, 0.5);
00987 if(code != CPL_ERROR_NONE) {
00988 cpl_msg_error(_id,"Error in SQRT operation <%s>",cpl_error_get_message());
00989 freevector(scales);
00990 freeilist(ilist);
00991 freeimage(median_all);
00992 freeimage(sum_data);
00993 freeimage(sum_good);
00994 freeimage(new_image);
00995 freeimage(dev);
00996 freemask(bpm_map);
00997 return -1;
00998 }
00999
01000 cpl_image_divide(dev, trim_raw);
01001
01002 threshold = omega_mflat_config.sigma * (sqrt(gain * data_scales[i]));
01003
01004 good = cpl_mask_threshold_image_create(dev, -threshold, threshold);
01005
01006 freeimage(dev);
01007 good_int = cpl_image_new_from_mask(good) ;
01008 freemask(good) ;
01009
01010 good_float = cpl_image_cast(good_int, CPL_TYPE_FLOAT);
01011 freeimage(good_int);
01012
01013 cpl_image_multiply(new_image, good_float);
01014 cpl_image_add(sum_data, new_image);
01015
01016 cpl_image_add(sum_good, good_float);
01017
01018 freeimage(new_image);
01019 freeimage(good_float);
01020
01021 }
01022
01023 freeimage(median_all);
01024 freevector(scales);
01025
01026
01027 ps.mtwilight = cpl_image_divide_create(sum_data, sum_good);
01028 if (ps.mtwilight == NULL) {
01029 cpl_msg_error(_id,"Error in division %s <%s>",MTWIL_PROCATG, cpl_error_get_message());
01030 freeilist(ilist);
01031 freeimage(sum_data);
01032 freeimage(sum_good);
01033 freemask(bpm_map);
01034 return -1;
01035 }
01036
01037 freeimage(sum_data);
01038 freeimage(sum_good);
01039 freeilist(ilist);
01040
01041
01042
01043 if(ps.mdomefr != NULL){
01044
01045 mdome = cpl_image_load(cpl_frame_get_filename(ps.mdomefr), CPL_TYPE_FLOAT,0,xn);
01046 if (mdome == NULL){
01047 cpl_msg_warning(_id,"Cannot load image %s", OMEGA_CALIB_DOME);
01048 ps.mflat = cpl_image_duplicate(ps.mtwilight);
01049 }
01050 else{
01051 ps.mflat = omega_make_mflat(mdome,ps.mtwilight,bpm_map,pars);
01052 if(ps.mflat == NULL){
01053 cpl_msg_warning(_id,"Cannot calculate Master Flat Field");
01054 ps.mflat = cpl_image_duplicate(ps.mtwilight);
01055 }
01056 freeimage(mdome);
01057 }
01058 }
01059 else{
01060 cpl_msg_warning(_id,"There is no Master Dome Flat in frame set");
01061 ps.mflat = cpl_image_duplicate(ps.mtwilight);
01062 }
01063
01064
01065 if (ps.nskyfr != NULL) {
01066 nsky = cpl_image_load(cpl_frame_get_filename(ps.nskyfr), CPL_TYPE_FLOAT,0,xn);
01067 if (nsky == NULL) {
01068 cpl_msg_warning(_id,"Cannot load image %s", OMEGA_CALIB_NSKY);
01069 }
01070 else{
01071 cpl_image_multiply (ps.mflat, nsky);
01072 freeimage(nsky);
01073 }
01074 }
01075
01076
01077
01078
01079 if(bpm_map != NULL)
01080 ps.bpixels = cpl_image_new_from_mask(bpm_map);
01081
01082 omega_mflat_config.bpm = cpl_mask_count(bpm_map);
01083 freemask(bpm_map);
01084
01085 return 0;
01086 }
01087
01088
01089 static void omega_mflat_init(void) {
01090 ps.bpixels = NULL;
01091 ps.cframe = NULL;
01092 ps.eh = NULL;
01093 ps.firstflat = NULL;
01094 ps.flatlist = NULL;
01095 ps.hframe = NULL;
01096 ps.labels = NULL;
01097 ps.mbframe = NULL;
01098 ps.mdomefr = NULL;
01099 ps.mflat = NULL;
01100 ps.mtwilight = NULL;
01101 ps.nskyfr = NULL;
01102 ps.stats = NULL;
01103 }
01104
01105
01106 static void omega_mflat_tidy(void) {
01107 freefits(ps.firstflat);
01108 freeframeset(ps.flatlist);
01109 freeimage(ps.bpixels);
01110 freeimage(ps.mflat);
01111 freeimage(ps.mtwilight);
01112 freespace(ps.labels);
01113 freestats(ps.stats);
01114 }
01115