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 #include "omega_wcscor.h"
00038
00062
00063
00064
00065
00066 static int omega_nightsky_flat_create(cpl_plugin *) ;
00067 static int omega_nightsky_flat_exec(cpl_plugin *) ;
00068 static int omega_nightsky_flat_destroy(cpl_plugin *) ;
00069 static int omega_nightsky_flat(cpl_frameset *, cpl_parameterlist *) ;
00070 cpl_image *omega_nsky_process(omega_fits *scifits, cpl_image *bias, cpl_image *flat,
00071 cpl_image *bpm, cpl_parameterlist *pars, int ext);
00072
00073 static int omega_nsky_load_calib(int ext);
00074 static void omega_nsky_init(void);
00075 static void omega_nsky_tidy(int level);
00076
00077
00078
00079 static struct {
00080
00081 int extnum;
00082 int oc;
00083
00084 }omega_nsky_config;
00085
00086 static struct {
00087
00088
00089 cpl_size *labels;
00090 const cpl_frame *mbiasfr;
00091 const cpl_frame *mflatfr;
00092 const cpl_frame *bpmfr;
00093 cpl_frameset *sciset;
00094 omega_fits *scifits;
00095
00096
00097 cpl_image *bpm;
00098 cpl_image *mbias;
00099 cpl_image *mflat;
00100 cpl_image *nsky;
00101
00102 }ps;
00103
00104 #define RECIPE "omega_nightsky_flat"
00105
00106
00115
00116 int cpl_plugin_get_info(cpl_pluginlist * list)
00117 {
00118 cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe)) ;
00119 cpl_plugin * plugin = &recipe->interface ;
00120
00121 cpl_plugin_init(plugin,
00122 CPL_PLUGIN_API,
00123 OMEGA_BINARY_VERSION,
00124 CPL_PLUGIN_TYPE_RECIPE,
00125 "omega_nightsky_flat",
00126 "OMEGA - Create Master Night Sky Flat.",
00127 "This recipe is used to create a Master Night Sky Flat or also called \n"
00128 "a Blank Sky Flat. The recipe always takes as input a list of at least 3 \n"
00129 "science frames, a master bias and a master flat. In addition to these, \n"
00130 "an optional Bad Pixels Map may be provided.",
00131 "Sandra Castro",
00132 "scastro@eso.org",
00133 omega_get_license(),
00134 omega_nightsky_flat_create,
00135 omega_nightsky_flat_exec,
00136 omega_nightsky_flat_destroy) ;
00137
00138 cpl_pluginlist_append(list, plugin) ;
00139
00140 return 0;
00141 }
00142
00143
00152
00153 static int omega_nightsky_flat_create(cpl_plugin * plugin)
00154 {
00155 cpl_recipe * recipe;
00156 cpl_parameter * p ;
00157
00158
00159 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00160 cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
00161 cpl_func, __LINE__, cpl_error_get_where());
00162 return (int)cpl_error_get_code();
00163 }
00164
00165 if (plugin == NULL) {
00166 cpl_msg_error(cpl_func, "Null plugin");
00167 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
00168 }
00169
00170
00171 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
00172 cpl_msg_error(cpl_func, "Plugin is not a recipe");
00173 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
00174 }
00175
00176
00177 recipe = (cpl_recipe *)plugin;
00178
00179
00180 recipe->parameters = cpl_parameterlist_new() ;
00181 if (recipe->parameters == NULL) {
00182 cpl_msg_error(cpl_func, "Parameter list allocation failed");
00183 cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
00184 }
00185
00186
00187 p = cpl_parameter_new_value("omega.omega_nightsky_flat.ExtensionNumber",
00188 CPL_TYPE_INT,
00189 "FITS extension number to load (1 to 32). (-1 == all)",
00190 "omega_nightsky_flat",
00191 -1) ;
00192
00193 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"ext") ;
00194 cpl_parameterlist_append(recipe->parameters, p) ;
00195
00196 p = cpl_parameter_new_range("omega.omega_nightsky_flat.OverscanMethod",
00197 CPL_TYPE_INT,
00198 "Overscan Correction Method",
00199 "omega_nightsky_flat",
00200 0, 0, 6);
00201 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI, "oc-meth") ;
00202 cpl_parameterlist_append(recipe->parameters, p) ;
00203
00204
00205 return 0;
00206 }
00207
00208
00214
00215 static int omega_nightsky_flat_exec(cpl_plugin * plugin)
00216 {
00217 cpl_recipe * recipe;
00218 int recipe_status;
00219
00220
00221 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00222 cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
00223 cpl_func, __LINE__, cpl_error_get_where());
00224 return (int)cpl_error_get_code();
00225 }
00226
00227 if (plugin == NULL) {
00228 cpl_msg_error(cpl_func, "Null plugin");
00229 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
00230 }
00231
00232
00233 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
00234 cpl_msg_error(cpl_func, "Plugin is not a recipe");
00235 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
00236 }
00237
00238
00239 recipe = (cpl_recipe *)plugin;
00240
00241
00242 if (recipe->parameters == NULL) {
00243 cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
00244 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
00245 }
00246 if (recipe->frames == NULL) {
00247 cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
00248 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
00249 }
00250
00251
00252 recipe_status = omega_nightsky_flat(recipe->frames, recipe->parameters);
00253
00254
00255 if (cpl_dfs_update_product_header(recipe->frames)) {
00256 if (!recipe_status) recipe_status = (int)cpl_error_get_code();
00257 }
00258
00259 return recipe_status;
00260 }
00261
00262
00268
00269 static int omega_nightsky_flat_destroy(cpl_plugin * plugin)
00270 {
00271 cpl_recipe * recipe;
00272
00273 if (plugin == NULL) {
00274 cpl_msg_error(cpl_func, "Null plugin");
00275 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
00276 }
00277
00278
00279 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
00280 cpl_msg_error(cpl_func, "Plugin is not a recipe");
00281 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
00282 }
00283
00284
00285 recipe = (cpl_recipe *)plugin;
00286
00287 cpl_parameterlist_delete(recipe->parameters) ;
00288
00289 return 0 ;
00290 }
00291
00292
00299
00300 static int omega_nightsky_flat(cpl_frameset *set, cpl_parameterlist *pars)
00301 {
00302
00303 int i,j,jst,jfn,isfirst;
00304 cpl_size nlab;
00305 int nraw = 0;
00306 char *outfile = NULL;
00307
00308 cpl_frame *sciframe, *product_frame;
00309 cpl_parameter *par;
00310 cpl_image *image;
00311 cpl_imagelist *ilist;
00312 cpl_propertylist *qclist;
00313 cpl_stats *stats;
00314
00315
00316
00317 if (!pars) {
00318 cpl_msg_error (cpl_func, "Parameters list not found");
00319 return -1;
00320 }
00321
00322 if (cpl_frameset_is_empty(set) == 1) {
00323 cpl_msg_error (cpl_func, "Frameset not found");
00324 return -1;
00325 }
00326
00327
00328 par = cpl_parameterlist_find(pars, "omega.omega_nightsky_flat.ExtensionNumber") ;
00329 omega_nsky_config.extnum = cpl_parameter_get_int(par) ;
00330
00331
00332 if (oc_dfs_set_groups(set)) {
00333 cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames") ;
00334 return -1 ;
00335 }
00336
00337
00338 omega_nsky_init();
00339
00340
00341 if ((ps.labels = cpl_frameset_labelise(set,omega_compare_tags,
00342 &nlab)) == NULL) {
00343 cpl_msg_error(cpl_func,"Cannot labelise the input frameset");
00344 omega_nsky_tidy(0);
00345 return -1;
00346 }
00347 if ((ps.sciset = omega_frameset_subgroup(set,ps.labels,nlab,
00348 NSKY_RAW)) == NULL) {
00349 cpl_msg_error(cpl_func,"Cannot find night sky frames in input frameset");
00350 omega_nsky_tidy(0);
00351 return -1;
00352 }
00353
00354
00355
00356 nraw = cpl_frameset_count_tags(ps.sciset, NSKY_RAW);
00357 if (nraw < 3) {
00358 cpl_msg_error (cpl_func, "Need at least 3 (%s) frames to run "
00359 "this recipe", NSKY_RAW);
00360 omega_nsky_tidy(0);
00361 return -1;
00362 }
00363
00364 cpl_msg_info (cpl_func,"There are %d %s frames in frame set",nraw, NSKY_RAW);
00365
00366
00367
00368 ps.mbiasfr = cpl_frameset_find_const(set, OMEGA_CALIB_BIAS);
00369 if (ps.mbiasfr == NULL) {
00370 cpl_msg_error(cpl_func,"Cannot find %s frame in frame set", OMEGA_CALIB_BIAS);
00371 omega_nsky_tidy(0);
00372 }
00373 cpl_msg_info(cpl_func,"Using %s %s",OMEGA_CALIB_BIAS, cpl_frame_get_filename(ps.mbiasfr));
00374
00375
00376 ps.mflatfr = cpl_frameset_find_const(set, OMEGA_CALIB_FLAT);
00377 if(ps.mflatfr == NULL) {
00378 cpl_msg_error(cpl_func,"Cannot find %s frame in frame set", OMEGA_CALIB_FLAT);
00379 omega_nsky_tidy(0);
00380 return -1;
00381 }
00382 cpl_msg_info(cpl_func,"Using %s %s", OMEGA_CALIB_FLAT, cpl_frame_get_filename(ps.mflatfr));
00383
00384
00385 ps.bpmfr = cpl_frameset_find (set,OMEGA_CALIB_BPM);
00386 if(ps.bpmfr != NULL)
00387 cpl_msg_info(cpl_func,"Using %s %s",OMEGA_CALIB_BPM,cpl_frame_get_filename(ps.bpmfr));
00388
00389
00390 sciframe = cpl_frameset_get_first(ps.sciset);
00391
00392
00393 omega_extensions(sciframe, omega_nsky_config.extnum,&jst,&jfn);
00394 if(omega_nsky_config.extnum == 0){
00395 cpl_msg_error(cpl_func,"Unsupported extension request, %d",omega_nsky_config.extnum);
00396 omega_nsky_tidy(0);
00397 return -1;
00398 }
00399
00400 for (j = jst; j <= jfn; j++) {
00401 isfirst = (j == jst);
00402 cpl_msg_indent_more();
00403 cpl_msg_info(cpl_func,".....Working on extension %d.....",j);
00404 cpl_msg_indent_less();
00405
00406
00407 if(omega_nsky_load_calib(j) != 0){
00408 cpl_msg_error(cpl_func,"Cannot load calibration frame(s)");
00409 freespace(outfile);
00410 omega_nsky_tidy(0);
00411 return -1;
00412 }
00413
00414 ilist = cpl_imagelist_new();
00415
00416 sciframe = cpl_frameset_get_first(ps.sciset);
00417 for(i = 0; i < nraw; i++) {
00418
00419 ps.scifits = omega_fits_load(sciframe, CPL_TYPE_FLOAT, j);
00420
00421
00422 image = omega_nsky_process(ps.scifits,ps.mbias,ps.mflat,ps.bpm, pars, j);
00423 if(image == NULL){
00424 cpl_msg_error(cpl_func,"Cannot reduce image %d of %d",i,nraw);
00425 freespace(outfile);
00426 freeilist(ilist);
00427 omega_nsky_tidy(0);
00428 return -1;
00429 }
00430
00431 cpl_imagelist_set(ilist, image,i);
00432 sciframe = cpl_frameset_get_next(ps.sciset);
00433 freefits(ps.scifits);
00434 ps.scifits = NULL;
00435
00436 }
00437 ps.nsky = omega_nsky_create(ilist,ps.bpm,nraw);
00438 freeilist(ilist);
00439
00440 if(isfirst){
00441 outfile = cpl_sprintf("%s_%s.fits", INSTRUME,NSKY_PROCATG);
00442 product_frame = omega_product_frame(outfile, NSKY_PROCATG, CPL_FRAME_TYPE_IMAGE);
00443 }
00444
00445 stats = cpl_stats_new_from_image(ps.nsky, CPL_STATS_ALL);
00446 qclist = cpl_propertylist_new();
00447 cpl_propertylist_append_double(qclist, "HIERARCH ESO QC NSKYMIN", cpl_stats_get_min(stats));
00448 cpl_propertylist_append_double(qclist, "HIERARCH ESO QC NSKYMAX", cpl_stats_get_max(stats));
00449 cpl_propertylist_append_double(qclist, "HIERARCH ESO QC NSKYMEAN", cpl_stats_get_mean(stats));
00450 cpl_propertylist_append_double(qclist, "HIERARCH ESO QC NSKYDEV", cpl_stats_get_stdev(stats));
00451 cpl_propertylist_append_double(qclist, "HIERARCH ESO QC NSKYMED", cpl_stats_get_median(stats));
00452 freestats(stats);
00453
00454 cpl_msg_info(cpl_func,"Saving Night Sky Flat");
00455
00456 if(omega_save_image(ps.nsky,set,pars,NULL,qclist,CPL_BPP_IEEE_FLOAT,outfile,
00457 RECIPE,product_frame,NULL,isfirst) == -1){
00458 cpl_msg_error(cpl_func,"Cannot save product %s",NSKY_PROCATG);
00459 freeplist(qclist);
00460 freespace(outfile);
00461 omega_nsky_tidy(0);
00462 return -1;
00463 }
00464
00465 freeplist(qclist);
00466 omega_nsky_tidy(1);
00467 }
00468
00469 freespace(outfile);
00470 omega_nsky_tidy(0);
00471
00472 return 0;
00473 }
00474
00487 cpl_image *omega_nsky_process(omega_fits *scifits, cpl_image *mbias, cpl_image *mflat,
00488 cpl_image *bpm, cpl_parameterlist *pars, int ext)
00489 {
00490 int oc = 0;
00491
00492 cpl_image *nsky;
00493 cpl_parameter *p;
00494 cpl_propertylist *xlist;
00495
00496 if((scifits == NULL) || (mbias == NULL) || (mflat == NULL) ||
00497 (bpm == NULL))
00498 return NULL;
00499
00500
00501 p = cpl_parameterlist_find(pars, "omega.omega_nightsky_flat.OverscanMethod") ;
00502 omega_nsky_config.oc = cpl_parameter_get_int(p);
00503
00504
00505 oc = omega_pfits_get_overscan(ps.mbiasfr, ext);
00506 if(oc != omega_nsky_config.oc) {
00507 cpl_msg_warning (cpl_func, "Overscan correction mode for Master Bias (oc = %d) differs from "
00508 "the one used here (oc = %d)", oc, omega_nsky_config.oc);
00509 }
00510
00511
00512 if((nsky = omega_trim_oscan_correct(scifits, omega_nsky_config.oc)) == NULL){
00513 cpl_msg_error(cpl_func,"Unable to trim image");
00514 return NULL;
00515 }
00516
00517
00518 xlist = omega_fits_get_ehu(scifits);
00519 omega_shift_refpix(omega_fits_get_frame(scifits), ext, xlist);
00520
00521
00522 omega_biascor(nsky, mbias);
00523
00524
00525 if(omega_flatcor(nsky, mflat, NULL) != 0){
00526 cpl_msg_error(cpl_func,"Error in flat correction");
00527 freeimage(nsky);
00528 xlist = NULL;
00529 return NULL;
00530 }
00531
00532 xlist = NULL;
00533
00534 return nsky;
00535 }
00536
00537
00538 static int omega_nsky_load_calib(int ext)
00539 {
00540
00541
00542
00543 ps.mbias = cpl_image_load(cpl_frame_get_filename(ps.mbiasfr), CPL_TYPE_FLOAT, 0, ext);
00544 if(ps.mbias == NULL){
00545 cpl_msg_error(cpl_func,"Cannot load Master Bias. %s", cpl_error_get_message());
00546 return -1;
00547 }
00548
00549 ps.mflat = cpl_image_load(cpl_frame_get_filename(ps.mflatfr),CPL_TYPE_FLOAT,0,ext);
00550 if (ps.mflat == NULL){
00551 cpl_msg_error(cpl_func,"Cannot load Master Flat. %s",cpl_error_get_message());
00552 return -1;
00553 }
00554
00555
00556
00557 if(ps.bpmfr != NULL){
00558 ps.bpm = cpl_image_load(cpl_frame_get_filename(ps.bpmfr), CPL_TYPE_INT, 0, ext);
00559 if(ps.bpm == NULL)
00560 cpl_msg_warning(cpl_func, "Cannot load BPM. %s", cpl_error_get_message());
00561
00562 }
00563
00564 return 0;
00565 }
00566
00567
00568 static void omega_nsky_init(void)
00569 {
00570 ps.sciset = NULL;
00571 ps.bpmfr = NULL;
00572 ps.mbiasfr = NULL;
00573 ps.mflatfr = NULL;
00574 ps.scifits = NULL;
00575 ps.labels = NULL;
00576 ps.mbias = NULL;
00577 ps.mflat = NULL;
00578 ps.bpm = NULL;
00579 ps.nsky = NULL;
00580 }
00581
00582
00583
00584
00585 static void omega_nsky_tidy(int level)
00586 {
00587 freeimage(ps.mbias);
00588 freeimage(ps.mflat);
00589 freeimage(ps.bpm);
00590 freeimage(ps.nsky);
00591 if(level == 1)
00592 return;
00593
00594 freeframeset(ps.sciset);
00595 freespace(ps.labels);
00596 freefits(ps.scifits);
00597 }
00598