FORS Pipeline Reference Manual 4.9.20
|
00001 /* $Id: fors_subtract_sky_lss.c,v 1.4 2013/02/28 15:16:22 cgarcia 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: cgarcia $ 00023 * $Date: 2013/02/28 15:16:22 $ 00024 * $Revision: 1.4 $ 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_subtract_sky_lss_create(cpl_plugin *); 00038 static int fors_subtract_sky_lss_exec(cpl_plugin *); 00039 static int fors_subtract_sky_lss_destroy(cpl_plugin *); 00040 static int fors_subtract_sky_lss(cpl_parameterlist *, cpl_frameset *); 00041 00042 static char fors_subtract_sky_lss_description[] = 00043 "This recipe is used to subtract the sky from wavelength calibrated\n" 00044 "scientific spectra produced by the recipe fors_resample. A simple median\n" 00045 "signal level is subtracted from each image column.\n" 00046 "In the table below the MXU acronym can be read alternatively as MOS\n" 00047 "and LSS, depending on the instrument mode of the input data. The acronym\n" 00048 "SCI may be read STD in case of standard stars observations.\n" 00049 "Note that only LSS or LSS-like MOS/MXU data are to be processed by this\n" 00050 "recipe.\n\n" 00051 "Input files:\n\n" 00052 " DO category: Type: Explanation: Required:\n" 00053 " MAPPED_ALL_SCI_MXU Raw Scientific exposure Y\n\n" 00054 "Output files:\n\n" 00055 " DO category: Data type: Explanation:\n" 00056 " MAPPED_SCI_MXU FITS image Rectified scientific spectra\n" 00057 " MAPPED_SKY_SCI_MXU FITS image Rectified sky spectra\n\n"; 00058 00059 #define fors_subtract_sky_lss_exit(message) \ 00060 { \ 00061 if (message) cpl_msg_error(recipe, message); \ 00062 cpl_image_delete(skymap); \ 00063 cpl_image_delete(sky); \ 00064 cpl_image_delete(spectra); \ 00065 cpl_propertylist_delete(header); \ 00066 cpl_msg_indent_less(); \ 00067 return -1; \ 00068 } 00069 00070 00071 #define fors_subtract_sky_lss_exit_memcheck(message) \ 00072 { \ 00073 if (message) cpl_msg_info(recipe, message); \ 00074 cpl_image_delete(skymap); \ 00075 cpl_image_delete(sky); \ 00076 cpl_image_delete(spectra); \ 00077 cpl_propertylist_delete(header); \ 00078 cpl_msg_indent_less(); \ 00079 return 0; \ 00080 } 00081 00082 00094 int cpl_plugin_get_info(cpl_pluginlist *list) 00095 { 00096 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe ); 00097 cpl_plugin *plugin = &recipe->interface; 00098 00099 cpl_plugin_init(plugin, 00100 CPL_PLUGIN_API, 00101 FORS_BINARY_VERSION, 00102 CPL_PLUGIN_TYPE_RECIPE, 00103 "fors_subtract_sky_lss", 00104 "Subtract sky from calibrated long slit exposure", 00105 fors_subtract_sky_lss_description, 00106 "Carlo Izzo", 00107 PACKAGE_BUGREPORT, 00108 "This file is currently part of the FORS Instrument Pipeline\n" 00109 "Copyright (C) 2002-2010 European Southern Observatory\n\n" 00110 "This program is free software; you can redistribute it and/or modify\n" 00111 "it under the terms of the GNU General Public License as published by\n" 00112 "the Free Software Foundation; either version 2 of the License, or\n" 00113 "(at your option) any later version.\n\n" 00114 "This program is distributed in the hope that it will be useful,\n" 00115 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" 00116 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" 00117 "GNU General Public License for more details.\n\n" 00118 "You should have received a copy of the GNU General Public License\n" 00119 "along with this program; if not, write to the Free Software Foundation,\n" 00120 "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n", 00121 fors_subtract_sky_lss_create, 00122 fors_subtract_sky_lss_exec, 00123 fors_subtract_sky_lss_destroy); 00124 00125 cpl_pluginlist_append(list, plugin); 00126 00127 return 0; 00128 } 00129 00130 00141 static int fors_subtract_sky_lss_create(cpl_plugin *plugin) 00142 { 00143 cpl_recipe *recipe; 00144 /* Uncomment in case parameters are defined 00145 cpl_parameter *p; 00146 */ 00147 00148 /* 00149 * Check that the plugin is part of a valid recipe 00150 */ 00151 00152 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00153 recipe = (cpl_recipe *)plugin; 00154 else 00155 return -1; 00156 00157 /* 00158 * Create the parameters list in the cpl_recipe object 00159 */ 00160 00161 recipe->parameters = cpl_parameterlist_new(); 00162 00163 return 0; 00164 } 00165 00166 00175 static int fors_subtract_sky_lss_exec(cpl_plugin *plugin) 00176 { 00177 cpl_recipe *recipe; 00178 00179 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00180 recipe = (cpl_recipe *)plugin; 00181 else 00182 return -1; 00183 00184 return fors_subtract_sky_lss(recipe->parameters, recipe->frames); 00185 } 00186 00187 00196 static int fors_subtract_sky_lss_destroy(cpl_plugin *plugin) 00197 { 00198 cpl_recipe *recipe; 00199 00200 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00201 recipe = (cpl_recipe *)plugin; 00202 else 00203 return -1; 00204 00205 cpl_parameterlist_delete(recipe->parameters); 00206 00207 return 0; 00208 } 00209 00210 00220 static int fors_subtract_sky_lss(cpl_parameterlist *parlist, 00221 cpl_frameset *frameset) 00222 { 00223 00224 const char *recipe = "fors_subtract_sky_lss"; 00225 00226 00227 /* 00228 * Input parameters (none) 00229 */ 00230 00231 /* 00232 * CPL objects 00233 */ 00234 00235 cpl_image *spectra = NULL; 00236 cpl_image *skymap = NULL; 00237 cpl_image *sky = NULL; 00238 cpl_table *maskslits = NULL; 00239 00240 cpl_propertylist *header = NULL; 00241 00242 /* 00243 * Auxiliary variables 00244 */ 00245 00246 char version[80]; 00247 char *instrume = NULL; 00248 const char *mapped_science_tag; 00249 const char *mapped_science_sky_tag; 00250 const char *mapped_sky_tag; 00251 int mxu, mos, lss; 00252 int treat_as_lss = 0; 00253 int nslits; 00254 int nscience; 00255 double *xpos; 00256 double mxpos; 00257 int nx, ny; 00258 int standard; 00259 float *data; 00260 float *sdata; 00261 int i, j; 00262 00263 00264 snprintf(version, 80, "%s-%s", PACKAGE, PACKAGE_VERSION); 00265 00266 cpl_msg_set_indentation(2); 00267 00268 if (dfs_files_dont_exist(frameset)) 00269 fors_subtract_sky_lss_exit(NULL); 00270 00271 00272 /* 00273 * Get configuration parameters (none) 00274 */ 00275 00276 /* 00277 * Check input set-of-frames 00278 */ 00279 00280 cpl_msg_indent_less(); 00281 cpl_msg_info(recipe, "Check input set-of-frames:"); 00282 cpl_msg_indent_more(); 00283 00284 mxu = cpl_frameset_count_tags(frameset, "MAPPED_ALL_SCI_MXU"); 00285 mos = cpl_frameset_count_tags(frameset, "MAPPED_ALL_SCI_MOS"); 00286 lss = cpl_frameset_count_tags(frameset, "MAPPED_ALL_SCI_LSS"); 00287 standard = 0; 00288 00289 if (mxu + mos + lss == 0) { 00290 mxu = cpl_frameset_count_tags(frameset, "MAPPED_ALL_STD_MXU"); 00291 mos = cpl_frameset_count_tags(frameset, "MAPPED_ALL_STD_MOS"); 00292 lss = cpl_frameset_count_tags(frameset, "MAPPED_ALL_STD_LSS"); 00293 standard = 1; 00294 } 00295 00296 if (mxu + mos + lss == 0) 00297 fors_subtract_sky_lss_exit("Missing input scientific frame"); 00298 00299 nscience = mxu + mos + lss; 00300 00301 if (nscience > 1) 00302 fors_subtract_sky_lss_exit("More than one scientific frame in input"); 00303 00304 if (mxu) { 00305 if (standard) { 00306 cpl_msg_info(recipe, "MXU data found"); 00307 mapped_science_tag = "MAPPED_STD_MXU"; 00308 mapped_science_sky_tag = "MAPPED_ALL_STD_MXU"; 00309 mapped_sky_tag = "MAPPED_SKY_STD_MXU"; 00310 } 00311 else { 00312 cpl_msg_info(recipe, "MXU data found"); 00313 mapped_science_tag = "MAPPED_SCI_MXU"; 00314 mapped_science_sky_tag = "MAPPED_ALL_SCI_MXU"; 00315 mapped_sky_tag = "MAPPED_SKY_SCI_MXU"; 00316 } 00317 } 00318 00319 if (lss) { 00320 if (standard) { 00321 cpl_msg_info(recipe, "LSS data found"); 00322 mapped_science_tag = "MAPPED_STD_LSS"; 00323 mapped_science_sky_tag = "MAPPED_ALL_STD_LSS"; 00324 mapped_sky_tag = "MAPPED_SKY_STD_LSS"; 00325 } 00326 else { 00327 cpl_msg_info(recipe, "LSS data found"); 00328 mapped_science_tag = "MAPPED_SCI_LSS"; 00329 mapped_science_sky_tag = "MAPPED_ALL_SCI_LSS"; 00330 mapped_sky_tag = "MAPPED_SKY_SCI_LSS"; 00331 } 00332 } 00333 00334 if (mos) { 00335 if (standard) { 00336 cpl_msg_info(recipe, "MOS data found"); 00337 mapped_science_tag = "MAPPED_STD_MOS"; 00338 mapped_science_sky_tag = "MAPPED_ALL_STD_MOS"; 00339 mapped_sky_tag = "MAPPED_SKY_STD_MOS"; 00340 } 00341 else { 00342 cpl_msg_info(recipe, "MOS data found"); 00343 mapped_science_tag = "MAPPED_SCI_MOS"; 00344 mapped_science_sky_tag = "MAPPED_ALL_SCI_MOS"; 00345 mapped_sky_tag = "MAPPED_SKY_SCI_MOS"; 00346 } 00347 } 00348 00349 /* 00350 * Loading input data 00351 */ 00352 00353 cpl_msg_info(recipe, "Load mapped scientific exposure..."); 00354 cpl_msg_indent_more(); 00355 00356 spectra = dfs_load_image(frameset, mapped_science_sky_tag, 00357 CPL_TYPE_FLOAT, 0, 0); 00358 00359 if (spectra == NULL) 00360 fors_subtract_sky_lss_exit("Cannot load input frame"); 00361 00362 header = dfs_load_header(frameset, mapped_science_sky_tag, 0); 00363 00364 if (header == NULL) 00365 fors_subtract_sky_lss_exit("Cannot load input frame header"); 00366 00367 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME"); 00368 if (instrume == NULL) 00369 fors_subtract_sky_lss_exit("Missing keyword INSTRUME in scientific header"); 00370 instrume = cpl_strdup(instrume); 00371 00372 if (instrume[4] == '1') 00373 snprintf(version, 80, "%s/%s", "fors1", VERSION); 00374 if (instrume[4] == '2') 00375 snprintf(version, 80, "%s/%s", "fors2", VERSION); 00376 00377 cpl_free(instrume); instrume = NULL; 00378 00379 cpl_msg_indent_less(); 00380 00381 if (mos || mxu) { 00382 int nslits_out_det = 0; 00383 00384 if (mos) 00385 maskslits = mos_load_slits_fors_mos(header, &nslits_out_det); 00386 else 00387 maskslits = mos_load_slits_fors_mxu(header); 00388 00389 /* 00390 * Check if all slits have the same X offset: in such case, 00391 * treat the observation as a long-slit one! 00392 */ 00393 00394 treat_as_lss = fors_mos_is_lss_like(maskslits, nslits_out_det); 00395 00396 cpl_table_delete(maskslits); maskslits = NULL; 00397 00398 if (treat_as_lss) 00399 cpl_msg_info(recipe, "All MOS slits have the same offset: %.2f\n" 00400 "The LSS data reduction strategy is applied.", 00401 mxpos); 00402 else 00403 fors_subtract_sky_lss_exit("This recipe can only be used " 00404 "with LSS-like data"); 00405 } 00406 00407 nx = cpl_image_get_size_x(spectra); 00408 ny = cpl_image_get_size_y(spectra); 00409 00410 skymap = cpl_image_new(nx, ny, CPL_TYPE_FLOAT); 00411 sky = cpl_image_collapse_median_create(spectra, 0, 0, 1); 00412 00413 data = cpl_image_get_data(skymap); 00414 00415 for (i = 0; i < ny; i++) { 00416 sdata = cpl_image_get_data(sky); 00417 for (j = 0; j < nx; j++) { 00418 *data++ = *sdata++; 00419 } 00420 } 00421 00422 cpl_image_delete(sky); sky = NULL; 00423 cpl_image_subtract(spectra, skymap); 00424 00425 if (dfs_save_image(frameset, skymap, mapped_sky_tag, header, 00426 parlist, recipe, version)) 00427 fors_subtract_sky_lss_exit(NULL); 00428 00429 cpl_image_delete(skymap); skymap = NULL; 00430 00431 if (dfs_save_image(frameset, spectra, mapped_science_tag, header, 00432 parlist, recipe, version)) 00433 fors_subtract_sky_lss_exit(NULL); 00434 00435 cpl_image_delete(spectra); spectra = NULL; 00436 00437 cpl_propertylist_delete(header); header = NULL; 00438 00439 if (cpl_error_get_code()) { 00440 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message()); 00441 fors_subtract_sky_lss_exit(NULL); 00442 } 00443 else 00444 return 0; 00445 }