35 #include "muse_exp_align_z.h" 54 static const char *muse_exp_align_help =
55 "Compute the coordinate offset for each input field-of-view image with respect to a reference. The created list of coordinate offsets can then be used in muse_exp_combine as the field coordinate offsets to properly align the exposures during their combination.";
57 static const char *muse_exp_align_help_esorex =
58 "\n\nInput frames for raw frame tag \"IMAGE_FOV\":\n" 59 "\n Frame tag Type Req #Fr Description" 60 "\n -------------------- ---- --- --- ------------" 61 "\n IMAGE_FOV raw Y >=2 Input field-of-view images" 62 "\n\nProduct frames for raw frame tag \"IMAGE_FOV\":\n" 63 "\n Frame tag Level Description" 64 "\n -------------------- -------- ------------" 65 "\n OFFSET_LIST final List of computed coordinate offsets.";
76 static cpl_recipeconfig *
77 muse_exp_align_new_recipeconfig(
void)
79 cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
81 cpl_recipeconfig_set_tag(recipeconfig,
"IMAGE_FOV", 2, -1);
82 cpl_recipeconfig_set_output(recipeconfig,
"IMAGE_FOV",
"OFFSET_LIST");
99 muse_exp_align_prepare_header(
const char *aFrametag, cpl_propertylist *aHeader)
101 cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
102 cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
103 if (!strcmp(aFrametag,
"OFFSET_LIST")) {
106 "Number of detected sources for input image i");
109 "Median number of matches of input image i with other images");
112 "Minimum of the median number of matches for all input images");
115 "Number of input images that do not have any matches with other images");
118 "[arcsec] RA minimum offset.");
121 "[arcsec] RA maximum offset.");
124 "[arcsec] RA mean offset.");
127 "[arcsec] Standard deviation of RA offsets.");
130 "[arcsec] DEC minimum offset.");
133 "[arcsec] DEC maximum offset.");
136 "[arcsec] DEC mean offset.");
139 "[arcsec] Standard deviation of DEC offsets.");
141 cpl_msg_warning(__func__,
"Frame tag %s is not defined", aFrametag);
142 return CPL_ERROR_ILLEGAL_INPUT;
144 return CPL_ERROR_NONE;
157 static cpl_frame_level
158 muse_exp_align_get_frame_level(
const char *aFrametag)
161 return CPL_FRAME_LEVEL_NONE;
163 if (!strcmp(aFrametag,
"OFFSET_LIST")) {
164 return CPL_FRAME_LEVEL_FINAL;
166 return CPL_FRAME_LEVEL_NONE;
180 muse_exp_align_get_frame_mode(
const char *aFrametag)
185 if (!strcmp(aFrametag,
"OFFSET_LIST")) {
203 muse_exp_align_create(cpl_plugin *aPlugin)
207 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
208 recipe = (cpl_recipe *)aPlugin;
216 muse_exp_align_new_recipeconfig(),
217 muse_exp_align_prepare_header,
218 muse_exp_align_get_frame_level,
219 muse_exp_align_get_frame_mode);
224 cpl_msg_set_time_on();
228 recipe->parameters = cpl_parameterlist_new();
235 p = cpl_parameter_new_value(
"muse.muse_exp_align.rsearch",
237 "Search radius (in arcsec) for each iteration of the offset computation.",
238 "muse.muse_exp_align",
239 (
const char *)
"30.,4.,2.,0.8");
240 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"rsearch");
241 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"rsearch");
243 cpl_parameterlist_append(recipe->parameters, p);
249 p = cpl_parameter_new_value(
"muse.muse_exp_align.nbins",
251 "Number of bins to use for 2D histogram on the first iteration of the offset computation.",
252 "muse.muse_exp_align",
254 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"nbins");
255 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nbins");
257 cpl_parameterlist_append(recipe->parameters, p);
260 p = cpl_parameter_new_value(
"muse.muse_exp_align.weight",
263 "muse.muse_exp_align",
265 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"weight");
266 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"weight");
268 cpl_parameterlist_append(recipe->parameters, p);
271 p = cpl_parameter_new_value(
"muse.muse_exp_align.fwhm",
273 "FWHM in pixels of the convolution filter.",
274 "muse.muse_exp_align",
276 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"fwhm");
277 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"fwhm");
279 cpl_parameterlist_append(recipe->parameters, p);
285 p = cpl_parameter_new_value(
"muse.muse_exp_align.threshold",
287 "Initial intensity threshold for detecting point sources in sigma above background RMS.",
288 "muse.muse_exp_align",
290 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"threshold");
291 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"threshold");
293 cpl_parameterlist_append(recipe->parameters, p);
296 p = cpl_parameter_new_value(
"muse.muse_exp_align.step",
298 "Increment/decrement of the threshold value in subsequent iterations.",
299 "muse.muse_exp_align",
301 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"step");
302 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"step");
304 cpl_parameterlist_append(recipe->parameters, p);
307 p = cpl_parameter_new_value(
"muse.muse_exp_align.iterations",
309 "Maximum number of iterations used for detecting sources.",
310 "muse.muse_exp_align",
312 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"iterations");
313 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"iterations");
315 cpl_parameterlist_append(recipe->parameters, p);
318 p = cpl_parameter_new_value(
"muse.muse_exp_align.srcmin",
320 "Minimum number of sources which must be found.",
321 "muse.muse_exp_align",
323 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"srcmin");
324 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"srcmin");
326 cpl_parameterlist_append(recipe->parameters, p);
329 p = cpl_parameter_new_value(
"muse.muse_exp_align.srcmax",
331 "Maximum number of sources which may be found.",
332 "muse.muse_exp_align",
334 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"srcmax");
335 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"srcmax");
337 cpl_parameterlist_append(recipe->parameters, p);
340 p = cpl_parameter_new_value(
"muse.muse_exp_align.roundmin",
342 "Lower limit of the allowed point-source roundness.",
343 "muse.muse_exp_align",
345 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"roundmin");
346 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"roundmin");
348 cpl_parameterlist_append(recipe->parameters, p);
351 p = cpl_parameter_new_value(
"muse.muse_exp_align.roundmax",
353 "Upper limit of the allowed point-source roundness.",
354 "muse.muse_exp_align",
356 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"roundmax");
357 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"roundmax");
359 cpl_parameterlist_append(recipe->parameters, p);
362 p = cpl_parameter_new_value(
"muse.muse_exp_align.sharpmin",
364 "Lower limit of the allowed point-source sharpness.",
365 "muse.muse_exp_align",
367 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"sharpmin");
368 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sharpmin");
370 cpl_parameterlist_append(recipe->parameters, p);
373 p = cpl_parameter_new_value(
"muse.muse_exp_align.sharpmax",
375 "Upper limit of the allowed point-source sharpness.",
376 "muse.muse_exp_align",
378 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"sharpmax");
379 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sharpmax");
381 cpl_parameterlist_append(recipe->parameters, p);
401 cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
402 cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
405 p = cpl_parameterlist_find(aParameters,
"muse.muse_exp_align.rsearch");
406 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
407 aParams->
rsearch = cpl_parameter_get_string(p);
409 p = cpl_parameterlist_find(aParameters,
"muse.muse_exp_align.nbins");
410 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
411 aParams->
nbins = cpl_parameter_get_int(p);
413 p = cpl_parameterlist_find(aParameters,
"muse.muse_exp_align.weight");
414 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
415 aParams->
weight = cpl_parameter_get_bool(p);
417 p = cpl_parameterlist_find(aParameters,
"muse.muse_exp_align.fwhm");
418 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
419 aParams->
fwhm = cpl_parameter_get_double(p);
421 p = cpl_parameterlist_find(aParameters,
"muse.muse_exp_align.threshold");
422 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
423 aParams->
threshold = cpl_parameter_get_double(p);
425 p = cpl_parameterlist_find(aParameters,
"muse.muse_exp_align.step");
426 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
427 aParams->
step = cpl_parameter_get_double(p);
429 p = cpl_parameterlist_find(aParameters,
"muse.muse_exp_align.iterations");
430 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
431 aParams->
iterations = cpl_parameter_get_int(p);
433 p = cpl_parameterlist_find(aParameters,
"muse.muse_exp_align.srcmin");
434 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
435 aParams->
srcmin = cpl_parameter_get_int(p);
437 p = cpl_parameterlist_find(aParameters,
"muse.muse_exp_align.srcmax");
438 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
439 aParams->
srcmax = cpl_parameter_get_int(p);
441 p = cpl_parameterlist_find(aParameters,
"muse.muse_exp_align.roundmin");
442 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
443 aParams->
roundmin = cpl_parameter_get_double(p);
445 p = cpl_parameterlist_find(aParameters,
"muse.muse_exp_align.roundmax");
446 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
447 aParams->
roundmax = cpl_parameter_get_double(p);
449 p = cpl_parameterlist_find(aParameters,
"muse.muse_exp_align.sharpmin");
450 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
451 aParams->
sharpmin = cpl_parameter_get_double(p);
453 p = cpl_parameterlist_find(aParameters,
"muse.muse_exp_align.sharpmax");
454 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
455 aParams->
sharpmax = cpl_parameter_get_double(p);
469 muse_exp_align_exec(cpl_plugin *aPlugin)
471 if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
475 cpl_recipe *recipe = (cpl_recipe *)aPlugin;
476 cpl_msg_set_threadid_on();
478 cpl_frameset *usedframes = cpl_frameset_new(),
479 *outframes = cpl_frameset_new();
481 muse_exp_align_params_fill(¶ms, recipe->parameters);
483 cpl_errorstate prestate = cpl_errorstate_get();
487 int rc = muse_exp_align_compute(proc, ¶ms);
488 cpl_frameset_join(usedframes, proc->
usedframes);
489 cpl_frameset_join(outframes, proc->
outframes);
492 if (!cpl_errorstate_is_equal(prestate)) {
496 cpl_msg_set_level(CPL_MSG_INFO);
507 cpl_frameset_join(recipe->frames, usedframes);
508 cpl_frameset_join(recipe->frames, outframes);
509 cpl_frameset_delete(usedframes);
510 cpl_frameset_delete(outframes);
523 muse_exp_align_destroy(cpl_plugin *aPlugin)
527 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
528 recipe = (cpl_recipe *)aPlugin;
534 cpl_parameterlist_delete(recipe->parameters);
551 cpl_plugin_get_info(cpl_pluginlist *aList)
553 cpl_recipe *recipe = cpl_calloc(1,
sizeof *recipe);
554 cpl_plugin *plugin = &recipe->interface;
558 helptext = cpl_sprintf(
"%s%s", muse_exp_align_help,
559 muse_exp_align_help_esorex);
561 helptext = cpl_sprintf(
"%s", muse_exp_align_help);
565 cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
566 CPL_PLUGIN_TYPE_RECIPE,
568 "Create a coordinate offset table to be used to align exposures during exposure combination.",
573 muse_exp_align_create,
575 muse_exp_align_destroy);
576 cpl_pluginlist_append(aList, plugin);
int srcmin
Minimum number of sources which must be found.
void muse_processing_delete(muse_processing *aProcessing)
Free the muse_processing structure.
double fwhm
FWHM in pixels of the convolution filter.
muse_cplframework_type muse_cplframework(void)
Return the CPL framework the recipe is run under.
double roundmax
Upper limit of the allowed point-source roundness.
double step
Increment/decrement of the threshold value in subsequent iterations.
cpl_frameset * usedframes
muse_processing * muse_processing_new(const char *aName, cpl_recipe *aRecipe)
Create a new processing structure.
double sharpmax
Upper limit of the allowed point-source sharpness.
const char * muse_get_license(void)
Get the pipeline copyright and license.
Structure to hold the parameters of the muse_exp_align recipe.
int srcmax
Maximum number of sources which may be found.
double threshold
Initial intensity threshold for detecting point sources in sigma above background RMS...
int iterations
Maximum number of iterations used for detecting sources.
int nbins
Number of bins to use for 2D histogram on the first iteration of the offset computation.
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.
const char * rsearch
Search radius (in arcsec) for each iteration of the offset computation.
cpl_error_code muse_cplframeset_erase_all(cpl_frameset *aFrames)
Erase all frames in a frameset.
double roundmin
Lower limit of the allowed point-source roundness.
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.
void muse_processing_recipeinfo(cpl_plugin *)
Output main pipeline configuration, inputs, and parameters.
double sharpmin
Lower limit of the allowed point-source sharpness.
cpl_error_code muse_processing_prepare_property(cpl_propertylist *, const char *, cpl_type, const char *)
Prepare and check the specified property.