35 #include "muse_bias_z.h"
63 static const char *muse_bias_help =
64 "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.";
66 static const char *muse_bias_help_esorex =
67 "\n\nInput frames for raw frame tag \"BIAS\":\n"
68 "\n Frame tag Type Req #Fr Description"
69 "\n -------------------- ---- --- --- ------------"
70 "\n BIAS raw Y >=3 Raw bias"
71 "\n BADPIX_TABLE calib . 1 Bad pixel table"
72 "\n\nProduct frames for raw frame tag \"BIAS\":\n"
73 "\n Frame tag Level Description"
74 "\n -------------------- -------- ------------"
75 "\n MASTER_BIAS final Master bias";
86 static cpl_recipeconfig *
87 muse_bias_new_recipeconfig(
void)
89 cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
93 cpl_recipeconfig_set_tag(recipeconfig, tag, 3, -1);
94 cpl_recipeconfig_set_input(recipeconfig, tag,
"BADPIX_TABLE", -1, 1);
95 cpl_recipeconfig_set_output(recipeconfig, tag,
"MASTER_BIAS");
111 static cpl_error_code
112 muse_bias_prepare_header(
const char *aFrametag, cpl_propertylist *aHeader)
114 cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
115 cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
116 if (!strcmp(aFrametag,
"MASTER_BIAS")) {
119 "Number of saturated pixels in raw bias i in input list");
122 "Median value of master bias in quadrant n");
125 "Mean value of master bias in quadrant n");
128 "Standard deviation value of master bias in quadrant n");
131 "Minimum value of master bias in quadrant n");
134 "Maximum value of master bias in quadrant n");
137 "[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");
140 "[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");
143 "[adu/pix] Average horizontal slope of master bias in quadrant n");
146 "[adu/pix] Average vertical slope of master bias in quadrant n");
149 "Bad pixels found as part of the bad column search in the master bias");
152 "Number of saturated pixels in output data");
154 cpl_msg_warning(__func__,
"Frame tag %s is not defined", aFrametag);
155 return CPL_ERROR_ILLEGAL_INPUT;
157 return CPL_ERROR_NONE;
170 static cpl_frame_level
171 muse_bias_get_frame_level(
const char *aFrametag)
174 return CPL_FRAME_LEVEL_NONE;
176 if (!strcmp(aFrametag,
"MASTER_BIAS")) {
177 return CPL_FRAME_LEVEL_FINAL;
179 return CPL_FRAME_LEVEL_NONE;
193 muse_bias_get_frame_mode(
const char *aFrametag)
198 if (!strcmp(aFrametag,
"MASTER_BIAS")) {
216 muse_bias_create(cpl_plugin *aPlugin)
220 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
221 recipe = (cpl_recipe *)aPlugin;
229 muse_bias_new_recipeconfig(),
230 muse_bias_prepare_header,
231 muse_bias_get_frame_level,
232 muse_bias_get_frame_mode);
237 cpl_msg_set_time_on();
241 recipe->parameters = cpl_parameterlist_new();
246 p = cpl_parameter_new_range(
"muse.muse_bias.nifu",
248 "IFU to handle. If set to 0, all IFUs are processed serially. If set to -1, all IFUs are processed in parallel.",
253 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"nifu");
254 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nifu");
256 cpl_parameterlist_append(recipe->parameters, p);
259 p = cpl_parameter_new_value(
"muse.muse_bias.overscan",
261 "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.",
263 (
const char *)
"vpoly");
264 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"overscan");
265 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"overscan");
267 cpl_parameterlist_append(recipe->parameters, p);
270 p = cpl_parameter_new_value(
"muse.muse_bias.ovscreject",
272 "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\").",
274 (
const char *)
"dcr");
275 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"ovscreject");
276 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ovscreject");
278 cpl_parameterlist_append(recipe->parameters, p);
281 p = cpl_parameter_new_value(
"muse.muse_bias.ovscsigma",
283 "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. Has no effect for overscan=\"offset\".",
286 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"ovscsigma");
287 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ovscsigma");
289 cpl_parameterlist_append(recipe->parameters, p);
292 p = cpl_parameter_new_value(
"muse.muse_bias.ovscignore",
294 "The number of pixels of the overscan adjacent to the data region of the CCD that are ignored when computing statistics or fits.",
297 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"ovscignore");
298 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ovscignore");
300 cpl_parameterlist_append(recipe->parameters, p);
303 p = cpl_parameter_new_enum(
"muse.muse_bias.combine",
305 "Type of image combination to use.",
307 (
const char *)
"sigclip",
309 (
const char *)
"average",
310 (
const char *)
"median",
311 (
const char *)
"minmax",
312 (
const char *)
"sigclip");
313 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"combine");
314 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"combine");
316 cpl_parameterlist_append(recipe->parameters, p);
319 p = cpl_parameter_new_value(
"muse.muse_bias.nlow",
321 "Number of minimum pixels to reject with minmax.",
324 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"nlow");
325 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nlow");
327 cpl_parameterlist_append(recipe->parameters, p);
330 p = cpl_parameter_new_value(
"muse.muse_bias.nhigh",
332 "Number of maximum pixels to reject with minmax.",
335 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"nhigh");
336 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nhigh");
338 cpl_parameterlist_append(recipe->parameters, p);
341 p = cpl_parameter_new_value(
"muse.muse_bias.nkeep",
343 "Number of pixels to keep with minmax.",
346 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"nkeep");
347 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nkeep");
349 cpl_parameterlist_append(recipe->parameters, p);
352 p = cpl_parameter_new_value(
"muse.muse_bias.lsigma",
354 "Low sigma for pixel rejection with sigclip.",
357 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"lsigma");
358 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"lsigma");
360 cpl_parameterlist_append(recipe->parameters, p);
363 p = cpl_parameter_new_value(
"muse.muse_bias.hsigma",
365 "High sigma for pixel rejection with sigclip.",
368 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"hsigma");
369 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"hsigma");
371 cpl_parameterlist_append(recipe->parameters, p);
374 p = cpl_parameter_new_value(
"muse.muse_bias.losigmabadpix",
376 "Low sigma to find dark columns in the combined bias",
379 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"losigmabadpix");
380 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"losigmabadpix");
382 cpl_parameterlist_append(recipe->parameters, p);
385 p = cpl_parameter_new_value(
"muse.muse_bias.hisigmabadpix",
387 "High sigma to find bright columns in the combined bias",
390 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"hisigmabadpix");
391 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"hisigmabadpix");
393 cpl_parameterlist_append(recipe->parameters, p);
413 cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
414 cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
417 p = cpl_parameterlist_find(aParameters,
"muse.muse_bias.nifu");
418 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
419 aParams->
nifu = cpl_parameter_get_int(p);
421 p = cpl_parameterlist_find(aParameters,
"muse.muse_bias.overscan");
422 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
423 aParams->
overscan = cpl_parameter_get_string(p);
425 p = cpl_parameterlist_find(aParameters,
"muse.muse_bias.ovscreject");
426 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
427 aParams->
ovscreject = cpl_parameter_get_string(p);
429 p = cpl_parameterlist_find(aParameters,
"muse.muse_bias.ovscsigma");
430 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
431 aParams->
ovscsigma = cpl_parameter_get_double(p);
433 p = cpl_parameterlist_find(aParameters,
"muse.muse_bias.ovscignore");
434 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
435 aParams->
ovscignore = cpl_parameter_get_int(p);
437 p = cpl_parameterlist_find(aParameters,
"muse.muse_bias.combine");
438 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
439 aParams->
combine_s = cpl_parameter_get_string(p);
441 (!strcasecmp(aParams->
combine_s,
"average")) ? MUSE_BIAS_PARAM_COMBINE_AVERAGE :
442 (!strcasecmp(aParams->
combine_s,
"median")) ? MUSE_BIAS_PARAM_COMBINE_MEDIAN :
443 (!strcasecmp(aParams->
combine_s,
"minmax")) ? MUSE_BIAS_PARAM_COMBINE_MINMAX :
444 (!strcasecmp(aParams->
combine_s,
"sigclip")) ? MUSE_BIAS_PARAM_COMBINE_SIGCLIP :
445 MUSE_BIAS_PARAM_COMBINE_INVALID_VALUE;
446 cpl_ensure_code(aParams->
combine != MUSE_BIAS_PARAM_COMBINE_INVALID_VALUE,
447 CPL_ERROR_ILLEGAL_INPUT);
449 p = cpl_parameterlist_find(aParameters,
"muse.muse_bias.nlow");
450 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
451 aParams->
nlow = cpl_parameter_get_int(p);
453 p = cpl_parameterlist_find(aParameters,
"muse.muse_bias.nhigh");
454 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
455 aParams->
nhigh = cpl_parameter_get_int(p);
457 p = cpl_parameterlist_find(aParameters,
"muse.muse_bias.nkeep");
458 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
459 aParams->
nkeep = cpl_parameter_get_int(p);
461 p = cpl_parameterlist_find(aParameters,
"muse.muse_bias.lsigma");
462 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
463 aParams->
lsigma = cpl_parameter_get_double(p);
465 p = cpl_parameterlist_find(aParameters,
"muse.muse_bias.hsigma");
466 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
467 aParams->
hsigma = cpl_parameter_get_double(p);
469 p = cpl_parameterlist_find(aParameters,
"muse.muse_bias.losigmabadpix");
470 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
473 p = cpl_parameterlist_find(aParameters,
"muse.muse_bias.hisigmabadpix");
474 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
489 muse_bias_exec(cpl_plugin *aPlugin)
491 if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
494 cpl_recipe *recipe = (cpl_recipe *)aPlugin;
495 cpl_msg_set_threadid_on();
497 cpl_frameset *usedframes = cpl_frameset_new(),
498 *outframes = cpl_frameset_new();
500 muse_bias_params_fill(¶ms, recipe->parameters);
502 cpl_errorstate prestate = cpl_errorstate_get();
504 if (params.
nifu < -1 || params.
nifu > kMuseNumIFUs) {
505 cpl_msg_error(__func__,
"Please specify a valid IFU number (between 1 and "
506 "%d), 0 (to process all IFUs consecutively), or -1 (to "
507 "process all IFUs in parallel) using --nifu.", kMuseNumIFUs);
512 if (params.
nifu > 0) {
515 rc = muse_bias_compute(proc, ¶ms);
516 cpl_frameset_join(usedframes, proc->
usedFrames);
519 }
else if (params.
nifu < 0) {
520 int *rcs = cpl_calloc(kMuseNumIFUs,
sizeof(
int));
522 #pragma omp parallel for default(none) \
523 shared(outframes, params, rcs, recipe, usedframes)
524 for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
530 int *rci = rcs + (nifu - 1);
531 *rci = muse_bias_compute(proc, pars);
532 if (rci && cpl_error_get_code() == MUSE_ERROR_CHIP_NOT_LIVE) {
536 #pragma omp critical(muse_processing_used_frames)
537 cpl_frameset_join(usedframes, proc->
usedFrames);
538 #pragma omp critical(muse_processing_output_frames)
544 for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
545 if (rcs[nifu-1] != 0) {
551 for (params.
nifu = 1; params.
nifu <= kMuseNumIFUs && !rc; params.
nifu++) {
554 rc = muse_bias_compute(proc, ¶ms);
555 if (rc && cpl_error_get_code() == MUSE_ERROR_CHIP_NOT_LIVE) {
558 cpl_frameset_join(usedframes, proc->
usedFrames);
564 if (!cpl_errorstate_is_equal(prestate)) {
568 cpl_msg_set_level(CPL_MSG_INFO);
578 cpl_frameset_join(recipe->frames, usedframes);
579 cpl_frameset_join(recipe->frames, outframes);
580 cpl_frameset_delete(usedframes);
581 cpl_frameset_delete(outframes);
594 muse_bias_destroy(cpl_plugin *aPlugin)
598 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
599 recipe = (cpl_recipe *)aPlugin;
605 cpl_parameterlist_delete(recipe->parameters);
622 cpl_plugin_get_info(cpl_pluginlist *aList)
624 cpl_recipe *recipe = cpl_calloc(1,
sizeof *recipe);
625 cpl_plugin *plugin = &recipe->interface;
629 helptext = cpl_sprintf(
"%s%s", muse_bias_help,
630 muse_bias_help_esorex);
632 helptext = cpl_sprintf(
"%s", muse_bias_help);
636 cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
637 CPL_PLUGIN_TYPE_RECIPE,
639 "Combine several separate bias images into one master bias file.",
647 cpl_pluginlist_append(aList, plugin);
const char * combine_s
Type of image combination to use. (as string)
double lsigma
Low sigma for pixel rejection with sigclip.
void muse_processing_delete(muse_processing *aProcessing)
Free the muse_processing structure.
int nhigh
Number of maximum pixels to reject with minmax.
double hisigmabadpix
High sigma to find bright columns in the combined bias.
muse_cplframework_type muse_cplframework(void)
Return the CPL framework the recipe is run under.
int combine
Type of image combination to use.
int nifu
IFU to handle. If set to 0, all IFUs are processed serially. If set to -1, all IFUs are processed in ...
const char * ovscreject
This influences how values are rejected when computing overscan statistics. Either no rejection at al...
int nkeep
Number of pixels to keep with minmax.
double losigmabadpix
Low sigma to find dark columns in the combined bias.
const char * muse_get_license(void)
Get the pipeline copyright and license.
muse_processing * muse_processing_new(const char *aRecipeName, cpl_recipe *aRecipe)
Create a new processing structure.
double ovscsigma
If the deviation of mean overscan levels between a raw input image and the reference image is higher ...
cpl_frameset * outputFrames
void muse_cplerrorstate_dump_some(unsigned aCurrent, unsigned aFirst, unsigned aLast)
Dump some CPL errors.
void muse_processinginfo_delete(cpl_recipe *)
Clear all information from the processing info and from the recipe config.
const char * overscan
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.
cpl_error_code muse_cplframeset_erase_duplicate(cpl_frameset *aFrames)
Erase all duplicate frames from a frameset.
cpl_error_code muse_cplframeset_erase_all(cpl_frameset *aFrames)
Erase all frames in a frameset.
int ovscignore
The number of pixels of the overscan adjacent to the data region of the CCD that are ignored when com...
void muse_processinginfo_register(cpl_recipe *, cpl_recipeconfig *, muse_processing_prepare_header_func *, muse_processing_get_frame_level_func *, muse_processing_get_frame_mode_func *)
Register extended functionalities for MUSE recipes.
cpl_frameset * usedFrames
int nlow
Number of minimum pixels to reject with minmax.
Structure to hold the parameters of the muse_bias recipe.
double hsigma
High sigma for pixel rejection with sigclip.
cpl_error_code muse_processing_prepare_property(cpl_propertylist *, const char *, cpl_type, const char *)
Prepare and check the specified property.