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_bias_z.h"
00036
00037
00057
00060
00061
00062
00063 static const char *muse_bias_help =
00064 "This recipe combines several separate bias images into one master bias file. The master bias contains the combined pixel values, in adu, of the raw bias exposures, with respect to the image combination method used. Processing trims the raw data and records the overscan statistics, corrects the data levels using the overscan (if overscan is not &none&) and combines the exposures using input parameters. The read-out noise is computed for each quadrant of the raw input images and stored as QC parameter. The variance extension is filled with an initial value accordingly, before image combination. Further QC statistics are computed on the output master bias. Additionally, bad columns are searched for and marked in the data quality extension.";
00065
00066 static const char *muse_bias_help_esorex =
00067 "\n\nInput frames for raw frame tag \"BIAS\":\n"
00068 "\n Frame tag Type Req #Fr Description"
00069 "\n -------------------- ---- --- --- ------------"
00070 "\n BIAS raw Y >=3 Raw bias"
00071 "\n BADPIX_TABLE calib . 1 Bad pixel table"
00072 "\n\nProduct frames for raw frame tag \"BIAS\":\n"
00073 "\n Frame tag Level Description"
00074 "\n -------------------- -------- ------------"
00075 "\n MASTER_BIAS final Master bias";
00076
00077
00085
00086 static cpl_recipeconfig *
00087 muse_bias_new_recipeconfig(void)
00088 {
00089 cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
00090
00091 cpl_recipeconfig_set_tag(recipeconfig, "BIAS", 3, -1);
00092 cpl_recipeconfig_set_input(recipeconfig, "BIAS", "BADPIX_TABLE", -1, 1);
00093 cpl_recipeconfig_set_output(recipeconfig, "BIAS", "MASTER_BIAS");
00094
00095 return recipeconfig;
00096 }
00097
00098
00108
00109 static cpl_error_code
00110 muse_bias_prepare_header(const char *aFrametag, cpl_propertylist *aHeader)
00111 {
00112 cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
00113 cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
00114 if (!strcmp(aFrametag, "MASTER_BIAS")) {
00115 muse_processing_prepare_property(aHeader, "ESO QC BIAS INPUT[0-9]+ NSATURATED",
00116 CPL_TYPE_INT,
00117 "Number of saturated pixels in raw bias i in input list");
00118 muse_processing_prepare_property(aHeader, "ESO QC BIAS MASTER[1234] MEDIAN",
00119 CPL_TYPE_FLOAT,
00120 "Median value of master bias in quadrant n");
00121 muse_processing_prepare_property(aHeader, "ESO QC BIAS MASTER[1234] MEAN",
00122 CPL_TYPE_FLOAT,
00123 "Mean value of master bias in quadrant n");
00124 muse_processing_prepare_property(aHeader, "ESO QC BIAS MASTER[1234] STDEV",
00125 CPL_TYPE_FLOAT,
00126 "Standard deviation value of master bias in quadrant n");
00127 muse_processing_prepare_property(aHeader, "ESO QC BIAS MASTER[1234] MIN",
00128 CPL_TYPE_FLOAT,
00129 "Minimum value of master bias in quadrant n");
00130 muse_processing_prepare_property(aHeader, "ESO QC BIAS MASTER[1234] MAX",
00131 CPL_TYPE_FLOAT,
00132 "Maximum value of master bias in quadrant n");
00133 muse_processing_prepare_property(aHeader, "ESO QC BIAS MASTER[1234] RON",
00134 CPL_TYPE_FLOAT,
00135 "[count] Read-out noise in quadrant n determined from difference images of each adjacent pair of biases in the input dataset in randomly placed windows");
00136 muse_processing_prepare_property(aHeader, "ESO QC BIAS MASTER[1234] RONERR",
00137 CPL_TYPE_FLOAT,
00138 "[count] Read-out noise error in quadrant n determined from difference images of each adjacent pair of biases in the input dataset in randomly placed windows");
00139 muse_processing_prepare_property(aHeader, "ESO QC BIAS MASTER[1234] SLOPE X",
00140 CPL_TYPE_FLOAT,
00141 "[adu/pix] Average horizontal slope of master bias in quadrant n");
00142 muse_processing_prepare_property(aHeader, "ESO QC BIAS MASTER[1234] SLOPE Y",
00143 CPL_TYPE_FLOAT,
00144 "[adu/pix] Average vertical slope of master bias in quadrant n");
00145 muse_processing_prepare_property(aHeader, "ESO QC BIAS MASTER NBADPIX",
00146 CPL_TYPE_INT,
00147 "Bad pixels found as part of the bad column search in the master bias");
00148 muse_processing_prepare_property(aHeader, "ESO QC BIAS MASTER NSATURATED",
00149 CPL_TYPE_INT,
00150 "Number of saturated pixels in output data");
00151 muse_processing_prepare_property(aHeader, "ESO QC BIAS LEVEL[1234] MEAN",
00152 CPL_TYPE_FLOAT,
00153 "[adu] Average of the raw median values of all input files in quadrant n");
00154 muse_processing_prepare_property(aHeader, "ESO QC BIAS LEVEL[1234] STDEV",
00155 CPL_TYPE_FLOAT,
00156 "[adu] Standard deviation of the raw median values of all input files in quadrant n");
00157 muse_processing_prepare_property(aHeader, "ESO QC BIAS LEVEL[1234] MEDIAN",
00158 CPL_TYPE_FLOAT,
00159 "[adu] Median of the raw median values of all input files in quadrant n");
00160 } else {
00161 cpl_msg_warning(__func__, "Frame tag %s is not defined", aFrametag);
00162 return CPL_ERROR_ILLEGAL_INPUT;
00163 }
00164 return CPL_ERROR_NONE;
00165 }
00166
00167
00176
00177 static cpl_frame_level
00178 muse_bias_get_frame_level(const char *aFrametag)
00179 {
00180 if (!aFrametag) {
00181 return CPL_FRAME_LEVEL_NONE;
00182 }
00183 if (!strcmp(aFrametag, "MASTER_BIAS")) {
00184 return CPL_FRAME_LEVEL_FINAL;
00185 }
00186 return CPL_FRAME_LEVEL_NONE;
00187 }
00188
00189
00198
00199 static muse_frame_mode
00200 muse_bias_get_frame_mode(const char *aFrametag)
00201 {
00202 if (!aFrametag) {
00203 return MUSE_FRAME_MODE_ALL;
00204 }
00205 if (!strcmp(aFrametag, "MASTER_BIAS")) {
00206 return MUSE_FRAME_MODE_MASTER;
00207 }
00208 return MUSE_FRAME_MODE_ALL;
00209 }
00210
00211
00221
00222 static int
00223 muse_bias_create(cpl_plugin *aPlugin)
00224 {
00225
00226 cpl_recipe *recipe;
00227 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
00228 recipe = (cpl_recipe *)aPlugin;
00229 } else {
00230 return -1;
00231 }
00232
00233
00234
00235 muse_processinginfo_register(recipe,
00236 muse_bias_new_recipeconfig(),
00237 muse_bias_prepare_header,
00238 muse_bias_get_frame_level,
00239 muse_bias_get_frame_mode);
00240
00241
00242
00243 if (muse_cplframework() == MUSE_CPLFRAMEWORK_ESOREX) {
00244 cpl_msg_set_time_on();
00245 }
00246
00247
00248 recipe->parameters = cpl_parameterlist_new();
00249
00250 cpl_parameter *p;
00251
00252
00253 p = cpl_parameter_new_range("muse.muse_bias.nifu",
00254 CPL_TYPE_INT,
00255 "IFU to handle. If set to 0, all IFUs are processed serially. If set to -1, all IFUs are processed in parallel.",
00256 "muse.muse_bias",
00257 (int)0,
00258 (int)-1,
00259 (int)24);
00260 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nifu");
00261 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nifu");
00262
00263 cpl_parameterlist_append(recipe->parameters, p);
00264
00265
00266 p = cpl_parameter_new_value("muse.muse_bias.overscan",
00267 CPL_TYPE_STRING,
00268 "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.",
00269 "muse.muse_bias",
00270 (const char *)"vpoly");
00271 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "overscan");
00272 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "overscan");
00273
00274 cpl_parameterlist_append(recipe->parameters, p);
00275
00276
00277 p = cpl_parameter_new_value("muse.muse_bias.ovscreject",
00278 CPL_TYPE_STRING,
00279 "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\").",
00280 "muse.muse_bias",
00281 (const char *)"dcr");
00282 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ovscreject");
00283 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ovscreject");
00284
00285 cpl_parameterlist_append(recipe->parameters, p);
00286
00287
00288 p = cpl_parameter_new_value("muse.muse_bias.ovscsigma",
00289 CPL_TYPE_DOUBLE,
00290 "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\".",
00291 "muse.muse_bias",
00292 (double)30.);
00293 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ovscsigma");
00294 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ovscsigma");
00295
00296 cpl_parameterlist_append(recipe->parameters, p);
00297
00298
00299 p = cpl_parameter_new_value("muse.muse_bias.ovscignore",
00300 CPL_TYPE_INT,
00301 "The number of pixels of the overscan adjacent to the data region of the CCD that are ignored when computing statistics or fits.",
00302 "muse.muse_bias",
00303 (int)3);
00304 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ovscignore");
00305 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ovscignore");
00306
00307 cpl_parameterlist_append(recipe->parameters, p);
00308
00309
00310 p = cpl_parameter_new_enum("muse.muse_bias.combine",
00311 CPL_TYPE_STRING,
00312 "Type of image combination to use.",
00313 "muse.muse_bias",
00314 (const char *)"sigclip",
00315 4,
00316 (const char *)"average",
00317 (const char *)"median",
00318 (const char *)"minmax",
00319 (const char *)"sigclip");
00320 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "combine");
00321 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "combine");
00322
00323 cpl_parameterlist_append(recipe->parameters, p);
00324
00325
00326 p = cpl_parameter_new_value("muse.muse_bias.nlow",
00327 CPL_TYPE_INT,
00328 "Number of minimum pixels to reject with minmax.",
00329 "muse.muse_bias",
00330 (int)1);
00331 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nlow");
00332 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nlow");
00333
00334 cpl_parameterlist_append(recipe->parameters, p);
00335
00336
00337 p = cpl_parameter_new_value("muse.muse_bias.nhigh",
00338 CPL_TYPE_INT,
00339 "Number of maximum pixels to reject with minmax.",
00340 "muse.muse_bias",
00341 (int)1);
00342 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nhigh");
00343 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nhigh");
00344
00345 cpl_parameterlist_append(recipe->parameters, p);
00346
00347
00348 p = cpl_parameter_new_value("muse.muse_bias.nkeep",
00349 CPL_TYPE_INT,
00350 "Number of pixels to keep with minmax.",
00351 "muse.muse_bias",
00352 (int)1);
00353 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nkeep");
00354 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nkeep");
00355
00356 cpl_parameterlist_append(recipe->parameters, p);
00357
00358
00359 p = cpl_parameter_new_value("muse.muse_bias.lsigma",
00360 CPL_TYPE_DOUBLE,
00361 "Low sigma for pixel rejection with sigclip.",
00362 "muse.muse_bias",
00363 (double)3);
00364 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lsigma");
00365 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lsigma");
00366
00367 cpl_parameterlist_append(recipe->parameters, p);
00368
00369
00370 p = cpl_parameter_new_value("muse.muse_bias.hsigma",
00371 CPL_TYPE_DOUBLE,
00372 "High sigma for pixel rejection with sigclip.",
00373 "muse.muse_bias",
00374 (double)3);
00375 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "hsigma");
00376 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "hsigma");
00377
00378 cpl_parameterlist_append(recipe->parameters, p);
00379
00380
00381 p = cpl_parameter_new_value("muse.muse_bias.losigmabadpix",
00382 CPL_TYPE_DOUBLE,
00383 "Low sigma to find dark columns in the combined bias",
00384 "muse.muse_bias",
00385 (double)30.);
00386 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "losigmabadpix");
00387 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "losigmabadpix");
00388
00389 cpl_parameterlist_append(recipe->parameters, p);
00390
00391
00392 p = cpl_parameter_new_value("muse.muse_bias.hisigmabadpix",
00393 CPL_TYPE_DOUBLE,
00394 "High sigma to find bright columns in the combined bias",
00395 "muse.muse_bias",
00396 (double)3.);
00397 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "hisigmabadpix");
00398 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "hisigmabadpix");
00399
00400 cpl_parameterlist_append(recipe->parameters, p);
00401
00402
00403 p = cpl_parameter_new_value("muse.muse_bias.merge",
00404 CPL_TYPE_BOOL,
00405 "Merge output products from different IFUs into a common file.",
00406 "muse.muse_bias",
00407 (int)FALSE);
00408 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "merge");
00409 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "merge");
00410
00411 cpl_parameterlist_append(recipe->parameters, p);
00412
00413 return 0;
00414 }
00415
00416
00427
00428 static int
00429 muse_bias_params_fill(muse_bias_params_t *aParams, cpl_parameterlist *aParameters)
00430 {
00431 cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
00432 cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
00433 cpl_parameter *p;
00434
00435 p = cpl_parameterlist_find(aParameters, "muse.muse_bias.nifu");
00436 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00437 aParams->nifu = cpl_parameter_get_int(p);
00438
00439 p = cpl_parameterlist_find(aParameters, "muse.muse_bias.overscan");
00440 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00441 aParams->overscan = cpl_parameter_get_string(p);
00442
00443 p = cpl_parameterlist_find(aParameters, "muse.muse_bias.ovscreject");
00444 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00445 aParams->ovscreject = cpl_parameter_get_string(p);
00446
00447 p = cpl_parameterlist_find(aParameters, "muse.muse_bias.ovscsigma");
00448 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00449 aParams->ovscsigma = cpl_parameter_get_double(p);
00450
00451 p = cpl_parameterlist_find(aParameters, "muse.muse_bias.ovscignore");
00452 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00453 aParams->ovscignore = cpl_parameter_get_int(p);
00454
00455 p = cpl_parameterlist_find(aParameters, "muse.muse_bias.combine");
00456 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00457 aParams->combine_s = cpl_parameter_get_string(p);
00458 aParams->combine =
00459 (!strcasecmp(aParams->combine_s, "average")) ? MUSE_BIAS_PARAM_COMBINE_AVERAGE :
00460 (!strcasecmp(aParams->combine_s, "median")) ? MUSE_BIAS_PARAM_COMBINE_MEDIAN :
00461 (!strcasecmp(aParams->combine_s, "minmax")) ? MUSE_BIAS_PARAM_COMBINE_MINMAX :
00462 (!strcasecmp(aParams->combine_s, "sigclip")) ? MUSE_BIAS_PARAM_COMBINE_SIGCLIP :
00463 MUSE_BIAS_PARAM_COMBINE_INVALID_VALUE;
00464 cpl_ensure_code(aParams->combine != MUSE_BIAS_PARAM_COMBINE_INVALID_VALUE,
00465 CPL_ERROR_ILLEGAL_INPUT);
00466
00467 p = cpl_parameterlist_find(aParameters, "muse.muse_bias.nlow");
00468 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00469 aParams->nlow = cpl_parameter_get_int(p);
00470
00471 p = cpl_parameterlist_find(aParameters, "muse.muse_bias.nhigh");
00472 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00473 aParams->nhigh = cpl_parameter_get_int(p);
00474
00475 p = cpl_parameterlist_find(aParameters, "muse.muse_bias.nkeep");
00476 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00477 aParams->nkeep = cpl_parameter_get_int(p);
00478
00479 p = cpl_parameterlist_find(aParameters, "muse.muse_bias.lsigma");
00480 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00481 aParams->lsigma = cpl_parameter_get_double(p);
00482
00483 p = cpl_parameterlist_find(aParameters, "muse.muse_bias.hsigma");
00484 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00485 aParams->hsigma = cpl_parameter_get_double(p);
00486
00487 p = cpl_parameterlist_find(aParameters, "muse.muse_bias.losigmabadpix");
00488 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00489 aParams->losigmabadpix = cpl_parameter_get_double(p);
00490
00491 p = cpl_parameterlist_find(aParameters, "muse.muse_bias.hisigmabadpix");
00492 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00493 aParams->hisigmabadpix = cpl_parameter_get_double(p);
00494
00495 p = cpl_parameterlist_find(aParameters, "muse.muse_bias.merge");
00496 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00497 aParams->merge = cpl_parameter_get_bool(p);
00498
00499 return 0;
00500 }
00501
00502
00509
00510 static int
00511 muse_bias_exec(cpl_plugin *aPlugin)
00512 {
00513 if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
00514 return -1;
00515 }
00516 muse_processing_recipeinfo(aPlugin);
00517 cpl_recipe *recipe = (cpl_recipe *)aPlugin;
00518 cpl_msg_set_threadid_on();
00519
00520 cpl_frameset *usedframes = cpl_frameset_new(),
00521 *outframes = cpl_frameset_new();
00522 muse_bias_params_t params;
00523 muse_bias_params_fill(¶ms, recipe->parameters);
00524
00525 cpl_errorstate prestate = cpl_errorstate_get();
00526
00527 if (params.nifu < -1 || params.nifu > kMuseNumIFUs) {
00528 cpl_msg_error(__func__, "Please specify a valid IFU number (between 1 and "
00529 "%d), 0 (to process all IFUs consecutively), or -1 (to "
00530 "process all IFUs in parallel) using --nifu.", kMuseNumIFUs);
00531 return -1;
00532 }
00533
00534 cpl_boolean donotmerge = CPL_FALSE;
00535 int rc = 0;
00536 if (params.nifu > 0) {
00537 muse_processing *proc = muse_processing_new("muse_bias",
00538 recipe);
00539 rc = muse_bias_compute(proc, ¶ms);
00540 cpl_frameset_join(usedframes, proc->usedframes);
00541 cpl_frameset_join(outframes, proc->outframes);
00542 muse_processing_delete(proc);
00543 donotmerge = CPL_TRUE;
00544 } else if (params.nifu < 0) {
00545 int *rcs = cpl_calloc(kMuseNumIFUs, sizeof(int));
00546 int nifu;
00547 #pragma omp parallel for default(none) \
00548 shared(outframes, params, rcs, recipe, usedframes)
00549 for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
00550 muse_processing *proc = muse_processing_new("muse_bias",
00551 recipe);
00552 muse_bias_params_t *pars = cpl_malloc(sizeof(muse_bias_params_t));
00553 memcpy(pars, ¶ms, sizeof(muse_bias_params_t));
00554 pars->nifu = nifu;
00555 int *rci = rcs + (nifu - 1);
00556 *rci = muse_bias_compute(proc, pars);
00557 if (rci && (int)cpl_error_get_code() == MUSE_ERROR_CHIP_NOT_LIVE) {
00558 *rci = 0;
00559 }
00560 cpl_free(pars);
00561 #pragma omp critical(muse_processing_used_frames)
00562 cpl_frameset_join(usedframes, proc->usedframes);
00563 #pragma omp critical(muse_processing_output_frames)
00564 cpl_frameset_join(outframes, proc->outframes);
00565 muse_processing_delete(proc);
00566 }
00567
00568
00569 for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
00570 if (rcs[nifu-1] != 0) {
00571 rc = rcs[nifu-1];
00572 }
00573 }
00574 cpl_free(rcs);
00575 } else {
00576 for (params.nifu = 1; params.nifu <= kMuseNumIFUs && !rc; params.nifu++) {
00577 muse_processing *proc = muse_processing_new("muse_bias",
00578 recipe);
00579 rc = muse_bias_compute(proc, ¶ms);
00580 if (rc && (int)cpl_error_get_code() == MUSE_ERROR_CHIP_NOT_LIVE) {
00581 rc = 0;
00582 }
00583 cpl_frameset_join(usedframes, proc->usedframes);
00584 cpl_frameset_join(outframes, proc->outframes);
00585 muse_processing_delete(proc);
00586 }
00587 }
00588 UNUSED_ARGUMENT(donotmerge);
00589
00590 if (!cpl_errorstate_is_equal(prestate)) {
00591
00592 cpl_errorstate_dump(prestate, CPL_FALSE, muse_cplerrorstate_dump_some);
00593
00594 cpl_msg_set_level(CPL_MSG_INFO);
00595 }
00596
00597 muse_cplframeset_erase_duplicate(usedframes);
00598 muse_cplframeset_erase_duplicate(outframes);
00599
00600
00601 if (params.merge && !donotmerge) {
00602 muse_utils_frameset_merge_frames(outframes, CPL_TRUE);
00603 }
00604
00605
00606
00607
00608
00609 muse_cplframeset_erase_all(recipe->frames);
00610 cpl_frameset_join(recipe->frames, usedframes);
00611 cpl_frameset_join(recipe->frames, outframes);
00612 cpl_frameset_delete(usedframes);
00613 cpl_frameset_delete(outframes);
00614 return rc;
00615 }
00616
00617
00624
00625 static int
00626 muse_bias_destroy(cpl_plugin *aPlugin)
00627 {
00628
00629 cpl_recipe *recipe;
00630 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
00631 recipe = (cpl_recipe *)aPlugin;
00632 } else {
00633 return -1;
00634 }
00635
00636
00637 cpl_parameterlist_delete(recipe->parameters);
00638 muse_processinginfo_delete(recipe);
00639 return 0;
00640 }
00641
00642
00652
00653 int
00654 cpl_plugin_get_info(cpl_pluginlist *aList)
00655 {
00656 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
00657 cpl_plugin *plugin = &recipe->interface;
00658
00659 char *helptext;
00660 if (muse_cplframework() == MUSE_CPLFRAMEWORK_ESOREX) {
00661 helptext = cpl_sprintf("%s%s", muse_bias_help,
00662 muse_bias_help_esorex);
00663 } else {
00664 helptext = cpl_sprintf("%s", muse_bias_help);
00665 }
00666
00667
00668 cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
00669 CPL_PLUGIN_TYPE_RECIPE,
00670 "muse_bias",
00671 "Combine several separate bias images into one master bias file.",
00672 helptext,
00673 "Peter Weilbacher",
00674 "usd-help@eso.org",
00675 muse_get_license(),
00676 muse_bias_create,
00677 muse_bias_exec,
00678 muse_bias_destroy);
00679 cpl_pluginlist_append(aList, plugin);
00680 cpl_free(helptext);
00681
00682 return 0;
00683 }
00684