FORS Pipeline Reference Manual 4.9.20
|
00001 /* $Id: fors_detect_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_20 $ 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_detect_objects_create(cpl_plugin *); 00038 static int fors_detect_objects_exec(cpl_plugin *); 00039 static int fors_detect_objects_destroy(cpl_plugin *); 00040 static int fors_detect_objects(cpl_parameterlist *, cpl_frameset *); 00041 00042 static char fors_detect_objects_description[] = 00043 "This recipe is used to detect scientific objects spectra on a resampled\n" 00044 "image produced with recipe fors_resample. Please refer to the FORS\n" 00045 "Pipeline User's Manual for more details on object detection.\n" 00046 "\n" 00047 "In the table below the MXU acronym can be alternatively read as MOS and\n" 00048 "LSS, and SCI as STD.\n\n" 00049 "Input files:\n\n" 00050 " DO category: Type: Explanation: Required:\n" 00051 " MAPPED_SCI_MXU Calib Resampled slit spectra Y\n" 00052 " SLIT_LOCATION_MXU Calib Slit location on image Y\n" 00053 "Output files:\n\n" 00054 " DO category: Data type: Explanation:\n" 00055 " OBJECT_TABLE_SCI_MXU FITS table Object positions in slit spectra\n\n"; 00056 00057 #define fors_detect_objects_exit(message) \ 00058 { \ 00059 if (message) cpl_msg_error(recipe, message); \ 00060 cpl_image_delete(dummy); \ 00061 cpl_image_delete(mapped); \ 00062 cpl_table_delete(slits); \ 00063 cpl_propertylist_delete(header); \ 00064 cpl_msg_indent_less(); \ 00065 return -1; \ 00066 } 00067 00068 #define fors_detect_objects_exit_memcheck(message) \ 00069 { \ 00070 if (message) cpl_msg_info(recipe, message); \ 00071 printf("free dummy (%p)\n", dummy); \ 00072 cpl_image_delete(dummy); \ 00073 printf("free mapped (%p)\n", mapped); \ 00074 cpl_image_delete(mapped); \ 00075 printf("free slits (%p)\n", slits); \ 00076 cpl_table_delete(slits); \ 00077 printf("free header (%p)\n", header); \ 00078 cpl_propertylist_delete(header); \ 00079 cpl_msg_indent_less(); \ 00080 return 0; \ 00081 } 00082 00083 00095 int cpl_plugin_get_info(cpl_pluginlist *list) 00096 { 00097 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe ); 00098 cpl_plugin *plugin = &recipe->interface; 00099 00100 cpl_plugin_init(plugin, 00101 CPL_PLUGIN_API, 00102 FORS_BINARY_VERSION, 00103 CPL_PLUGIN_TYPE_RECIPE, 00104 "fors_detect_objects", 00105 "Detect objects in slit spectra", 00106 fors_detect_objects_description, 00107 "Carlo Izzo", 00108 PACKAGE_BUGREPORT, 00109 "This file is currently part of the FORS Instrument Pipeline\n" 00110 "Copyright (C) 2002-2010 European Southern Observatory\n\n" 00111 "This program is free software; you can redistribute it and/or modify\n" 00112 "it under the terms of the GNU General Public License as published by\n" 00113 "the Free Software Foundation; either version 2 of the License, or\n" 00114 "(at your option) any later version.\n\n" 00115 "This program is distributed in the hope that it will be useful,\n" 00116 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" 00117 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" 00118 "GNU General Public License for more details.\n\n" 00119 "You should have received a copy of the GNU General Public License\n" 00120 "along with this program; if not, write to the Free Software Foundation,\n" 00121 "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n", 00122 fors_detect_objects_create, 00123 fors_detect_objects_exec, 00124 fors_detect_objects_destroy); 00125 00126 cpl_pluginlist_append(list, plugin); 00127 00128 return 0; 00129 } 00130 00131 00142 static int fors_detect_objects_create(cpl_plugin *plugin) 00143 { 00144 cpl_recipe *recipe; 00145 cpl_parameter *p; 00146 00147 /* 00148 * Check that the plugin is part of a valid recipe 00149 */ 00150 00151 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00152 recipe = (cpl_recipe *)plugin; 00153 else 00154 return -1; 00155 00156 /* 00157 * Create the (empty) parameters list in the cpl_recipe object 00158 */ 00159 00160 recipe->parameters = cpl_parameterlist_new(); 00161 00162 /* 00163 * Slit margin 00164 */ 00165 00166 p = cpl_parameter_new_value("fors.fors_detect_objects.slit_margin", 00167 CPL_TYPE_INT, 00168 "Number of pixels to exclude at each slit " 00169 "in object detection and extraction", 00170 "fors.fors_detect_objects", 00171 3); 00172 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slit_margin"); 00173 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00174 cpl_parameterlist_append(recipe->parameters, p); 00175 00176 /* 00177 * Extraction radius 00178 */ 00179 00180 p = cpl_parameter_new_value("fors.fors_detect_objects.ext_radius", 00181 CPL_TYPE_INT, 00182 "Maximum extraction radius for detected " 00183 "objects (pixel)", 00184 "fors.fors_detect_objects", 00185 6); 00186 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ext_radius"); 00187 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00188 cpl_parameterlist_append(recipe->parameters, p); 00189 00190 /* 00191 * Contamination radius 00192 */ 00193 00194 p = cpl_parameter_new_value("fors.fors_detect_objects.cont_radius", 00195 CPL_TYPE_INT, 00196 "Minimum distance at which two objects " 00197 "of equal luminosity do not contaminate " 00198 "each other (pixel)", 00199 "fors.fors_detect_objects", 00200 0); 00201 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "cont_radius"); 00202 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00203 cpl_parameterlist_append(recipe->parameters, p); 00204 00205 return 0; 00206 } 00207 00208 00217 static int fors_detect_objects_exec(cpl_plugin *plugin) 00218 { 00219 cpl_recipe *recipe; 00220 00221 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00222 recipe = (cpl_recipe *)plugin; 00223 else 00224 return -1; 00225 00226 return fors_detect_objects(recipe->parameters, recipe->frames); 00227 } 00228 00229 00238 static int fors_detect_objects_destroy(cpl_plugin *plugin) 00239 { 00240 cpl_recipe *recipe; 00241 00242 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00243 recipe = (cpl_recipe *)plugin; 00244 else 00245 return -1; 00246 00247 cpl_parameterlist_delete(recipe->parameters); 00248 00249 return 0; 00250 } 00251 00252 00262 static int fors_detect_objects(cpl_parameterlist *parlist, 00263 cpl_frameset *frameset) 00264 { 00265 00266 const char *recipe = "fors_detect_objects"; 00267 00268 00269 /* 00270 * Input parameters 00271 */ 00272 00273 int slit_margin; 00274 int ext_radius; 00275 int cont_radius; 00276 00277 /* 00278 * CPL objects 00279 */ 00280 00281 cpl_image *mapped = NULL; 00282 cpl_image *dummy = NULL; 00283 cpl_table *slits = NULL; 00284 cpl_propertylist *header = NULL; 00285 00286 /* 00287 * Auxiliary variables 00288 */ 00289 00290 char version[80]; 00291 const char *slit_location_tag; 00292 const char *input_tag; 00293 const char *outpt_tag; 00294 int nframes; 00295 double gain; 00296 int scimxu; 00297 int scimos; 00298 int scilss; 00299 int stdmxu; 00300 int stdmos; 00301 int stdlss; 00302 00303 char *instrume = NULL; 00304 00305 00306 cpl_msg_set_indentation(2); 00307 00308 if (dfs_files_dont_exist(frameset)) 00309 fors_detect_objects_exit(NULL); 00310 00311 00312 /* 00313 * Get configuration parameters 00314 */ 00315 00316 cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe); 00317 cpl_msg_indent_more(); 00318 00319 slit_margin = dfs_get_parameter_int(parlist, 00320 "fors.fors_detect_objects.slit_margin", 00321 NULL); 00322 if (slit_margin < 0) 00323 fors_detect_objects_exit("Value must be zero or positive"); 00324 00325 ext_radius = dfs_get_parameter_int(parlist, 00326 "fors.fors_detect_objects.ext_radius", 00327 NULL); 00328 if (ext_radius < 0) 00329 fors_detect_objects_exit("Value must be zero or positive"); 00330 00331 cont_radius = dfs_get_parameter_int(parlist, 00332 "fors.fors_detect_objects.cont_radius", 00333 NULL); 00334 if (cont_radius < 0) 00335 fors_detect_objects_exit("Value must be zero or positive"); 00336 00337 if (cpl_error_get_code()) 00338 fors_detect_objects_exit("Failure reading configuration parameters"); 00339 00340 00341 cpl_msg_indent_less(); 00342 cpl_msg_info(recipe, "Check input set-of-frames:"); 00343 cpl_msg_indent_more(); 00344 00345 nframes = scimxu = cpl_frameset_count_tags(frameset, "MAPPED_SCI_MXU"); 00346 nframes += scimos = cpl_frameset_count_tags(frameset, "MAPPED_SCI_MOS"); 00347 nframes += scilss = cpl_frameset_count_tags(frameset, "MAPPED_SCI_LSS"); 00348 nframes += stdmxu = cpl_frameset_count_tags(frameset, "MAPPED_STD_MXU"); 00349 nframes += stdmos = cpl_frameset_count_tags(frameset, "MAPPED_STD_MOS"); 00350 nframes += stdlss = cpl_frameset_count_tags(frameset, "MAPPED_STD_LSS"); 00351 00352 if (nframes == 0) { 00353 fors_detect_objects_exit("Missing input scientific spectra"); 00354 } 00355 if (nframes > 1) { 00356 cpl_msg_error(recipe, "Too many input scientific spectra (%d > 1)", 00357 nframes); 00358 fors_detect_objects_exit(NULL); 00359 } 00360 00361 if (scimxu) { 00362 input_tag = "MAPPED_SCI_MXU"; 00363 outpt_tag = "OBJECT_TABLE_SCI_MXU"; 00364 slit_location_tag = "SLIT_LOCATION_MXU"; 00365 } 00366 else if (scimos) { 00367 input_tag = "MAPPED_SCI_MOS"; 00368 outpt_tag = "OBJECT_TABLE_SCI_MOS"; 00369 slit_location_tag = "SLIT_LOCATION_MOS"; 00370 } 00371 else if (scilss) { 00372 input_tag = "MAPPED_SCI_LSS"; 00373 outpt_tag = "OBJECT_TABLE_SCI_LSS"; 00374 slit_location_tag = "SLIT_LOCATION_LSS"; 00375 } 00376 else if (stdmxu) { 00377 input_tag = "MAPPED_STD_MXU"; 00378 outpt_tag = "OBJECT_TABLE_SCI_MXU"; 00379 slit_location_tag = "SLIT_LOCATION_MXU"; 00380 } 00381 else if (stdmos) { 00382 input_tag = "MAPPED_STD_MOS"; 00383 outpt_tag = "OBJECT_TABLE_SCI_MOS"; 00384 slit_location_tag = "SLIT_LOCATION_MOS"; 00385 } 00386 else if (stdlss) { 00387 input_tag = "MAPPED_STD_LSS"; 00388 outpt_tag = "OBJECT_TABLE_SCI_LSS"; 00389 slit_location_tag = "SLIT_LOCATION_LSS"; 00390 } 00391 00392 if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID")) 00393 fors_detect_objects_exit("Input frames are not from the same grism"); 00394 00395 if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID")) 00396 fors_detect_objects_exit("Input frames are not from the same filter"); 00397 00398 if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID")) 00399 fors_detect_objects_exit("Input frames are not from the same chip"); 00400 00401 header = dfs_load_header(frameset, input_tag, 0); 00402 if (header == NULL) 00403 fors_detect_objects_exit("Cannot load scientific frame header"); 00404 00405 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME"); 00406 if (instrume == NULL) 00407 fors_detect_objects_exit("Missing keyword INSTRUME in reference frame " 00408 "header"); 00409 00410 if (instrume[4] == '1') 00411 snprintf(version, 80, "%s/%s", "fors1", VERSION); 00412 if (instrume[4] == '2') 00413 snprintf(version, 80, "%s/%s", "fors2", VERSION); 00414 00415 gain = cpl_propertylist_get_double(header, "ESO DET OUT1 CONAD"); 00416 00417 cpl_propertylist_delete(header); header = NULL; 00418 00419 if (cpl_error_get_code() != CPL_ERROR_NONE) 00420 fors_detect_objects_exit("Missing keyword ESO DET OUT1 CONAD in " 00421 "scientific frame header"); 00422 00423 cpl_msg_info(recipe, "The gain factor is: %.2f e-/ADU", gain); 00424 00425 00426 cpl_msg_indent_less(); 00427 cpl_msg_info(recipe, "Load input frames..."); 00428 cpl_msg_indent_more(); 00429 00430 mapped = dfs_load_image(frameset, input_tag, CPL_TYPE_FLOAT, 0, 0); 00431 if (mapped == NULL) 00432 fors_detect_objects_exit("Cannot load input scientific frame"); 00433 00434 slits = dfs_load_table(frameset, slit_location_tag, 1); 00435 if (slits == NULL) 00436 fors_detect_objects_exit("Cannot load slits location table"); 00437 00438 cpl_msg_indent_less(); 00439 cpl_msg_info(recipe, "Object detection..."); 00440 cpl_msg_indent_more(); 00441 00442 mos_clean_cosmics(mapped, gain, -1., -1.); 00443 dummy = mos_detect_objects(mapped, slits, slit_margin, 00444 ext_radius, cont_radius); 00445 00446 cpl_image_delete(mapped); mapped = NULL; 00447 cpl_image_delete(dummy); dummy = NULL; 00448 00449 if (dfs_save_table(frameset, slits, outpt_tag, NULL, parlist, 00450 recipe, version)) 00451 fors_detect_objects_exit(NULL); 00452 00453 cpl_table_delete(slits); slits = NULL; 00454 00455 return 0; 00456 }