35 #include "muse_flat_z.h"
75 static const char *muse_flat_help =
76 "This recipe combines several separate flat-field images into one master flat-field file and traces the location of the slices on the CCD. The master flat contains the combined pixel values of the raw flat exposures, with respect to the image combination method used, normalized to the mean flux. The trace table contains polynomials defining the location of the slices on the CCD. 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 the exposures using input parameters. To trace the position of the slices on the CCD, their edges are located using a threshold method. The edge detection is repeated at given intervals thereby tracing the central position (the mean of both edges) and width of each slit vertically across the CCD. Deviant positions of detections on CCD rows can be detected and excluded before fitting a polynomial to all positions measured for one slice. The polynomial parameters for each slice are saved in the output trace table. Finally, the area between the now known slice edges is searched for dark (and bright) pixels, using statistics in each row of the master flat.";
78 static const char *muse_flat_help_esorex =
79 "\n\nInput frames for raw frame tag \"FLAT\":\n"
80 "\n Frame tag Type Req #Fr Description"
81 "\n -------------------- ---- --- --- ------------"
82 "\n FLAT raw Y >=3 Raw flat"
83 "\n MASTER_BIAS calib Y 1 Master bias"
84 "\n MASTER_DARK calib . 1 Master dark"
85 "\n BADPIX_TABLE calib . 1 Bad pixel table"
86 "\n\nProduct frames for raw frame tag \"FLAT\":\n"
87 "\n Frame tag Level Description"
88 "\n -------------------- -------- ------------"
89 "\n MASTER_FLAT final Master flat"
90 "\n TRACE_TABLE final Trace table"
91 "\n TRACE_SAMPLES final Table containing all tracing sample points, if --samples=true";
102 static cpl_recipeconfig *
103 muse_flat_new_recipeconfig(
void)
105 cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
109 cpl_recipeconfig_set_tag(recipeconfig, tag, 3, -1);
110 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_BIAS", 1, 1);
111 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_DARK", -1, 1);
112 cpl_recipeconfig_set_input(recipeconfig, tag,
"BADPIX_TABLE", -1, 1);
113 cpl_recipeconfig_set_output(recipeconfig, tag,
"MASTER_FLAT");
114 cpl_recipeconfig_set_output(recipeconfig, tag,
"TRACE_TABLE");
115 cpl_recipeconfig_set_output(recipeconfig, tag,
"TRACE_SAMPLES");
131 static cpl_error_code
132 muse_flat_prepare_header(
const char *aFrametag, cpl_propertylist *aHeader)
134 cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
135 cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
136 if (!strcmp(aFrametag,
"MASTER_FLAT")) {
139 "Median value of raw flat i in input list");
142 "Mean value of raw flat i in input list");
145 "Standard deviation of raw flat i in input list");
148 "Minimum value of raw flat i in input list");
151 "Maximum value of raw flat i in input list");
154 "Number of saturated pixels in raw flat i in input list");
157 "Median value of the master flat before normalization");
160 "Mean value of the master flat before normalization");
163 "Standard deviation of the master flat before normalization");
166 "Minimum value of the master flat before normalization");
169 "Maximum value of the master flat before normalization");
172 "Flux value, integrated over the whole master flat field before normalization");
175 "Number of saturated pixels in output data");
178 "Mean value around the vertical center of slice j before normalization");
181 "Standard deviation around the vertical center of slice j before normalization");
182 }
else if (!strcmp(aFrametag,
"TRACE_TABLE")) {
185 "[pix] Location of midpoint of leftmost slice");
188 "[deg] Tilt of leftmost slice, measured as angle from vertical direction");
191 "[pix] Location of midpoint of rightmost slice");
194 "[deg] Tilt of rightmost slice, measured as angle from vertical direction");
197 "The maximum slope of the derived tracing functions of slice j within the CCD.");
200 "[pix] Width of top left slice in the IFU (10 on CCD)");
203 "[pix] Width of top right slice in the IFU (46 on CCD)");
206 "[pix] Width of bottom left slice in the IFU (3 on CCD)");
209 "[pix] Width of bottom right slice in the IFU (39 on CCD)");
212 "[pix] Median width of slices");
215 "[pix] Mean width of slices");
218 "[pix] Standard deviation of widths of slices");
221 "[pix] Minimum width of slices");
224 "[pix] Maximum width of slices");
227 "[pix] Median of gaps between slices");
230 "[pix] Mean of gaps between slices");
233 "[pix] Standard deviation of gaps between slices");
236 "[pix] Minimum of gap between slices");
239 "[pix] Maximum gap between slices");
240 }
else if (!strcmp(aFrametag,
"TRACE_SAMPLES")) {
242 cpl_msg_warning(__func__,
"Frame tag %s is not defined", aFrametag);
243 return CPL_ERROR_ILLEGAL_INPUT;
245 return CPL_ERROR_NONE;
258 static cpl_frame_level
259 muse_flat_get_frame_level(
const char *aFrametag)
262 return CPL_FRAME_LEVEL_NONE;
264 if (!strcmp(aFrametag,
"MASTER_FLAT")) {
265 return CPL_FRAME_LEVEL_FINAL;
267 if (!strcmp(aFrametag,
"TRACE_TABLE")) {
268 return CPL_FRAME_LEVEL_FINAL;
270 if (!strcmp(aFrametag,
"TRACE_SAMPLES")) {
271 return CPL_FRAME_LEVEL_FINAL;
273 return CPL_FRAME_LEVEL_NONE;
287 muse_flat_get_frame_mode(
const char *aFrametag)
292 if (!strcmp(aFrametag,
"MASTER_FLAT")) {
295 if (!strcmp(aFrametag,
"TRACE_TABLE")) {
298 if (!strcmp(aFrametag,
"TRACE_SAMPLES")) {
316 muse_flat_create(cpl_plugin *aPlugin)
320 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
321 recipe = (cpl_recipe *)aPlugin;
329 muse_flat_new_recipeconfig(),
330 muse_flat_prepare_header,
331 muse_flat_get_frame_level,
332 muse_flat_get_frame_mode);
337 cpl_msg_set_time_on();
341 recipe->parameters = cpl_parameterlist_new();
346 p = cpl_parameter_new_range(
"muse.muse_flat.nifu",
348 "IFU to handle. If set to 0, all IFUs are processed serially. If set to -1, all IFUs are processed in parallel.",
353 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"nifu");
354 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nifu");
356 cpl_parameterlist_append(recipe->parameters, p);
359 p = cpl_parameter_new_value(
"muse.muse_flat.overscan",
361 "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.",
363 (
const char *)
"vpoly");
364 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"overscan");
365 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"overscan");
367 cpl_parameterlist_append(recipe->parameters, p);
370 p = cpl_parameter_new_value(
"muse.muse_flat.ovscreject",
372 "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\").",
374 (
const char *)
"dcr");
375 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"ovscreject");
376 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ovscreject");
378 cpl_parameterlist_append(recipe->parameters, p);
381 p = cpl_parameter_new_value(
"muse.muse_flat.ovscsigma",
383 "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\".",
386 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"ovscsigma");
387 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ovscsigma");
389 cpl_parameterlist_append(recipe->parameters, p);
392 p = cpl_parameter_new_value(
"muse.muse_flat.ovscignore",
394 "The number of pixels of the overscan adjacent to the data region of the CCD that are ignored when computing statistics or fits.",
397 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"ovscignore");
398 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ovscignore");
400 cpl_parameterlist_append(recipe->parameters, p);
403 p = cpl_parameter_new_enum(
"muse.muse_flat.combine",
405 "Type of combination to use",
407 (
const char *)
"sigclip",
409 (
const char *)
"average",
410 (
const char *)
"median",
411 (
const char *)
"minmax",
412 (
const char *)
"sigclip");
413 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"combine");
414 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"combine");
416 cpl_parameterlist_append(recipe->parameters, p);
419 p = cpl_parameter_new_value(
"muse.muse_flat.nlow",
421 "Number of minimum pixels to reject with minmax",
424 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"nlow");
425 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nlow");
427 cpl_parameterlist_append(recipe->parameters, p);
430 p = cpl_parameter_new_value(
"muse.muse_flat.nhigh",
432 "Number of maximum pixels to reject with minmax",
435 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"nhigh");
436 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nhigh");
438 cpl_parameterlist_append(recipe->parameters, p);
441 p = cpl_parameter_new_value(
"muse.muse_flat.nkeep",
443 "Number of pixels to keep with minmax",
446 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"nkeep");
447 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nkeep");
449 cpl_parameterlist_append(recipe->parameters, p);
452 p = cpl_parameter_new_value(
"muse.muse_flat.lsigma",
454 "Low sigma for pixel rejection with sigclip",
457 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"lsigma");
458 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"lsigma");
460 cpl_parameterlist_append(recipe->parameters, p);
463 p = cpl_parameter_new_value(
"muse.muse_flat.hsigma",
465 "High sigma for pixel rejection with sigclip",
468 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"hsigma");
469 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"hsigma");
471 cpl_parameterlist_append(recipe->parameters, p);
474 p = cpl_parameter_new_value(
"muse.muse_flat.scale",
476 "Scale the individual images to a common exposure time before combining them.",
479 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"scale");
480 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"scale");
482 cpl_parameterlist_append(recipe->parameters, p);
485 p = cpl_parameter_new_value(
"muse.muse_flat.normalize",
487 "Normalize the master flat to the average flux",
490 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"normalize");
491 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"normalize");
493 cpl_parameterlist_append(recipe->parameters, p);
496 p = cpl_parameter_new_value(
"muse.muse_flat.trace",
498 "Trace the position of the slices on the master flat",
501 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"trace");
502 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"trace");
504 cpl_parameterlist_append(recipe->parameters, p);
507 p = cpl_parameter_new_value(
"muse.muse_flat.nsum",
509 "Number of lines over which to average when tracing",
512 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"nsum");
513 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nsum");
515 cpl_parameterlist_append(recipe->parameters, p);
518 p = cpl_parameter_new_value(
"muse.muse_flat.order",
520 "Order of polynomial fit to the trace",
523 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"order");
524 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"order");
526 cpl_parameterlist_append(recipe->parameters, p);
529 p = cpl_parameter_new_value(
"muse.muse_flat.edgefrac",
531 "Fractional change required to identify edge when tracing",
534 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"edgefrac");
535 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"edgefrac");
537 cpl_parameterlist_append(recipe->parameters, p);
540 p = cpl_parameter_new_value(
"muse.muse_flat.losigmabadpix",
542 "Low sigma to find dark pixels in the master flat",
545 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"losigmabadpix");
546 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"losigmabadpix");
548 cpl_parameterlist_append(recipe->parameters, p);
551 p = cpl_parameter_new_value(
"muse.muse_flat.hisigmabadpix",
553 "High sigma to find bright pixels in the master flat",
556 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"hisigmabadpix");
557 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"hisigmabadpix");
559 cpl_parameterlist_append(recipe->parameters, p);
562 p = cpl_parameter_new_value(
"muse.muse_flat.samples",
564 "Create a table containing all tracing sample points.",
567 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"samples");
568 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"samples");
570 cpl_parameterlist_append(recipe->parameters, p);
573 p = cpl_parameter_new_value(
"muse.muse_flat.merge",
575 "Merge output products from different IFUs into a common file.",
578 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"merge");
579 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"merge");
581 cpl_parameterlist_append(recipe->parameters, p);
601 cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
602 cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
605 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.nifu");
606 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
607 aParams->
nifu = cpl_parameter_get_int(p);
609 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.overscan");
610 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
611 aParams->
overscan = cpl_parameter_get_string(p);
613 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.ovscreject");
614 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
615 aParams->
ovscreject = cpl_parameter_get_string(p);
617 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.ovscsigma");
618 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
619 aParams->
ovscsigma = cpl_parameter_get_double(p);
621 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.ovscignore");
622 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
623 aParams->
ovscignore = cpl_parameter_get_int(p);
625 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.combine");
626 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
627 aParams->
combine_s = cpl_parameter_get_string(p);
629 (!strcasecmp(aParams->
combine_s,
"average")) ? MUSE_FLAT_PARAM_COMBINE_AVERAGE :
630 (!strcasecmp(aParams->
combine_s,
"median")) ? MUSE_FLAT_PARAM_COMBINE_MEDIAN :
631 (!strcasecmp(aParams->
combine_s,
"minmax")) ? MUSE_FLAT_PARAM_COMBINE_MINMAX :
632 (!strcasecmp(aParams->
combine_s,
"sigclip")) ? MUSE_FLAT_PARAM_COMBINE_SIGCLIP :
633 MUSE_FLAT_PARAM_COMBINE_INVALID_VALUE;
634 cpl_ensure_code(aParams->
combine != MUSE_FLAT_PARAM_COMBINE_INVALID_VALUE,
635 CPL_ERROR_ILLEGAL_INPUT);
637 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.nlow");
638 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
639 aParams->
nlow = cpl_parameter_get_int(p);
641 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.nhigh");
642 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
643 aParams->
nhigh = cpl_parameter_get_int(p);
645 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.nkeep");
646 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
647 aParams->
nkeep = cpl_parameter_get_int(p);
649 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.lsigma");
650 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
651 aParams->
lsigma = cpl_parameter_get_double(p);
653 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.hsigma");
654 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
655 aParams->
hsigma = cpl_parameter_get_double(p);
657 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.scale");
658 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
659 aParams->
scale = cpl_parameter_get_bool(p);
661 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.normalize");
662 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
663 aParams->
normalize = cpl_parameter_get_bool(p);
665 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.trace");
666 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
667 aParams->
trace = cpl_parameter_get_bool(p);
669 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.nsum");
670 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
671 aParams->
nsum = cpl_parameter_get_int(p);
673 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.order");
674 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
675 aParams->
order = cpl_parameter_get_int(p);
677 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.edgefrac");
678 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
679 aParams->
edgefrac = cpl_parameter_get_double(p);
681 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.losigmabadpix");
682 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
685 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.hisigmabadpix");
686 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
689 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.samples");
690 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
691 aParams->
samples = cpl_parameter_get_bool(p);
693 p = cpl_parameterlist_find(aParameters,
"muse.muse_flat.merge");
694 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
695 aParams->
merge = cpl_parameter_get_bool(p);
709 muse_flat_exec(cpl_plugin *aPlugin)
711 if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
714 cpl_recipe *recipe = (cpl_recipe *)aPlugin;
715 cpl_msg_set_threadid_on();
717 cpl_frameset *usedframes = cpl_frameset_new(),
718 *outframes = cpl_frameset_new();
720 muse_flat_params_fill(¶ms, recipe->parameters);
722 cpl_errorstate prestate = cpl_errorstate_get();
724 if (params.
nifu < -1 || params.
nifu > kMuseNumIFUs) {
725 cpl_msg_error(__func__,
"Please specify a valid IFU number (between 1 and "
726 "%d), 0 (to process all IFUs consecutively), or -1 (to "
727 "process all IFUs in parallel) using --nifu.", kMuseNumIFUs);
731 cpl_boolean donotmerge = CPL_FALSE;
733 if (params.
nifu > 0) {
736 rc = muse_flat_compute(proc, ¶ms);
737 cpl_frameset_join(usedframes, proc->
usedframes);
738 cpl_frameset_join(outframes, proc->
outframes);
740 donotmerge = CPL_TRUE;
741 }
else if (params.
nifu < 0) {
742 int *rcs = cpl_calloc(kMuseNumIFUs,
sizeof(
int));
744 #pragma omp parallel for default(none) \
745 shared(outframes, params, rcs, recipe, usedframes)
746 for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
752 int *rci = rcs + (nifu - 1);
753 *rci = muse_flat_compute(proc, pars);
754 if (rci && cpl_error_get_code() == MUSE_ERROR_CHIP_NOT_LIVE) {
758 #pragma omp critical(muse_processing_used_frames)
759 cpl_frameset_join(usedframes, proc->
usedframes);
760 #pragma omp critical(muse_processing_output_frames)
761 cpl_frameset_join(outframes, proc->
outframes);
766 for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
767 if (rcs[nifu-1] != 0) {
773 for (params.
nifu = 1; params.
nifu <= kMuseNumIFUs && !rc; params.
nifu++) {
776 rc = muse_flat_compute(proc, ¶ms);
777 if (rc && cpl_error_get_code() == MUSE_ERROR_CHIP_NOT_LIVE) {
780 cpl_frameset_join(usedframes, proc->
usedframes);
781 cpl_frameset_join(outframes, proc->
outframes);
785 UNUSED_ARGUMENT(donotmerge);
787 if (!cpl_errorstate_is_equal(prestate)) {
791 cpl_msg_set_level(CPL_MSG_INFO);
798 if (params.
merge && !donotmerge) {
799 muse_utils_frameset_merge_frames(outframes);
807 cpl_frameset_join(recipe->frames, usedframes);
808 cpl_frameset_join(recipe->frames, outframes);
809 cpl_frameset_delete(usedframes);
810 cpl_frameset_delete(outframes);
823 muse_flat_destroy(cpl_plugin *aPlugin)
827 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
828 recipe = (cpl_recipe *)aPlugin;
834 cpl_parameterlist_delete(recipe->parameters);
851 cpl_plugin_get_info(cpl_pluginlist *aList)
853 cpl_recipe *recipe = cpl_calloc(1,
sizeof *recipe);
854 cpl_plugin *plugin = &recipe->interface;
858 helptext = cpl_sprintf(
"%s%s", muse_flat_help,
859 muse_flat_help_esorex);
861 helptext = cpl_sprintf(
"%s", muse_flat_help);
865 cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
866 CPL_PLUGIN_TYPE_RECIPE,
868 "Combine several separate flat images into one master flat file, trace slice locations, and locate dark pixels.",
870 "Peter Weilbacher (based on Joris Gerssen's draft)",
876 cpl_pluginlist_append(aList, plugin);
int nifu
IFU to handle. If set to 0, all IFUs are processed serially. If set to -1, all IFUs are processed in ...
void muse_processing_delete(muse_processing *aProcessing)
Free the muse_processing structure.
int order
Order of polynomial fit to the trace.
double lsigma
Low sigma for pixel rejection with sigclip.
int scale
Scale the individual images to a common exposure time before combining them.
muse_cplframework_type muse_cplframework(void)
Return the CPL framework the recipe is run under.
double ovscsigma
If the deviation of mean overscan levels between a raw input image and the reference image is higher ...
int normalize
Normalize the master flat to the average flux.
Structure to hold the parameters of the muse_flat recipe.
int combine
Type of combination to use.
cpl_frameset * usedframes
muse_processing * muse_processing_new(const char *aName, cpl_recipe *aRecipe)
Create a new processing structure.
const char * muse_get_license(void)
Get the pipeline copyright and license.
int merge
Merge output products from different IFUs into a common file.
int nsum
Number of lines over which to average when tracing.
const char * ovscreject
This influences how values are rejected when computing overscan statistics. Either no rejection at al...
int samples
Create a table containing all tracing sample points.
int nkeep
Number of pixels to keep with minmax.
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.
int nlow
Number of minimum pixels to reject with minmax.
int ovscignore
The number of pixels of the overscan adjacent to the data region of the CCD that are ignored when com...
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.
double edgefrac
Fractional change required to identify edge when tracing.
cpl_error_code muse_cplframeset_erase_all(cpl_frameset *aFrames)
Erase all frames in a frameset.
double losigmabadpix
Low sigma to find dark pixels in the master flat.
double hsigma
High sigma for pixel rejection with sigclip.
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.
int trace
Trace the position of the slices on the master flat.
const char * combine_s
Type of combination to use (as string)
int nhigh
Number of maximum pixels to reject with minmax.
double hisigmabadpix
High sigma to find bright pixels in the master flat.
cpl_error_code muse_processing_prepare_property(cpl_propertylist *, const char *, cpl_type, const char *)
Prepare and check the specified property.