00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028
00029
00030
00031 #include <string.h>
00032 #include <strings.h>
00033 #include <cpl.h>
00034
00035 #include "muse_twilight_z.h"
00036
00037
00087
00090
00091
00092
00093 static const char *muse_twilight_help =
00094 "Processing first handles each raw input image separately: it trims the raw data and records the overscan statistics, subtracts the bias (taking account of the overscan, if --overscan is not &none&), converts the images from adu to count, subtracts the dark, divides by the flat-field and combines all the exposures using input parameters. The input calibrations geometry table, trace table, and wavelength calibration table are used to assign 3D coordinates to each CCD-based pixel, thereby creating a pixel table from the master sky-flat. These pixel tables are then cut in wavelength using the --lambdamin and --lambdamax parameters. The integrated flux in each IFU is computed as the sum of the data in the pixel table, and saved in the header, to be used later as estimate for the relative throughput of each IFU. If an ILLUM exposure was given as input, it is then used to correct the relative illumination between all slices of one IFU. For this, the data of each slice within the pixel table of each IFU is multiplied by the normalized median flux of that slice in the ILLUM exposure. The pixel tables of all IFUs are then merged, using the integrated fluxes as inverse scaling factors, and a cube is reconstructed from the merged dataset, using given parameters. A white-light image is created from the cube. This skyflat cube is then saved to disk, with the white-light image as one extension. To construct a smooth 3D illumination correction, the cube is post-processed in the following way: the white-light image is used to create a mask of the illuminated area. From this area, the optional vignetting mask is removed. The smoothing is then computed for each plane of the cube: the illuminated area is smoothed (by a 5x7 median filter), normalized, fit with a 2D polynomial (of given polynomial orders), and normalized again. A smooth white image is then created by collapsing the smooth cube. If a vignetting mask was given, the corner area given by the mask is used to compute a 2D correction for the vignetted area: the original unsmoothed white-light image is corrected for large scale gradients by dividing it with the smooth white image. The residuals in the corner area then smoothed using input parameters. This smoothed vignetting correction is the multiplied onto each plane of the smooth cube, normalizing each plane again. This twilight cube is then saved to disk.";
00095
00096 static const char *muse_twilight_help_esorex =
00097 "\n\nInput frames for raw frame tag \"SKYFLAT\":\n"
00098 "\n Frame tag Type Req #Fr Description"
00099 "\n -------------------- ---- --- --- ------------"
00100 "\n SKYFLAT raw Y >=3 Raw twilight skyflat"
00101 "\n ILLUM raw . 1 Single optional raw (attached/illumination) flat-field exposure"
00102 "\n MASTER_BIAS calib Y 1 Master bias"
00103 "\n MASTER_DARK calib . 1 Master dark"
00104 "\n MASTER_FLAT calib Y 1 Master flat"
00105 "\n BADPIX_TABLE calib . 1 Known bad pixels"
00106 "\n TRACE_TABLE calib Y 1 Tracing table for all slices"
00107 "\n WAVECAL_TABLE calib Y 1 Wavelength calibration table"
00108 "\n GEOMETRY_TABLE calib Y 1 Relative positions of the slices in the field of view"
00109 "\n VIGNETTING_MASK calib . 1 Mask to mark vignetted regions in the MUSE field of view"
00110 "\n\nProduct frames for raw frame tag \"SKYFLAT\":\n"
00111 "\n Frame tag Level Description"
00112 "\n -------------------- -------- ------------"
00113 "\n DATACUBE_SKYFLAT final Cube of combined twilight skyflat exposures"
00114 "\n TWILIGHT_CUBE final Smoothed cube of twilight sky";
00115
00116
00124
00125 static cpl_recipeconfig *
00126 muse_twilight_new_recipeconfig(void)
00127 {
00128 cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
00129
00130 cpl_recipeconfig_set_tag(recipeconfig, "SKYFLAT", 3, -1);
00131 cpl_recipeconfig_set_input(recipeconfig, "SKYFLAT", "MASTER_BIAS", 1, 1);
00132 cpl_recipeconfig_set_input(recipeconfig, "SKYFLAT", "MASTER_DARK", -1, 1);
00133 cpl_recipeconfig_set_input(recipeconfig, "SKYFLAT", "MASTER_FLAT", 1, 1);
00134 cpl_recipeconfig_set_input(recipeconfig, "SKYFLAT", "BADPIX_TABLE", -1, 1);
00135 cpl_recipeconfig_set_input(recipeconfig, "SKYFLAT", "TRACE_TABLE", 1, 1);
00136 cpl_recipeconfig_set_input(recipeconfig, "SKYFLAT", "WAVECAL_TABLE", 1, 1);
00137 cpl_recipeconfig_set_input(recipeconfig, "SKYFLAT", "GEOMETRY_TABLE", 1, 1);
00138 cpl_recipeconfig_set_input(recipeconfig, "SKYFLAT", "VIGNETTING_MASK", -1, 1);
00139 cpl_recipeconfig_set_output(recipeconfig, "SKYFLAT", "DATACUBE_SKYFLAT");
00140 cpl_recipeconfig_set_output(recipeconfig, "SKYFLAT", "TWILIGHT_CUBE");
00141 cpl_recipeconfig_set_tag(recipeconfig, "ILLUM", -1, 1);
00142 cpl_recipeconfig_set_input(recipeconfig, "ILLUM", "MASTER_BIAS", 1, 1);
00143 cpl_recipeconfig_set_input(recipeconfig, "ILLUM", "MASTER_DARK", -1, 1);
00144 cpl_recipeconfig_set_input(recipeconfig, "ILLUM", "MASTER_FLAT", 1, 1);
00145 cpl_recipeconfig_set_input(recipeconfig, "ILLUM", "BADPIX_TABLE", -1, 1);
00146 cpl_recipeconfig_set_input(recipeconfig, "ILLUM", "TRACE_TABLE", 1, 1);
00147 cpl_recipeconfig_set_input(recipeconfig, "ILLUM", "WAVECAL_TABLE", 1, 1);
00148 cpl_recipeconfig_set_input(recipeconfig, "ILLUM", "GEOMETRY_TABLE", 1, 1);
00149 cpl_recipeconfig_set_input(recipeconfig, "ILLUM", "VIGNETTING_MASK", -1, 1);
00150
00151 return recipeconfig;
00152 }
00153
00154
00164
00165 static cpl_error_code
00166 muse_twilight_prepare_header(const char *aFrametag, cpl_propertylist *aHeader)
00167 {
00168 cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
00169 cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
00170 if (!strcmp(aFrametag, "DATACUBE_SKYFLAT")) {
00171 muse_processing_prepare_property(aHeader, "ESO QC TWILIGHT[0-9]+ INPUT[0-9]+ MEDIAN",
00172 CPL_TYPE_FLOAT,
00173 "Median value of raw exposure i of IFU m in input list");
00174 muse_processing_prepare_property(aHeader, "ESO QC TWILIGHT[0-9]+ INPUT[0-9]+ MEAN",
00175 CPL_TYPE_FLOAT,
00176 "Mean value of raw exposure i of IFU m in input list");
00177 muse_processing_prepare_property(aHeader, "ESO QC TWILIGHT[0-9]+ INPUT[0-9]+ STDEV",
00178 CPL_TYPE_FLOAT,
00179 "Standard deviation of raw exposure i of IFU m in input list");
00180 muse_processing_prepare_property(aHeader, "ESO QC TWILIGHT[0-9]+ INPUT[0-9]+ MIN",
00181 CPL_TYPE_FLOAT,
00182 "Minimum value of raw exposure i of IFU m in input list");
00183 muse_processing_prepare_property(aHeader, "ESO QC TWILIGHT[0-9]+ INPUT[0-9]+ MAX",
00184 CPL_TYPE_FLOAT,
00185 "Maximum value of raw exposure i of IFU m in input list");
00186 muse_processing_prepare_property(aHeader, "ESO QC TWILIGHT[0-9]+ INPUT[0-9]+ NSATURATED",
00187 CPL_TYPE_INT,
00188 "Number of saturated pixels in raw exposure i of IFU m in input list");
00189 muse_processing_prepare_property(aHeader, "ESO QC TWILIGHT[0-9]+ MASTER MEDIAN",
00190 CPL_TYPE_FLOAT,
00191 "Median value of the combined exposures in IFU m");
00192 muse_processing_prepare_property(aHeader, "ESO QC TWILIGHT[0-9]+ MASTER MEAN",
00193 CPL_TYPE_FLOAT,
00194 "Mean value of the combined exposures in IFU m");
00195 muse_processing_prepare_property(aHeader, "ESO QC TWILIGHT[0-9]+ MASTER STDEV",
00196 CPL_TYPE_FLOAT,
00197 "Standard deviation of the combined exposures in IFU m");
00198 muse_processing_prepare_property(aHeader, "ESO QC TWILIGHT[0-9]+ MASTER MIN",
00199 CPL_TYPE_FLOAT,
00200 "Minimum value of the combined exposures in IFU m");
00201 muse_processing_prepare_property(aHeader, "ESO QC TWILIGHT[0-9]+ MASTER MAX",
00202 CPL_TYPE_FLOAT,
00203 "Maximum value of the combined exposures in IFU m");
00204 muse_processing_prepare_property(aHeader, "ESO QC TWILIGHT[0-9]+ MASTER INTFLUX",
00205 CPL_TYPE_FLOAT,
00206 "Flux integrated over the whole CCD of the combined exposures of IFU m");
00207 muse_processing_prepare_property(aHeader, "ESO QC TWILIGHT[0-9]+ INTFLUX",
00208 CPL_TYPE_FLOAT,
00209 "Flux integrated over all slices of IFU m. Computed using the pixel table of the exposure.");
00210 } else if (!strcmp(aFrametag, "TWILIGHT_CUBE")) {
00211 } else {
00212 cpl_msg_warning(__func__, "Frame tag %s is not defined", aFrametag);
00213 return CPL_ERROR_ILLEGAL_INPUT;
00214 }
00215 return CPL_ERROR_NONE;
00216 }
00217
00218
00227
00228 static cpl_frame_level
00229 muse_twilight_get_frame_level(const char *aFrametag)
00230 {
00231 if (!aFrametag) {
00232 return CPL_FRAME_LEVEL_NONE;
00233 }
00234 if (!strcmp(aFrametag, "DATACUBE_SKYFLAT")) {
00235 return CPL_FRAME_LEVEL_FINAL;
00236 }
00237 if (!strcmp(aFrametag, "TWILIGHT_CUBE")) {
00238 return CPL_FRAME_LEVEL_FINAL;
00239 }
00240 return CPL_FRAME_LEVEL_NONE;
00241 }
00242
00243
00252
00253 static muse_frame_mode
00254 muse_twilight_get_frame_mode(const char *aFrametag)
00255 {
00256 if (!aFrametag) {
00257 return MUSE_FRAME_MODE_ALL;
00258 }
00259 if (!strcmp(aFrametag, "DATACUBE_SKYFLAT")) {
00260 return MUSE_FRAME_MODE_MASTER;
00261 }
00262 if (!strcmp(aFrametag, "TWILIGHT_CUBE")) {
00263 return MUSE_FRAME_MODE_MASTER;
00264 }
00265 return MUSE_FRAME_MODE_ALL;
00266 }
00267
00268
00278
00279 static int
00280 muse_twilight_create(cpl_plugin *aPlugin)
00281 {
00282
00283 cpl_recipe *recipe;
00284 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
00285 recipe = (cpl_recipe *)aPlugin;
00286 } else {
00287 return -1;
00288 }
00289
00290
00291
00292 muse_processinginfo_register(recipe,
00293 muse_twilight_new_recipeconfig(),
00294 muse_twilight_prepare_header,
00295 muse_twilight_get_frame_level,
00296 muse_twilight_get_frame_mode);
00297
00298
00299
00300 if (muse_cplframework() == MUSE_CPLFRAMEWORK_ESOREX) {
00301 cpl_msg_set_time_on();
00302 }
00303
00304
00305 recipe->parameters = cpl_parameterlist_new();
00306
00307 cpl_parameter *p;
00308
00309
00310 p = cpl_parameter_new_value("muse.muse_twilight.overscan",
00311 CPL_TYPE_STRING,
00312 "If this is \"none\", stop when detecting discrepant overscan levels (see ovscsigma), for \"offset\" it assumes that the mean overscan level represents the real offset in the bias levels of the exposures involved, and adjusts the data accordingly; for \"vpoly\", a polynomial is fit to the vertical overscan and subtracted from the whole quadrant.",
00313 "muse.muse_twilight",
00314 (const char *)"vpoly");
00315 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "overscan");
00316 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "overscan");
00317
00318 cpl_parameterlist_append(recipe->parameters, p);
00319
00320
00321 p = cpl_parameter_new_value("muse.muse_twilight.ovscreject",
00322 CPL_TYPE_STRING,
00323 "This influences how values are rejected when computing overscan statistics. Either no rejection at all (\"none\"), rejection using the DCR algorithm (\"dcr\"), or rejection using an iterative constant fit (\"fit\").",
00324 "muse.muse_twilight",
00325 (const char *)"dcr");
00326 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ovscreject");
00327 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ovscreject");
00328
00329 cpl_parameterlist_append(recipe->parameters, p);
00330
00331
00332 p = cpl_parameter_new_value("muse.muse_twilight.ovscsigma",
00333 CPL_TYPE_DOUBLE,
00334 "If the deviation of mean overscan levels between a raw input image and the reference image is higher than |ovscsigma x stdev|, stop the processing. If overscan=\"vpoly\", this is used as sigma rejection level for the iterative polynomial fit (the level comparison is then done afterwards with |100 x stdev| to guard against incompatible settings). Has no effect for overscan=\"offset\".",
00335 "muse.muse_twilight",
00336 (double)30.);
00337 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ovscsigma");
00338 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ovscsigma");
00339
00340 cpl_parameterlist_append(recipe->parameters, p);
00341
00342
00343 p = cpl_parameter_new_value("muse.muse_twilight.ovscignore",
00344 CPL_TYPE_INT,
00345 "The number of pixels of the overscan adjacent to the data region of the CCD that are ignored when computing statistics or fits.",
00346 "muse.muse_twilight",
00347 (int)3);
00348 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ovscignore");
00349 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ovscignore");
00350
00351 cpl_parameterlist_append(recipe->parameters, p);
00352
00353
00354 p = cpl_parameter_new_enum("muse.muse_twilight.combine",
00355 CPL_TYPE_STRING,
00356 "Type of combination to use",
00357 "muse.muse_twilight",
00358 (const char *)"sigclip",
00359 4,
00360 (const char *)"average",
00361 (const char *)"median",
00362 (const char *)"minmax",
00363 (const char *)"sigclip");
00364 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "combine");
00365 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "combine");
00366
00367 cpl_parameterlist_append(recipe->parameters, p);
00368
00369
00370 p = cpl_parameter_new_value("muse.muse_twilight.nlow",
00371 CPL_TYPE_INT,
00372 "Number of minimum pixels to reject with minmax",
00373 "muse.muse_twilight",
00374 (int)1);
00375 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nlow");
00376 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nlow");
00377
00378 cpl_parameterlist_append(recipe->parameters, p);
00379
00380
00381 p = cpl_parameter_new_value("muse.muse_twilight.nhigh",
00382 CPL_TYPE_INT,
00383 "Number of maximum pixels to reject with minmax",
00384 "muse.muse_twilight",
00385 (int)1);
00386 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nhigh");
00387 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nhigh");
00388
00389 cpl_parameterlist_append(recipe->parameters, p);
00390
00391
00392 p = cpl_parameter_new_value("muse.muse_twilight.nkeep",
00393 CPL_TYPE_INT,
00394 "Number of pixels to keep with minmax",
00395 "muse.muse_twilight",
00396 (int)1);
00397 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nkeep");
00398 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nkeep");
00399
00400 cpl_parameterlist_append(recipe->parameters, p);
00401
00402
00403 p = cpl_parameter_new_value("muse.muse_twilight.lsigma",
00404 CPL_TYPE_DOUBLE,
00405 "Low sigma for pixel rejection with sigclip",
00406 "muse.muse_twilight",
00407 (double)3);
00408 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lsigma");
00409 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lsigma");
00410
00411 cpl_parameterlist_append(recipe->parameters, p);
00412
00413
00414 p = cpl_parameter_new_value("muse.muse_twilight.hsigma",
00415 CPL_TYPE_DOUBLE,
00416 "High sigma for pixel rejection with sigclip",
00417 "muse.muse_twilight",
00418 (double)3);
00419 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "hsigma");
00420 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "hsigma");
00421
00422 cpl_parameterlist_append(recipe->parameters, p);
00423
00424
00425 p = cpl_parameter_new_value("muse.muse_twilight.scale",
00426 CPL_TYPE_BOOL,
00427 "Scale the individual images to a common exposure time before combining them.",
00428 "muse.muse_twilight",
00429 (int)FALSE);
00430 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "scale");
00431 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "scale");
00432
00433 cpl_parameterlist_append(recipe->parameters, p);
00434
00435
00436 p = cpl_parameter_new_enum("muse.muse_twilight.resample",
00437 CPL_TYPE_STRING,
00438 "The resampling technique to use for the final output cube.",
00439 "muse.muse_twilight",
00440 (const char *)"drizzle",
00441 6,
00442 (const char *)"nearest",
00443 (const char *)"linear",
00444 (const char *)"quadratic",
00445 (const char *)"renka",
00446 (const char *)"drizzle",
00447 (const char *)"lanczos");
00448 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "resample");
00449 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "resample");
00450
00451 cpl_parameterlist_append(recipe->parameters, p);
00452
00453
00454 p = cpl_parameter_new_enum("muse.muse_twilight.crtype",
00455 CPL_TYPE_STRING,
00456 "Type of statistics used for detection of cosmic rays during final resampling. \"iraf\" uses the variance information, \"mean\" uses standard (mean/stdev) statistics, \"median\" uses median and the median median of the absolute median deviation.",
00457 "muse.muse_twilight",
00458 (const char *)"median",
00459 3,
00460 (const char *)"iraf",
00461 (const char *)"mean",
00462 (const char *)"median");
00463 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "crtype");
00464 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "crtype");
00465
00466 cpl_parameterlist_append(recipe->parameters, p);
00467
00468
00469 p = cpl_parameter_new_value("muse.muse_twilight.crsigma",
00470 CPL_TYPE_DOUBLE,
00471 "Sigma rejection factor to use for cosmic ray rejection during final resampling. A zero or negative value switches cosmic ray rejection off.",
00472 "muse.muse_twilight",
00473 (double)50.);
00474 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "crsigma");
00475 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "crsigma");
00476
00477 cpl_parameterlist_append(recipe->parameters, p);
00478
00479
00480 p = cpl_parameter_new_value("muse.muse_twilight.lambdamin",
00481 CPL_TYPE_DOUBLE,
00482 "Minimum wavelength for twilight reconstruction.",
00483 "muse.muse_twilight",
00484 (double)5000.);
00485 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambdamin");
00486 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambdamin");
00487
00488 cpl_parameterlist_append(recipe->parameters, p);
00489
00490
00491 p = cpl_parameter_new_value("muse.muse_twilight.lambdamax",
00492 CPL_TYPE_DOUBLE,
00493 "Maximum wavelength for twilight reconstruction.",
00494 "muse.muse_twilight",
00495 (double)9000.);
00496 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambdamax");
00497 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambdamax");
00498
00499 cpl_parameterlist_append(recipe->parameters, p);
00500
00501
00502 p = cpl_parameter_new_value("muse.muse_twilight.dlambda",
00503 CPL_TYPE_DOUBLE,
00504 "Sampling for twilight reconstruction, this should result in planes of equal wavelength coverage.",
00505 "muse.muse_twilight",
00506 (double)250.);
00507 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "dlambda");
00508 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dlambda");
00509
00510 cpl_parameterlist_append(recipe->parameters, p);
00511
00512
00513 p = cpl_parameter_new_value("muse.muse_twilight.xorder",
00514 CPL_TYPE_INT,
00515 "Polynomial order to use in x direction to fit the full field of view.",
00516 "muse.muse_twilight",
00517 (int)2);
00518 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "xorder");
00519 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "xorder");
00520
00521 cpl_parameterlist_append(recipe->parameters, p);
00522
00523
00524 p = cpl_parameter_new_value("muse.muse_twilight.yorder",
00525 CPL_TYPE_INT,
00526 "Polynomial order to use in y direction to fit the full field of view.",
00527 "muse.muse_twilight",
00528 (int)2);
00529 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "yorder");
00530 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "yorder");
00531
00532 cpl_parameterlist_append(recipe->parameters, p);
00533
00534
00535 p = cpl_parameter_new_value("muse.muse_twilight.vignmaskedges",
00536 CPL_TYPE_DOUBLE,
00537 "Pixels on edges stronger than this fraction in the normalized image are excluded from the fit to the vignetted area. Set to non-positive number to include them in the fit.",
00538 "muse.muse_twilight",
00539 (double)0.02);
00540 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "vignmaskedges");
00541 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "vignmaskedges");
00542
00543 cpl_parameterlist_append(recipe->parameters, p);
00544
00545
00546 p = cpl_parameter_new_enum("muse.muse_twilight.vignsmooth",
00547 CPL_TYPE_STRING,
00548 "Type of smoothing to use for the vignetted region given by the VIGNETTING_MASK; gaussian uses (vignxpar + vignypar)/2 as FWHM.",
00549 "muse.muse_twilight",
00550 (const char *)"polyfit",
00551 3,
00552 (const char *)"polyfit",
00553 (const char *)"gaussian",
00554 (const char *)"median");
00555 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "vignsmooth");
00556 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "vignsmooth");
00557
00558 cpl_parameterlist_append(recipe->parameters, p);
00559
00560
00561 p = cpl_parameter_new_value("muse.muse_twilight.vignxpar",
00562 CPL_TYPE_INT,
00563 "Parameter used by the vignetting smoothing: x order for polyfit (default, recommended 4), parameter that influences the FWHM for the gaussian (recommended: 10), or x dimension of median filter (recommended 5).",
00564 "muse.muse_twilight",
00565 (int)4);
00566 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "vignxpar");
00567 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "vignxpar");
00568
00569 cpl_parameterlist_append(recipe->parameters, p);
00570
00571
00572 p = cpl_parameter_new_value("muse.muse_twilight.vignypar",
00573 CPL_TYPE_INT,
00574 "Parameter used by the vignetting smoothing: y order for polyfit (default, recommended 4), parameter that influences the FWHM for the gaussian (recommended: 10), or y dimension of median filter (recommended 5).",
00575 "muse.muse_twilight",
00576 (int)4);
00577 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "vignypar");
00578 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "vignypar");
00579
00580 cpl_parameterlist_append(recipe->parameters, p);
00581
00582 return 0;
00583 }
00584
00585
00596
00597 static int
00598 muse_twilight_params_fill(muse_twilight_params_t *aParams, cpl_parameterlist *aParameters)
00599 {
00600 cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
00601 cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
00602 cpl_parameter *p;
00603
00604 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.overscan");
00605 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00606 aParams->overscan = cpl_parameter_get_string(p);
00607
00608 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.ovscreject");
00609 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00610 aParams->ovscreject = cpl_parameter_get_string(p);
00611
00612 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.ovscsigma");
00613 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00614 aParams->ovscsigma = cpl_parameter_get_double(p);
00615
00616 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.ovscignore");
00617 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00618 aParams->ovscignore = cpl_parameter_get_int(p);
00619
00620 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.combine");
00621 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00622 aParams->combine_s = cpl_parameter_get_string(p);
00623 aParams->combine =
00624 (!strcasecmp(aParams->combine_s, "average")) ? MUSE_TWILIGHT_PARAM_COMBINE_AVERAGE :
00625 (!strcasecmp(aParams->combine_s, "median")) ? MUSE_TWILIGHT_PARAM_COMBINE_MEDIAN :
00626 (!strcasecmp(aParams->combine_s, "minmax")) ? MUSE_TWILIGHT_PARAM_COMBINE_MINMAX :
00627 (!strcasecmp(aParams->combine_s, "sigclip")) ? MUSE_TWILIGHT_PARAM_COMBINE_SIGCLIP :
00628 MUSE_TWILIGHT_PARAM_COMBINE_INVALID_VALUE;
00629 cpl_ensure_code(aParams->combine != MUSE_TWILIGHT_PARAM_COMBINE_INVALID_VALUE,
00630 CPL_ERROR_ILLEGAL_INPUT);
00631
00632 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.nlow");
00633 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00634 aParams->nlow = cpl_parameter_get_int(p);
00635
00636 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.nhigh");
00637 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00638 aParams->nhigh = cpl_parameter_get_int(p);
00639
00640 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.nkeep");
00641 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00642 aParams->nkeep = cpl_parameter_get_int(p);
00643
00644 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.lsigma");
00645 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00646 aParams->lsigma = cpl_parameter_get_double(p);
00647
00648 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.hsigma");
00649 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00650 aParams->hsigma = cpl_parameter_get_double(p);
00651
00652 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.scale");
00653 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00654 aParams->scale = cpl_parameter_get_bool(p);
00655
00656 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.resample");
00657 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00658 aParams->resample_s = cpl_parameter_get_string(p);
00659 aParams->resample =
00660 (!strcasecmp(aParams->resample_s, "nearest")) ? MUSE_TWILIGHT_PARAM_RESAMPLE_NEAREST :
00661 (!strcasecmp(aParams->resample_s, "linear")) ? MUSE_TWILIGHT_PARAM_RESAMPLE_LINEAR :
00662 (!strcasecmp(aParams->resample_s, "quadratic")) ? MUSE_TWILIGHT_PARAM_RESAMPLE_QUADRATIC :
00663 (!strcasecmp(aParams->resample_s, "renka")) ? MUSE_TWILIGHT_PARAM_RESAMPLE_RENKA :
00664 (!strcasecmp(aParams->resample_s, "drizzle")) ? MUSE_TWILIGHT_PARAM_RESAMPLE_DRIZZLE :
00665 (!strcasecmp(aParams->resample_s, "lanczos")) ? MUSE_TWILIGHT_PARAM_RESAMPLE_LANCZOS :
00666 MUSE_TWILIGHT_PARAM_RESAMPLE_INVALID_VALUE;
00667 cpl_ensure_code(aParams->resample != MUSE_TWILIGHT_PARAM_RESAMPLE_INVALID_VALUE,
00668 CPL_ERROR_ILLEGAL_INPUT);
00669
00670 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.crtype");
00671 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00672 aParams->crtype_s = cpl_parameter_get_string(p);
00673 aParams->crtype =
00674 (!strcasecmp(aParams->crtype_s, "iraf")) ? MUSE_TWILIGHT_PARAM_CRTYPE_IRAF :
00675 (!strcasecmp(aParams->crtype_s, "mean")) ? MUSE_TWILIGHT_PARAM_CRTYPE_MEAN :
00676 (!strcasecmp(aParams->crtype_s, "median")) ? MUSE_TWILIGHT_PARAM_CRTYPE_MEDIAN :
00677 MUSE_TWILIGHT_PARAM_CRTYPE_INVALID_VALUE;
00678 cpl_ensure_code(aParams->crtype != MUSE_TWILIGHT_PARAM_CRTYPE_INVALID_VALUE,
00679 CPL_ERROR_ILLEGAL_INPUT);
00680
00681 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.crsigma");
00682 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00683 aParams->crsigma = cpl_parameter_get_double(p);
00684
00685 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.lambdamin");
00686 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00687 aParams->lambdamin = cpl_parameter_get_double(p);
00688
00689 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.lambdamax");
00690 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00691 aParams->lambdamax = cpl_parameter_get_double(p);
00692
00693 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.dlambda");
00694 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00695 aParams->dlambda = cpl_parameter_get_double(p);
00696
00697 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.xorder");
00698 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00699 aParams->xorder = cpl_parameter_get_int(p);
00700
00701 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.yorder");
00702 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00703 aParams->yorder = cpl_parameter_get_int(p);
00704
00705 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.vignmaskedges");
00706 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00707 aParams->vignmaskedges = cpl_parameter_get_double(p);
00708
00709 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.vignsmooth");
00710 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00711 aParams->vignsmooth_s = cpl_parameter_get_string(p);
00712 aParams->vignsmooth =
00713 (!strcasecmp(aParams->vignsmooth_s, "polyfit")) ? MUSE_TWILIGHT_PARAM_VIGNSMOOTH_POLYFIT :
00714 (!strcasecmp(aParams->vignsmooth_s, "gaussian")) ? MUSE_TWILIGHT_PARAM_VIGNSMOOTH_GAUSSIAN :
00715 (!strcasecmp(aParams->vignsmooth_s, "median")) ? MUSE_TWILIGHT_PARAM_VIGNSMOOTH_MEDIAN :
00716 MUSE_TWILIGHT_PARAM_VIGNSMOOTH_INVALID_VALUE;
00717 cpl_ensure_code(aParams->vignsmooth != MUSE_TWILIGHT_PARAM_VIGNSMOOTH_INVALID_VALUE,
00718 CPL_ERROR_ILLEGAL_INPUT);
00719
00720 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.vignxpar");
00721 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00722 aParams->vignxpar = cpl_parameter_get_int(p);
00723
00724 p = cpl_parameterlist_find(aParameters, "muse.muse_twilight.vignypar");
00725 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00726 aParams->vignypar = cpl_parameter_get_int(p);
00727
00728 return 0;
00729 }
00730
00731
00738
00739 static int
00740 muse_twilight_exec(cpl_plugin *aPlugin)
00741 {
00742 if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
00743 return -1;
00744 }
00745 muse_processing_recipeinfo(aPlugin);
00746 cpl_recipe *recipe = (cpl_recipe *)aPlugin;
00747 cpl_msg_set_threadid_on();
00748
00749 cpl_frameset *usedframes = cpl_frameset_new(),
00750 *outframes = cpl_frameset_new();
00751 muse_twilight_params_t params;
00752 muse_twilight_params_fill(¶ms, recipe->parameters);
00753
00754 cpl_errorstate prestate = cpl_errorstate_get();
00755
00756 muse_processing *proc = muse_processing_new("muse_twilight",
00757 recipe);
00758 int rc = muse_twilight_compute(proc, ¶ms);
00759 cpl_frameset_join(usedframes, proc->usedframes);
00760 cpl_frameset_join(outframes, proc->outframes);
00761 muse_processing_delete(proc);
00762
00763 if (!cpl_errorstate_is_equal(prestate)) {
00764
00765 cpl_errorstate_dump(prestate, CPL_FALSE, muse_cplerrorstate_dump_some);
00766
00767 cpl_msg_set_level(CPL_MSG_INFO);
00768 }
00769
00770 muse_cplframeset_erase_duplicate(usedframes);
00771 muse_cplframeset_erase_duplicate(outframes);
00772
00773
00774
00775
00776
00777 muse_cplframeset_erase_all(recipe->frames);
00778 cpl_frameset_join(recipe->frames, usedframes);
00779 cpl_frameset_join(recipe->frames, outframes);
00780 cpl_frameset_delete(usedframes);
00781 cpl_frameset_delete(outframes);
00782 return rc;
00783 }
00784
00785
00792
00793 static int
00794 muse_twilight_destroy(cpl_plugin *aPlugin)
00795 {
00796
00797 cpl_recipe *recipe;
00798 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
00799 recipe = (cpl_recipe *)aPlugin;
00800 } else {
00801 return -1;
00802 }
00803
00804
00805 cpl_parameterlist_delete(recipe->parameters);
00806 muse_processinginfo_delete(recipe);
00807 return 0;
00808 }
00809
00810
00820
00821 int
00822 cpl_plugin_get_info(cpl_pluginlist *aList)
00823 {
00824 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
00825 cpl_plugin *plugin = &recipe->interface;
00826
00827 char *helptext;
00828 if (muse_cplframework() == MUSE_CPLFRAMEWORK_ESOREX) {
00829 helptext = cpl_sprintf("%s%s", muse_twilight_help,
00830 muse_twilight_help_esorex);
00831 } else {
00832 helptext = cpl_sprintf("%s", muse_twilight_help);
00833 }
00834
00835
00836 cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
00837 CPL_PLUGIN_TYPE_RECIPE,
00838 "muse_twilight",
00839 "Combine several twilight skyflats into one cube, compute correction factors for each IFU, and create a smooth 3D illumination correction.",
00840 helptext,
00841 "Peter Weilbacher",
00842 "usd-help@eso.org",
00843 muse_get_license(),
00844 muse_twilight_create,
00845 muse_twilight_exec,
00846 muse_twilight_destroy);
00847 cpl_pluginlist_append(aList, plugin);
00848 cpl_free(helptext);
00849
00850 return 0;
00851 }
00852