00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032 #include <math.h>
00033 #include <cpl.h>
00034 #include <moses.h>
00035 #include <fors_dfs.h>
00036
00037 static int fors_extract_objects_create(cpl_plugin *);
00038 static int fors_extract_objects_exec(cpl_plugin *);
00039 static int fors_extract_objects_destroy(cpl_plugin *);
00040 static int fors_extract_objects(cpl_parameterlist *, cpl_frameset *);
00041
00042 static char fors_extract_objects_description[] =
00043 "This recipe is used to extract scientific objects spectra on a resampled\n"
00044 "image produced with recipe fors_resample, at the positions listed in the\n"
00045 "object table produced by recipe fors_detect_objects. Please refer to the\n"
00046 "FORS Pipeline User's Manual for more details on object extraction.\n"
00047 "\n"
00048 "In the table below the MXU acronym can be alternatively read as MOS and\n"
00049 "LSS, and SCI as STD.\n\n"
00050 "Input files:\n\n"
00051 " DO category: Type: Explanation: Required:\n"
00052 " MAPPED_SCI_MXU Calib Resampled slit spectra Y\n"
00053 " MAPPED_SKY_SCI_MXU Calib Resampled sky spectra Y\n"
00054 " OBJECT_TABLE_SCI_MXU Calib Object table Y\n\n"
00055 "Output files:\n\n"
00056 " DO category: Data type: Explanation:\n"
00057 " REDUCED_SCI_MXU FITS image Extracted object spectra\n"
00058 " REDUCED_SKY_SCI_MXU FITS image Extracted sky spectra\n"
00059 " REDUCED_ERROR_SCI_MXU FITS image Error on extracted spectra\n\n";
00060
00061 #define fors_extract_objects_exit(message) \
00062 { \
00063 if ((const char *)message != NULL) cpl_msg_error(recipe, message); \
00064 cpl_image_delete(mapped); \
00065 cpl_image_delete(skymapped); \
00066 cpl_table_delete(slits); \
00067 cpl_propertylist_delete(header); \
00068 cpl_msg_indent_less(); \
00069 return -1; \
00070 }
00071
00072 #define fors_extract_objects_exit_memcheck(message) \
00073 { \
00074 if ((const char *)message != NULL) cpl_msg_info(recipe, message); \
00075 printf("free mapped (%p)\n", mapped); \
00076 cpl_image_delete(mapped); \
00077 printf("free skymapped (%p)\n", skymapped); \
00078 cpl_image_delete(skymapped); \
00079 printf("free slits (%p)\n", slits); \
00080 cpl_table_delete(slits); \
00081 printf("free header (%p)\n", header); \
00082 cpl_propertylist_delete(header); \
00083 cpl_msg_indent_less(); \
00084 return 0; \
00085 }
00086
00087
00099 int cpl_plugin_get_info(cpl_pluginlist *list)
00100 {
00101 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe );
00102 cpl_plugin *plugin = &recipe->interface;
00103
00104 cpl_plugin_init(plugin,
00105 CPL_PLUGIN_API,
00106 FORS_BINARY_VERSION,
00107 CPL_PLUGIN_TYPE_RECIPE,
00108 "fors_extract_objects",
00109 "Extract objects in slit spectra",
00110 fors_extract_objects_description,
00111 "Carlo Izzo",
00112 PACKAGE_BUGREPORT,
00113 "This file is currently part of the FORS Instrument Pipeline\n"
00114 "Copyright (C) 2002-2010 European Southern Observatory\n\n"
00115 "This program is free software; you can redistribute it and/or modify\n"
00116 "it under the terms of the GNU General Public License as published by\n"
00117 "the Free Software Foundation; either version 2 of the License, or\n"
00118 "(at your option) any later version.\n\n"
00119 "This program is distributed in the hope that it will be useful,\n"
00120 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00121 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00122 "GNU General Public License for more details.\n\n"
00123 "You should have received a copy of the GNU General Public License\n"
00124 "along with this program; if not, write to the Free Software Foundation,\n"
00125 "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n",
00126 fors_extract_objects_create,
00127 fors_extract_objects_exec,
00128 fors_extract_objects_destroy);
00129
00130 cpl_pluginlist_append(list, plugin);
00131
00132 return 0;
00133 }
00134
00135
00146 static int fors_extract_objects_create(cpl_plugin *plugin)
00147 {
00148 cpl_recipe *recipe;
00149 cpl_parameter *p;
00150
00151
00152
00153
00154
00155 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00156 recipe = (cpl_recipe *)plugin;
00157 else
00158 return -1;
00159
00160
00161
00162
00163
00164 recipe->parameters = cpl_parameterlist_new();
00165
00166
00167
00168
00169
00170 p = cpl_parameter_new_value("fors.fors_extract_objects.ext_mode",
00171 CPL_TYPE_INT,
00172 "Object extraction method: 0 = aperture, "
00173 "1 = Horne optimal extraction",
00174 "fors.fors_extract_objects",
00175 1);
00176 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ext_mode");
00177 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00178 cpl_parameterlist_append(recipe->parameters, p);
00179
00180 return 0;
00181 }
00182
00183
00192 static int fors_extract_objects_exec(cpl_plugin *plugin)
00193 {
00194 cpl_recipe *recipe;
00195
00196 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00197 recipe = (cpl_recipe *)plugin;
00198 else
00199 return -1;
00200
00201 return fors_extract_objects(recipe->parameters, recipe->frames);
00202 }
00203
00204
00213 static int fors_extract_objects_destroy(cpl_plugin *plugin)
00214 {
00215 cpl_recipe *recipe;
00216
00217 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00218 recipe = (cpl_recipe *)plugin;
00219 else
00220 return -1;
00221
00222 cpl_parameterlist_delete(recipe->parameters);
00223
00224 return 0;
00225 }
00226
00227
00237 static int fors_extract_objects(cpl_parameterlist *parlist,
00238 cpl_frameset *frameset)
00239 {
00240
00241 const char *recipe = "fors_extract_objects";
00242
00243
00244
00245
00246
00247
00248 int ext_mode;
00249
00250
00251
00252
00253
00254 cpl_image **images;
00255 cpl_image *mapped = NULL;
00256 cpl_image *skymapped = NULL;
00257 cpl_table *slits = NULL;
00258 cpl_propertylist *header = NULL;
00259
00260
00261
00262
00263
00264 char version[80];
00265 const char *object_tag;
00266 const char *science_tag;
00267 const char *sky_tag;
00268 const char *reduced_tag;
00269 const char *reduced_sky_tag;
00270 const char *reduced_err_tag;
00271 int nframes;
00272 double gain;
00273 double ron;
00274 int scimxu;
00275 int scimos;
00276 int scilss;
00277 int stdmxu;
00278 int stdmos;
00279 int stdlss;
00280
00281 char *instrume = NULL;
00282
00283
00284 cpl_msg_set_indentation(2);
00285
00286
00287
00288
00289
00290
00291 cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe);
00292 cpl_msg_indent_more();
00293
00294 ext_mode = dfs_get_parameter_int(parlist,
00295 "fors.fors_extract_objects.ext_mode",
00296 NULL);
00297 if (ext_mode < 0 || ext_mode > 1)
00298 fors_extract_objects_exit("Invalid object extraction mode");
00299
00300 if (cpl_error_get_code())
00301 fors_extract_objects_exit("Failure reading configuration parameters");
00302
00303
00304 cpl_msg_indent_less();
00305 cpl_msg_info(recipe, "Check input set-of-frames:");
00306 cpl_msg_indent_more();
00307
00308 nframes = scimxu = cpl_frameset_count_tags(frameset, "MAPPED_SCI_MXU");
00309 nframes += scimos = cpl_frameset_count_tags(frameset, "MAPPED_SCI_MOS");
00310 nframes += scilss = cpl_frameset_count_tags(frameset, "MAPPED_SCI_LSS");
00311 nframes += stdmxu = cpl_frameset_count_tags(frameset, "MAPPED_STD_MXU");
00312 nframes += stdmos = cpl_frameset_count_tags(frameset, "MAPPED_STD_MOS");
00313 nframes += stdlss = cpl_frameset_count_tags(frameset, "MAPPED_STD_LSS");
00314
00315 if (nframes == 0) {
00316 fors_extract_objects_exit("Missing input scientific spectra");
00317 }
00318 if (nframes > 1) {
00319 cpl_msg_error(recipe, "Too many input scientific spectra (%d > 1)",
00320 nframes);
00321 fors_extract_objects_exit(NULL);
00322 }
00323
00324 if (scimxu) {
00325 science_tag = "MAPPED_SCI_MXU";
00326 sky_tag = "MAPPED_SKY_SCI_MXU";
00327 object_tag = "OBJECT_TABLE_SCI_MXU";
00328 reduced_tag = "REDUCED_SCI_MXU";
00329 reduced_sky_tag = "REDUCED_SKY_SCI_MXU";
00330 reduced_err_tag = "REDUCED_ERROR_SCI_MXU";
00331 }
00332 else if (scimos) {
00333 science_tag = "MAPPED_SCI_MOS";
00334 sky_tag = "MAPPED_SKY_SCI_MOS";
00335 object_tag = "OBJECT_TABLE_SCI_MOS";
00336 reduced_tag = "REDUCED_SCI_MOS";
00337 reduced_sky_tag = "REDUCED_SKY_SCI_MOS";
00338 reduced_err_tag = "REDUCED_ERROR_SCI_MOS";
00339 }
00340 else if (scilss) {
00341 science_tag = "MAPPED_SCI_LSS";
00342 sky_tag = "MAPPED_SKY_SCI_LSS";
00343 object_tag = "OBJECT_TABLE_SCI_LSS";
00344 reduced_tag = "REDUCED_SCI_LSS";
00345 reduced_sky_tag = "REDUCED_SKY_SCI_LSS";
00346 reduced_err_tag = "REDUCED_ERROR_SCI_LSS";
00347 }
00348 else if (stdmxu) {
00349 science_tag = "MAPPED_STD_MXU";
00350 sky_tag = "MAPPED_SKY_STD_MXU";
00351 object_tag = "OBJECT_TABLE_SCI_MXU";
00352 reduced_tag = "REDUCED_STD_MXU";
00353 reduced_sky_tag = "REDUCED_SKY_STD_MXU";
00354 reduced_err_tag = "REDUCED_ERROR_STD_MXU";
00355 }
00356 else if (stdmos) {
00357 science_tag = "MAPPED_STD_MOS";
00358 sky_tag = "MAPPED_SKY_STD_MOS";
00359 object_tag = "OBJECT_TABLE_SCI_MOS";
00360 reduced_tag = "REDUCED_STD_MOS";
00361 reduced_sky_tag = "REDUCED_SKY_STD_MOS";
00362 reduced_err_tag = "REDUCED_ERROR_STD_MOS";
00363 }
00364 else if (stdlss) {
00365 science_tag = "MAPPED_STD_LSS";
00366 sky_tag = "MAPPED_SKY_STD_LSS";
00367 object_tag = "OBJECT_TABLE_SCI_LSS";
00368 reduced_tag = "REDUCED_STD_LSS";
00369 reduced_sky_tag = "REDUCED_SKY_STD_LSS";
00370 reduced_err_tag = "REDUCED_ERROR_STD_LSS";
00371 }
00372
00373 if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
00374 fors_extract_objects_exit("Input frames are not from the same grism");
00375
00376 if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
00377 fors_extract_objects_exit("Input frames are not from the same filter");
00378
00379 if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
00380 fors_extract_objects_exit("Input frames are not from the same chip");
00381
00382 header = dfs_load_header(frameset, science_tag, 0);
00383 if (header == NULL)
00384 fors_extract_objects_exit("Cannot load scientific frame header");
00385
00386 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00387 if (instrume == NULL)
00388 fors_extract_objects_exit("Missing keyword INSTRUME in reference frame "
00389 "header");
00390
00391 if (instrume[4] == '1')
00392 snprintf(version, 80, "%s/%s", "fors1", VERSION);
00393 if (instrume[4] == '2')
00394 snprintf(version, 80, "%s/%s", "fors2", VERSION);
00395
00396 gain = cpl_propertylist_get_double(header, "ESO DET OUT1 CONAD");
00397
00398 if (cpl_error_get_code() != CPL_ERROR_NONE)
00399 fors_extract_objects_exit("Missing keyword ESO DET OUT1 CONAD in "
00400 "scientific frame header");
00401
00402 cpl_msg_info(recipe, "The gain factor is: %.2f e-/ADU", gain);
00403
00404
00405 ron = cpl_propertylist_get_double(header, "ESO DET OUT1 RON");
00406
00407 if (cpl_error_get_code() != CPL_ERROR_NONE)
00408 fors_extract_objects_exit("Missing keyword ESO DET OUT1 RON in "
00409 "scientific frame header");
00410
00411 ron /= gain;
00412
00413 cpl_msg_info(recipe, "The read-out-noise is: %.2f ADU", ron);
00414
00415
00416 cpl_msg_indent_less();
00417 cpl_msg_info(recipe, "Load input frames...");
00418 cpl_msg_indent_more();
00419
00420 mapped = dfs_load_image(frameset, science_tag, CPL_TYPE_FLOAT, 0, 0);
00421 if (mapped == NULL)
00422 fors_extract_objects_exit("Cannot load input scientific frame");
00423
00424 skymapped = dfs_load_image(frameset, sky_tag, CPL_TYPE_FLOAT, 0, 0);
00425 if (skymapped == NULL)
00426 fors_extract_objects_exit("Cannot load input sky frame");
00427
00428 slits = dfs_load_table(frameset, object_tag, 1);
00429 if (slits == NULL)
00430 fors_extract_objects_exit("Cannot load input object table");
00431
00432
00433 cpl_msg_indent_less();
00434 cpl_msg_info(recipe, "Object extraction...");
00435 cpl_msg_indent_more();
00436
00437
00438
00439 images = mos_extract_objects(mapped, NULL, skymapped, slits,
00440 ext_mode, ron, gain, 1);
00441
00442 cpl_image_delete(mapped); mapped = NULL;
00443 cpl_image_delete(skymapped); skymapped = NULL;
00444 cpl_table_delete(slits); slits = NULL;
00445
00446 if (images) {
00447
00448 if (dfs_save_image(frameset, images[0], reduced_tag, header,
00449 parlist, recipe, version))
00450 fors_extract_objects_exit(NULL);
00451 cpl_image_delete(images[0]);
00452
00453 if (dfs_save_image(frameset, images[1], reduced_sky_tag, header,
00454 parlist, recipe, version))
00455 fors_extract_objects_exit(NULL);
00456 cpl_image_delete(images[1]);
00457
00458 if (dfs_save_image(frameset, images[2], reduced_err_tag, header,
00459 parlist, recipe, version))
00460 fors_extract_objects_exit(NULL);
00461 cpl_image_delete(images[2]);
00462
00463 cpl_free(images);
00464 }
00465 else {
00466 cpl_msg_warning(recipe, "No objects found: the products "
00467 "%s, %s, and %s are not created",
00468 reduced_tag, reduced_sky_tag, reduced_err_tag);
00469 }
00470
00471 cpl_propertylist_delete(header); header = NULL;
00472
00473 return 0;
00474 }