FORS Pipeline Reference Manual 4.9.20
|
00001 /* $Id: fors_subtract_sky.c,v 1.7 2013/02/28 15:16:34 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:34 $ 00024 * $Revision: 1.7 $ 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_create(cpl_plugin *); 00038 static int fors_subtract_sky_exec(cpl_plugin *); 00039 static int fors_subtract_sky_destroy(cpl_plugin *); 00040 static int fors_subtract_sky(cpl_parameterlist *, cpl_frameset *); 00041 00042 static char fors_subtract_sky_description[] = 00043 "This recipe is used to subtract the sky emission from unrebinned slit\n" 00044 "spectra. This is obtained by robust fitting (i.e., excluding the signal\n" 00045 "from possible point-like objects in slit) of the emission along the CCD\n" 00046 "columns within each spectrum). This method doesn't work if extended\n" 00047 "objects are in slit (it really destroys the object spectra), and is\n" 00048 "not applicable to LSS data. The input scientific frames are produced\n" 00049 "by the recipes fors_remove_bias and fors_flatfield.\n" 00050 "\n" 00051 "This recipe cannot be applied to LSS or long-slit like data (MOS/MXU with\n" 00052 "all slits at the same offset). No automatic recipe is available for this.\n" 00053 "Please refer to the FORS Pipeline User's Manual for more details.\n" 00054 "\n" 00055 "In the table below the MXU acronym can be alternatively read as MOS, and\n" 00056 "SCI as STD.\n\n" 00057 "Input files:\n\n" 00058 " DO category: Type: Explanation: Required:\n" 00059 " SCIENCE_UNBIAS_MXU\n" 00060 " or SCIENCE_UNFLAT_MXU\n" 00061 " or STANDARD_UNBIAS_MXU\n" 00062 " or STANDARD_UNFLAT_MXU Calib Frame with sky lines Y\n" 00063 " CURV_COEFF_MXU Calib Spectral curvature Y\n" 00064 " SLIT_LOCATION_MXU Calib Slit location on CCD Y\n" 00065 " GRISM_TABLE Calib Grism table .\n\n" 00066 "Output files:\n\n" 00067 " DO category: Data type: Explanation:\n" 00068 " UNMAPPED_SCI_MXU\n" 00069 " or UNMAPPED_STD_MXU FITS image Sky subtracted scientific frame\n" 00070 " UNMAPPED_SKY_SCI_MXU\n" 00071 " or UNMAPPED_SKY_STD_MXU FITS image Subtracted sky frame\n\n"; 00072 00073 #define fors_subtract_sky_exit(message) \ 00074 { \ 00075 if (message) cpl_msg_error(recipe, message); \ 00076 cpl_image_delete(spectra); \ 00077 cpl_image_delete(skymap); \ 00078 cpl_table_delete(grism_table); \ 00079 cpl_table_delete(maskslits); \ 00080 cpl_table_delete(slits); \ 00081 cpl_table_delete(polytraces); \ 00082 cpl_propertylist_delete(header); \ 00083 cpl_msg_indent_less(); \ 00084 return -1; \ 00085 } 00086 00087 #define fors_subtract_sky_exit_memcheck(message) \ 00088 { \ 00089 if (message) cpl_msg_info(recipe, message); \ 00090 printf("free spectra (%p)\n", spectra); \ 00091 cpl_image_delete(spectra); \ 00092 printf("free skymap (%p)\n", skymap); \ 00093 cpl_image_delete(skymap); \ 00094 printf("free grism_table (%p)\n", grism_table); \ 00095 cpl_table_delete(grism_table); \ 00096 printf("free maskslits (%p)\n", maskslits); \ 00097 cpl_table_delete(maskslits); \ 00098 printf("free slits (%p)\n", slits); \ 00099 cpl_table_delete(slits); \ 00100 printf("free polytraces (%p)\n", polytraces); \ 00101 cpl_table_delete(polytraces); \ 00102 printf("free header (%p)\n", header); \ 00103 cpl_propertylist_delete(header); \ 00104 cpl_msg_indent_less(); \ 00105 return 0; \ 00106 } 00107 00108 00120 int cpl_plugin_get_info(cpl_pluginlist *list) 00121 { 00122 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe ); 00123 cpl_plugin *plugin = &recipe->interface; 00124 00125 cpl_plugin_init(plugin, 00126 CPL_PLUGIN_API, 00127 FORS_BINARY_VERSION, 00128 CPL_PLUGIN_TYPE_RECIPE, 00129 "fors_subtract_sky", 00130 "Subtract sky from scientific spectra", 00131 fors_subtract_sky_description, 00132 "Carlo Izzo", 00133 PACKAGE_BUGREPORT, 00134 "This file is currently part of the FORS Instrument Pipeline\n" 00135 "Copyright (C) 2002-2010 European Southern Observatory\n\n" 00136 "This program is free software; you can redistribute it and/or modify\n" 00137 "it under the terms of the GNU General Public License as published by\n" 00138 "the Free Software Foundation; either version 2 of the License, or\n" 00139 "(at your option) any later version.\n\n" 00140 "This program is distributed in the hope that it will be useful,\n" 00141 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" 00142 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" 00143 "GNU General Public License for more details.\n\n" 00144 "You should have received a copy of the GNU General Public License\n" 00145 "along with this program; if not, write to the Free Software Foundation,\n" 00146 "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n", 00147 fors_subtract_sky_create, 00148 fors_subtract_sky_exec, 00149 fors_subtract_sky_destroy); 00150 00151 cpl_pluginlist_append(list, plugin); 00152 00153 return 0; 00154 } 00155 00156 00167 static int fors_subtract_sky_create(cpl_plugin *plugin) 00168 { 00169 cpl_recipe *recipe; 00170 cpl_parameter *p; 00171 00172 /* 00173 * Check that the plugin is part of a valid recipe 00174 */ 00175 00176 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00177 recipe = (cpl_recipe *)plugin; 00178 else 00179 return -1; 00180 00181 /* 00182 * Create the (empty) parameters list in the cpl_recipe object 00183 */ 00184 00185 recipe->parameters = cpl_parameterlist_new(); 00186 00187 /* 00188 * Dispersion 00189 */ 00190 00191 p = cpl_parameter_new_value("fors.fors_subtract_sky.dispersion", 00192 CPL_TYPE_DOUBLE, 00193 "Expected spectral dispersion (Angstrom/pixel)", 00194 "fors.fors_subtract_sky", 00195 0.0); 00196 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dispersion"); 00197 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00198 cpl_parameterlist_append(recipe->parameters, p); 00199 00200 /* 00201 * Start wavelength for spectral extraction 00202 */ 00203 00204 p = cpl_parameter_new_value("fors.fors_subtract_sky.startwavelength", 00205 CPL_TYPE_DOUBLE, 00206 "Start wavelength in spectral extraction", 00207 "fors.fors_subtract_sky", 00208 0.0); 00209 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "startwavelength"); 00210 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00211 cpl_parameterlist_append(recipe->parameters, p); 00212 00213 /* 00214 * End wavelength for spectral extraction 00215 */ 00216 00217 p = cpl_parameter_new_value("fors.fors_subtract_sky.endwavelength", 00218 CPL_TYPE_DOUBLE, 00219 "End wavelength in spectral extraction", 00220 "fors.fors_subtract_sky", 00221 0.0); 00222 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "endwavelength"); 00223 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00224 cpl_parameterlist_append(recipe->parameters, p); 00225 00226 /* 00227 * Cosmic rays removal 00228 */ 00229 00230 p = cpl_parameter_new_value("fors.fors_subtract_sky.cosmics", 00231 CPL_TYPE_BOOL, 00232 "Eliminate cosmic rays hits", 00233 "fors.fors_subtract_sky", 00234 FALSE); 00235 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "cosmics"); 00236 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00237 cpl_parameterlist_append(recipe->parameters, p); 00238 00239 return 0; 00240 } 00241 00242 00251 static int fors_subtract_sky_exec(cpl_plugin *plugin) 00252 { 00253 cpl_recipe *recipe; 00254 00255 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00256 recipe = (cpl_recipe *)plugin; 00257 else 00258 return -1; 00259 00260 return fors_subtract_sky(recipe->parameters, recipe->frames); 00261 } 00262 00263 00272 static int fors_subtract_sky_destroy(cpl_plugin *plugin) 00273 { 00274 cpl_recipe *recipe; 00275 00276 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00277 recipe = (cpl_recipe *)plugin; 00278 else 00279 return -1; 00280 00281 cpl_parameterlist_delete(recipe->parameters); 00282 00283 return 0; 00284 } 00285 00286 00296 static int fors_subtract_sky(cpl_parameterlist *parlist, 00297 cpl_frameset *frameset) 00298 { 00299 00300 const char *recipe = "fors_subtract_sky"; 00301 00302 00303 /* 00304 * Input parameters 00305 */ 00306 00307 double dispersion; 00308 double startwavelength; 00309 double endwavelength; 00310 int cosmics; 00311 00312 /* 00313 * CPL objects 00314 */ 00315 00316 cpl_image *spectra = NULL; 00317 cpl_image *skymap = NULL; 00318 cpl_table *grism_table = NULL; 00319 cpl_table *polytraces = NULL; 00320 cpl_table *slits = NULL; 00321 cpl_table *maskslits = NULL; 00322 cpl_propertylist *header = NULL; 00323 00324 /* 00325 * Auxiliary variables 00326 */ 00327 00328 char version[80]; 00329 const char *slit_location_tag; 00330 const char *input_tag; 00331 const char *curv_coeff_tag; 00332 const char *unmapped_tag; 00333 const char *unmapped_sky_tag; 00334 int nframes; 00335 int rebin; 00336 int nslits; 00337 int treat_as_lss; 00338 int i; 00339 double reference; 00340 double gain; 00341 double *xpos; 00342 double mxpos; 00343 int mxu, mos, lss; 00344 int rec_scib; 00345 int rec_stdb; 00346 int rec_scif; 00347 int rec_stdf; 00348 int nslits_out_det = 0; 00349 00350 char *instrume = NULL; 00351 00352 00353 cpl_msg_set_indentation(2); 00354 00355 if (dfs_files_dont_exist(frameset)) 00356 fors_subtract_sky_exit(NULL); 00357 00358 00359 /* 00360 * Get configuration parameters 00361 */ 00362 00363 cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe); 00364 cpl_msg_indent_more(); 00365 00366 if (cpl_frameset_count_tags(frameset, "GRISM_TABLE") > 1) 00367 fors_subtract_sky_exit("Too many in input: GRISM_TABLE"); 00368 00369 grism_table = dfs_load_table(frameset, "GRISM_TABLE", 1); 00370 00371 dispersion = dfs_get_parameter_double(parlist, 00372 "fors.fors_subtract_sky.dispersion", grism_table); 00373 00374 if (dispersion <= 0.0) 00375 fors_subtract_sky_exit("Invalid spectral dispersion value"); 00376 00377 startwavelength = dfs_get_parameter_double(parlist, 00378 "fors.fors_subtract_sky.startwavelength", grism_table); 00379 if (startwavelength > 1.0) 00380 if (startwavelength < 3000.0 || startwavelength > 13000.0) 00381 fors_subtract_sky_exit("Invalid wavelength"); 00382 00383 endwavelength = dfs_get_parameter_double(parlist, 00384 "fors.fors_subtract_sky.endwavelength", grism_table); 00385 if (endwavelength > 1.0) { 00386 if (endwavelength < 3000.0 || endwavelength > 13000.0) 00387 fors_subtract_sky_exit("Invalid wavelength"); 00388 if (startwavelength < 1.0) 00389 fors_subtract_sky_exit("Invalid wavelength interval"); 00390 } 00391 00392 if (startwavelength > 1.0) 00393 if (endwavelength - startwavelength <= 0.0) 00394 fors_subtract_sky_exit("Invalid wavelength interval"); 00395 00396 cosmics = dfs_get_parameter_bool(parlist, 00397 "fors.fors_subtract_sky.cosmics", NULL); 00398 00399 cpl_table_delete(grism_table); grism_table = NULL; 00400 00401 if (cpl_error_get_code()) 00402 fors_subtract_sky_exit("Failure reading the configuration parameters"); 00403 00404 00405 cpl_msg_indent_less(); 00406 cpl_msg_info(recipe, "Check input set-of-frames:"); 00407 cpl_msg_indent_more(); 00408 00409 mxu = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_MXU"); 00410 mos = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_MOS"); 00411 lss = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_LSS"); 00412 00413 if (lss) 00414 fors_subtract_sky_exit("Use this recipe just with MOS/MXU data."); 00415 00416 nframes = mos + mxu; 00417 00418 if (nframes == 0) { 00419 fors_subtract_sky_exit("Missing input slit location table"); 00420 } 00421 if (nframes > 1) { 00422 cpl_msg_error(recipe, 00423 "Too many input slit location tables (%d > 1)", nframes); 00424 fors_subtract_sky_exit(NULL); 00425 } 00426 00427 if (mxu) 00428 curv_coeff_tag = "CURV_COEFF_MXU"; 00429 else 00430 curv_coeff_tag = "CURV_COEFF_MXU"; 00431 00432 00433 nframes = cpl_frameset_count_tags(frameset, curv_coeff_tag); 00434 00435 if (nframes == 0) { 00436 cpl_msg_error(recipe, "Missing input %s", curv_coeff_tag); 00437 fors_subtract_sky_exit(NULL); 00438 } 00439 if (nframes > 1) { 00440 cpl_msg_error(recipe, "Too many input %s (%d > 1)", curv_coeff_tag, 00441 nframes); 00442 fors_subtract_sky_exit(NULL); 00443 } 00444 00445 if (mxu) { 00446 rec_scib = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_MXU"); 00447 rec_stdb = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_MXU"); 00448 rec_scif = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_MXU"); 00449 rec_stdf = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_MXU"); 00450 } 00451 else { 00452 rec_scib = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_MOS"); 00453 rec_stdb = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_MOS"); 00454 rec_scif = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_MOS"); 00455 rec_stdf = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_MOS"); 00456 } 00457 00458 nframes = rec_scib + rec_stdb + rec_scif + rec_stdf; 00459 00460 if (nframes == 0) { 00461 fors_subtract_sky_exit("Missing input scientific spectra"); 00462 } 00463 if (nframes > 1) { 00464 cpl_msg_error(recipe, "Too many input scientific spectra (%d > 1)", 00465 nframes); 00466 fors_subtract_sky_exit(NULL); 00467 } 00468 00469 if (rec_scib) { 00470 if (mxu) { 00471 input_tag = "SCIENCE_UNBIAS_MXU"; 00472 slit_location_tag = "SLIT_LOCATION_MXU"; 00473 unmapped_tag = "UNMAPPED_SCI_MXU"; 00474 unmapped_sky_tag = "UNMAPPED_SKY_SCI_MXU"; 00475 } 00476 else { 00477 input_tag = "SCIENCE_UNBIAS_MOS"; 00478 slit_location_tag = "SLIT_LOCATION_MOS"; 00479 unmapped_tag = "UNMAPPED_SCI_MOS"; 00480 unmapped_sky_tag = "UNMAPPED_SKY_SCI_MOS"; 00481 } 00482 } 00483 else if (rec_stdb) { 00484 if (mxu) { 00485 input_tag = "STANDARD_UNBIAS_MXU"; 00486 slit_location_tag = "SLIT_LOCATION_MXU"; 00487 unmapped_tag = "UNMAPPED_STD_MXU"; 00488 unmapped_sky_tag = "UNMAPPED_SKY_STD_MXU"; 00489 } 00490 else { 00491 input_tag = "STANDARD_UNBIAS_MOS"; 00492 slit_location_tag = "SLIT_LOCATION_MOS"; 00493 unmapped_tag = "UNMAPPED_STD_MOS"; 00494 unmapped_sky_tag = "UNMAPPED_SKY_STD_MOS"; 00495 } 00496 } 00497 else if (rec_scif) { 00498 if (mxu) { 00499 input_tag = "SCIENCE_UNFLAT_MXU"; 00500 slit_location_tag = "SLIT_LOCATION_MXU"; 00501 unmapped_tag = "UNMAPPED_SCI_MXU"; 00502 unmapped_sky_tag = "UNMAPPED_SKY_SCI_MXU"; 00503 } 00504 else { 00505 input_tag = "SCIENCE_UNFLAT_MOS"; 00506 slit_location_tag = "SLIT_LOCATION_MOS"; 00507 unmapped_tag = "UNMAPPED_SCI_MOS"; 00508 unmapped_sky_tag = "UNMAPPED_SKY_SCI_MOS"; 00509 } 00510 } 00511 else if (rec_stdf) { 00512 if (mxu) { 00513 input_tag = "STANDARD_UNFLAT_MXU"; 00514 slit_location_tag = "SLIT_LOCATION_MXU"; 00515 unmapped_tag = "UNMAPPED_STD_MXU"; 00516 unmapped_sky_tag = "UNMAPPED_SKY_STD_MXU"; 00517 } 00518 else { 00519 input_tag = "STANDARD_UNFLAT_MOS"; 00520 slit_location_tag = "SLIT_LOCATION_MOS"; 00521 unmapped_tag = "UNMAPPED_STD_MOS"; 00522 unmapped_sky_tag = "UNMAPPED_SKY_STD_MOS"; 00523 } 00524 } 00525 00526 00527 header = dfs_load_header(frameset, input_tag, 0); 00528 00529 if (header == NULL) 00530 fors_subtract_sky_exit("Cannot load scientific frame header"); 00531 00532 if (mos) 00533 maskslits = mos_load_slits_fors_mos(header, &nslits_out_det); 00534 else 00535 maskslits = mos_load_slits_fors_mxu(header); 00536 00537 /* 00538 * Check if all slits have the same X offset: if not, abort! 00539 */ 00540 00541 treat_as_lss = fors_mos_is_lss_like(maskslits, nslits_out_det); 00542 00543 cpl_table_delete(maskslits); maskslits = NULL; 00544 00545 if (treat_as_lss) 00546 fors_subtract_sky_exit("This recipe cannot process MOS/MXU " 00547 "data with all slits at the same offset."); 00548 00549 00550 if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID")) 00551 fors_subtract_sky_exit("Input frames are not from the same grism"); 00552 00553 if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID")) 00554 fors_subtract_sky_exit("Input frames are not from the same filter"); 00555 00556 if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID")) 00557 fors_subtract_sky_exit("Input frames are not from the same chip"); 00558 00559 00560 /* 00561 * Get the reference wavelength and the rebin factor along the 00562 * dispersion direction from the reference frame 00563 */ 00564 00565 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME"); 00566 if (instrume == NULL) 00567 fors_subtract_sky_exit("Missing keyword INSTRUME in reference frame " 00568 "header"); 00569 00570 if (instrume[4] == '1') 00571 snprintf(version, 80, "%s/%s", "fors1", VERSION); 00572 if (instrume[4] == '2') 00573 snprintf(version, 80, "%s/%s", "fors2", VERSION); 00574 00575 reference = cpl_propertylist_get_double(header, "ESO INS GRIS1 WLEN"); 00576 00577 if (cpl_error_get_code() != CPL_ERROR_NONE) 00578 fors_subtract_sky_exit("Missing keyword ESO INS GRIS1 WLEN " 00579 "in reference frame header"); 00580 00581 if (reference < 3000.0) /* Perhaps in nanometers... */ 00582 reference *= 10; 00583 00584 if (reference < 3000.0 || reference > 13000.0) { 00585 cpl_msg_error(recipe, "Invalid central wavelength %.2f read from " 00586 "keyword ESO INS GRIS1 WLEN in reference frame header", 00587 reference); 00588 fors_subtract_sky_exit(NULL); 00589 } 00590 00591 cpl_msg_info(recipe, "The central wavelength is: %.2f", reference); 00592 00593 rebin = cpl_propertylist_get_int(header, "ESO DET WIN1 BINX"); 00594 00595 if (cpl_error_get_code() != CPL_ERROR_NONE) 00596 fors_subtract_sky_exit("Missing keyword ESO DET WIN1 BINX " 00597 "in reference frame header"); 00598 00599 if (rebin != 1) { 00600 dispersion *= rebin; 00601 cpl_msg_warning(recipe, "The rebin factor is %d, and therefore the " 00602 "working dispersion used is %f A/pixel", rebin, 00603 dispersion); 00604 } 00605 00606 if (cosmics) { 00607 gain = cpl_propertylist_get_double(header, "ESO DET OUT1 CONAD"); 00608 00609 if (cpl_error_get_code() != CPL_ERROR_NONE) 00610 fors_subtract_sky_exit("Missing keyword ESO DET OUT1 CONAD in " 00611 "scientific frame header"); 00612 00613 cpl_msg_info(recipe, "The gain factor is: %.2f e-/ADU", gain); 00614 } 00615 00616 00617 cpl_msg_indent_less(); 00618 cpl_msg_info(recipe, "Load input frames..."); 00619 cpl_msg_indent_more(); 00620 00621 spectra = dfs_load_image(frameset, input_tag, CPL_TYPE_FLOAT, 0, 0); 00622 if (spectra == NULL) 00623 fors_subtract_sky_exit("Cannot load input scientific frame"); 00624 00625 slits = dfs_load_table(frameset, slit_location_tag, 1); 00626 if (slits == NULL) 00627 fors_subtract_sky_exit("Cannot load slits location table"); 00628 00629 polytraces = dfs_load_table(frameset, curv_coeff_tag, 1); 00630 if (polytraces == NULL) 00631 fors_subtract_sky_exit("Cannot load spectral curvature table"); 00632 00633 cpl_msg_indent_less(); 00634 cpl_msg_info(recipe, "Local sky determination..."); 00635 cpl_msg_indent_more(); 00636 skymap = mos_subtract_sky(spectra, slits, polytraces, reference, 00637 startwavelength, endwavelength, dispersion); 00638 00639 cpl_table_delete(polytraces); polytraces = NULL; 00640 cpl_table_delete(slits); slits = NULL; 00641 00642 if (cosmics) { 00643 cpl_msg_info(recipe, "Removing cosmic rays..."); 00644 mos_clean_cosmics(spectra, gain, -1., -1.); 00645 } 00646 00647 if (dfs_save_image(frameset, spectra, unmapped_tag, 00648 header, parlist, recipe, version)) 00649 fors_subtract_sky_exit(NULL); 00650 00651 cpl_image_delete(spectra); spectra = NULL; 00652 00653 if (dfs_save_image(frameset, skymap, unmapped_sky_tag, 00654 header, parlist, recipe, version)) 00655 fors_subtract_sky_exit(NULL); 00656 00657 cpl_image_delete(skymap); skymap = NULL; 00658 00659 cpl_propertylist_delete(header); header = NULL; 00660 00661 return 0; 00662 }