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_ampl_z.h"
00036
00037
00063
00066
00067
00068
00069 static const char *muse_ampl_help =
00070 "This recipe combines several separate amplifier images (flat-fields with special FITS headers containing pico amplifier measurements) into one master image file and computes the instrumental throughput per IFU (and slice). Processing trims the raw data and records the overscan statistics, subtracts the bias (taking account of the overscan, if overscan is not &none&), and optionally, the dark from each raw input image, converts them from adu to count, scales them according to their exposure time, and combines them using input parameters. To compute the throughput the image is converted into a pixel table, the flux is then integrated over the given filter band, and the ratio of the expected flux (FITS header INS.AMPL2.CURR) to measured flux is taken, in the same units. If a geometry table was given as input, the relative area of the IFUs is taken into account when computing the flux per unit area. The resulting ratio is the instrument efficiency (throughput) and saved as QC parameters for the whole input image and per slice in the output pixel table.";
00071
00072 static const char *muse_ampl_help_esorex =
00073 "\n\nInput frames for raw frame tag \"AMPL\":\n"
00074 "\n Frame tag Type Req #Fr Description"
00075 "\n -------------------- ---- --- --- ------------"
00076 "\n AMPL raw Y >=3 Special raw flat-field taken with pico-amplifier readings in the FITS header"
00077 "\n MASTER_BIAS calib Y 1 Master bias"
00078 "\n MASTER_DARK calib . 1 Master dark"
00079 "\n BADPIX_TABLE calib . 1 Known bad pixels"
00080 "\n GEOMETRY_TABLE calib . 1 Relative positions of the slices in the field of view"
00081 "\n FILTER_LIST calib Y 1 Filter definitions; here, it has to contain the filter curve for the filter given in INS.AMPL2.FILTER"
00082 "\n TRACE_TABLE calib Y 1 Trace table"
00083 "\n WAVECAL_TABLE calib Y 1 Wavelength calibration table"
00084 "\n\nProduct frames for raw frame tag \"AMPL\":\n"
00085 "\n Frame tag Level Description"
00086 "\n -------------------- -------- ------------"
00087 "\n MASTER_AMPL final Combined master AMPL image, written if --savemaster=true"
00088 "\n TABLE_AMPL final Output table with computations for each CCD pixel, written if --savetable=true."
00089 "\n AMPL_CONVOLVED final Combined and convolved master AMPL image";
00090
00091
00099
00100 static cpl_recipeconfig *
00101 muse_ampl_new_recipeconfig(void)
00102 {
00103 cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
00104
00105 cpl_recipeconfig_set_tag(recipeconfig, "AMPL", 3, -1);
00106 cpl_recipeconfig_set_input(recipeconfig, "AMPL", "MASTER_BIAS", 1, 1);
00107 cpl_recipeconfig_set_input(recipeconfig, "AMPL", "MASTER_DARK", -1, 1);
00108 cpl_recipeconfig_set_input(recipeconfig, "AMPL", "BADPIX_TABLE", -1, 1);
00109 cpl_recipeconfig_set_input(recipeconfig, "AMPL", "GEOMETRY_TABLE", -1, 1);
00110 cpl_recipeconfig_set_input(recipeconfig, "AMPL", "FILTER_LIST", 1, 1);
00111 cpl_recipeconfig_set_input(recipeconfig, "AMPL", "TRACE_TABLE", 1, 1);
00112 cpl_recipeconfig_set_input(recipeconfig, "AMPL", "WAVECAL_TABLE", 1, 1);
00113 cpl_recipeconfig_set_output(recipeconfig, "AMPL", "MASTER_AMPL");
00114 cpl_recipeconfig_set_output(recipeconfig, "AMPL", "TABLE_AMPL");
00115 cpl_recipeconfig_set_output(recipeconfig, "AMPL", "AMPL_CONVOLVED");
00116
00117 return recipeconfig;
00118 }
00119
00120
00130
00131 static cpl_error_code
00132 muse_ampl_prepare_header(const char *aFrametag, cpl_propertylist *aHeader)
00133 {
00134 cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
00135 cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
00136 if (!strcmp(aFrametag, "MASTER_AMPL")) {
00137 muse_processing_prepare_property(aHeader, "ESO QC AMPL INPUT[0-9]+ NSATURATED",
00138 CPL_TYPE_INT,
00139 "Number of saturated pixels in raw image i in input list");
00140 muse_processing_prepare_property(aHeader, "ESO QC AMPL MASTER NSATURATED",
00141 CPL_TYPE_INT,
00142 "Number of saturated pixels in output master image");
00143 } else if (!strcmp(aFrametag, "TABLE_AMPL")) {
00144 muse_processing_prepare_property(aHeader, "ESO QC AMPL PHOTONS",
00145 CPL_TYPE_FLOAT,
00146 "[ph] Integrated number of photons detected on the CCD");
00147 muse_processing_prepare_property(aHeader, "ESO QC AMPL POWER",
00148 CPL_TYPE_FLOAT,
00149 "[W] Integrated power detected on the CCD");
00150 muse_processing_prepare_property(aHeader, "ESO QC AMPL THRU[0-9]+",
00151 CPL_TYPE_FLOAT,
00152 "[%] Channel throughput compared to photodiode a");
00153 muse_processing_prepare_property(aHeader, "ESO QC AMPL THRU2ERR",
00154 CPL_TYPE_FLOAT,
00155 "[%] Estimated error of throughput compared to photodiode 2");
00156 muse_processing_prepare_property(aHeader, "ESO QC AMPL SLICE[0-9]+ THRU2",
00157 CPL_TYPE_FLOAT,
00158 "[%] Slice j throughput compared to photodiode 2");
00159 } else if (!strcmp(aFrametag, "AMPL_CONVOLVED")) {
00160 muse_processing_prepare_property(aHeader, "ESO QC AMPL INPUT[0-9]+ NSATURATED",
00161 CPL_TYPE_INT,
00162 "Number of saturated pixels in raw image i in input list");
00163 muse_processing_prepare_property(aHeader, "ESO QC AMPL MASTER NSATURATED",
00164 CPL_TYPE_INT,
00165 "Number of saturated pixels in output master image");
00166 muse_processing_prepare_property(aHeader, "ESO QC AMPL PHOTONS",
00167 CPL_TYPE_FLOAT,
00168 "[ph] Integrated number of photons detected on the CCD");
00169 muse_processing_prepare_property(aHeader, "ESO QC AMPL POWER",
00170 CPL_TYPE_FLOAT,
00171 "[W] Integrated power detected on the CCD");
00172 muse_processing_prepare_property(aHeader, "ESO QC AMPL THRU[0-9]+",
00173 CPL_TYPE_FLOAT,
00174 "[%] Channel throughput compared to photodiode a");
00175 muse_processing_prepare_property(aHeader, "ESO QC AMPL THRU2ERR",
00176 CPL_TYPE_FLOAT,
00177 "[%] Estimated error of throughput compared to photodiode 2");
00178 muse_processing_prepare_property(aHeader, "ESO QC AMPL SLICE[0-9]+ THRU2",
00179 CPL_TYPE_FLOAT,
00180 "[%] Slice j throughput compared to photodiode 2");
00181 } else {
00182 cpl_msg_warning(__func__, "Frame tag %s is not defined", aFrametag);
00183 return CPL_ERROR_ILLEGAL_INPUT;
00184 }
00185 return CPL_ERROR_NONE;
00186 }
00187
00188
00197
00198 static cpl_frame_level
00199 muse_ampl_get_frame_level(const char *aFrametag)
00200 {
00201 if (!aFrametag) {
00202 return CPL_FRAME_LEVEL_NONE;
00203 }
00204 if (!strcmp(aFrametag, "MASTER_AMPL")) {
00205 return CPL_FRAME_LEVEL_FINAL;
00206 }
00207 if (!strcmp(aFrametag, "TABLE_AMPL")) {
00208 return CPL_FRAME_LEVEL_FINAL;
00209 }
00210 if (!strcmp(aFrametag, "AMPL_CONVOLVED")) {
00211 return CPL_FRAME_LEVEL_FINAL;
00212 }
00213 return CPL_FRAME_LEVEL_NONE;
00214 }
00215
00216
00225
00226 static muse_frame_mode
00227 muse_ampl_get_frame_mode(const char *aFrametag)
00228 {
00229 if (!aFrametag) {
00230 return MUSE_FRAME_MODE_ALL;
00231 }
00232 if (!strcmp(aFrametag, "MASTER_AMPL")) {
00233 return MUSE_FRAME_MODE_MASTER;
00234 }
00235 if (!strcmp(aFrametag, "TABLE_AMPL")) {
00236 return MUSE_FRAME_MODE_MASTER;
00237 }
00238 if (!strcmp(aFrametag, "AMPL_CONVOLVED")) {
00239 return MUSE_FRAME_MODE_MASTER;
00240 }
00241 return MUSE_FRAME_MODE_ALL;
00242 }
00243
00244
00254
00255 static int
00256 muse_ampl_create(cpl_plugin *aPlugin)
00257 {
00258
00259 cpl_recipe *recipe;
00260 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
00261 recipe = (cpl_recipe *)aPlugin;
00262 } else {
00263 return -1;
00264 }
00265
00266
00267
00268 muse_processinginfo_register(recipe,
00269 muse_ampl_new_recipeconfig(),
00270 muse_ampl_prepare_header,
00271 muse_ampl_get_frame_level,
00272 muse_ampl_get_frame_mode);
00273
00274
00275
00276 if (muse_cplframework() == MUSE_CPLFRAMEWORK_ESOREX) {
00277 cpl_msg_set_time_on();
00278 }
00279
00280
00281 recipe->parameters = cpl_parameterlist_new();
00282
00283 cpl_parameter *p;
00284
00285
00286 p = cpl_parameter_new_range("muse.muse_ampl.nifu",
00287 CPL_TYPE_INT,
00288 "IFU to handle. If set to 0, all IFUs are processed serially. If set to -1, all IFUs are processed in parallel.",
00289 "muse.muse_ampl",
00290 (int)0,
00291 (int)-1,
00292 (int)24);
00293 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nifu");
00294 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nifu");
00295
00296 cpl_parameterlist_append(recipe->parameters, p);
00297
00298
00299 p = cpl_parameter_new_value("muse.muse_ampl.overscan",
00300 CPL_TYPE_STRING,
00301 "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.",
00302 "muse.muse_ampl",
00303 (const char *)"vpoly");
00304 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "overscan");
00305 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "overscan");
00306
00307 cpl_parameterlist_append(recipe->parameters, p);
00308
00309
00310 p = cpl_parameter_new_value("muse.muse_ampl.ovscreject",
00311 CPL_TYPE_STRING,
00312 "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\").",
00313 "muse.muse_ampl",
00314 (const char *)"dcr");
00315 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ovscreject");
00316 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ovscreject");
00317
00318 cpl_parameterlist_append(recipe->parameters, p);
00319
00320
00321 p = cpl_parameter_new_value("muse.muse_ampl.ovscsigma",
00322 CPL_TYPE_DOUBLE,
00323 "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\".",
00324 "muse.muse_ampl",
00325 (double)30.);
00326 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ovscsigma");
00327 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ovscsigma");
00328
00329 cpl_parameterlist_append(recipe->parameters, p);
00330
00331
00332 p = cpl_parameter_new_value("muse.muse_ampl.ovscignore",
00333 CPL_TYPE_INT,
00334 "The number of pixels of the overscan adjacent to the data region of the CCD that are ignored when computing statistics or fits.",
00335 "muse.muse_ampl",
00336 (int)3);
00337 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ovscignore");
00338 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ovscignore");
00339
00340 cpl_parameterlist_append(recipe->parameters, p);
00341
00342
00343 p = cpl_parameter_new_enum("muse.muse_ampl.combine",
00344 CPL_TYPE_STRING,
00345 "Type of combination to use",
00346 "muse.muse_ampl",
00347 (const char *)"sigclip",
00348 4,
00349 (const char *)"average",
00350 (const char *)"median",
00351 (const char *)"minmax",
00352 (const char *)"sigclip");
00353 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "combine");
00354 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "combine");
00355
00356 cpl_parameterlist_append(recipe->parameters, p);
00357
00358
00359 p = cpl_parameter_new_value("muse.muse_ampl.nlow",
00360 CPL_TYPE_INT,
00361 "Number of minimum pixels to reject with minmax",
00362 "muse.muse_ampl",
00363 (int)1);
00364 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nlow");
00365 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nlow");
00366
00367 cpl_parameterlist_append(recipe->parameters, p);
00368
00369
00370 p = cpl_parameter_new_value("muse.muse_ampl.nhigh",
00371 CPL_TYPE_INT,
00372 "Number of maximum pixels to reject with minmax",
00373 "muse.muse_ampl",
00374 (int)1);
00375 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nhigh");
00376 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nhigh");
00377
00378 cpl_parameterlist_append(recipe->parameters, p);
00379
00380
00381 p = cpl_parameter_new_value("muse.muse_ampl.nkeep",
00382 CPL_TYPE_INT,
00383 "Number of pixels to keep with minmax",
00384 "muse.muse_ampl",
00385 (int)1);
00386 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nkeep");
00387 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nkeep");
00388
00389 cpl_parameterlist_append(recipe->parameters, p);
00390
00391
00392 p = cpl_parameter_new_value("muse.muse_ampl.lsigma",
00393 CPL_TYPE_DOUBLE,
00394 "Low sigma for pixel rejection with sigclip",
00395 "muse.muse_ampl",
00396 (double)3);
00397 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lsigma");
00398 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lsigma");
00399
00400 cpl_parameterlist_append(recipe->parameters, p);
00401
00402
00403 p = cpl_parameter_new_value("muse.muse_ampl.hsigma",
00404 CPL_TYPE_DOUBLE,
00405 "High sigma for pixel rejection with sigclip",
00406 "muse.muse_ampl",
00407 (double)3);
00408 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "hsigma");
00409 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "hsigma");
00410
00411 cpl_parameterlist_append(recipe->parameters, p);
00412
00413
00414 p = cpl_parameter_new_value("muse.muse_ampl.fbeam",
00415 CPL_TYPE_DOUBLE,
00416 "Factor to describe the widening of the beam from the focal plane to photo diode 2.",
00417 "muse.muse_ampl",
00418 (double)1.10);
00419 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "fbeam");
00420 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fbeam");
00421
00422 cpl_parameterlist_append(recipe->parameters, p);
00423
00424
00425 p = cpl_parameter_new_value("muse.muse_ampl.temp",
00426 CPL_TYPE_DOUBLE,
00427 "Lamp temperature [K] used to create the black body function.",
00428 "muse.muse_ampl",
00429 (double)3200.);
00430 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "temp");
00431 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "temp");
00432
00433 cpl_parameterlist_append(recipe->parameters, p);
00434
00435
00436 p = cpl_parameter_new_value("muse.muse_ampl.savemaster",
00437 CPL_TYPE_BOOL,
00438 "Save the processed and combined master image before any concolution is done.",
00439 "muse.muse_ampl",
00440 (int)FALSE);
00441 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "savemaster");
00442 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "savemaster");
00443
00444 cpl_parameterlist_append(recipe->parameters, p);
00445
00446
00447 p = cpl_parameter_new_value("muse.muse_ampl.savetable",
00448 CPL_TYPE_BOOL,
00449 "Save the table with all the processed pixel values.",
00450 "muse.muse_ampl",
00451 (int)FALSE);
00452 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "savetable");
00453 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "savetable");
00454
00455 cpl_parameterlist_append(recipe->parameters, p);
00456
00457
00458 p = cpl_parameter_new_value("muse.muse_ampl.merge",
00459 CPL_TYPE_BOOL,
00460 "Merge output products from different IFUs into a common file.",
00461 "muse.muse_ampl",
00462 (int)FALSE);
00463 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "merge");
00464 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "merge");
00465
00466 cpl_parameterlist_append(recipe->parameters, p);
00467
00468 return 0;
00469 }
00470
00471
00482
00483 static int
00484 muse_ampl_params_fill(muse_ampl_params_t *aParams, cpl_parameterlist *aParameters)
00485 {
00486 cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
00487 cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
00488 cpl_parameter *p;
00489
00490 p = cpl_parameterlist_find(aParameters, "muse.muse_ampl.nifu");
00491 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00492 aParams->nifu = cpl_parameter_get_int(p);
00493
00494 p = cpl_parameterlist_find(aParameters, "muse.muse_ampl.overscan");
00495 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00496 aParams->overscan = cpl_parameter_get_string(p);
00497
00498 p = cpl_parameterlist_find(aParameters, "muse.muse_ampl.ovscreject");
00499 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00500 aParams->ovscreject = cpl_parameter_get_string(p);
00501
00502 p = cpl_parameterlist_find(aParameters, "muse.muse_ampl.ovscsigma");
00503 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00504 aParams->ovscsigma = cpl_parameter_get_double(p);
00505
00506 p = cpl_parameterlist_find(aParameters, "muse.muse_ampl.ovscignore");
00507 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00508 aParams->ovscignore = cpl_parameter_get_int(p);
00509
00510 p = cpl_parameterlist_find(aParameters, "muse.muse_ampl.combine");
00511 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00512 aParams->combine_s = cpl_parameter_get_string(p);
00513 aParams->combine =
00514 (!strcasecmp(aParams->combine_s, "average")) ? MUSE_AMPL_PARAM_COMBINE_AVERAGE :
00515 (!strcasecmp(aParams->combine_s, "median")) ? MUSE_AMPL_PARAM_COMBINE_MEDIAN :
00516 (!strcasecmp(aParams->combine_s, "minmax")) ? MUSE_AMPL_PARAM_COMBINE_MINMAX :
00517 (!strcasecmp(aParams->combine_s, "sigclip")) ? MUSE_AMPL_PARAM_COMBINE_SIGCLIP :
00518 MUSE_AMPL_PARAM_COMBINE_INVALID_VALUE;
00519 cpl_ensure_code(aParams->combine != MUSE_AMPL_PARAM_COMBINE_INVALID_VALUE,
00520 CPL_ERROR_ILLEGAL_INPUT);
00521
00522 p = cpl_parameterlist_find(aParameters, "muse.muse_ampl.nlow");
00523 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00524 aParams->nlow = cpl_parameter_get_int(p);
00525
00526 p = cpl_parameterlist_find(aParameters, "muse.muse_ampl.nhigh");
00527 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00528 aParams->nhigh = cpl_parameter_get_int(p);
00529
00530 p = cpl_parameterlist_find(aParameters, "muse.muse_ampl.nkeep");
00531 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00532 aParams->nkeep = cpl_parameter_get_int(p);
00533
00534 p = cpl_parameterlist_find(aParameters, "muse.muse_ampl.lsigma");
00535 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00536 aParams->lsigma = cpl_parameter_get_double(p);
00537
00538 p = cpl_parameterlist_find(aParameters, "muse.muse_ampl.hsigma");
00539 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00540 aParams->hsigma = cpl_parameter_get_double(p);
00541
00542 p = cpl_parameterlist_find(aParameters, "muse.muse_ampl.fbeam");
00543 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00544 aParams->fbeam = cpl_parameter_get_double(p);
00545
00546 p = cpl_parameterlist_find(aParameters, "muse.muse_ampl.temp");
00547 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00548 aParams->temp = cpl_parameter_get_double(p);
00549
00550 p = cpl_parameterlist_find(aParameters, "muse.muse_ampl.savemaster");
00551 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00552 aParams->savemaster = cpl_parameter_get_bool(p);
00553
00554 p = cpl_parameterlist_find(aParameters, "muse.muse_ampl.savetable");
00555 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00556 aParams->savetable = cpl_parameter_get_bool(p);
00557
00558 p = cpl_parameterlist_find(aParameters, "muse.muse_ampl.merge");
00559 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00560 aParams->merge = cpl_parameter_get_bool(p);
00561
00562 return 0;
00563 }
00564
00565
00572
00573 static int
00574 muse_ampl_exec(cpl_plugin *aPlugin)
00575 {
00576 if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
00577 return -1;
00578 }
00579 muse_processing_recipeinfo(aPlugin);
00580 cpl_recipe *recipe = (cpl_recipe *)aPlugin;
00581 cpl_msg_set_threadid_on();
00582
00583 cpl_frameset *usedframes = cpl_frameset_new(),
00584 *outframes = cpl_frameset_new();
00585 muse_ampl_params_t params;
00586 muse_ampl_params_fill(¶ms, recipe->parameters);
00587
00588 cpl_errorstate prestate = cpl_errorstate_get();
00589
00590 if (params.nifu < -1 || params.nifu > kMuseNumIFUs) {
00591 cpl_msg_error(__func__, "Please specify a valid IFU number (between 1 and "
00592 "%d), 0 (to process all IFUs consecutively), or -1 (to "
00593 "process all IFUs in parallel) using --nifu.", kMuseNumIFUs);
00594 return -1;
00595 }
00596
00597 cpl_boolean donotmerge = CPL_FALSE;
00598 int rc = 0;
00599 if (params.nifu > 0) {
00600 muse_processing *proc = muse_processing_new("muse_ampl",
00601 recipe);
00602 rc = muse_ampl_compute(proc, ¶ms);
00603 cpl_frameset_join(usedframes, proc->usedframes);
00604 cpl_frameset_join(outframes, proc->outframes);
00605 muse_processing_delete(proc);
00606 donotmerge = CPL_TRUE;
00607 } else if (params.nifu < 0) {
00608 int *rcs = cpl_calloc(kMuseNumIFUs, sizeof(int));
00609 int nifu;
00610 #pragma omp parallel for default(none) \
00611 shared(outframes, params, rcs, recipe, usedframes)
00612 for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
00613 muse_processing *proc = muse_processing_new("muse_ampl",
00614 recipe);
00615 muse_ampl_params_t *pars = cpl_malloc(sizeof(muse_ampl_params_t));
00616 memcpy(pars, ¶ms, sizeof(muse_ampl_params_t));
00617 pars->nifu = nifu;
00618 int *rci = rcs + (nifu - 1);
00619 *rci = muse_ampl_compute(proc, pars);
00620 if (rci && (int)cpl_error_get_code() == MUSE_ERROR_CHIP_NOT_LIVE) {
00621 *rci = 0;
00622 }
00623 cpl_free(pars);
00624 #pragma omp critical(muse_processing_used_frames)
00625 cpl_frameset_join(usedframes, proc->usedframes);
00626 #pragma omp critical(muse_processing_output_frames)
00627 cpl_frameset_join(outframes, proc->outframes);
00628 muse_processing_delete(proc);
00629 }
00630
00631
00632 for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
00633 if (rcs[nifu-1] != 0) {
00634 rc = rcs[nifu-1];
00635 }
00636 }
00637 cpl_free(rcs);
00638 } else {
00639 for (params.nifu = 1; params.nifu <= kMuseNumIFUs && !rc; params.nifu++) {
00640 muse_processing *proc = muse_processing_new("muse_ampl",
00641 recipe);
00642 rc = muse_ampl_compute(proc, ¶ms);
00643 if (rc && (int)cpl_error_get_code() == MUSE_ERROR_CHIP_NOT_LIVE) {
00644 rc = 0;
00645 }
00646 cpl_frameset_join(usedframes, proc->usedframes);
00647 cpl_frameset_join(outframes, proc->outframes);
00648 muse_processing_delete(proc);
00649 }
00650 }
00651 UNUSED_ARGUMENT(donotmerge);
00652
00653 if (!cpl_errorstate_is_equal(prestate)) {
00654
00655 cpl_errorstate_dump(prestate, CPL_FALSE, muse_cplerrorstate_dump_some);
00656
00657 cpl_msg_set_level(CPL_MSG_INFO);
00658 }
00659
00660 muse_cplframeset_erase_duplicate(usedframes);
00661 muse_cplframeset_erase_duplicate(outframes);
00662
00663
00664 if (params.merge && !donotmerge) {
00665 muse_utils_frameset_merge_frames(outframes, CPL_TRUE);
00666 }
00667
00668
00669
00670
00671
00672 muse_cplframeset_erase_all(recipe->frames);
00673 cpl_frameset_join(recipe->frames, usedframes);
00674 cpl_frameset_join(recipe->frames, outframes);
00675 cpl_frameset_delete(usedframes);
00676 cpl_frameset_delete(outframes);
00677 return rc;
00678 }
00679
00680
00687
00688 static int
00689 muse_ampl_destroy(cpl_plugin *aPlugin)
00690 {
00691
00692 cpl_recipe *recipe;
00693 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
00694 recipe = (cpl_recipe *)aPlugin;
00695 } else {
00696 return -1;
00697 }
00698
00699
00700 cpl_parameterlist_delete(recipe->parameters);
00701 muse_processinginfo_delete(recipe);
00702 return 0;
00703 }
00704
00705
00715
00716 int
00717 cpl_plugin_get_info(cpl_pluginlist *aList)
00718 {
00719 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
00720 cpl_plugin *plugin = &recipe->interface;
00721
00722 char *helptext;
00723 if (muse_cplframework() == MUSE_CPLFRAMEWORK_ESOREX) {
00724 helptext = cpl_sprintf("%s%s", muse_ampl_help,
00725 muse_ampl_help_esorex);
00726 } else {
00727 helptext = cpl_sprintf("%s", muse_ampl_help);
00728 }
00729
00730
00731 cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
00732 CPL_PLUGIN_TYPE_RECIPE,
00733 "muse_ampl",
00734 "Determine the instrumental throughput from exposures taken with the pico-amplifier / photo diode readings.",
00735 helptext,
00736 "Peter Weilbacher",
00737 "usd-help@eso.org",
00738 muse_get_license(),
00739 muse_ampl_create,
00740 muse_ampl_exec,
00741 muse_ampl_destroy);
00742 cpl_pluginlist_append(aList, plugin);
00743 cpl_free(helptext);
00744
00745 return 0;
00746 }
00747