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_scipost_correct_dar_z.h"
00036
00037
00043
00046
00047
00048
00049 static const char *muse_scipost_correct_dar_help =
00050 "Correct the coordinates in the pixel table by differential atmospheric refraction. This is a task separated from muse_scipost.";
00051
00052 static const char *muse_scipost_correct_dar_help_esorex =
00053 "\n\nInput frames for raw frame tag \"PIXTABLE_OBJECT\":\n"
00054 "\n Frame tag Type Req #Fr Description"
00055 "\n -------------------- ---- --- --- ------------"
00056 "\n PIXTABLE_OBJECT raw Y Pixel table without DAR correction"
00057 "\n\nProduct frames for raw frame tag \"PIXTABLE_OBJECT\":\n"
00058 "\n Frame tag Level Description"
00059 "\n -------------------- -------- ------------"
00060 "\n PIXTABLE_OBJECT final DAR corrected pixel table";
00061
00062
00070
00071 static cpl_recipeconfig *
00072 muse_scipost_correct_dar_new_recipeconfig(void)
00073 {
00074 cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
00075
00076 cpl_recipeconfig_set_tag(recipeconfig, "PIXTABLE_OBJECT", 1, -1);
00077 cpl_recipeconfig_set_output(recipeconfig, "PIXTABLE_OBJECT", "PIXTABLE_OBJECT");
00078
00079 return recipeconfig;
00080 }
00081
00082
00092
00093 static cpl_error_code
00094 muse_scipost_correct_dar_prepare_header(const char *aFrametag, cpl_propertylist *aHeader)
00095 {
00096 cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
00097 cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
00098 if (!strcmp(aFrametag, "PIXTABLE_OBJECT")) {
00099 } else {
00100 cpl_msg_warning(__func__, "Frame tag %s is not defined", aFrametag);
00101 return CPL_ERROR_ILLEGAL_INPUT;
00102 }
00103 return CPL_ERROR_NONE;
00104 }
00105
00106
00115
00116 static cpl_frame_level
00117 muse_scipost_correct_dar_get_frame_level(const char *aFrametag)
00118 {
00119 if (!aFrametag) {
00120 return CPL_FRAME_LEVEL_NONE;
00121 }
00122 if (!strcmp(aFrametag, "PIXTABLE_OBJECT")) {
00123 return CPL_FRAME_LEVEL_FINAL;
00124 }
00125 return CPL_FRAME_LEVEL_NONE;
00126 }
00127
00128
00137
00138 static muse_frame_mode
00139 muse_scipost_correct_dar_get_frame_mode(const char *aFrametag)
00140 {
00141 if (!aFrametag) {
00142 return MUSE_FRAME_MODE_ALL;
00143 }
00144 if (!strcmp(aFrametag, "PIXTABLE_OBJECT")) {
00145 return MUSE_FRAME_MODE_ALL;
00146 }
00147 return MUSE_FRAME_MODE_ALL;
00148 }
00149
00150
00160
00161 static int
00162 muse_scipost_correct_dar_create(cpl_plugin *aPlugin)
00163 {
00164
00165 cpl_recipe *recipe;
00166 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
00167 recipe = (cpl_recipe *)aPlugin;
00168 } else {
00169 return -1;
00170 }
00171
00172
00173
00174 muse_processinginfo_register(recipe,
00175 muse_scipost_correct_dar_new_recipeconfig(),
00176 muse_scipost_correct_dar_prepare_header,
00177 muse_scipost_correct_dar_get_frame_level,
00178 muse_scipost_correct_dar_get_frame_mode);
00179
00180
00181
00182 if (muse_cplframework() == MUSE_CPLFRAMEWORK_ESOREX) {
00183 cpl_msg_set_time_on();
00184 }
00185
00186
00187 recipe->parameters = cpl_parameterlist_new();
00188
00189 cpl_parameter *p;
00190
00191
00192 p = cpl_parameter_new_value("muse.muse_scipost_correct_dar.lambdamin",
00193 CPL_TYPE_DOUBLE,
00194 "Cut off the data below this wavelength after loading the pixel table(s).",
00195 "muse.muse_scipost_correct_dar",
00196 (double)4000.);
00197 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambdamin");
00198 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambdamin");
00199
00200 cpl_parameterlist_append(recipe->parameters, p);
00201
00202
00203 p = cpl_parameter_new_value("muse.muse_scipost_correct_dar.lambdamax",
00204 CPL_TYPE_DOUBLE,
00205 "Cut off the data above this wavelength after loading the pixel table(s).",
00206 "muse.muse_scipost_correct_dar",
00207 (double)10000.);
00208 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambdamax");
00209 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambdamax");
00210
00211 cpl_parameterlist_append(recipe->parameters, p);
00212
00213
00214 p = cpl_parameter_new_value("muse.muse_scipost_correct_dar.lambdaref",
00215 CPL_TYPE_DOUBLE,
00216 "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.",
00217 "muse.muse_scipost_correct_dar",
00218 (double)7000.);
00219 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambdaref");
00220 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambdaref");
00221
00222 cpl_parameterlist_append(recipe->parameters, p);
00223
00224
00225 p = cpl_parameter_new_enum("muse.muse_scipost_correct_dar.darcheck",
00226 CPL_TYPE_STRING,
00227 "Carry out a check of the theoretical DAR correction using source centroiding. If \"correct\" it will also apply an empirical correction.",
00228 "muse.muse_scipost_correct_dar",
00229 (const char *)"none",
00230 3,
00231 (const char *)"none",
00232 (const char *)"check",
00233 (const char *)"correct");
00234 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "darcheck");
00235 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "darcheck");
00236
00237 cpl_parameterlist_append(recipe->parameters, p);
00238
00239 return 0;
00240 }
00241
00242
00253
00254 static int
00255 muse_scipost_correct_dar_params_fill(muse_scipost_correct_dar_params_t *aParams, cpl_parameterlist *aParameters)
00256 {
00257 cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
00258 cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
00259 cpl_parameter *p;
00260
00261 p = cpl_parameterlist_find(aParameters, "muse.muse_scipost_correct_dar.lambdamin");
00262 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00263 aParams->lambdamin = cpl_parameter_get_double(p);
00264
00265 p = cpl_parameterlist_find(aParameters, "muse.muse_scipost_correct_dar.lambdamax");
00266 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00267 aParams->lambdamax = cpl_parameter_get_double(p);
00268
00269 p = cpl_parameterlist_find(aParameters, "muse.muse_scipost_correct_dar.lambdaref");
00270 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00271 aParams->lambdaref = cpl_parameter_get_double(p);
00272
00273 p = cpl_parameterlist_find(aParameters, "muse.muse_scipost_correct_dar.darcheck");
00274 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00275 aParams->darcheck_s = cpl_parameter_get_string(p);
00276 aParams->darcheck =
00277 (!strcasecmp(aParams->darcheck_s, "none")) ? MUSE_SCIPOST_CORRECT_DAR_PARAM_DARCHECK_NONE :
00278 (!strcasecmp(aParams->darcheck_s, "check")) ? MUSE_SCIPOST_CORRECT_DAR_PARAM_DARCHECK_CHECK :
00279 (!strcasecmp(aParams->darcheck_s, "correct")) ? MUSE_SCIPOST_CORRECT_DAR_PARAM_DARCHECK_CORRECT :
00280 MUSE_SCIPOST_CORRECT_DAR_PARAM_DARCHECK_INVALID_VALUE;
00281 cpl_ensure_code(aParams->darcheck != MUSE_SCIPOST_CORRECT_DAR_PARAM_DARCHECK_INVALID_VALUE,
00282 CPL_ERROR_ILLEGAL_INPUT);
00283
00284 return 0;
00285 }
00286
00287
00294
00295 static int
00296 muse_scipost_correct_dar_exec(cpl_plugin *aPlugin)
00297 {
00298 if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
00299 return -1;
00300 }
00301 muse_processing_recipeinfo(aPlugin);
00302 cpl_recipe *recipe = (cpl_recipe *)aPlugin;
00303 cpl_msg_set_threadid_on();
00304
00305 cpl_frameset *usedframes = cpl_frameset_new(),
00306 *outframes = cpl_frameset_new();
00307 muse_scipost_correct_dar_params_t params;
00308 muse_scipost_correct_dar_params_fill(¶ms, recipe->parameters);
00309
00310 cpl_errorstate prestate = cpl_errorstate_get();
00311
00312 muse_processing *proc = muse_processing_new("muse_scipost_correct_dar",
00313 recipe);
00314 int rc = muse_scipost_correct_dar_compute(proc, ¶ms);
00315 cpl_frameset_join(usedframes, proc->usedframes);
00316 cpl_frameset_join(outframes, proc->outframes);
00317 muse_processing_delete(proc);
00318
00319 if (!cpl_errorstate_is_equal(prestate)) {
00320
00321 cpl_errorstate_dump(prestate, CPL_FALSE, muse_cplerrorstate_dump_some);
00322
00323 cpl_msg_set_level(CPL_MSG_INFO);
00324 }
00325
00326 muse_cplframeset_erase_duplicate(usedframes);
00327 muse_cplframeset_erase_duplicate(outframes);
00328
00329
00330
00331
00332
00333 muse_cplframeset_erase_all(recipe->frames);
00334 cpl_frameset_join(recipe->frames, usedframes);
00335 cpl_frameset_join(recipe->frames, outframes);
00336 cpl_frameset_delete(usedframes);
00337 cpl_frameset_delete(outframes);
00338 return rc;
00339 }
00340
00341
00348
00349 static int
00350 muse_scipost_correct_dar_destroy(cpl_plugin *aPlugin)
00351 {
00352
00353 cpl_recipe *recipe;
00354 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
00355 recipe = (cpl_recipe *)aPlugin;
00356 } else {
00357 return -1;
00358 }
00359
00360
00361 cpl_parameterlist_delete(recipe->parameters);
00362 muse_processinginfo_delete(recipe);
00363 return 0;
00364 }
00365
00366
00376
00377 int
00378 cpl_plugin_get_info(cpl_pluginlist *aList)
00379 {
00380 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
00381 cpl_plugin *plugin = &recipe->interface;
00382
00383 char *helptext;
00384 if (muse_cplframework() == MUSE_CPLFRAMEWORK_ESOREX) {
00385 helptext = cpl_sprintf("%s%s", muse_scipost_correct_dar_help,
00386 muse_scipost_correct_dar_help_esorex);
00387 } else {
00388 helptext = cpl_sprintf("%s", muse_scipost_correct_dar_help);
00389 }
00390
00391
00392 cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
00393 CPL_PLUGIN_TYPE_RECIPE,
00394 "muse_scipost_correct_dar",
00395 "Apply DAR correction for MUSE pixel tables.",
00396 helptext,
00397 "Ole Streicher",
00398 "usd-help@eso.org",
00399 muse_get_license(),
00400 muse_scipost_correct_dar_create,
00401 muse_scipost_correct_dar_exec,
00402 muse_scipost_correct_dar_destroy);
00403 cpl_pluginlist_append(aList, plugin);
00404 cpl_free(helptext);
00405
00406 return 0;
00407 }
00408