FORS Pipeline Reference Manual 4.9.9
|
00001 /* $Id: fors_extract_objects.c,v 1.5 2010/09/14 07:38:16 cizzo Exp $ 00002 * 00003 * This file is part of the FORS Data Reduction Pipeline 00004 * Copyright (C) 2002-2010 European Southern Observatory 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 /* 00022 * $Author: cizzo $ 00023 * $Date: 2010/09/14 07:38:16 $ 00024 * $Revision: 1.5 $ 00025 * $Name: fors-4_9_9 $ 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 * Check that the plugin is part of a valid recipe 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 * Create the (empty) parameters list in the cpl_recipe object 00162 */ 00163 00164 recipe->parameters = cpl_parameterlist_new(); 00165 00166 /* 00167 * Object extraction method 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 * Input parameters 00246 */ 00247 00248 int ext_mode; 00249 00250 /* 00251 * CPL objects 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 * Auxiliary variables 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 * Get configuration parameters 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; /* Convert from electrons to ADU */ 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 }