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_lingain_z.h"
00036
00037
00070
00073
00074
00075
00076 static const char *muse_lingain_help =
00077 "The recipe uses the bias and flat field images of a detector monitoring exposure sequence to determine the detector gain in counts/ADU and to model the residual non-linearity for each of the four detector quadrants of all IFUs. All measurements done by the recipe are done on the illuminated parts of the detector, i.e. on the slices. The location of the slices is taken from the given trace table, which is a mandatory input. Using the traces of the slices on the detector a set of measurement windows is placed along these traces. The data used for the determination of the gain and the residual non-linearity is the taken from these windows. Bad pixels indicated by an, optionally, provided bad pixel table, or flagged during the preprocessing (bias subtraction) of the input data are excluded from the measurements. Local measurements of the read-out-noise, the signal and the gain are calculated for each of the measurement windows. Using these measurements the gain for each detector quadrant is computed as the zero-order coefficient of a 1st order polynomial fitted to the binned gain measurements as a function of the signal level. The residual non-linearity is modelled by a (high) order polynomial which is fitted to the fractional percentage deviation of the count rate from an expected constant count rate (the linear case) as function of the signal level.";
00078
00079 static const char *muse_lingain_help_esorex =
00080 "\n\nInput frames for raw frame tag \"DETMON_LAMP_OFF\":\n"
00081 "\n Frame tag Type Req #Fr Description"
00082 "\n -------------------- ---- --- --- ------------"
00083 "\n DETMON_LAMP_OFF raw Y >=2 Detector monitoring bias images"
00084 "\n DETMON_LAMP_ON raw Y >=2 Detector monitoring flat field images"
00085 "\n MASTER_BIAS calib Y 1 Master bias"
00086 "\n TRACE_TABLE calib Y 1 Trace table"
00087 "\n BADPIX_TABLE calib . 1 Bad pixel table"
00088 "\n\nProduct frames for raw frame tag \"DETMON_LAMP_OFF\":\n"
00089 "\n Frame tag Level Description"
00090 "\n -------------------- -------- ------------"
00091 "\n NONLINEARITY_GAIN final List of non-linearity and gain parameters for each detector readout port.";
00092
00093
00101
00102 static cpl_recipeconfig *
00103 muse_lingain_new_recipeconfig(void)
00104 {
00105 cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
00106
00107 cpl_recipeconfig_set_tag(recipeconfig, "DETMON_LAMP_OFF", 2, -1);
00108 cpl_recipeconfig_set_input(recipeconfig, "DETMON_LAMP_OFF", "MASTER_BIAS", 1, 1);
00109 cpl_recipeconfig_set_input(recipeconfig, "DETMON_LAMP_OFF", "TRACE_TABLE", 1, 1);
00110 cpl_recipeconfig_set_input(recipeconfig, "DETMON_LAMP_OFF", "BADPIX_TABLE", -1, 1);
00111 cpl_recipeconfig_set_output(recipeconfig, "DETMON_LAMP_OFF", "NONLINEARITY_GAIN");
00112 cpl_recipeconfig_set_tag(recipeconfig, "DETMON_LAMP_ON", 2, -1);
00113 cpl_recipeconfig_set_input(recipeconfig, "DETMON_LAMP_ON", "MASTER_BIAS", 1, 1);
00114 cpl_recipeconfig_set_input(recipeconfig, "DETMON_LAMP_ON", "TRACE_TABLE", 1, 1);
00115 cpl_recipeconfig_set_input(recipeconfig, "DETMON_LAMP_ON", "BADPIX_TABLE", -1, 1);
00116 cpl_recipeconfig_set_output(recipeconfig, "DETMON_LAMP_ON", "NONLINEARITY_GAIN");
00117
00118 return recipeconfig;
00119 }
00120
00121
00131
00132 static cpl_error_code
00133 muse_lingain_prepare_header(const char *aFrametag, cpl_propertylist *aHeader)
00134 {
00135 cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
00136 cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
00137 if (!strcmp(aFrametag, "NONLINEARITY_GAIN")) {
00138 muse_processing_prepare_property(aHeader, "ESO QC LINGAIN GFIT[1234] RMS",
00139 CPL_TYPE_DOUBLE,
00140 "RMS of the first order polynomial fit used to determine the gain.");
00141 muse_processing_prepare_property(aHeader, "ESO QC LINGAIN NLFIT[1234] RMS",
00142 CPL_TYPE_DOUBLE,
00143 "RMS of the residual non-linearity fit.");
00144 } else {
00145 cpl_msg_warning(__func__, "Frame tag %s is not defined", aFrametag);
00146 return CPL_ERROR_ILLEGAL_INPUT;
00147 }
00148 return CPL_ERROR_NONE;
00149 }
00150
00151
00160
00161 static cpl_frame_level
00162 muse_lingain_get_frame_level(const char *aFrametag)
00163 {
00164 if (!aFrametag) {
00165 return CPL_FRAME_LEVEL_NONE;
00166 }
00167 if (!strcmp(aFrametag, "NONLINEARITY_GAIN")) {
00168 return CPL_FRAME_LEVEL_FINAL;
00169 }
00170 return CPL_FRAME_LEVEL_NONE;
00171 }
00172
00173
00182
00183 static muse_frame_mode
00184 muse_lingain_get_frame_mode(const char *aFrametag)
00185 {
00186 if (!aFrametag) {
00187 return MUSE_FRAME_MODE_ALL;
00188 }
00189 if (!strcmp(aFrametag, "NONLINEARITY_GAIN")) {
00190 return MUSE_FRAME_MODE_MASTER;
00191 }
00192 return MUSE_FRAME_MODE_ALL;
00193 }
00194
00195
00205
00206 static int
00207 muse_lingain_create(cpl_plugin *aPlugin)
00208 {
00209
00210 cpl_recipe *recipe;
00211 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
00212 recipe = (cpl_recipe *)aPlugin;
00213 } else {
00214 return -1;
00215 }
00216
00217
00218
00219 muse_processinginfo_register(recipe,
00220 muse_lingain_new_recipeconfig(),
00221 muse_lingain_prepare_header,
00222 muse_lingain_get_frame_level,
00223 muse_lingain_get_frame_mode);
00224
00225
00226
00227 if (muse_cplframework() == MUSE_CPLFRAMEWORK_ESOREX) {
00228 cpl_msg_set_time_on();
00229 }
00230
00231
00232 recipe->parameters = cpl_parameterlist_new();
00233
00234 cpl_parameter *p;
00235
00236
00237 p = cpl_parameter_new_range("muse.muse_lingain.nifu",
00238 CPL_TYPE_INT,
00239 "IFU to handle. If set to 0, all IFUs are processed serially. If set to -1, all IFUs are processed in parallel.",
00240 "muse.muse_lingain",
00241 (int)0,
00242 (int)-1,
00243 (int)24);
00244 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nifu");
00245 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nifu");
00246
00247 cpl_parameterlist_append(recipe->parameters, p);
00248
00249
00250
00251
00252 p = cpl_parameter_new_value("muse.muse_lingain.ybox",
00253 CPL_TYPE_INT,
00254 "Size of windows along the traces of the slices.",
00255 "muse.muse_lingain",
00256 (int)50);
00257 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ybox");
00258 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ybox");
00259
00260 cpl_parameterlist_append(recipe->parameters, p);
00261
00262
00263
00264
00265 p = cpl_parameter_new_value("muse.muse_lingain.xgap",
00266 CPL_TYPE_INT,
00267 "Extra offset from tracing edge.",
00268 "muse.muse_lingain",
00269 (int)3);
00270 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "xgap");
00271 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "xgap");
00272
00273 cpl_parameterlist_append(recipe->parameters, p);
00274
00275
00276
00277
00278 p = cpl_parameter_new_value("muse.muse_lingain.xborder",
00279 CPL_TYPE_INT,
00280 "Extra offset from the detector edge used for the selection of slices.",
00281 "muse.muse_lingain",
00282 (int)10);
00283 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "xborder");
00284 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "xborder");
00285
00286 cpl_parameterlist_append(recipe->parameters, p);
00287
00288
00289
00290
00291 p = cpl_parameter_new_value("muse.muse_lingain.order",
00292 CPL_TYPE_INT,
00293 "Order of the polynomial used to fit the non-linearity residuals.",
00294 "muse.muse_lingain",
00295 (int)12);
00296 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "order");
00297 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "order");
00298
00299 cpl_parameterlist_append(recipe->parameters, p);
00300
00301
00302
00303
00304 p = cpl_parameter_new_value("muse.muse_lingain.toffset",
00305 CPL_TYPE_DOUBLE,
00306 "Exposure time offset in seconds to apply to linearity flat fields.",
00307 "muse.muse_lingain",
00308 (double)0.018);
00309 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "toffset");
00310 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "toffset");
00311
00312 cpl_parameterlist_append(recipe->parameters, p);
00313
00314
00315
00316
00317 p = cpl_parameter_new_value("muse.muse_lingain.fluxtol",
00318 CPL_TYPE_DOUBLE,
00319 "Tolerance value for the overall flux consistency check of a pair of flat fields. The value is the maximum relative offset.",
00320 "muse.muse_lingain",
00321 (double)0.01);
00322 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "fluxtol");
00323 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fluxtol");
00324
00325 cpl_parameterlist_append(recipe->parameters, p);
00326
00327
00328 p = cpl_parameter_new_value("muse.muse_lingain.sigma",
00329 CPL_TYPE_DOUBLE,
00330 "Sigma value used for signal value clipping.",
00331 "muse.muse_lingain",
00332 (double)3.);
00333 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "sigma");
00334 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "sigma");
00335
00336 cpl_parameterlist_append(recipe->parameters, p);
00337
00338
00339 p = cpl_parameter_new_value("muse.muse_lingain.signalmin",
00340 CPL_TYPE_DOUBLE,
00341 "Minimum signal value in log(ADU) used for the gain analysis and the non-linearity polynomial model.",
00342 "muse.muse_lingain",
00343 (double)0.);
00344 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "signalmin");
00345 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "signalmin");
00346
00347 cpl_parameterlist_append(recipe->parameters, p);
00348
00349
00350 p = cpl_parameter_new_value("muse.muse_lingain.signalmax",
00351 CPL_TYPE_DOUBLE,
00352 "Maximum signal value in log(ADU) used for the gain analysis and the non-linearity polynomial model.",
00353 "muse.muse_lingain",
00354 (double)4.9);
00355 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "signalmax");
00356 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "signalmax");
00357
00358 cpl_parameterlist_append(recipe->parameters, p);
00359
00360
00361 p = cpl_parameter_new_value("muse.muse_lingain.signalbin",
00362 CPL_TYPE_DOUBLE,
00363 "Size of a signal bin in log10(ADU) used for the gain analysis and the non-linearity polynomial model.",
00364 "muse.muse_lingain",
00365 (double)0.1);
00366 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "signalbin");
00367 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "signalbin");
00368
00369 cpl_parameterlist_append(recipe->parameters, p);
00370
00371
00372 p = cpl_parameter_new_value("muse.muse_lingain.gainlimit",
00373 CPL_TYPE_DOUBLE,
00374 "Minimum signal value [ADU] used for fitting the gain relation.",
00375 "muse.muse_lingain",
00376 (double)100.);
00377 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "gainlimit");
00378 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "gainlimit");
00379
00380 cpl_parameterlist_append(recipe->parameters, p);
00381
00382
00383 p = cpl_parameter_new_value("muse.muse_lingain.gainsigma",
00384 CPL_TYPE_DOUBLE,
00385 "Sigma value for gain value clipping.",
00386 "muse.muse_lingain",
00387 (double)3.);
00388 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "gainsigma");
00389 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "gainsigma");
00390
00391 cpl_parameterlist_append(recipe->parameters, p);
00392
00393
00394 p = cpl_parameter_new_value("muse.muse_lingain.ctsmin",
00395 CPL_TYPE_DOUBLE,
00396 "Minimum signal value in log(counts) to consider for the non-linearity analysis.",
00397 "muse.muse_lingain",
00398 (double)3.);
00399 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ctsmin");
00400 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ctsmin");
00401
00402 cpl_parameterlist_append(recipe->parameters, p);
00403
00404
00405 p = cpl_parameter_new_value("muse.muse_lingain.ctsmax",
00406 CPL_TYPE_DOUBLE,
00407 "Maximum signal value in log(counts) to consider for the non-linearity analysis.",
00408 "muse.muse_lingain",
00409 (double)4.9);
00410 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ctsmax");
00411 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ctsmax");
00412
00413 cpl_parameterlist_append(recipe->parameters, p);
00414
00415
00416 p = cpl_parameter_new_value("muse.muse_lingain.ctsbin",
00417 CPL_TYPE_DOUBLE,
00418 "Size of a signal bin in log10(counts) used for the non-linearity analysis.",
00419 "muse.muse_lingain",
00420 (double)0.1);
00421 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ctsbin");
00422 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ctsbin");
00423
00424 cpl_parameterlist_append(recipe->parameters, p);
00425
00426
00427 p = cpl_parameter_new_value("muse.muse_lingain.linearmin",
00428 CPL_TYPE_DOUBLE,
00429 "Lower limit of desired linear range in log10(counts).",
00430 "muse.muse_lingain",
00431 (double)2.5);
00432 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "linearmin");
00433 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "linearmin");
00434
00435 cpl_parameterlist_append(recipe->parameters, p);
00436
00437
00438 p = cpl_parameter_new_value("muse.muse_lingain.linearmax",
00439 CPL_TYPE_DOUBLE,
00440 "Upper limit of desired linear range in log10(counts).",
00441 "muse.muse_lingain",
00442 (double)3.);
00443 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "linearmax");
00444 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "linearmax");
00445
00446 cpl_parameterlist_append(recipe->parameters, p);
00447
00448
00449 p = cpl_parameter_new_value("muse.muse_lingain.merge",
00450 CPL_TYPE_BOOL,
00451 "Merge output products from different IFUs into a common file.",
00452 "muse.muse_lingain",
00453 (int)FALSE);
00454 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "merge");
00455 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "merge");
00456
00457 cpl_parameterlist_append(recipe->parameters, p);
00458
00459 return 0;
00460 }
00461
00462
00473
00474 static int
00475 muse_lingain_params_fill(muse_lingain_params_t *aParams, cpl_parameterlist *aParameters)
00476 {
00477 cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
00478 cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
00479 cpl_parameter *p;
00480
00481 p = cpl_parameterlist_find(aParameters, "muse.muse_lingain.nifu");
00482 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00483 aParams->nifu = cpl_parameter_get_int(p);
00484
00485 p = cpl_parameterlist_find(aParameters, "muse.muse_lingain.ybox");
00486 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00487 aParams->ybox = cpl_parameter_get_int(p);
00488
00489 p = cpl_parameterlist_find(aParameters, "muse.muse_lingain.xgap");
00490 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00491 aParams->xgap = cpl_parameter_get_int(p);
00492
00493 p = cpl_parameterlist_find(aParameters, "muse.muse_lingain.xborder");
00494 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00495 aParams->xborder = cpl_parameter_get_int(p);
00496
00497 p = cpl_parameterlist_find(aParameters, "muse.muse_lingain.order");
00498 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00499 aParams->order = cpl_parameter_get_int(p);
00500
00501 p = cpl_parameterlist_find(aParameters, "muse.muse_lingain.toffset");
00502 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00503 aParams->toffset = cpl_parameter_get_double(p);
00504
00505 p = cpl_parameterlist_find(aParameters, "muse.muse_lingain.fluxtol");
00506 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00507 aParams->fluxtol = cpl_parameter_get_double(p);
00508
00509 p = cpl_parameterlist_find(aParameters, "muse.muse_lingain.sigma");
00510 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00511 aParams->sigma = cpl_parameter_get_double(p);
00512
00513 p = cpl_parameterlist_find(aParameters, "muse.muse_lingain.signalmin");
00514 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00515 aParams->signalmin = cpl_parameter_get_double(p);
00516
00517 p = cpl_parameterlist_find(aParameters, "muse.muse_lingain.signalmax");
00518 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00519 aParams->signalmax = cpl_parameter_get_double(p);
00520
00521 p = cpl_parameterlist_find(aParameters, "muse.muse_lingain.signalbin");
00522 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00523 aParams->signalbin = cpl_parameter_get_double(p);
00524
00525 p = cpl_parameterlist_find(aParameters, "muse.muse_lingain.gainlimit");
00526 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00527 aParams->gainlimit = cpl_parameter_get_double(p);
00528
00529 p = cpl_parameterlist_find(aParameters, "muse.muse_lingain.gainsigma");
00530 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00531 aParams->gainsigma = cpl_parameter_get_double(p);
00532
00533 p = cpl_parameterlist_find(aParameters, "muse.muse_lingain.ctsmin");
00534 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00535 aParams->ctsmin = cpl_parameter_get_double(p);
00536
00537 p = cpl_parameterlist_find(aParameters, "muse.muse_lingain.ctsmax");
00538 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00539 aParams->ctsmax = cpl_parameter_get_double(p);
00540
00541 p = cpl_parameterlist_find(aParameters, "muse.muse_lingain.ctsbin");
00542 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00543 aParams->ctsbin = cpl_parameter_get_double(p);
00544
00545 p = cpl_parameterlist_find(aParameters, "muse.muse_lingain.linearmin");
00546 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00547 aParams->linearmin = cpl_parameter_get_double(p);
00548
00549 p = cpl_parameterlist_find(aParameters, "muse.muse_lingain.linearmax");
00550 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00551 aParams->linearmax = cpl_parameter_get_double(p);
00552
00553 p = cpl_parameterlist_find(aParameters, "muse.muse_lingain.merge");
00554 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00555 aParams->merge = cpl_parameter_get_bool(p);
00556
00557 return 0;
00558 }
00559
00560
00567
00568 static int
00569 muse_lingain_exec(cpl_plugin *aPlugin)
00570 {
00571 if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
00572 return -1;
00573 }
00574 muse_processing_recipeinfo(aPlugin);
00575 cpl_recipe *recipe = (cpl_recipe *)aPlugin;
00576 cpl_msg_set_threadid_on();
00577
00578 cpl_frameset *usedframes = cpl_frameset_new(),
00579 *outframes = cpl_frameset_new();
00580 muse_lingain_params_t params;
00581 muse_lingain_params_fill(¶ms, recipe->parameters);
00582
00583 cpl_errorstate prestate = cpl_errorstate_get();
00584
00585 if (params.nifu < -1 || params.nifu > kMuseNumIFUs) {
00586 cpl_msg_error(__func__, "Please specify a valid IFU number (between 1 and "
00587 "%d), 0 (to process all IFUs consecutively), or -1 (to "
00588 "process all IFUs in parallel) using --nifu.", kMuseNumIFUs);
00589 return -1;
00590 }
00591
00592 cpl_boolean donotmerge = CPL_FALSE;
00593 int rc = 0;
00594 if (params.nifu > 0) {
00595 muse_processing *proc = muse_processing_new("muse_lingain",
00596 recipe);
00597 rc = muse_lingain_compute(proc, ¶ms);
00598 cpl_frameset_join(usedframes, proc->usedframes);
00599 cpl_frameset_join(outframes, proc->outframes);
00600 muse_processing_delete(proc);
00601 donotmerge = CPL_TRUE;
00602 } else if (params.nifu < 0) {
00603 int *rcs = cpl_calloc(kMuseNumIFUs, sizeof(int));
00604 int nifu;
00605 #pragma omp parallel for default(none) \
00606 shared(outframes, params, rcs, recipe, usedframes)
00607 for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
00608 muse_processing *proc = muse_processing_new("muse_lingain",
00609 recipe);
00610 muse_lingain_params_t *pars = cpl_malloc(sizeof(muse_lingain_params_t));
00611 memcpy(pars, ¶ms, sizeof(muse_lingain_params_t));
00612 pars->nifu = nifu;
00613 int *rci = rcs + (nifu - 1);
00614 *rci = muse_lingain_compute(proc, pars);
00615 if (rci && (int)cpl_error_get_code() == MUSE_ERROR_CHIP_NOT_LIVE) {
00616 *rci = 0;
00617 }
00618 cpl_free(pars);
00619 #pragma omp critical(muse_processing_used_frames)
00620 cpl_frameset_join(usedframes, proc->usedframes);
00621 #pragma omp critical(muse_processing_output_frames)
00622 cpl_frameset_join(outframes, proc->outframes);
00623 muse_processing_delete(proc);
00624 }
00625
00626
00627 for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
00628 if (rcs[nifu-1] != 0) {
00629 rc = rcs[nifu-1];
00630 }
00631 }
00632 cpl_free(rcs);
00633 } else {
00634 for (params.nifu = 1; params.nifu <= kMuseNumIFUs && !rc; params.nifu++) {
00635 muse_processing *proc = muse_processing_new("muse_lingain",
00636 recipe);
00637 rc = muse_lingain_compute(proc, ¶ms);
00638 if (rc && (int)cpl_error_get_code() == MUSE_ERROR_CHIP_NOT_LIVE) {
00639 rc = 0;
00640 }
00641 cpl_frameset_join(usedframes, proc->usedframes);
00642 cpl_frameset_join(outframes, proc->outframes);
00643 muse_processing_delete(proc);
00644 }
00645 }
00646 UNUSED_ARGUMENT(donotmerge);
00647
00648 if (!cpl_errorstate_is_equal(prestate)) {
00649
00650 cpl_errorstate_dump(prestate, CPL_FALSE, muse_cplerrorstate_dump_some);
00651
00652 cpl_msg_set_level(CPL_MSG_INFO);
00653 }
00654
00655 muse_cplframeset_erase_duplicate(usedframes);
00656 muse_cplframeset_erase_duplicate(outframes);
00657
00658
00659 if (params.merge && !donotmerge) {
00660 muse_utils_frameset_merge_frames(outframes, CPL_TRUE);
00661 }
00662
00663
00664
00665
00666
00667 muse_cplframeset_erase_all(recipe->frames);
00668 cpl_frameset_join(recipe->frames, usedframes);
00669 cpl_frameset_join(recipe->frames, outframes);
00670 cpl_frameset_delete(usedframes);
00671 cpl_frameset_delete(outframes);
00672 return rc;
00673 }
00674
00675
00682
00683 static int
00684 muse_lingain_destroy(cpl_plugin *aPlugin)
00685 {
00686
00687 cpl_recipe *recipe;
00688 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
00689 recipe = (cpl_recipe *)aPlugin;
00690 } else {
00691 return -1;
00692 }
00693
00694
00695 cpl_parameterlist_delete(recipe->parameters);
00696 muse_processinginfo_delete(recipe);
00697 return 0;
00698 }
00699
00700
00710
00711 int
00712 cpl_plugin_get_info(cpl_pluginlist *aList)
00713 {
00714 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
00715 cpl_plugin *plugin = &recipe->interface;
00716
00717 char *helptext;
00718 if (muse_cplframework() == MUSE_CPLFRAMEWORK_ESOREX) {
00719 helptext = cpl_sprintf("%s%s", muse_lingain_help,
00720 muse_lingain_help_esorex);
00721 } else {
00722 helptext = cpl_sprintf("%s", muse_lingain_help);
00723 }
00724
00725
00726 cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
00727 CPL_PLUGIN_TYPE_RECIPE,
00728 "muse_lingain",
00729 "Compute the gain and a model of the residual non-linearity for each detector quadrant",
00730 helptext,
00731 "Ralf Palsa",
00732 "usd-help@eso.org",
00733 muse_get_license(),
00734 muse_lingain_create,
00735 muse_lingain_exec,
00736 muse_lingain_destroy);
00737 cpl_pluginlist_append(aList, plugin);
00738 cpl_free(helptext);
00739
00740 return 0;
00741 }
00742