FORS Pipeline Reference Manual 4.9.9
|
00001 /* $Id: fors_flatfield.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_flatfield_create(cpl_plugin *); 00038 static int fors_flatfield_exec(cpl_plugin *); 00039 static int fors_flatfield_destroy(cpl_plugin *); 00040 static int fors_flatfield(cpl_parameterlist *, cpl_frameset *); 00041 00042 static char fors_flatfield_description[] = 00043 "This recipe is used to divide the input frame by the normalised flat\n" 00044 "field frame produced by recipe fors_normalise_flat. The input frame must\n" 00045 "be already bias subtracted (e.g., by recipe fors_remove_bias).\n" 00046 "In the table below the MXU acronym can be alternatively read as MOS and\n" 00047 "LSS.\n\n" 00048 "Input files:\n\n" 00049 " DO category: Type: Explanation: Required:\n" 00050 " SCIENCE_UNBIAS_MXU\n" 00051 " or STANDARD_UNBIAS_MXU Raw Bias subtracted frame Y\n" 00052 " MASTER_NORM_FLAT_MXU Calib Normalised flat frame Y\n\n" 00053 "Output files:\n\n" 00054 " DO category: Data type: Explanation:\n" 00055 " SCIENCE_UNFLAT_MXU\n" 00056 " or STANDARD_UNFLAT_MXU FITS image Flat field corrected frame\n\n"; 00057 00058 #define fors_flatfield_exit(message) \ 00059 { \ 00060 if (message) cpl_msg_error(recipe, message); \ 00061 cpl_image_delete(raw_image); \ 00062 cpl_image_delete(norm_flat); \ 00063 cpl_propertylist_delete(header); \ 00064 cpl_msg_indent_less(); \ 00065 return -1; \ 00066 } 00067 00068 #define fors_flatfield_exit_memcheck(message) \ 00069 { \ 00070 if (message) cpl_msg_info(recipe, message); \ 00071 printf("free raw_image (%p)\n", raw_image); \ 00072 cpl_image_delete(raw_image); \ 00073 printf("free norm_flat (%p)\n", norm_flat); \ 00074 cpl_image_delete(norm_flat); \ 00075 printf("free header (%p)\n", header); \ 00076 cpl_propertylist_delete(header); \ 00077 cpl_msg_indent_less(); \ 00078 return 0; \ 00079 } 00080 00081 00093 int cpl_plugin_get_info(cpl_pluginlist *list) 00094 { 00095 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe ); 00096 cpl_plugin *plugin = &recipe->interface; 00097 00098 cpl_plugin_init(plugin, 00099 CPL_PLUGIN_API, 00100 FORS_BINARY_VERSION, 00101 CPL_PLUGIN_TYPE_RECIPE, 00102 "fors_flatfield", 00103 "Flat field correction of input frame", 00104 fors_flatfield_description, 00105 "Carlo Izzo", 00106 PACKAGE_BUGREPORT, 00107 "This file is currently part of the FORS Instrument Pipeline\n" 00108 "Copyright (C) 2002-2010 European Southern Observatory\n\n" 00109 "This program is free software; you can redistribute it and/or modify\n" 00110 "it under the terms of the GNU General Public License as published by\n" 00111 "the Free Software Foundation; either version 2 of the License, or\n" 00112 "(at your option) any later version.\n\n" 00113 "This program is distributed in the hope that it will be useful,\n" 00114 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" 00115 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" 00116 "GNU General Public License for more details.\n\n" 00117 "You should have received a copy of the GNU General Public License\n" 00118 "along with this program; if not, write to the Free Software Foundation,\n" 00119 "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n", 00120 fors_flatfield_create, 00121 fors_flatfield_exec, 00122 fors_flatfield_destroy); 00123 00124 cpl_pluginlist_append(list, plugin); 00125 00126 return 0; 00127 } 00128 00129 00140 static int fors_flatfield_create(cpl_plugin *plugin) 00141 { 00142 cpl_recipe *recipe; 00143 /* Uncomment in case parameters are defined 00144 cpl_parameter *p; 00145 */ 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 return 0; 00163 } 00164 00165 00174 static int fors_flatfield_exec(cpl_plugin *plugin) 00175 { 00176 cpl_recipe *recipe; 00177 00178 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00179 recipe = (cpl_recipe *)plugin; 00180 else 00181 return -1; 00182 00183 return fors_flatfield(recipe->parameters, recipe->frames); 00184 } 00185 00186 00195 static int fors_flatfield_destroy(cpl_plugin *plugin) 00196 { 00197 cpl_recipe *recipe; 00198 00199 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00200 recipe = (cpl_recipe *)plugin; 00201 else 00202 return -1; 00203 00204 cpl_parameterlist_delete(recipe->parameters); 00205 00206 return 0; 00207 } 00208 00209 00219 static int fors_flatfield(cpl_parameterlist *parlist, cpl_frameset *frameset) 00220 { 00221 00222 const char *recipe = "fors_flatfield"; 00223 00224 00225 /* 00226 * CPL objects 00227 */ 00228 00229 cpl_image *raw_image = NULL; 00230 cpl_image *norm_flat = NULL; 00231 cpl_propertylist *header = NULL; 00232 00233 /* 00234 * Auxiliary variables 00235 */ 00236 00237 char version[80]; 00238 const char *norm_flat_tag; 00239 const char *raw_image_tag; 00240 const char *pro_image_tag; 00241 char *instrume = NULL; 00242 int science_mxu; 00243 int science_mos; 00244 int science_lss; 00245 int standard_mxu; 00246 int standard_mos; 00247 int standard_lss; 00248 int nflat, nframe; 00249 00250 00251 cpl_msg_set_indentation(2); 00252 00253 if (dfs_files_dont_exist(frameset)) 00254 fors_flatfield_exit(NULL); 00255 00256 00257 cpl_msg_info(recipe, "Check input set-of-frames:"); 00258 cpl_msg_indent_more(); 00259 00260 nframe = science_mxu = cpl_frameset_count_tags(frameset, 00261 "SCIENCE_UNBIAS_MXU"); 00262 nframe += science_mos = cpl_frameset_count_tags(frameset, 00263 "SCIENCE_UNBIAS_MOS"); 00264 nframe += science_lss = cpl_frameset_count_tags(frameset, 00265 "SCIENCE_UNBIAS_LSS"); 00266 nframe += standard_mxu = cpl_frameset_count_tags(frameset, 00267 "STANDARD_UNBIAS_MXU"); 00268 nframe += standard_mos = cpl_frameset_count_tags(frameset, 00269 "STANDARD_UNBIAS_MOS"); 00270 nframe += standard_lss = cpl_frameset_count_tags(frameset, 00271 "STANDARD_UNBIAS_LSS"); 00272 00273 if (nframe == 0) { 00274 fors_flatfield_exit("Missing required input scientific frame"); 00275 } 00276 if (nframe > 1) { 00277 cpl_msg_error(recipe, "Too many input scientific frames (%d > 1)", 00278 nframe); 00279 fors_flatfield_exit(NULL); 00280 } 00281 00282 if (science_mxu) { 00283 norm_flat_tag = "MASTER_NORM_FLAT_MXU"; 00284 pro_image_tag = "SCIENCE_UNFLAT_MXU"; 00285 raw_image_tag = "SCIENCE_UNBIAS_MXU"; 00286 } 00287 else if (science_mos) { 00288 norm_flat_tag = "MASTER_NORM_FLAT_MOS"; 00289 pro_image_tag = "SCIENCE_UNFLAT_MOS"; 00290 raw_image_tag = "SCIENCE_UNBIAS_MOS"; 00291 } 00292 else if (science_lss) { 00293 norm_flat_tag = "MASTER_NORM_FLAT_LSS"; 00294 pro_image_tag = "SCIENCE_UNFLAT_LSS"; 00295 raw_image_tag = "SCIENCE_UNBIAS_LSS"; 00296 } 00297 else if (standard_mxu) { 00298 norm_flat_tag = "MASTER_NORM_FLAT_MXU"; 00299 pro_image_tag = "STANDARD_UNFLAT_MXU"; 00300 raw_image_tag = "STANDARD_UNBIAS_MXU"; 00301 } 00302 else if (standard_mos) { 00303 norm_flat_tag = "MASTER_NORM_FLAT_MOS"; 00304 pro_image_tag = "STANDARD_UNFLAT_MOS"; 00305 raw_image_tag = "STANDARD_UNBIAS_MOS"; 00306 } 00307 else if (standard_lss) { 00308 norm_flat_tag = "MASTER_NORM_FLAT_LSS"; 00309 pro_image_tag = "STANDARD_UNFLAT_LSS"; 00310 raw_image_tag = "STANDARD_UNBIAS_LSS"; 00311 } 00312 00313 nflat = cpl_frameset_count_tags(frameset, norm_flat_tag); 00314 if (nflat == 0) { 00315 cpl_msg_error(recipe, "Missing required input: %s", norm_flat_tag); 00316 fors_flatfield_exit(NULL); 00317 } 00318 if (nflat > 1) { 00319 cpl_msg_error(recipe, "Too many in input (%d > 1): %s", 00320 nflat, norm_flat_tag); 00321 fors_flatfield_exit(NULL); 00322 } 00323 00324 if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID")) 00325 fors_flatfield_exit("Input frames are not from the same grism"); 00326 00327 if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID")) 00328 fors_flatfield_exit("Input frames are not from the same filter"); 00329 00330 if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID")) 00331 fors_flatfield_exit("Input frames are not from the same chip"); 00332 00333 header = dfs_load_header(frameset, raw_image_tag, 0); 00334 00335 if (header == NULL) { 00336 cpl_msg_error(recipe, "Cannot load header of %s frame", raw_image_tag); 00337 fors_flatfield_exit(NULL); 00338 } 00339 00340 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME"); 00341 if (instrume == NULL) { 00342 cpl_msg_error(recipe, "Missing keyword INSTRUME in %s header", 00343 raw_image_tag); 00344 fors_flatfield_exit(NULL); 00345 } 00346 00347 if (instrume[4] == '1') 00348 snprintf(version, 80, "%s/%s", "fors1", VERSION); 00349 if (instrume[4] == '2') 00350 snprintf(version, 80, "%s/%s", "fors2", VERSION); 00351 00352 cpl_msg_indent_less(); 00353 cpl_msg_info(recipe, "Load input frames:"); 00354 cpl_msg_indent_more(); 00355 00356 norm_flat = dfs_load_image(frameset, norm_flat_tag, CPL_TYPE_FLOAT, 0, 1); 00357 if (norm_flat == NULL) 00358 fors_flatfield_exit("Cannot load normalised flat field"); 00359 00360 raw_image = dfs_load_image(frameset, raw_image_tag, CPL_TYPE_FLOAT, 0, 0); 00361 if (raw_image == NULL) { 00362 cpl_msg_error(recipe, "Cannot load %s frame", raw_image_tag); 00363 fors_flatfield_exit(NULL); 00364 } 00365 00366 cpl_msg_indent_less(); 00367 cpl_msg_info(recipe, "Divide input %s by flat field...", raw_image_tag); 00368 cpl_msg_indent_more(); 00369 00370 if (cpl_image_divide(raw_image, norm_flat) != CPL_ERROR_NONE) { 00371 cpl_msg_error(recipe, "Failure of flat field correction: %s", 00372 cpl_error_get_message()); 00373 fors_flatfield_exit(NULL); 00374 } 00375 cpl_image_delete(norm_flat); norm_flat = NULL; 00376 00377 cpl_msg_indent_less(); 00378 00379 if (dfs_save_image(frameset, raw_image, pro_image_tag, 00380 header, parlist, recipe, version)) 00381 fors_flatfield_exit(NULL); 00382 00383 cpl_propertylist_delete(header); header = NULL; 00384 cpl_image_delete(raw_image); raw_image = NULL; 00385 00386 return 0; 00387 }