35 #include "muse_create_sky_z.h" 53 static const char *muse_create_sky_help =
54 "This recipe creates the continuum and the atmospheric transition line spectra of the night sky from the data in a pixel table(s) belonging to one exposure of (mostly) empty sky.";
56 static const char *muse_create_sky_help_esorex =
57 "\n\nInput frames for raw frame tag \"PIXTABLE_SKY\":\n" 58 "\n Frame tag Type Req #Fr Description" 59 "\n -------------------- ---- --- --- ------------" 60 "\n PIXTABLE_SKY raw Y Input pixel table. If the pixel table is not already flux calibrated, the corresponding flux calibration frames should be given as well." 61 "\n EXTINCT_TABLE calib Y 1 Atmospheric extinction table" 62 "\n STD_RESPONSE calib Y 1 Response curve as derived from standard star(s)" 63 "\n STD_TELLURIC calib . 1 Telluric absorption as derived from standard star(s)" 64 "\n SKY_LINES calib Y 1 List of OH transitions and other sky lines" 65 "\n SKY_CONTINUUM calib . 1 Sky continuum to use" 66 "\n LSF_PROFILE calib Y 1 Slice specific LSF parameters cubes" 67 "\n SKY_MASK calib . 1 Sky mask to use" 68 "\n\nProduct frames for raw frame tag \"PIXTABLE_SKY\":\n" 69 "\n Frame tag Level Description" 70 "\n -------------------- -------- ------------" 71 "\n SKY_MASK intermed Created sky mask" 72 "\n IMAGE_FOV intermed Whitelight image used to create the sky mask" 73 "\n SKY_SPECTRUM intermed Sky spectrum within the sky mask" 74 "\n SKY_LINES final Estimated sky line flux table" 75 "\n SKY_CONTINUUM final Estimated continuum flux spectrum";
86 static cpl_recipeconfig *
87 muse_create_sky_new_recipeconfig(
void)
89 cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
91 cpl_recipeconfig_set_tag(recipeconfig,
"PIXTABLE_SKY", 1, -1);
92 cpl_recipeconfig_set_input(recipeconfig,
"PIXTABLE_SKY",
"EXTINCT_TABLE", 1, 1);
93 cpl_recipeconfig_set_input(recipeconfig,
"PIXTABLE_SKY",
"STD_RESPONSE", 1, 1);
94 cpl_recipeconfig_set_input(recipeconfig,
"PIXTABLE_SKY",
"STD_TELLURIC", -1, 1);
95 cpl_recipeconfig_set_input(recipeconfig,
"PIXTABLE_SKY",
"SKY_LINES", 1, 1);
96 cpl_recipeconfig_set_input(recipeconfig,
"PIXTABLE_SKY",
"SKY_CONTINUUM", 0, 1);
97 cpl_recipeconfig_set_input(recipeconfig,
"PIXTABLE_SKY",
"LSF_PROFILE", 1, 1);
98 cpl_recipeconfig_set_input(recipeconfig,
"PIXTABLE_SKY",
"SKY_MASK", 0, 1);
99 cpl_recipeconfig_set_output(recipeconfig,
"PIXTABLE_SKY",
"SKY_MASK");
100 cpl_recipeconfig_set_output(recipeconfig,
"PIXTABLE_SKY",
"IMAGE_FOV");
101 cpl_recipeconfig_set_output(recipeconfig,
"PIXTABLE_SKY",
"SKY_SPECTRUM");
102 cpl_recipeconfig_set_output(recipeconfig,
"PIXTABLE_SKY",
"SKY_LINES");
103 cpl_recipeconfig_set_output(recipeconfig,
"PIXTABLE_SKY",
"SKY_CONTINUUM");
119 static cpl_error_code
120 muse_create_sky_prepare_header(
const char *aFrametag, cpl_propertylist *aHeader)
122 cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
123 cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
124 if (!strcmp(aFrametag,
"SKY_MASK")) {
127 "Threshold in the white light considered as sky, used to create this mask");
128 }
else if (!strcmp(aFrametag,
"IMAGE_FOV")) {
129 }
else if (!strcmp(aFrametag,
"SKY_SPECTRUM")) {
130 }
else if (!strcmp(aFrametag,
"SKY_LINES")) {
133 "Name of the strongest line in group k");
136 "[Angstrom] Wavelength (air) of the strongest line of group l");
139 "[erg/(s cm2 arcsec2)] Flux of the strongest line of group l");
140 }
else if (!strcmp(aFrametag,
"SKY_CONTINUUM")) {
143 "[erg/(s cm2 arcsec2)] Total flux of the continuum");
146 "[erg/(s cm2 arcsec2 Angstrom)] Maximum (absolute value) of the derivative of the continuum spectrum");
148 cpl_msg_warning(__func__,
"Frame tag %s is not defined", aFrametag);
149 return CPL_ERROR_ILLEGAL_INPUT;
151 return CPL_ERROR_NONE;
164 static cpl_frame_level
165 muse_create_sky_get_frame_level(
const char *aFrametag)
168 return CPL_FRAME_LEVEL_NONE;
170 if (!strcmp(aFrametag,
"SKY_MASK")) {
171 return CPL_FRAME_LEVEL_INTERMEDIATE;
173 if (!strcmp(aFrametag,
"IMAGE_FOV")) {
174 return CPL_FRAME_LEVEL_INTERMEDIATE;
176 if (!strcmp(aFrametag,
"SKY_SPECTRUM")) {
177 return CPL_FRAME_LEVEL_INTERMEDIATE;
179 if (!strcmp(aFrametag,
"SKY_LINES")) {
180 return CPL_FRAME_LEVEL_FINAL;
182 if (!strcmp(aFrametag,
"SKY_CONTINUUM")) {
183 return CPL_FRAME_LEVEL_FINAL;
185 return CPL_FRAME_LEVEL_NONE;
199 muse_create_sky_get_frame_mode(
const char *aFrametag)
204 if (!strcmp(aFrametag,
"SKY_MASK")) {
207 if (!strcmp(aFrametag,
"IMAGE_FOV")) {
210 if (!strcmp(aFrametag,
"SKY_SPECTRUM")) {
213 if (!strcmp(aFrametag,
"SKY_LINES")) {
216 if (!strcmp(aFrametag,
"SKY_CONTINUUM")) {
234 muse_create_sky_create(cpl_plugin *aPlugin)
238 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
239 recipe = (cpl_recipe *)aPlugin;
247 muse_create_sky_new_recipeconfig(),
248 muse_create_sky_prepare_header,
249 muse_create_sky_get_frame_level,
250 muse_create_sky_get_frame_mode);
255 cpl_msg_set_time_on();
259 recipe->parameters = cpl_parameterlist_new();
264 p = cpl_parameter_new_value(
"muse.muse_create_sky.fraction",
266 "Fraction of the image (without the ignored part) to be considered as sky. If an input sky mask is provided, the fraction is applied to the regions within the mask. If the whole sky mask should be used, set this parameter to 1.",
267 "muse.muse_create_sky",
269 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"fraction");
270 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"fraction");
272 cpl_parameterlist_append(recipe->parameters, p);
275 p = cpl_parameter_new_value(
"muse.muse_create_sky.ignore",
277 "Fraction of the image to be ignored. If an input sky mask is provided, the fraction is applied to the regions within the mask. If the whole sky mask should be used, set this parameter to 0.",
278 "muse.muse_create_sky",
280 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"ignore");
281 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ignore");
283 cpl_parameterlist_append(recipe->parameters, p);
286 p = cpl_parameter_new_value(
"muse.muse_create_sky.sampling",
288 "Spectral sampling of the sky spectrum [Angstrom].",
289 "muse.muse_create_sky",
291 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"sampling");
292 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sampling");
293 if (!getenv(
"MUSE_EXPERT_USER")) {
294 cpl_parameter_disable(p, CPL_PARAMETER_MODE_CLI);
297 cpl_parameterlist_append(recipe->parameters, p);
300 p = cpl_parameter_new_value(
"muse.muse_create_sky.csampling",
302 "Spectral sampling of the continuum spectrum [Angstrom].",
303 "muse.muse_create_sky",
305 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"csampling");
306 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"csampling");
307 if (!getenv(
"MUSE_EXPERT_USER")) {
308 cpl_parameter_disable(p, CPL_PARAMETER_MODE_CLI);
311 cpl_parameterlist_append(recipe->parameters, p);
314 p = cpl_parameter_new_value(
"muse.muse_create_sky.crsigma",
316 "Sigma level clipping for cube-based and spectrum-based CR rejection. This has to be a string of two comma-separated floating-point numbers. The first value gives the sigma-level rejection for cube-based CR rejection (using \"median\", see muse_scipost), the second value the sigma-level for spectrum-based CR cleaning. Both can be switched off, by passing zero or a negative value; by default, the spectrum-based rejection is switched off.",
317 "muse.muse_create_sky",
318 (
const char *)
"15.,15.");
319 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"crsigma");
320 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"crsigma");
321 if (!getenv(
"MUSE_EXPERT_USER")) {
322 cpl_parameter_disable(p, CPL_PARAMETER_MODE_CLI);
325 cpl_parameterlist_append(recipe->parameters, p);
328 p = cpl_parameter_new_value(
"muse.muse_create_sky.lambdamin",
330 "Cut off the data below this wavelength after loading the pixel table(s).",
331 "muse.muse_create_sky",
333 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"lambdamin");
334 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"lambdamin");
336 cpl_parameterlist_append(recipe->parameters, p);
339 p = cpl_parameter_new_value(
"muse.muse_create_sky.lambdamax",
341 "Cut off the data above this wavelength after loading the pixel table(s).",
342 "muse.muse_create_sky",
344 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"lambdamax");
345 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"lambdamax");
347 cpl_parameterlist_append(recipe->parameters, p);
350 p = cpl_parameter_new_value(
"muse.muse_create_sky.lambdaref",
352 "Reference wavelength used for correction of differential atmospheric refraction. The R-band (peak wavelength ~7000 Angstrom) that is usually used for guiding, is close to the central wavelength of MUSE, so a value of 7000.0 Angstrom should be used if nothing else is known. A value less than zero switches DAR correction off.",
353 "muse.muse_create_sky",
355 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"lambdaref");
356 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"lambdaref");
358 cpl_parameterlist_append(recipe->parameters, p);
378 cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
379 cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
382 p = cpl_parameterlist_find(aParameters,
"muse.muse_create_sky.fraction");
383 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
384 aParams->
fraction = cpl_parameter_get_double(p);
386 p = cpl_parameterlist_find(aParameters,
"muse.muse_create_sky.ignore");
387 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
388 aParams->
ignore = cpl_parameter_get_double(p);
390 p = cpl_parameterlist_find(aParameters,
"muse.muse_create_sky.sampling");
391 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
392 aParams->
sampling = cpl_parameter_get_double(p);
394 p = cpl_parameterlist_find(aParameters,
"muse.muse_create_sky.csampling");
395 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
396 aParams->
csampling = cpl_parameter_get_double(p);
398 p = cpl_parameterlist_find(aParameters,
"muse.muse_create_sky.crsigma");
399 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
400 aParams->
crsigma = cpl_parameter_get_string(p);
402 p = cpl_parameterlist_find(aParameters,
"muse.muse_create_sky.lambdamin");
403 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
404 aParams->
lambdamin = cpl_parameter_get_double(p);
406 p = cpl_parameterlist_find(aParameters,
"muse.muse_create_sky.lambdamax");
407 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
408 aParams->
lambdamax = cpl_parameter_get_double(p);
410 p = cpl_parameterlist_find(aParameters,
"muse.muse_create_sky.lambdaref");
411 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
412 aParams->
lambdaref = cpl_parameter_get_double(p);
426 muse_create_sky_exec(cpl_plugin *aPlugin)
428 if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
432 cpl_recipe *recipe = (cpl_recipe *)aPlugin;
433 cpl_msg_set_threadid_on();
435 cpl_frameset *usedframes = cpl_frameset_new(),
436 *outframes = cpl_frameset_new();
438 muse_create_sky_params_fill(¶ms, recipe->parameters);
440 cpl_errorstate prestate = cpl_errorstate_get();
444 int rc = muse_create_sky_compute(proc, ¶ms);
445 cpl_frameset_join(usedframes, proc->
usedframes);
446 cpl_frameset_join(outframes, proc->
outframes);
449 if (!cpl_errorstate_is_equal(prestate)) {
453 cpl_msg_set_level(CPL_MSG_INFO);
464 cpl_frameset_join(recipe->frames, usedframes);
465 cpl_frameset_join(recipe->frames, outframes);
466 cpl_frameset_delete(usedframes);
467 cpl_frameset_delete(outframes);
480 muse_create_sky_destroy(cpl_plugin *aPlugin)
484 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
485 recipe = (cpl_recipe *)aPlugin;
491 cpl_parameterlist_delete(recipe->parameters);
508 cpl_plugin_get_info(cpl_pluginlist *aList)
510 cpl_recipe *recipe = cpl_calloc(1,
sizeof *recipe);
511 cpl_plugin *plugin = &recipe->interface;
515 helptext = cpl_sprintf(
"%s%s", muse_create_sky_help,
516 muse_create_sky_help_esorex);
518 helptext = cpl_sprintf(
"%s", muse_create_sky_help);
522 cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
523 CPL_PLUGIN_TYPE_RECIPE,
525 "Create night sky model from selected pixels of an exposure of empty sky.",
530 muse_create_sky_create,
531 muse_create_sky_exec,
532 muse_create_sky_destroy);
533 cpl_pluginlist_append(aList, plugin);
void muse_processing_delete(muse_processing *aProcessing)
Free the muse_processing structure.
muse_cplframework_type muse_cplframework(void)
Return the CPL framework the recipe is run under.
double csampling
Spectral sampling of the continuum spectrum [Angstrom].
const char * crsigma
Sigma level clipping for cube-based and spectrum-based CR rejection. This has to be a string of two c...
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.
double ignore
Fraction of the image to be ignored. If an input sky mask is provided, the fraction is applied to the...
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.
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.
double lambdamin
Cut off the data below this wavelength after loading the pixel table(s).
double sampling
Spectral sampling of the sky spectrum [Angstrom].
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.
double fraction
Fraction of the image (without the ignored part) to be considered as sky. If an input sky mask is pro...
double lambdamax
Cut off the data above this wavelength after loading the pixel table(s).
double lambdaref
Reference wavelength used for correction of differential atmospheric refraction. The R-band (peak wav...
void muse_processing_recipeinfo(cpl_plugin *)
Output main pipeline configuration, inputs, and parameters.
Structure to hold the parameters of the muse_create_sky recipe.
cpl_error_code muse_processing_prepare_property(cpl_propertylist *, const char *, cpl_type, const char *)
Prepare and check the specified property.