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_astrometry_z.h"
00036
00037
00059
00062
00063
00064
00065 static const char *muse_astrometry_help =
00066 "Merge pixel tables from all IFUs, apply correction for differential atmospheric refraction, optionally apply flux calibration and telluric correction (if the necessary input data was given), and resample the data from all exposures into a datacube. Use the cube to detect objects which are then matched to their reference positions from which a two-dimensional WCS solution is computed. The main output is the ASTROMETRY_WCS file which is a bare FITS header containing the world coordinate solution. The secondary product is DATACUBE_ASTROMETRY, it is not needed for further processing but can be used for verification and debugging. It contains the reconstructed cube and two images created from it in further FITS extensions: a white-light image and the special image created from the central planes of the cube used to detect and centroid the stars (as well as its variance).";
00067
00068 static const char *muse_astrometry_help_esorex =
00069 "\n\nInput frames for raw frame tag \"PIXTABLE_ASTROMETRY\":\n"
00070 "\n Frame tag Type Req #Fr Description"
00071 "\n -------------------- ---- --- --- ------------"
00072 "\n PIXTABLE_ASTROMETRY raw Y Pixel table of an astrometric field"
00073 "\n ASTROMETRY_REFERENCE calib Y 1 Reference table of known objects for astrometry"
00074 "\n EXTINCT_TABLE calib . 1 Atmospheric extinction table"
00075 "\n STD_RESPONSE calib . 1 Response curve as derived from standard star(s)"
00076 "\n STD_TELLURIC calib . 1 Telluric absorption as derived from standard star(s)"
00077 "\n\nProduct frames for raw frame tag \"PIXTABLE_ASTROMETRY\":\n"
00078 "\n Frame tag Level Description"
00079 "\n -------------------- -------- ------------"
00080 "\n DATACUBE_ASTROMETRY final Reduced astrometry field exposure"
00081 "\n ASTROMETRY_WCS final Astrometric solution";
00082
00083
00091
00092 static cpl_recipeconfig *
00093 muse_astrometry_new_recipeconfig(void)
00094 {
00095 cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
00096
00097 cpl_recipeconfig_set_tag(recipeconfig, "PIXTABLE_ASTROMETRY", 1, -1);
00098 cpl_recipeconfig_set_input(recipeconfig, "PIXTABLE_ASTROMETRY", "ASTROMETRY_REFERENCE", 1, 1);
00099 cpl_recipeconfig_set_input(recipeconfig, "PIXTABLE_ASTROMETRY", "EXTINCT_TABLE", -1, 1);
00100 cpl_recipeconfig_set_input(recipeconfig, "PIXTABLE_ASTROMETRY", "STD_RESPONSE", -1, 1);
00101 cpl_recipeconfig_set_input(recipeconfig, "PIXTABLE_ASTROMETRY", "STD_TELLURIC", -1, 1);
00102 cpl_recipeconfig_set_output(recipeconfig, "PIXTABLE_ASTROMETRY", "DATACUBE_ASTROMETRY");
00103 cpl_recipeconfig_set_output(recipeconfig, "PIXTABLE_ASTROMETRY", "ASTROMETRY_WCS");
00104
00105 return recipeconfig;
00106 }
00107
00108
00118
00119 static cpl_error_code
00120 muse_astrometry_prepare_header(const char *aFrametag, cpl_propertylist *aHeader)
00121 {
00122 cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
00123 cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
00124 if (!strcmp(aFrametag, "DATACUBE_ASTROMETRY")) {
00125 muse_processing_prepare_property(aHeader, "ESO QC ASTRO NDET",
00126 CPL_TYPE_INT,
00127 "Number of detected sources in output cube.");
00128 muse_processing_prepare_property(aHeader, "ESO QC ASTRO LAMBDA",
00129 CPL_TYPE_FLOAT,
00130 "[Angstrom] Wavelength of plane in combined cube that was used for object detection.");
00131 muse_processing_prepare_property(aHeader, "ESO QC ASTRO POS[0-9]+ X",
00132 CPL_TYPE_FLOAT,
00133 "[pix] Position of source k in x-direction in output cube. If the FWHM measurement fails, this value will be -1.");
00134 muse_processing_prepare_property(aHeader, "ESO QC ASTRO POS[0-9]+ Y",
00135 CPL_TYPE_FLOAT,
00136 "[pix] Position of source k in y-direction in output cube. If the FWHM measurement fails, this value will be -1.");
00137 muse_processing_prepare_property(aHeader, "ESO QC ASTRO FWHM[0-9]+ X",
00138 CPL_TYPE_FLOAT,
00139 "[arcsec] FWHM of source k in x-direction in output cube. If the FWHM measurement fails, this value will be -1.");
00140 muse_processing_prepare_property(aHeader, "ESO QC ASTRO FWHM[0-9]+ Y",
00141 CPL_TYPE_FLOAT,
00142 "[arcsec] FWHM of source k in y-direction in output cube. If the FWHM measurement fails, this value will be -1.");
00143 muse_processing_prepare_property(aHeader, "ESO QC ASTRO FWHM NVALID",
00144 CPL_TYPE_INT,
00145 "Number of detected sources with valid FWHM in output cube.");
00146 muse_processing_prepare_property(aHeader, "ESO QC ASTRO FWHM MEDIAN",
00147 CPL_TYPE_FLOAT,
00148 "[arcsec] Median FWHM of all sources with valid FWHM measurement (in x- and y-direction) in output cube. If less than three sources with valid FWHM are detected, this value is zero.");
00149 muse_processing_prepare_property(aHeader, "ESO QC ASTRO FWHM MAD",
00150 CPL_TYPE_FLOAT,
00151 "[arcsec] Median absolute deviation of the FWHM of all sources with valid FWHM measurement (in x- and y-direction) in output cube. If less than three sources with valid FWHM are detected, this value is zero.");
00152 } else if (!strcmp(aFrametag, "ASTROMETRY_WCS")) {
00153 muse_processing_prepare_property(aHeader, "ESO QC ASTRO NSTARS",
00154 CPL_TYPE_INT,
00155 "Number of stars identified for the astrometric solution");
00156 muse_processing_prepare_property(aHeader, "ESO QC ASTRO SCALE X",
00157 CPL_TYPE_FLOAT,
00158 "[arcsec] Computed scale in x-direction");
00159 muse_processing_prepare_property(aHeader, "ESO QC ASTRO SCALE Y",
00160 CPL_TYPE_FLOAT,
00161 "[arcsec] Computed scale in y-direction");
00162 muse_processing_prepare_property(aHeader, "ESO QC ASTRO ANGLE X",
00163 CPL_TYPE_FLOAT,
00164 "[deg] Computed angle in x-direction");
00165 muse_processing_prepare_property(aHeader, "ESO QC ASTRO ANGLE Y",
00166 CPL_TYPE_FLOAT,
00167 "[deg] Computed angle in y-direction");
00168 muse_processing_prepare_property(aHeader, "ESO QC ASTRO MEDRES X",
00169 CPL_TYPE_FLOAT,
00170 "[arcsec] Median residuals of astrometric fit in x-direction");
00171 muse_processing_prepare_property(aHeader, "ESO QC ASTRO MEDRES Y",
00172 CPL_TYPE_FLOAT,
00173 "[arcsec] Median residuals of astrometric fit in y-direction");
00174 } else {
00175 cpl_msg_warning(__func__, "Frame tag %s is not defined", aFrametag);
00176 return CPL_ERROR_ILLEGAL_INPUT;
00177 }
00178 return CPL_ERROR_NONE;
00179 }
00180
00181
00190
00191 static cpl_frame_level
00192 muse_astrometry_get_frame_level(const char *aFrametag)
00193 {
00194 if (!aFrametag) {
00195 return CPL_FRAME_LEVEL_NONE;
00196 }
00197 if (!strcmp(aFrametag, "DATACUBE_ASTROMETRY")) {
00198 return CPL_FRAME_LEVEL_FINAL;
00199 }
00200 if (!strcmp(aFrametag, "ASTROMETRY_WCS")) {
00201 return CPL_FRAME_LEVEL_FINAL;
00202 }
00203 return CPL_FRAME_LEVEL_NONE;
00204 }
00205
00206
00215
00216 static muse_frame_mode
00217 muse_astrometry_get_frame_mode(const char *aFrametag)
00218 {
00219 if (!aFrametag) {
00220 return MUSE_FRAME_MODE_ALL;
00221 }
00222 if (!strcmp(aFrametag, "DATACUBE_ASTROMETRY")) {
00223 return MUSE_FRAME_MODE_DATEOBS;
00224 }
00225 if (!strcmp(aFrametag, "ASTROMETRY_WCS")) {
00226 return MUSE_FRAME_MODE_DATEOBS;
00227 }
00228 return MUSE_FRAME_MODE_ALL;
00229 }
00230
00231
00241
00242 static int
00243 muse_astrometry_create(cpl_plugin *aPlugin)
00244 {
00245
00246 cpl_recipe *recipe;
00247 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
00248 recipe = (cpl_recipe *)aPlugin;
00249 } else {
00250 return -1;
00251 }
00252
00253
00254
00255 muse_processinginfo_register(recipe,
00256 muse_astrometry_new_recipeconfig(),
00257 muse_astrometry_prepare_header,
00258 muse_astrometry_get_frame_level,
00259 muse_astrometry_get_frame_mode);
00260
00261
00262
00263 if (muse_cplframework() == MUSE_CPLFRAMEWORK_ESOREX) {
00264 cpl_msg_set_time_on();
00265 }
00266
00267
00268 recipe->parameters = cpl_parameterlist_new();
00269
00270 cpl_parameter *p;
00271
00272
00273 p = cpl_parameter_new_enum("muse.muse_astrometry.centroid",
00274 CPL_TYPE_STRING,
00275 "Centroiding method to use for objects in the field of view. \"gaussian\" and \"moffat\" use 2D fits to derive the centroid, \"box\" is a simple centroid in a square box.",
00276 "muse.muse_astrometry",
00277 (const char *)"moffat",
00278 3,
00279 (const char *)"gaussian",
00280 (const char *)"moffat",
00281 (const char *)"box");
00282 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "centroid");
00283 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "centroid");
00284
00285 cpl_parameterlist_append(recipe->parameters, p);
00286
00287
00288 p = cpl_parameter_new_value("muse.muse_astrometry.detsigma",
00289 CPL_TYPE_DOUBLE,
00290 "Source detection sigma level to use. If this is negative, values between its absolute and 1.0 are tested with a stepsize of 0.1, to find an optimal solution.",
00291 "muse.muse_astrometry",
00292 (double)-3.0);
00293 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "detsigma");
00294 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "detsigma");
00295
00296 cpl_parameterlist_append(recipe->parameters, p);
00297
00298
00299 p = cpl_parameter_new_value("muse.muse_astrometry.radius",
00300 CPL_TYPE_DOUBLE,
00301 "Initial radius in pixels for pattern matching identification in the astrometric field.",
00302 "muse.muse_astrometry",
00303 (double)5.);
00304 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "radius");
00305 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "radius");
00306
00307 cpl_parameterlist_append(recipe->parameters, p);
00308
00309
00310 p = cpl_parameter_new_value("muse.muse_astrometry.faccuracy",
00311 CPL_TYPE_DOUBLE,
00312 "Factor of initial accuracy relative to mean positional accuracy of the measured positions to use for pattern matching.",
00313 "muse.muse_astrometry",
00314 (double)5.);
00315 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "faccuracy");
00316 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "faccuracy");
00317
00318 cpl_parameterlist_append(recipe->parameters, p);
00319
00320
00321 p = cpl_parameter_new_value("muse.muse_astrometry.niter",
00322 CPL_TYPE_INT,
00323 "Number of iterations of the astrometric fit.",
00324 "muse.muse_astrometry",
00325 (int)2);
00326 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "niter");
00327 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "niter");
00328
00329 cpl_parameterlist_append(recipe->parameters, p);
00330
00331
00332 p = cpl_parameter_new_value("muse.muse_astrometry.rejsigma",
00333 CPL_TYPE_DOUBLE,
00334 "Rejection sigma level of the astrometric fit.",
00335 "muse.muse_astrometry",
00336 (double)3.);
00337 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "rejsigma");
00338 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "rejsigma");
00339
00340 cpl_parameterlist_append(recipe->parameters, p);
00341
00342
00343 p = cpl_parameter_new_value("muse.muse_astrometry.rotcenter",
00344 CPL_TYPE_STRING,
00345 "Center of rotation of the instrument, given as two comma-separated floating point values in pixels.",
00346 "muse.muse_astrometry",
00347 (const char *)"-0.01,-1.20");
00348 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "rotcenter");
00349 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "rotcenter");
00350
00351 cpl_parameterlist_append(recipe->parameters, p);
00352
00353
00354 p = cpl_parameter_new_value("muse.muse_astrometry.lambdamin",
00355 CPL_TYPE_DOUBLE,
00356 "Cut off the data below this wavelength after loading the pixel table(s).",
00357 "muse.muse_astrometry",
00358 (double)4000.);
00359 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambdamin");
00360 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambdamin");
00361
00362 cpl_parameterlist_append(recipe->parameters, p);
00363
00364
00365 p = cpl_parameter_new_value("muse.muse_astrometry.lambdamax",
00366 CPL_TYPE_DOUBLE,
00367 "Cut off the data above this wavelength after loading the pixel table(s).",
00368 "muse.muse_astrometry",
00369 (double)10000.);
00370 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambdamax");
00371 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambdamax");
00372
00373 cpl_parameterlist_append(recipe->parameters, p);
00374
00375
00376 p = cpl_parameter_new_value("muse.muse_astrometry.lambdaref",
00377 CPL_TYPE_DOUBLE,
00378 "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.",
00379 "muse.muse_astrometry",
00380 (double)7000.);
00381 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambdaref");
00382 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambdaref");
00383
00384 cpl_parameterlist_append(recipe->parameters, p);
00385
00386
00387 p = cpl_parameter_new_enum("muse.muse_astrometry.darcheck",
00388 CPL_TYPE_STRING,
00389 "Carry out a check of the theoretical DAR correction using source centroiding. If \"correct\" it will also apply an empirical correction.",
00390 "muse.muse_astrometry",
00391 (const char *)"none",
00392 3,
00393 (const char *)"none",
00394 (const char *)"check",
00395 (const char *)"correct");
00396 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "darcheck");
00397 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "darcheck");
00398
00399 cpl_parameterlist_append(recipe->parameters, p);
00400
00401 return 0;
00402 }
00403
00404
00415
00416 static int
00417 muse_astrometry_params_fill(muse_astrometry_params_t *aParams, cpl_parameterlist *aParameters)
00418 {
00419 cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
00420 cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
00421 cpl_parameter *p;
00422
00423 p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.centroid");
00424 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00425 aParams->centroid_s = cpl_parameter_get_string(p);
00426 aParams->centroid =
00427 (!strcasecmp(aParams->centroid_s, "gaussian")) ? MUSE_ASTROMETRY_PARAM_CENTROID_GAUSSIAN :
00428 (!strcasecmp(aParams->centroid_s, "moffat")) ? MUSE_ASTROMETRY_PARAM_CENTROID_MOFFAT :
00429 (!strcasecmp(aParams->centroid_s, "box")) ? MUSE_ASTROMETRY_PARAM_CENTROID_BOX :
00430 MUSE_ASTROMETRY_PARAM_CENTROID_INVALID_VALUE;
00431 cpl_ensure_code(aParams->centroid != MUSE_ASTROMETRY_PARAM_CENTROID_INVALID_VALUE,
00432 CPL_ERROR_ILLEGAL_INPUT);
00433
00434 p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.detsigma");
00435 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00436 aParams->detsigma = cpl_parameter_get_double(p);
00437
00438 p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.radius");
00439 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00440 aParams->radius = cpl_parameter_get_double(p);
00441
00442 p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.faccuracy");
00443 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00444 aParams->faccuracy = cpl_parameter_get_double(p);
00445
00446 p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.niter");
00447 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00448 aParams->niter = cpl_parameter_get_int(p);
00449
00450 p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.rejsigma");
00451 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00452 aParams->rejsigma = cpl_parameter_get_double(p);
00453
00454 p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.rotcenter");
00455 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00456 aParams->rotcenter = cpl_parameter_get_string(p);
00457
00458 p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.lambdamin");
00459 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00460 aParams->lambdamin = cpl_parameter_get_double(p);
00461
00462 p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.lambdamax");
00463 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00464 aParams->lambdamax = cpl_parameter_get_double(p);
00465
00466 p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.lambdaref");
00467 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00468 aParams->lambdaref = cpl_parameter_get_double(p);
00469
00470 p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.darcheck");
00471 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00472 aParams->darcheck_s = cpl_parameter_get_string(p);
00473 aParams->darcheck =
00474 (!strcasecmp(aParams->darcheck_s, "none")) ? MUSE_ASTROMETRY_PARAM_DARCHECK_NONE :
00475 (!strcasecmp(aParams->darcheck_s, "check")) ? MUSE_ASTROMETRY_PARAM_DARCHECK_CHECK :
00476 (!strcasecmp(aParams->darcheck_s, "correct")) ? MUSE_ASTROMETRY_PARAM_DARCHECK_CORRECT :
00477 MUSE_ASTROMETRY_PARAM_DARCHECK_INVALID_VALUE;
00478 cpl_ensure_code(aParams->darcheck != MUSE_ASTROMETRY_PARAM_DARCHECK_INVALID_VALUE,
00479 CPL_ERROR_ILLEGAL_INPUT);
00480
00481 return 0;
00482 }
00483
00484
00491
00492 static int
00493 muse_astrometry_exec(cpl_plugin *aPlugin)
00494 {
00495 if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
00496 return -1;
00497 }
00498 muse_processing_recipeinfo(aPlugin);
00499 cpl_recipe *recipe = (cpl_recipe *)aPlugin;
00500 cpl_msg_set_threadid_on();
00501
00502 cpl_frameset *usedframes = cpl_frameset_new(),
00503 *outframes = cpl_frameset_new();
00504 muse_astrometry_params_t params;
00505 muse_astrometry_params_fill(¶ms, recipe->parameters);
00506
00507 cpl_errorstate prestate = cpl_errorstate_get();
00508
00509 muse_processing *proc = muse_processing_new("muse_astrometry",
00510 recipe);
00511 int rc = muse_astrometry_compute(proc, ¶ms);
00512 cpl_frameset_join(usedframes, proc->usedframes);
00513 cpl_frameset_join(outframes, proc->outframes);
00514 muse_processing_delete(proc);
00515
00516 if (!cpl_errorstate_is_equal(prestate)) {
00517
00518 cpl_errorstate_dump(prestate, CPL_FALSE, muse_cplerrorstate_dump_some);
00519
00520 cpl_msg_set_level(CPL_MSG_INFO);
00521 }
00522
00523 muse_cplframeset_erase_duplicate(usedframes);
00524 muse_cplframeset_erase_duplicate(outframes);
00525
00526
00527
00528
00529
00530 muse_cplframeset_erase_all(recipe->frames);
00531 cpl_frameset_join(recipe->frames, usedframes);
00532 cpl_frameset_join(recipe->frames, outframes);
00533 cpl_frameset_delete(usedframes);
00534 cpl_frameset_delete(outframes);
00535 return rc;
00536 }
00537
00538
00545
00546 static int
00547 muse_astrometry_destroy(cpl_plugin *aPlugin)
00548 {
00549
00550 cpl_recipe *recipe;
00551 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
00552 recipe = (cpl_recipe *)aPlugin;
00553 } else {
00554 return -1;
00555 }
00556
00557
00558 cpl_parameterlist_delete(recipe->parameters);
00559 muse_processinginfo_delete(recipe);
00560 return 0;
00561 }
00562
00563
00573
00574 int
00575 cpl_plugin_get_info(cpl_pluginlist *aList)
00576 {
00577 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
00578 cpl_plugin *plugin = &recipe->interface;
00579
00580 char *helptext;
00581 if (muse_cplframework() == MUSE_CPLFRAMEWORK_ESOREX) {
00582 helptext = cpl_sprintf("%s%s", muse_astrometry_help,
00583 muse_astrometry_help_esorex);
00584 } else {
00585 helptext = cpl_sprintf("%s", muse_astrometry_help);
00586 }
00587
00588
00589 cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
00590 CPL_PLUGIN_TYPE_RECIPE,
00591 "muse_astrometry",
00592 "Compute an astrometric solution.",
00593 helptext,
00594 "Peter Weilbacher",
00595 "usd-help@eso.org",
00596 muse_get_license(),
00597 muse_astrometry_create,
00598 muse_astrometry_exec,
00599 muse_astrometry_destroy);
00600 cpl_pluginlist_append(aList, plugin);
00601 cpl_free(helptext);
00602
00603 return 0;
00604 }
00605