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 (message) 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 (message) 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 if (dfs_files_dont_exist(frameset))
00287 fors_extract_objects_exit(NULL);
00288
00289
00290
00291
00292
00293
00294 cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe);
00295 cpl_msg_indent_more();
00296
00297 ext_mode = dfs_get_parameter_int(parlist,
00298 "fors.fors_extract_objects.ext_mode",
00299 NULL);
00300 if (ext_mode < 0 || ext_mode > 1)
00301 fors_extract_objects_exit("Invalid object extraction mode");
00302
00303 if (cpl_error_get_code())
00304 fors_extract_objects_exit("Failure reading configuration parameters");
00305
00306
00307 cpl_msg_indent_less();
00308 cpl_msg_info(recipe, "Check input set-of-frames:");
00309 cpl_msg_indent_more();
00310
00311 nframes = scimxu = cpl_frameset_count_tags(frameset, "MAPPED_SCI_MXU");
00312 nframes += scimos = cpl_frameset_count_tags(frameset, "MAPPED_SCI_MOS");
00313 nframes += scilss = cpl_frameset_count_tags(frameset, "MAPPED_SCI_LSS");
00314 nframes += stdmxu = cpl_frameset_count_tags(frameset, "MAPPED_STD_MXU");
00315 nframes += stdmos = cpl_frameset_count_tags(frameset, "MAPPED_STD_MOS");
00316 nframes += stdlss = cpl_frameset_count_tags(frameset, "MAPPED_STD_LSS");
00317
00318 if (nframes == 0) {
00319 fors_extract_objects_exit("Missing input scientific spectra");
00320 }
00321 if (nframes > 1) {
00322 cpl_msg_error(recipe, "Too many input scientific spectra (%d > 1)",
00323 nframes);
00324 fors_extract_objects_exit(NULL);
00325 }
00326
00327 if (scimxu) {
00328 science_tag = "MAPPED_SCI_MXU";
00329 sky_tag = "MAPPED_SKY_SCI_MXU";
00330 object_tag = "OBJECT_TABLE_SCI_MXU";
00331 reduced_tag = "REDUCED_SCI_MXU";
00332 reduced_sky_tag = "REDUCED_SKY_SCI_MXU";
00333 reduced_err_tag = "REDUCED_ERROR_SCI_MXU";
00334 }
00335 else if (scimos) {
00336 science_tag = "MAPPED_SCI_MOS";
00337 sky_tag = "MAPPED_SKY_SCI_MOS";
00338 object_tag = "OBJECT_TABLE_SCI_MOS";
00339 reduced_tag = "REDUCED_SCI_MOS";
00340 reduced_sky_tag = "REDUCED_SKY_SCI_MOS";
00341 reduced_err_tag = "REDUCED_ERROR_SCI_MOS";
00342 }
00343 else if (scilss) {
00344 science_tag = "MAPPED_SCI_LSS";
00345 sky_tag = "MAPPED_SKY_SCI_LSS";
00346 object_tag = "OBJECT_TABLE_SCI_LSS";
00347 reduced_tag = "REDUCED_SCI_LSS";
00348 reduced_sky_tag = "REDUCED_SKY_SCI_LSS";
00349 reduced_err_tag = "REDUCED_ERROR_SCI_LSS";
00350 }
00351 else if (stdmxu) {
00352 science_tag = "MAPPED_STD_MXU";
00353 sky_tag = "MAPPED_SKY_STD_MXU";
00354 object_tag = "OBJECT_TABLE_SCI_MXU";
00355 reduced_tag = "REDUCED_STD_MXU";
00356 reduced_sky_tag = "REDUCED_SKY_STD_MXU";
00357 reduced_err_tag = "REDUCED_ERROR_STD_MXU";
00358 }
00359 else if (stdmos) {
00360 science_tag = "MAPPED_STD_MOS";
00361 sky_tag = "MAPPED_SKY_STD_MOS";
00362 object_tag = "OBJECT_TABLE_SCI_MOS";
00363 reduced_tag = "REDUCED_STD_MOS";
00364 reduced_sky_tag = "REDUCED_SKY_STD_MOS";
00365 reduced_err_tag = "REDUCED_ERROR_STD_MOS";
00366 }
00367 else if (stdlss) {
00368 science_tag = "MAPPED_STD_LSS";
00369 sky_tag = "MAPPED_SKY_STD_LSS";
00370 object_tag = "OBJECT_TABLE_SCI_LSS";
00371 reduced_tag = "REDUCED_STD_LSS";
00372 reduced_sky_tag = "REDUCED_SKY_STD_LSS";
00373 reduced_err_tag = "REDUCED_ERROR_STD_LSS";
00374 }
00375
00376 if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
00377 fors_extract_objects_exit("Input frames are not from the same grism");
00378
00379 if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
00380 fors_extract_objects_exit("Input frames are not from the same filter");
00381
00382 if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
00383 fors_extract_objects_exit("Input frames are not from the same chip");
00384
00385 header = dfs_load_header(frameset, science_tag, 0);
00386 if (header == NULL)
00387 fors_extract_objects_exit("Cannot load scientific frame header");
00388
00389 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00390 if (instrume == NULL)
00391 fors_extract_objects_exit("Missing keyword INSTRUME in reference frame "
00392 "header");
00393
00394 if (instrume[4] == '1')
00395 snprintf(version, 80, "%s/%s", "fors1", VERSION);
00396 if (instrume[4] == '2')
00397 snprintf(version, 80, "%s/%s", "fors2", VERSION);
00398
00399 gain = cpl_propertylist_get_double(header, "ESO DET OUT1 CONAD");
00400
00401 if (cpl_error_get_code() != CPL_ERROR_NONE)
00402 fors_extract_objects_exit("Missing keyword ESO DET OUT1 CONAD in "
00403 "scientific frame header");
00404
00405 cpl_msg_info(recipe, "The gain factor is: %.2f e-/ADU", gain);
00406
00407
00408 ron = cpl_propertylist_get_double(header, "ESO DET OUT1 RON");
00409
00410 if (cpl_error_get_code() != CPL_ERROR_NONE)
00411 fors_extract_objects_exit("Missing keyword ESO DET OUT1 RON in "
00412 "scientific frame header");
00413
00414 ron /= gain;
00415
00416 cpl_msg_info(recipe, "The read-out-noise is: %.2f ADU", ron);
00417
00418
00419 cpl_msg_indent_less();
00420 cpl_msg_info(recipe, "Load input frames...");
00421 cpl_msg_indent_more();
00422
00423 mapped = dfs_load_image(frameset, science_tag, CPL_TYPE_FLOAT, 0, 0);
00424 if (mapped == NULL)
00425 fors_extract_objects_exit("Cannot load input scientific frame");
00426
00427 skymapped = dfs_load_image(frameset, sky_tag, CPL_TYPE_FLOAT, 0, 0);
00428 if (skymapped == NULL)
00429 fors_extract_objects_exit("Cannot load input sky frame");
00430
00431 slits = dfs_load_table(frameset, object_tag, 1);
00432 if (slits == NULL)
00433 fors_extract_objects_exit("Cannot load input object table");
00434
00435
00436 cpl_msg_indent_less();
00437 cpl_msg_info(recipe, "Object extraction...");
00438 cpl_msg_indent_more();
00439
00440 images = mos_extract_objects(mapped, skymapped, slits,
00441 ext_mode, ron, gain, 1);
00442
00443 cpl_image_delete(mapped); mapped = NULL;
00444 cpl_image_delete(skymapped); skymapped = NULL;
00445 cpl_table_delete(slits); slits = NULL;
00446
00447 if (images) {
00448
00449 if (dfs_save_image(frameset, images[0], reduced_tag, header,
00450 parlist, recipe, version))
00451 fors_extract_objects_exit(NULL);
00452 cpl_image_delete(images[0]);
00453
00454 if (dfs_save_image(frameset, images[1], reduced_sky_tag, header,
00455 parlist, recipe, version))
00456 fors_extract_objects_exit(NULL);
00457 cpl_image_delete(images[1]);
00458
00459 if (dfs_save_image(frameset, images[2], reduced_err_tag, header,
00460 parlist, recipe, version))
00461 fors_extract_objects_exit(NULL);
00462 cpl_image_delete(images[2]);
00463
00464 cpl_free(images);
00465 }
00466 else {
00467 cpl_msg_warning(recipe, "No objects found: the products "
00468 "%s, %s, and %s are not created",
00469 reduced_tag, reduced_sky_tag, reduced_err_tag);
00470 }
00471
00472 cpl_propertylist_delete(header); header = NULL;
00473
00474 return 0;
00475 }