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_lsf_z.h"
00036
00037
00045
00048
00049
00050
00051 static const char *muse_lsf_help =
00052 "Compute the slice and wavelength dependent LSF from a lines spectrum (ARC lamp).";
00053
00054 static const char *muse_lsf_help_esorex =
00055 "\n\nInput frames for raw frame tag \"ARC\":\n"
00056 "\n Frame tag Type Req #Fr Description"
00057 "\n -------------------- ---- --- --- ------------"
00058 "\n ARC raw . Raw arc lamp exposures (from a standard arc sequence)"
00059 "\n ARC_LSF raw . Raw arc lamp exposures (from a long LSF arc sequence)"
00060 "\n MASTER_BIAS calib Y 1 Master bias"
00061 "\n MASTER_DARK calib . 1 Master dark"
00062 "\n MASTER_FLAT calib . 1 Master flat"
00063 "\n TRACE_TABLE calib Y 1 Trace table"
00064 "\n WAVECAL_TABLE calib Y 1 Wavelength calibration table"
00065 "\n BADPIX_TABLE calib . 1 Known bad pixels"
00066 "\n LINE_CATALOG calib Y 1 Arc line catalog"
00067 "\n\nProduct frames for raw frame tag \"ARC\":\n"
00068 "\n Frame tag Level Description"
00069 "\n -------------------- -------- ------------"
00070 "\n LSF_PROFILE final Slice specific LSF images, stacked into one data cube per IFU."
00071 "\n PIXTABLE_SUBTRACTED final Subtracted combined pixel table, if --save_subtracted=true. This file contains only the subtracted arc lines that contributed to the LSF calculation. There are additional columns line_lambda and line_flux with the reference wavelength and the estimated line flux of the corresponding arc line.";
00072
00073
00081
00082 static cpl_recipeconfig *
00083 muse_lsf_new_recipeconfig(void)
00084 {
00085 cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
00086
00087 cpl_recipeconfig_set_tag(recipeconfig, "ARC", -1, -1);
00088 cpl_recipeconfig_set_input(recipeconfig, "ARC", "MASTER_BIAS", 1, 1);
00089 cpl_recipeconfig_set_input(recipeconfig, "ARC", "MASTER_DARK", -1, 1);
00090 cpl_recipeconfig_set_input(recipeconfig, "ARC", "MASTER_FLAT", -1, 1);
00091 cpl_recipeconfig_set_input(recipeconfig, "ARC", "TRACE_TABLE", 1, 1);
00092 cpl_recipeconfig_set_input(recipeconfig, "ARC", "WAVECAL_TABLE", 1, 1);
00093 cpl_recipeconfig_set_input(recipeconfig, "ARC", "BADPIX_TABLE", -1, 1);
00094 cpl_recipeconfig_set_input(recipeconfig, "ARC", "LINE_CATALOG", 1, 1);
00095 cpl_recipeconfig_set_output(recipeconfig, "ARC", "LSF_PROFILE");
00096 cpl_recipeconfig_set_output(recipeconfig, "ARC", "PIXTABLE_SUBTRACTED");
00097 cpl_recipeconfig_set_tag(recipeconfig, "ARC_LSF", -1, -1);
00098 cpl_recipeconfig_set_input(recipeconfig, "ARC_LSF", "MASTER_BIAS", 1, 1);
00099 cpl_recipeconfig_set_input(recipeconfig, "ARC_LSF", "MASTER_DARK", -1, 1);
00100 cpl_recipeconfig_set_input(recipeconfig, "ARC_LSF", "MASTER_FLAT", -1, 1);
00101 cpl_recipeconfig_set_input(recipeconfig, "ARC_LSF", "TRACE_TABLE", 1, 1);
00102 cpl_recipeconfig_set_input(recipeconfig, "ARC_LSF", "WAVECAL_TABLE", 1, 1);
00103 cpl_recipeconfig_set_input(recipeconfig, "ARC_LSF", "BADPIX_TABLE", -1, 1);
00104 cpl_recipeconfig_set_input(recipeconfig, "ARC_LSF", "LINE_CATALOG", 1, 1);
00105 cpl_recipeconfig_set_output(recipeconfig, "ARC_LSF", "LSF_PROFILE");
00106 cpl_recipeconfig_set_output(recipeconfig, "ARC_LSF", "PIXTABLE_SUBTRACTED");
00107
00108 return recipeconfig;
00109 }
00110
00111
00121
00122 static cpl_error_code
00123 muse_lsf_prepare_header(const char *aFrametag, cpl_propertylist *aHeader)
00124 {
00125 cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
00126 cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
00127 if (!strcmp(aFrametag, "LSF_PROFILE")) {
00128 muse_processing_prepare_property(aHeader, "ESO QC LSF SLICE[0-9]+ FWHM MEAN",
00129 CPL_TYPE_FLOAT,
00130 "Mean FWHM of the LSF slice j");
00131 muse_processing_prepare_property(aHeader, "ESO QC LSF SLICE[0-9]+ FWHM STDEV",
00132 CPL_TYPE_FLOAT,
00133 "Standard deviation of the LSF in slice j");
00134 muse_processing_prepare_property(aHeader, "ESO QC LSF SLICE[0-9]+ FWHM MIN",
00135 CPL_TYPE_FLOAT,
00136 "Minimum FWHM of the LSF in slice j");
00137 muse_processing_prepare_property(aHeader, "ESO QC LSF SLICE[0-9]+ FWHM MAX",
00138 CPL_TYPE_FLOAT,
00139 "Maximum FWHM of the LSF in slice j");
00140 } else if (!strcmp(aFrametag, "PIXTABLE_SUBTRACTED")) {
00141 } else {
00142 cpl_msg_warning(__func__, "Frame tag %s is not defined", aFrametag);
00143 return CPL_ERROR_ILLEGAL_INPUT;
00144 }
00145 return CPL_ERROR_NONE;
00146 }
00147
00148
00157
00158 static cpl_frame_level
00159 muse_lsf_get_frame_level(const char *aFrametag)
00160 {
00161 if (!aFrametag) {
00162 return CPL_FRAME_LEVEL_NONE;
00163 }
00164 if (!strcmp(aFrametag, "LSF_PROFILE")) {
00165 return CPL_FRAME_LEVEL_FINAL;
00166 }
00167 if (!strcmp(aFrametag, "PIXTABLE_SUBTRACTED")) {
00168 return CPL_FRAME_LEVEL_FINAL;
00169 }
00170 return CPL_FRAME_LEVEL_NONE;
00171 }
00172
00173
00182
00183 static muse_frame_mode
00184 muse_lsf_get_frame_mode(const char *aFrametag)
00185 {
00186 if (!aFrametag) {
00187 return MUSE_FRAME_MODE_ALL;
00188 }
00189 if (!strcmp(aFrametag, "LSF_PROFILE")) {
00190 return MUSE_FRAME_MODE_MASTER;
00191 }
00192 if (!strcmp(aFrametag, "PIXTABLE_SUBTRACTED")) {
00193 return MUSE_FRAME_MODE_MASTER;
00194 }
00195 return MUSE_FRAME_MODE_ALL;
00196 }
00197
00198
00208
00209 static int
00210 muse_lsf_create(cpl_plugin *aPlugin)
00211 {
00212
00213 cpl_recipe *recipe;
00214 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
00215 recipe = (cpl_recipe *)aPlugin;
00216 } else {
00217 return -1;
00218 }
00219
00220
00221
00222 muse_processinginfo_register(recipe,
00223 muse_lsf_new_recipeconfig(),
00224 muse_lsf_prepare_header,
00225 muse_lsf_get_frame_level,
00226 muse_lsf_get_frame_mode);
00227
00228
00229
00230 if (muse_cplframework() == MUSE_CPLFRAMEWORK_ESOREX) {
00231 cpl_msg_set_time_on();
00232 }
00233
00234
00235 recipe->parameters = cpl_parameterlist_new();
00236
00237 cpl_parameter *p;
00238
00239
00240 p = cpl_parameter_new_range("muse.muse_lsf.nifu",
00241 CPL_TYPE_INT,
00242 "IFU to handle. If set to 0, all IFUs are processed serially. If set to -1, all IFUs are processed in parallel.",
00243 "muse.muse_lsf",
00244 (int)0,
00245 (int)-1,
00246 (int)24);
00247 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nifu");
00248 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nifu");
00249
00250 cpl_parameterlist_append(recipe->parameters, p);
00251
00252
00253 p = cpl_parameter_new_value("muse.muse_lsf.overscan",
00254 CPL_TYPE_STRING,
00255 "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.",
00256 "muse.muse_lsf",
00257 (const char *)"vpoly");
00258 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "overscan");
00259 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "overscan");
00260
00261 cpl_parameterlist_append(recipe->parameters, p);
00262
00263
00264 p = cpl_parameter_new_value("muse.muse_lsf.ovscreject",
00265 CPL_TYPE_STRING,
00266 "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\").",
00267 "muse.muse_lsf",
00268 (const char *)"dcr");
00269 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ovscreject");
00270 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ovscreject");
00271
00272 cpl_parameterlist_append(recipe->parameters, p);
00273
00274
00275 p = cpl_parameter_new_value("muse.muse_lsf.ovscsigma",
00276 CPL_TYPE_DOUBLE,
00277 "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\".",
00278 "muse.muse_lsf",
00279 (double)30.);
00280 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ovscsigma");
00281 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ovscsigma");
00282
00283 cpl_parameterlist_append(recipe->parameters, p);
00284
00285
00286 p = cpl_parameter_new_value("muse.muse_lsf.ovscignore",
00287 CPL_TYPE_INT,
00288 "The number of pixels of the overscan adjacent to the data region of the CCD that are ignored when computing statistics or fits.",
00289 "muse.muse_lsf",
00290 (int)3);
00291 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ovscignore");
00292 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ovscignore");
00293
00294 cpl_parameterlist_append(recipe->parameters, p);
00295
00296
00297 p = cpl_parameter_new_value("muse.muse_lsf.save_subtracted",
00298 CPL_TYPE_BOOL,
00299 "Save the pixel table after the LSF subtraction.",
00300 "muse.muse_lsf",
00301 (int)FALSE);
00302 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "save_subtracted");
00303 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "save_subtracted");
00304
00305 cpl_parameterlist_append(recipe->parameters, p);
00306
00307
00308 p = cpl_parameter_new_value("muse.muse_lsf.line_quality",
00309 CPL_TYPE_INT,
00310 "Minimal quality flag in line catalog for selection",
00311 "muse.muse_lsf",
00312 (int)3);
00313 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "line_quality");
00314 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "line_quality");
00315
00316 cpl_parameterlist_append(recipe->parameters, p);
00317
00318
00319 p = cpl_parameter_new_value("muse.muse_lsf.lsf_range",
00320 CPL_TYPE_DOUBLE,
00321 "Wavelength window (half size) around each line to estimate LSF",
00322 "muse.muse_lsf",
00323 (double)7.5);
00324 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lsf_range");
00325 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lsf_range");
00326
00327 cpl_parameterlist_append(recipe->parameters, p);
00328
00329
00330 p = cpl_parameter_new_value("muse.muse_lsf.lsf_size",
00331 CPL_TYPE_INT,
00332 "Image size in LSF direction",
00333 "muse.muse_lsf",
00334 (int)150);
00335 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lsf_size");
00336 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lsf_size");
00337
00338 cpl_parameterlist_append(recipe->parameters, p);
00339
00340
00341 p = cpl_parameter_new_value("muse.muse_lsf.lambda_size",
00342 CPL_TYPE_INT,
00343 "Image size in line wavelength direction",
00344 "muse.muse_lsf",
00345 (int)30);
00346 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambda_size");
00347 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambda_size");
00348
00349 cpl_parameterlist_append(recipe->parameters, p);
00350
00351
00352 p = cpl_parameter_new_value("muse.muse_lsf.lsf_regression_window",
00353 CPL_TYPE_DOUBLE,
00354 "Size of the regression window in LSF direction",
00355 "muse.muse_lsf",
00356 (double)0.7);
00357 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lsf_regression_window");
00358 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lsf_regression_window");
00359
00360 cpl_parameterlist_append(recipe->parameters, p);
00361
00362
00363 p = cpl_parameter_new_value("muse.muse_lsf.merge",
00364 CPL_TYPE_BOOL,
00365 "Merge output products from different IFUs into a common file.",
00366 "muse.muse_lsf",
00367 (int)FALSE);
00368 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "merge");
00369 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "merge");
00370
00371 cpl_parameterlist_append(recipe->parameters, p);
00372
00373
00374 p = cpl_parameter_new_enum("muse.muse_lsf.combine",
00375 CPL_TYPE_STRING,
00376 "Type of lampwise image combination to use.",
00377 "muse.muse_lsf",
00378 (const char *)"sigclip",
00379 4,
00380 (const char *)"average",
00381 (const char *)"median",
00382 (const char *)"minmax",
00383 (const char *)"sigclip");
00384 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "combine");
00385 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "combine");
00386
00387 cpl_parameterlist_append(recipe->parameters, p);
00388
00389
00390 p = cpl_parameter_new_enum("muse.muse_lsf.method",
00391 CPL_TYPE_STRING,
00392 "LSF generation method. Depending on this value, either an interpolated LSF cube is created, or a table with the parameters of a hermitean gaussian.",
00393 "muse.muse_lsf",
00394 (const char *)"interpolate",
00395 2,
00396 (const char *)"interpolate",
00397 (const char *)"hermit");
00398 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "method");
00399 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "method");
00400
00401 cpl_parameterlist_append(recipe->parameters, p);
00402
00403 return 0;
00404 }
00405
00406
00417
00418 static int
00419 muse_lsf_params_fill(muse_lsf_params_t *aParams, cpl_parameterlist *aParameters)
00420 {
00421 cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
00422 cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
00423 cpl_parameter *p;
00424
00425 p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.nifu");
00426 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00427 aParams->nifu = cpl_parameter_get_int(p);
00428
00429 p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.overscan");
00430 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00431 aParams->overscan = cpl_parameter_get_string(p);
00432
00433 p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.ovscreject");
00434 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00435 aParams->ovscreject = cpl_parameter_get_string(p);
00436
00437 p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.ovscsigma");
00438 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00439 aParams->ovscsigma = cpl_parameter_get_double(p);
00440
00441 p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.ovscignore");
00442 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00443 aParams->ovscignore = cpl_parameter_get_int(p);
00444
00445 p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.save_subtracted");
00446 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00447 aParams->save_subtracted = cpl_parameter_get_bool(p);
00448
00449 p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.line_quality");
00450 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00451 aParams->line_quality = cpl_parameter_get_int(p);
00452
00453 p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.lsf_range");
00454 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00455 aParams->lsf_range = cpl_parameter_get_double(p);
00456
00457 p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.lsf_size");
00458 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00459 aParams->lsf_size = cpl_parameter_get_int(p);
00460
00461 p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.lambda_size");
00462 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00463 aParams->lambda_size = cpl_parameter_get_int(p);
00464
00465 p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.lsf_regression_window");
00466 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00467 aParams->lsf_regression_window = cpl_parameter_get_double(p);
00468
00469 p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.merge");
00470 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00471 aParams->merge = cpl_parameter_get_bool(p);
00472
00473 p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.combine");
00474 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00475 aParams->combine_s = cpl_parameter_get_string(p);
00476 aParams->combine =
00477 (!strcasecmp(aParams->combine_s, "average")) ? MUSE_LSF_PARAM_COMBINE_AVERAGE :
00478 (!strcasecmp(aParams->combine_s, "median")) ? MUSE_LSF_PARAM_COMBINE_MEDIAN :
00479 (!strcasecmp(aParams->combine_s, "minmax")) ? MUSE_LSF_PARAM_COMBINE_MINMAX :
00480 (!strcasecmp(aParams->combine_s, "sigclip")) ? MUSE_LSF_PARAM_COMBINE_SIGCLIP :
00481 MUSE_LSF_PARAM_COMBINE_INVALID_VALUE;
00482 cpl_ensure_code(aParams->combine != MUSE_LSF_PARAM_COMBINE_INVALID_VALUE,
00483 CPL_ERROR_ILLEGAL_INPUT);
00484
00485 p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.method");
00486 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00487 aParams->method_s = cpl_parameter_get_string(p);
00488 aParams->method =
00489 (!strcasecmp(aParams->method_s, "interpolate")) ? MUSE_LSF_PARAM_METHOD_INTERPOLATE :
00490 (!strcasecmp(aParams->method_s, "hermit")) ? MUSE_LSF_PARAM_METHOD_HERMIT :
00491 MUSE_LSF_PARAM_METHOD_INVALID_VALUE;
00492 cpl_ensure_code(aParams->method != MUSE_LSF_PARAM_METHOD_INVALID_VALUE,
00493 CPL_ERROR_ILLEGAL_INPUT);
00494
00495 return 0;
00496 }
00497
00498
00505
00506 static int
00507 muse_lsf_exec(cpl_plugin *aPlugin)
00508 {
00509 if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
00510 return -1;
00511 }
00512 muse_processing_recipeinfo(aPlugin);
00513 cpl_recipe *recipe = (cpl_recipe *)aPlugin;
00514 cpl_msg_set_threadid_on();
00515
00516 cpl_frameset *usedframes = cpl_frameset_new(),
00517 *outframes = cpl_frameset_new();
00518 muse_lsf_params_t params;
00519 muse_lsf_params_fill(¶ms, recipe->parameters);
00520
00521 cpl_errorstate prestate = cpl_errorstate_get();
00522
00523 if (params.nifu < -1 || params.nifu > kMuseNumIFUs) {
00524 cpl_msg_error(__func__, "Please specify a valid IFU number (between 1 and "
00525 "%d), 0 (to process all IFUs consecutively), or -1 (to "
00526 "process all IFUs in parallel) using --nifu.", kMuseNumIFUs);
00527 return -1;
00528 }
00529
00530 cpl_boolean donotmerge = CPL_FALSE;
00531 int rc = 0;
00532 if (params.nifu > 0) {
00533 muse_processing *proc = muse_processing_new("muse_lsf",
00534 recipe);
00535 rc = muse_lsf_compute(proc, ¶ms);
00536 cpl_frameset_join(usedframes, proc->usedframes);
00537 cpl_frameset_join(outframes, proc->outframes);
00538 muse_processing_delete(proc);
00539 donotmerge = CPL_TRUE;
00540 } else if (params.nifu < 0) {
00541 int *rcs = cpl_calloc(kMuseNumIFUs, sizeof(int));
00542 int nifu;
00543 #pragma omp parallel for default(none) \
00544 shared(outframes, params, rcs, recipe, usedframes)
00545 for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
00546 muse_processing *proc = muse_processing_new("muse_lsf",
00547 recipe);
00548 muse_lsf_params_t *pars = cpl_malloc(sizeof(muse_lsf_params_t));
00549 memcpy(pars, ¶ms, sizeof(muse_lsf_params_t));
00550 pars->nifu = nifu;
00551 int *rci = rcs + (nifu - 1);
00552 *rci = muse_lsf_compute(proc, pars);
00553 if (rci && (int)cpl_error_get_code() == MUSE_ERROR_CHIP_NOT_LIVE) {
00554 *rci = 0;
00555 }
00556 cpl_free(pars);
00557 #pragma omp critical(muse_processing_used_frames)
00558 cpl_frameset_join(usedframes, proc->usedframes);
00559 #pragma omp critical(muse_processing_output_frames)
00560 cpl_frameset_join(outframes, proc->outframes);
00561 muse_processing_delete(proc);
00562 }
00563
00564
00565 for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
00566 if (rcs[nifu-1] != 0) {
00567 rc = rcs[nifu-1];
00568 }
00569 }
00570 cpl_free(rcs);
00571 } else {
00572 for (params.nifu = 1; params.nifu <= kMuseNumIFUs && !rc; params.nifu++) {
00573 muse_processing *proc = muse_processing_new("muse_lsf",
00574 recipe);
00575 rc = muse_lsf_compute(proc, ¶ms);
00576 if (rc && (int)cpl_error_get_code() == MUSE_ERROR_CHIP_NOT_LIVE) {
00577 rc = 0;
00578 }
00579 cpl_frameset_join(usedframes, proc->usedframes);
00580 cpl_frameset_join(outframes, proc->outframes);
00581 muse_processing_delete(proc);
00582 }
00583 }
00584 UNUSED_ARGUMENT(donotmerge);
00585
00586 if (!cpl_errorstate_is_equal(prestate)) {
00587
00588 cpl_errorstate_dump(prestate, CPL_FALSE, muse_cplerrorstate_dump_some);
00589
00590 cpl_msg_set_level(CPL_MSG_INFO);
00591 }
00592
00593 muse_cplframeset_erase_duplicate(usedframes);
00594 muse_cplframeset_erase_duplicate(outframes);
00595
00596
00597 if (params.merge && !donotmerge) {
00598 muse_utils_frameset_merge_frames(outframes, CPL_TRUE);
00599 }
00600
00601
00602
00603
00604
00605 muse_cplframeset_erase_all(recipe->frames);
00606 cpl_frameset_join(recipe->frames, usedframes);
00607 cpl_frameset_join(recipe->frames, outframes);
00608 cpl_frameset_delete(usedframes);
00609 cpl_frameset_delete(outframes);
00610 return rc;
00611 }
00612
00613
00620
00621 static int
00622 muse_lsf_destroy(cpl_plugin *aPlugin)
00623 {
00624
00625 cpl_recipe *recipe;
00626 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
00627 recipe = (cpl_recipe *)aPlugin;
00628 } else {
00629 return -1;
00630 }
00631
00632
00633 cpl_parameterlist_delete(recipe->parameters);
00634 muse_processinginfo_delete(recipe);
00635 return 0;
00636 }
00637
00638
00648
00649 int
00650 cpl_plugin_get_info(cpl_pluginlist *aList)
00651 {
00652 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
00653 cpl_plugin *plugin = &recipe->interface;
00654
00655 char *helptext;
00656 if (muse_cplframework() == MUSE_CPLFRAMEWORK_ESOREX) {
00657 helptext = cpl_sprintf("%s%s", muse_lsf_help,
00658 muse_lsf_help_esorex);
00659 } else {
00660 helptext = cpl_sprintf("%s", muse_lsf_help);
00661 }
00662
00663
00664 cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
00665 CPL_PLUGIN_TYPE_RECIPE,
00666 "muse_lsf",
00667 "Compute the LSF",
00668 helptext,
00669 "Ole Streicher",
00670 "usd-help@eso.org",
00671 muse_get_license(),
00672 muse_lsf_create,
00673 muse_lsf_exec,
00674 muse_lsf_destroy);
00675 cpl_pluginlist_append(aList, plugin);
00676 cpl_free(helptext);
00677
00678 return 0;
00679 }
00680