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
00661 cpl_propertylist_update_int(alist, "ESO DRS OVERSCAN METHOD", omega_mflat_config.oc);
00662 cpl_propertylist_set_comment(alist, "ESO DRS OVERSCAN METHOD", "overscan correction method");
00663
00664 if(omega_save_image(ps.mflat,set,pars,alist,qclist,CPL_BPP_IEEE_FLOAT,outmflat,
00665 RECIPE,prframe_mflat,NULL,isfirst) == -1){
00666 cpl_msg_error(_id,"Cannot save product %s", MFLAT_PROCATG);
00667 freeplist(alist);
00668 freeplist(qclist);
00669 freespace(outmflat);
00670 freespace(outtwilight);
00671 freespace(outbpm);
00672 omega_mflat_tidy();
00673 return -1;;
00674 }
00675
00676
00677 freeplist(qclist);
00678 freeimage(ps.mflat);
00679 status = 0;
00680
00681
00682
00683 ps.stats = cpl_stats_new_from_image(ps.mtwilight, CPL_STATS_ALL);
00684 if(ps.stats != NULL) {
00685 omega_mflat_config.Mean = cpl_stats_get_mean(ps.stats);
00686 omega_mflat_config.Median = cpl_stats_get_median(ps.stats);
00687 omega_mflat_config.Stdev = cpl_stats_get_stdev(ps.stats);
00688 freestats(ps.stats);
00689 }
00690
00691
00692 qclist = cpl_propertylist_new();
00693 cpl_propertylist_append_double(qclist, "ESO QC MASTER TWILIGHT MEAN",
00694 omega_mflat_config.Mean) ;
00695 cpl_propertylist_set_comment(qclist,"ESO QC MASTER TWILIGHT MEAN",
00696 "Mean value of master twilight flat");
00697 cpl_propertylist_append_double(qclist, "ESO QC MASTER TWILIGHT MEDIAN",
00698 omega_mflat_config.Median) ;
00699 cpl_propertylist_set_comment(qclist,"ESO QC MASTER TWILIGHT MEDIAN",
00700 "Median value of master twilight flat");
00701 cpl_propertylist_append_double(qclist, "ESO QC MASTER TWILIGHT STDEV",
00702 omega_mflat_config.Stdev) ;
00703 cpl_propertylist_set_comment(qclist,"ESO QC MASTER TWILIGHT STDEV",
00704 "Standard deviation value of master twilight flat");
00705
00706 cpl_propertylist_append_double(qclist, "ESO QC RAW TWILIGHT MIN",
00707 omega_mflat_config.RawMin);
00708 cpl_propertylist_append_double(qclist, "ESO QC RAW TWILIGHT MAX",
00709 omega_mflat_config.RawMax);
00710 cpl_propertylist_append_double(qclist, "ESO QC RAW TWILIGHT MEAN",
00711 omega_mflat_config.RawMean);
00712 cpl_propertylist_append_double(qclist, "ESO QC RAW TWILIGHT MEDIAN",
00713 omega_mflat_config.RawMedian);
00714 cpl_propertylist_append_double(qclist, "ESO QC RAW TWILIGHT STDEV",
00715 omega_mflat_config.RawStdev);
00716
00717 cpl_propertylist_set_comment(qclist, "ESO QC RAW TWILIGHT MIN",
00718 "median value of the raw flat flat having the lowest flux");
00719 cpl_propertylist_set_comment(qclist, "ESO QC RAW TWILIGHT MAX",
00720 "median value of the raw flat flat having the highest flux");
00721 cpl_propertylist_set_comment(qclist, "ESO QC RAW TWILIGHT MEAN",
00722 "mean value of all input raw flat flats (ADU)");
00723 cpl_propertylist_set_comment(qclist, "ESO QC RAW TWILIGHT MEDIAN",
00724 "median value of all input raw flat flats (ADU)");
00725 cpl_propertylist_set_comment(qclist, "ESO QC RAW TWILIGHT STDEV",
00726 "standard deviation of all input raw flat flats (ADU)");
00727
00728
00729 if(isfirst){
00730 outtwilight = cpl_sprintf("%s_%s.fits", INSTRUME,MTWIL_PROCATG);
00731 prframe_twil = omega_product_frame(outtwilight, MTWIL_PROCATG, CPL_FRAME_TYPE_IMAGE);
00732 }
00733
00734 if(omega_save_image(ps.mtwilight,set,pars,alist,qclist,CPL_BPP_IEEE_FLOAT,outtwilight,
00735 RECIPE,prframe_twil,NULL,isfirst) == -1){
00736 cpl_msg_error(_id,"Cannot save product %s", MTWIL_PROCATG);
00737 freeplist(qclist);
00738 freeplist(alist);
00739 freespace(outtwilight);
00740 freespace(outbpm);
00741 freespace(outmflat);
00742 omega_mflat_tidy();
00743 return -1;;
00744 }
00745
00746 freeplist(qclist);
00747 freeimage(ps.mtwilight);
00748 status = 0;
00749
00750
00751
00752 qclist = cpl_propertylist_new();
00753 cpl_propertylist_append_int(qclist, "ESO QC NUMBER BAD PIXELS",omega_mflat_config.bpm);
00754 cpl_propertylist_set_comment(qclist,"ESO QC NUMBER BAD PIXELS",
00755 "Number of bad pixels");
00756
00757 if(isfirst){
00758 outbpm = cpl_sprintf("%s_%s.fits", INSTRUME,BPM_PROCATG);
00759 prframe_bpm = omega_product_frame(outbpm, BPM_PROCATG, CPL_FRAME_TYPE_IMAGE);
00760 }
00761
00762 if(omega_save_image(ps.bpixels,set,pars,alist,qclist,CPL_BPP_16_SIGNED,outbpm,
00763 RECIPE,prframe_bpm,NULL,isfirst) == -1){
00764 cpl_msg_error(_id,"Cannot save product %s", BPM_PROCATG);
00765 freeplist(alist);
00766 freeplist(qclist);
00767 freespace(outbpm);
00768 freespace(outtwilight);
00769 freespace(outmflat);
00770 omega_mflat_tidy();
00771 return -1;;
00772 }
00773
00774 freeplist(qclist);
00775 freeplist(alist);
00776 freeimage(ps.bpixels);
00777 freefits(ps.firstflat);
00778 ps.firstflat = NULL;
00779 ps.eh = NULL;
00780
00781 }
00782
00783
00784 freespace(outbpm);
00785 freespace(outtwilight);
00786 freespace(outmflat);
00787 omega_mflat_tidy();
00788
00789 if(!cpl_errorstate_is_equal(prestate)){
00790 cpl_errorstate_dump(prestate,CPL_FALSE,NULL);
00791 }
00792
00793 return 0;
00794
00795 }
00796
00797
00808 int omega_mflat_combine(cpl_parameterlist *pars, int xn)
00809 {
00810
00811 int i,nflats,live, naxis1, naxis2;
00812 float bias = BIAS;
00813 double gain = 0.0;
00814 double median = 1.0;
00815 double threshold = 0.0;
00816 double *data_scales;
00817 const char *_id = "omega_mflat_combine";
00818
00819 cpl_error_code code;
00820 const cpl_frame *flatfr;
00821 cpl_vector *scales;
00822 cpl_vector *median_vector = NULL;
00823 cpl_image *trim_raw,*dev,*good_float,*good_int,*median_all,*new_image;
00824 cpl_image *sum_data,*sum_good;
00825 cpl_image *mbias;
00826 cpl_image *mdome;
00827 cpl_image *nsky;
00828 cpl_mask *bpm_map;
00829 cpl_imagelist *ilist;
00830 cpl_mask *good;
00831
00832 nflats = cpl_frameset_get_size(ps.flatlist);
00833 flatfr = cpl_frameset_get_first_const(ps.flatlist);
00834
00835
00836 omega_pfits_get_detlive(ps.eh,&live);
00837 if (! live) {
00838 return 1;
00839 }
00840
00841
00842 if(ps.mbframe != NULL){
00843 mbias = cpl_image_load(cpl_frame_get_filename(ps.mbframe), CPL_TYPE_FLOAT,0,xn);
00844 if (mbias == NULL) {
00845 cpl_msg_warning(_id,"Cannot load image %s", OMEGA_CALIB_BIAS);
00846 }
00847 }
00848
00849
00850 bpm_map = makebpm(ps.hframe, ps.cframe, xn);
00851 if(bpm_map != NULL){
00852
00853 omega_mflat_config.bpm = cpl_mask_count(bpm_map);
00854 }
00855
00856 scales = cpl_vector_new(nflats);
00857 data_scales = cpl_vector_get_data(scales);
00858
00859 median_vector = cpl_vector_new (nflats);
00860 cpl_vector_fill(median_vector,0.0);
00861
00862 ilist = cpl_imagelist_new();
00863 cpl_msg_info (_id,"Doing trim and overscan correction on images");
00864
00865
00866 for (i=0; i< nflats; i++)
00867 {
00868
00869 trim_raw = TrimOscanCorrect(flatfr, omega_mflat_config.oc, xn);
00870 if(trim_raw == NULL){
00871 freevector(scales);
00872 freevector(median_vector);
00873 freeilist(ilist);
00874 freemask(bpm_map);
00875 freeimage(mbias);
00876 return -1;
00877 }
00878
00879 if (mbias != NULL)
00880 cpl_image_subtract(trim_raw, mbias);
00881 else
00882 cpl_image_subtract_scalar(trim_raw, bias);
00883
00884 if (bpm_map == NULL) {
00885 ps.stats = cpl_stats_new_from_image(trim_raw, CPL_STATS_ALL);
00886 median = cpl_stats_get_median(ps.stats);
00887 }
00888 else {
00889 cpl_image_reject_from_mask(trim_raw, bpm_map);
00890 ps.stats = cpl_stats_new_from_image(trim_raw, CPL_STATS_ALL);
00891 median = cpl_stats_get_median(ps.stats);
00892 }
00893
00894 cpl_vector_set(median_vector, i, median);
00895
00896 data_scales[i] = (double)1.0/median;
00897
00898 cpl_image_divide_scalar(trim_raw, median);
00899
00900 cpl_imagelist_set(ilist, trim_raw, i);
00901
00902
00903 flatfr = cpl_frameset_get_next_const(ps.flatlist);
00904 if (flatfr == NULL)
00905 break;
00906
00907 freestats(ps.stats);
00908
00909 }
00910
00911 omega_mflat_config.RawMin = cpl_vector_get_min(median_vector);
00912 omega_mflat_config.RawMax = cpl_vector_get_max(median_vector);
00913 omega_mflat_config.RawMean = cpl_vector_get_mean(median_vector);
00914 omega_mflat_config.RawMedian = cpl_vector_get_median(median_vector);
00915 omega_mflat_config.RawStdev = cpl_vector_get_stdev(median_vector);
00916
00917 freevector(median_vector);
00918
00919 freestats(ps.stats);
00920 freeimage(mbias);
00921
00922 if (ilist == NULL) {
00923 cpl_msg_error(_id,"Error in image list <%s>",cpl_error_get_message());
00924 freevector(scales);
00925 freeimage(trim_raw);
00926 freemask(bpm_map);
00927 return -1;
00928 }
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938 omega_pfits_get_conad(ps.eh, &gain);
00939
00940
00941 if (gain < 0.1){
00942 omega_pfits_get_gain(ps.eh, &gain);
00943
00944 if(gain < 0.1) {
00945 cpl_msg_info(_id,"Using default value for gain");
00946 gain = 2.0;
00947 }
00948 }
00949 else {
00950 cpl_msg_info(_id,"Gain value from images is %g", gain);
00951 }
00952
00953 cpl_msg_info (_id,"Computing the median of all images...");
00954 median_all = cpl_imagelist_collapse_median_create(ilist);
00955
00956 if (median_all == NULL) {
00957 cpl_msg_error (_id,"Cannot take median of imset <%s>",cpl_error_get_message());
00958 freevector(scales);
00959 freeilist(ilist);
00960 freemask(bpm_map);
00961 return -1;
00962 }
00963
00964 naxis1 = cpl_image_get_size_x(median_all);
00965 naxis2 = cpl_image_get_size_y(median_all);
00966
00967 sum_data = cpl_image_new(naxis1,naxis2,CPL_TYPE_FLOAT);
00968 sum_good = cpl_image_new(naxis1,naxis2,CPL_TYPE_FLOAT);
00969
00970
00971 for (i=0; i< nflats; i++)
00972 {
00973 trim_raw = cpl_imagelist_get(ilist, i);
00974 new_image = cpl_image_duplicate(trim_raw);
00975
00976
00977
00978
00979
00980 cpl_image_threshold(trim_raw, 0, FLT_MAX, 0, 2e20);
00981
00982 dev = cpl_image_subtract_create(median_all, trim_raw);
00983
00984 code = cpl_image_power(trim_raw, 0.5);
00985 if(code != CPL_ERROR_NONE) {
00986 cpl_msg_error(_id,"Error in SQRT operation <%s>",cpl_error_get_message());
00987 freevector(scales);
00988 freeilist(ilist);
00989 freeimage(median_all);
00990 freeimage(sum_data);
00991 freeimage(sum_good);
00992 freeimage(new_image);
00993 freeimage(dev);
00994 freemask(bpm_map);
00995 return -1;
00996 }
00997
00998 cpl_image_divide(dev, trim_raw);
00999
01000 threshold = omega_mflat_config.sigma * (sqrt(gain * data_scales[i]));
01001
01002 good = cpl_mask_threshold_image_create(dev, -threshold, threshold);
01003
01004 freeimage(dev);
01005 good_int = cpl_image_new_from_mask(good) ;
01006 freemask(good) ;
01007
01008 good_float = cpl_image_cast(good_int, CPL_TYPE_FLOAT);
01009 freeimage(good_int);
01010
01011 cpl_image_multiply(new_image, good_float);
01012 cpl_image_add(sum_data, new_image);
01013
01014 cpl_image_add(sum_good, good_float);
01015
01016 freeimage(new_image);
01017 freeimage(good_float);
01018
01019 }
01020
01021 freeimage(median_all);
01022 freevector(scales);
01023
01024
01025 ps.mtwilight = cpl_image_divide_create(sum_data, sum_good);
01026 if (ps.mtwilight == NULL) {
01027 cpl_msg_error(_id,"Error in division %s <%s>",MTWIL_PROCATG, cpl_error_get_message());
01028 freeilist(ilist);
01029 freeimage(sum_data);
01030 freeimage(sum_good);
01031 freemask(bpm_map);
01032 return -1;
01033 }
01034
01035 freeimage(sum_data);
01036 freeimage(sum_good);
01037 freeilist(ilist);
01038
01039
01040
01041 if(ps.mdomefr != NULL){
01042
01043 mdome = cpl_image_load(cpl_frame_get_filename(ps.mdomefr), CPL_TYPE_FLOAT,0,xn);
01044 if (mdome == NULL){
01045 cpl_msg_warning(_id,"Cannot load image %s", OMEGA_CALIB_DOME);
01046 ps.mflat = cpl_image_duplicate(ps.mtwilight);
01047 }
01048 else{
01049 ps.mflat = omega_make_mflat(mdome,ps.mtwilight,bpm_map,pars);
01050 if(ps.mflat == NULL){
01051 cpl_msg_warning(_id,"Cannot calculate Master Flat Field");
01052 ps.mflat = cpl_image_duplicate(ps.mtwilight);
01053 }
01054 freeimage(mdome);
01055 }
01056 }
01057 else{
01058 cpl_msg_warning(_id,"There is no Master Dome Flat in frame set");
01059 ps.mflat = cpl_image_duplicate(ps.mtwilight);
01060 }
01061
01062
01063 if (ps.nskyfr != NULL) {
01064 nsky = cpl_image_load(cpl_frame_get_filename(ps.nskyfr), CPL_TYPE_FLOAT,0,xn);
01065 if (nsky == NULL) {
01066 cpl_msg_warning(_id,"Cannot load image %s", OMEGA_CALIB_NSKY);
01067 }
01068 else{
01069 cpl_image_multiply (ps.mflat, nsky);
01070 freeimage(nsky);
01071 }
01072 }
01073
01074
01075
01076
01077 if(bpm_map != NULL)
01078 ps.bpixels = cpl_image_new_from_mask(bpm_map);
01079
01080 omega_mflat_config.bpm = cpl_mask_count(bpm_map);
01081 freemask(bpm_map);
01082
01083 return 0;
01084 }
01085
01086
01087 static void omega_mflat_init(void) {
01088 ps.bpixels = NULL;
01089 ps.cframe = NULL;
01090 ps.eh = NULL;
01091 ps.firstflat = NULL;
01092 ps.flatlist = NULL;
01093 ps.hframe = NULL;
01094 ps.labels = NULL;
01095 ps.mbframe = NULL;
01096 ps.mdomefr = NULL;
01097 ps.mflat = NULL;
01098 ps.mtwilight = NULL;
01099 ps.nskyfr = NULL;
01100 ps.stats = NULL;
01101 }
01102
01103
01104 static void omega_mflat_tidy(void) {
01105 freefits(ps.firstflat);
01106 freeframeset(ps.flatlist);
01107 freeimage(ps.bpixels);
01108 freeimage(ps.mflat);
01109 freeimage(ps.mtwilight);
01110 freespace(ps.labels);
01111 freestats(ps.stats);
01112 }
01113