FORS Pipeline Reference Manual 4.9.20
|
00001 /* $Id: fors_extract_slits.c,v 1.6 2013/02/28 15:13:48 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:13:48 $ 00024 * $Revision: 1.6 $ 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_extract_slits_create(cpl_plugin *); 00038 static int fors_extract_slits_exec(cpl_plugin *); 00039 static int fors_extract_slits_destroy(cpl_plugin *); 00040 static int fors_extract_slits(cpl_parameterlist *, cpl_frameset *); 00041 00042 static char fors_extract_slits_description[] = 00043 "This recipe is used to extract MOS/MXU slit spectra, following their\n" 00044 "curvature, and to remap them into a spatially rectified image.\n" 00045 "Please refer to the FORS Pipeline User's Manual for details about\n" 00046 "the spectra remapping technique. Note however that the interpolation\n" 00047 "is done exclusively along the spatial direction, and therefore the\n" 00048 "output rectified image will have the same x size of the input spectral\n" 00049 "image.\n" 00050 "\n" 00051 "In the table below the MXU acronym can be alternatively read as MOS.\n\n" 00052 "Input files:\n\n" 00053 " DO category: Type: Explanation: Required:\n" 00054 " LAMP_UNBIAS_MXU\n" 00055 " or SCIENCE_UNBIAS_MXU\n" 00056 " or SCIENCE_UNFLAT_MXU\n" 00057 " or STANDARD_UNBIAS_MXU\n" 00058 " or STANDARD_UNFLAT_MXU\n" 00059 " or UNMAPPED_SCI_MXU\n" 00060 " or UNMAPPED_STD_MXU\n" 00061 " or UNMAPPED_SKY_SCI_MXU\n" 00062 " or UNMAPPED_SKY_STD_MXU Calib Spectral frame Y\n" 00063 " SLIT_LOCATION_DETECT_MXU\n" 00064 " or SLIT_LOCATION_MXU Calib Master flat frame Y\n" 00065 " CURV_COEFF_MXU Calib Spectral curvature Y\n" 00066 " GRISM_TABLE Calib Grism table .\n\n" 00067 "Output files:\n\n" 00068 " DO category: Data type: Explanation:\n" 00069 " RECTIFIED_LAMP_MXU\n" 00070 " or RECTIFIED_ALL_SCI_MXU\n" 00071 " or RECTIFIED_ALL_STD_MXU\n" 00072 " or RECTIFIED_SCI_MXU\n" 00073 " or RECTIFIED_STD_MXU\n" 00074 " or RECTIFIED_SKY_SCI_MXU\n" 00075 " or RECTIFIED_SKY_STD_MXU FITS image Rectified slit spectra\n\n"; 00076 00077 #define fors_extract_slits_exit(message) \ 00078 { \ 00079 if (message) cpl_msg_error(recipe, message); \ 00080 cpl_image_delete(spectra); \ 00081 cpl_image_delete(spatial); \ 00082 cpl_table_delete(grism_table); \ 00083 cpl_table_delete(maskslits); \ 00084 cpl_table_delete(slits); \ 00085 cpl_table_delete(polytraces); \ 00086 cpl_propertylist_delete(header); \ 00087 cpl_msg_indent_less(); \ 00088 return -1; \ 00089 } 00090 00091 #define fors_extract_slits_exit_memcheck(message) \ 00092 { \ 00093 if (message) cpl_msg_info(recipe, message); \ 00094 printf("free spectra (%p)\n", spectra); \ 00095 cpl_image_delete(spectra); \ 00096 printf("free spatial (%p)\n", spatial); \ 00097 cpl_image_delete(spatial); \ 00098 printf("free grism_table (%p)\n", grism_table); \ 00099 cpl_table_delete(grism_table); \ 00100 printf("free maskslits (%p)\n", maskslits); \ 00101 cpl_table_delete(maskslits); \ 00102 printf("free slits (%p)\n", slits); \ 00103 cpl_table_delete(slits); \ 00104 printf("free polytraces (%p)\n", polytraces); \ 00105 cpl_table_delete(polytraces); \ 00106 printf("free header (%p)\n", header); \ 00107 cpl_propertylist_delete(header); \ 00108 cpl_msg_indent_less(); \ 00109 return 0; \ 00110 } 00111 00112 00124 int cpl_plugin_get_info(cpl_pluginlist *list) 00125 { 00126 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe ); 00127 cpl_plugin *plugin = &recipe->interface; 00128 00129 cpl_plugin_init(plugin, 00130 CPL_PLUGIN_API, 00131 FORS_BINARY_VERSION, 00132 CPL_PLUGIN_TYPE_RECIPE, 00133 "fors_extract_slits", 00134 "Spatial rectification of spectral image", 00135 fors_extract_slits_description, 00136 "Carlo Izzo", 00137 PACKAGE_BUGREPORT, 00138 "This file is currently part of the FORS Instrument Pipeline\n" 00139 "Copyright (C) 2002-2010 European Southern Observatory\n\n" 00140 "This program is free software; you can redistribute it and/or modify\n" 00141 "it under the terms of the GNU General Public License as published by\n" 00142 "the Free Software Foundation; either version 2 of the License, or\n" 00143 "(at your option) any later version.\n\n" 00144 "This program is distributed in the hope that it will be useful,\n" 00145 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" 00146 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" 00147 "GNU General Public License for more details.\n\n" 00148 "You should have received a copy of the GNU General Public License\n" 00149 "along with this program; if not, write to the Free Software Foundation,\n" 00150 "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n", 00151 fors_extract_slits_create, 00152 fors_extract_slits_exec, 00153 fors_extract_slits_destroy); 00154 00155 cpl_pluginlist_append(list, plugin); 00156 00157 return 0; 00158 } 00159 00160 00171 static int fors_extract_slits_create(cpl_plugin *plugin) 00172 { 00173 cpl_recipe *recipe; 00174 cpl_parameter *p; 00175 00176 /* 00177 * Check that the plugin is part of a valid recipe 00178 */ 00179 00180 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00181 recipe = (cpl_recipe *)plugin; 00182 else 00183 return -1; 00184 00185 /* 00186 * Create the (empty) parameters list in the cpl_recipe object 00187 */ 00188 00189 recipe->parameters = cpl_parameterlist_new(); 00190 00191 /* 00192 * Dispersion 00193 */ 00194 00195 p = cpl_parameter_new_value("fors.fors_extract_slits.dispersion", 00196 CPL_TYPE_DOUBLE, 00197 "Expected spectral dispersion (Angstrom/pixel)", 00198 "fors.fors_extract_slits", 00199 0.0); 00200 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dispersion"); 00201 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00202 cpl_parameterlist_append(recipe->parameters, p); 00203 00204 /* 00205 * Start wavelength for spectral extraction 00206 */ 00207 00208 p = cpl_parameter_new_value("fors.fors_extract_slits.startwavelength", 00209 CPL_TYPE_DOUBLE, 00210 "Start wavelength in spectral extraction", 00211 "fors.fors_extract_slits", 00212 0.0); 00213 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "startwavelength"); 00214 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00215 cpl_parameterlist_append(recipe->parameters, p); 00216 00217 /* 00218 * End wavelength for spectral extraction 00219 */ 00220 00221 p = cpl_parameter_new_value("fors.fors_extract_slits.endwavelength", 00222 CPL_TYPE_DOUBLE, 00223 "End wavelength in spectral extraction", 00224 "fors.fors_extract_slits", 00225 0.0); 00226 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "endwavelength"); 00227 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00228 cpl_parameterlist_append(recipe->parameters, p); 00229 00230 /* 00231 * Flux conservation 00232 */ 00233 00234 p = cpl_parameter_new_value("fors.fors_extract_slits.flux", 00235 CPL_TYPE_BOOL, 00236 "Apply flux conservation", 00237 "fors.fors_extract_slits", 00238 TRUE); 00239 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "flux"); 00240 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00241 cpl_parameterlist_append(recipe->parameters, p); 00242 00243 return 0; 00244 } 00245 00246 00255 static int fors_extract_slits_exec(cpl_plugin *plugin) 00256 { 00257 cpl_recipe *recipe; 00258 00259 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00260 recipe = (cpl_recipe *)plugin; 00261 else 00262 return -1; 00263 00264 return fors_extract_slits(recipe->parameters, recipe->frames); 00265 } 00266 00267 00276 static int fors_extract_slits_destroy(cpl_plugin *plugin) 00277 { 00278 cpl_recipe *recipe; 00279 00280 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00281 recipe = (cpl_recipe *)plugin; 00282 else 00283 return -1; 00284 00285 cpl_parameterlist_delete(recipe->parameters); 00286 00287 return 0; 00288 } 00289 00290 00300 static int fors_extract_slits(cpl_parameterlist *parlist, 00301 cpl_frameset *frameset) 00302 { 00303 00304 const char *recipe = "fors_extract_slits"; 00305 00306 00307 /* 00308 * Input parameters 00309 */ 00310 00311 double dispersion; 00312 double startwavelength; 00313 double endwavelength; 00314 int flux; 00315 00316 /* 00317 * CPL objects 00318 */ 00319 00320 cpl_image *spectra = NULL; 00321 cpl_image *spatial = NULL; 00322 cpl_table *grism_table = NULL; 00323 cpl_table *slits = NULL; 00324 cpl_table *polytraces = NULL; 00325 cpl_table *maskslits = NULL; 00326 cpl_propertylist *header = NULL; 00327 00328 /* 00329 * Auxiliary variables 00330 */ 00331 00332 char version[80]; 00333 const char *input_tag; 00334 const char *output_tag; 00335 const char *slit_location_tag; 00336 const char *curv_coeff_tag; 00337 int nframes; 00338 int rebin; 00339 int nslits; 00340 int treat_as_lss; 00341 int i; 00342 double reference; 00343 double *xpos; 00344 double mxpos; 00345 int mxu, mos, lss; 00346 int slit_l, slit_d; 00347 int lamp_mxu; 00348 int lamp_mos; 00349 int lamp_lss; 00350 int scib_mxu; 00351 int scib_mos; 00352 int scib_lss; 00353 int scif_mxu; 00354 int scif_mos; 00355 int scif_lss; 00356 int stab_mxu; 00357 int stab_mos; 00358 int stab_lss; 00359 int staf_mxu; 00360 int staf_mos; 00361 int staf_lss; 00362 int sciu_mxu; 00363 int sciu_mos; 00364 int sciu_lss; 00365 int stau_mxu; 00366 int stau_mos; 00367 int stau_lss; 00368 int scis_mxu; 00369 int scis_mos; 00370 int scis_lss; 00371 int stas_mxu; 00372 int stas_mos; 00373 int stas_lss; 00374 int nslits_out_det = 0; 00375 00376 char *instrume = NULL; 00377 00378 00379 cpl_msg_set_indentation(2); 00380 00381 if (dfs_files_dont_exist(frameset)) 00382 fors_extract_slits_exit(NULL); 00383 00384 00385 /* 00386 * Get configuration parameters 00387 */ 00388 00389 cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe); 00390 cpl_msg_indent_more(); 00391 00392 if (cpl_frameset_count_tags(frameset, "GRISM_TABLE") > 1) 00393 fors_extract_slits_exit("Too many in input: GRISM_TABLE"); 00394 00395 grism_table = dfs_load_table(frameset, "GRISM_TABLE", 1); 00396 00397 dispersion = dfs_get_parameter_double(parlist, 00398 "fors.fors_extract_slits.dispersion", grism_table); 00399 00400 if (dispersion <= 0.0) 00401 fors_extract_slits_exit("Invalid spectral dispersion value"); 00402 00403 startwavelength = dfs_get_parameter_double(parlist, 00404 "fors.fors_extract_slits.startwavelength", grism_table); 00405 if (startwavelength > 1.0) 00406 if (startwavelength < 3000.0 || startwavelength > 13000.0) 00407 fors_extract_slits_exit("Invalid wavelength"); 00408 00409 endwavelength = dfs_get_parameter_double(parlist, 00410 "fors.fors_extract_slits.endwavelength", grism_table); 00411 if (endwavelength > 1.0) { 00412 if (endwavelength < 3000.0 || endwavelength > 13000.0) 00413 fors_extract_slits_exit("Invalid wavelength"); 00414 if (startwavelength < 1.0) 00415 fors_extract_slits_exit("Invalid wavelength interval"); 00416 } 00417 00418 if (startwavelength > 1.0) 00419 if (endwavelength - startwavelength <= 0.0) 00420 fors_extract_slits_exit("Invalid wavelength interval"); 00421 00422 flux = dfs_get_parameter_bool(parlist, 00423 "fors.fors_extract_slits.flux", NULL); 00424 00425 cpl_table_delete(grism_table); grism_table = NULL; 00426 00427 if (cpl_error_get_code()) 00428 fors_extract_slits_exit("Failure reading the configuration parameters"); 00429 00430 00431 cpl_msg_indent_less(); 00432 cpl_msg_info(recipe, "Check input set-of-frames:"); 00433 cpl_msg_indent_more(); 00434 00435 mxu = lamp_mxu = cpl_frameset_count_tags(frameset, "LAMP_UNBIAS_MXU"); 00436 mos = lamp_mos = cpl_frameset_count_tags(frameset, "LAMP_UNBIAS_MOS"); 00437 lss = lamp_lss = cpl_frameset_count_tags(frameset, "LAMP_UNBIAS_LSS"); 00438 mxu += scib_mxu = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_MXU"); 00439 mos += scib_mos = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_MOS"); 00440 lss += scib_lss = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_LSS"); 00441 mxu += scif_mxu = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_MXU"); 00442 mos += scif_mos = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_MOS"); 00443 lss += scif_lss = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_LSS"); 00444 mxu += stab_mxu = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_MXU"); 00445 mos += stab_mos = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_MOS"); 00446 lss += stab_lss = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_LSS"); 00447 mxu += staf_mxu = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_MXU"); 00448 mos += staf_mos = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_MOS"); 00449 lss += staf_lss = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_LSS"); 00450 mxu += sciu_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_SCI_MXU"); 00451 mos += sciu_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_SCI_MOS"); 00452 lss += sciu_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_SCI_LSS"); 00453 mxu += stau_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_STD_MXU"); 00454 mos += stau_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_STD_MOS"); 00455 lss += stau_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_STD_LSS"); 00456 mxu += scis_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_SCI_MXU"); 00457 mos += scis_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_SCI_MOS"); 00458 lss += scis_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_SCI_LSS"); 00459 mxu += stas_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_STD_MXU"); 00460 mos += stas_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_STD_MOS"); 00461 lss += stas_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_STD_LSS"); 00462 00463 nframes = mos + mxu + lss; 00464 00465 if (nframes == 0) { 00466 fors_extract_slits_exit("Missing input spectral frame"); 00467 } 00468 if (nframes > 1) { 00469 cpl_msg_error(recipe, 00470 "Too many input spectral frames (%d > 1)", nframes); 00471 fors_extract_slits_exit(NULL); 00472 } 00473 00474 if (lss) 00475 fors_extract_slits_exit("Use this recipe just with MOS/MXU data."); 00476 00477 if (mxu) { 00478 slit_l = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_MXU"); 00479 slit_d = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_DETECT_MXU"); 00480 } 00481 else { 00482 slit_l = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_MOS"); 00483 slit_d = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_DETECT_MOS"); 00484 } 00485 00486 nframes = slit_l + slit_d; 00487 00488 if (nframes == 0) { 00489 fors_extract_slits_exit("Missing input slit location table"); 00490 } 00491 if (nframes > 1) { 00492 cpl_msg_error(recipe, 00493 "Too many input slit location tables (%d > 1)", nframes); 00494 fors_extract_slits_exit(NULL); 00495 } 00496 00497 if (slit_l) { 00498 if (mxu) 00499 slit_location_tag = "SLIT_LOCATION_MXU"; 00500 else 00501 slit_location_tag = "SLIT_LOCATION_MOS"; 00502 } 00503 else { 00504 if (mxu) 00505 slit_location_tag = "SLIT_LOCATION_DETECT_MXU"; 00506 else 00507 slit_location_tag = "SLIT_LOCATION_DETECT_MOS"; 00508 } 00509 00510 if (mxu) 00511 curv_coeff_tag = "CURV_COEFF_MXU"; 00512 else 00513 curv_coeff_tag = "CURV_COEFF_MOS"; 00514 00515 if (lamp_mxu) { 00516 input_tag = "LAMP_UNBIAS_MXU"; 00517 output_tag = "RECTIFIED_LAMP_MXU"; 00518 } 00519 else if (lamp_mos) { 00520 input_tag = "LAMP_UNBIAS_MOS"; 00521 output_tag = "RECTIFIED_LAMP_MOS"; 00522 } 00523 else if (scib_mxu) { 00524 input_tag = "SCIENCE_UNBIAS_MXU"; 00525 output_tag = "RECTIFIED_ALL_SCI_MXU"; 00526 } 00527 else if (scib_mos) { 00528 input_tag = "SCIENCE_UNBIAS_MOS"; 00529 output_tag = "RECTIFIED_ALL_SCI_MOS"; 00530 } 00531 else if (scif_mxu) { 00532 input_tag = "SCIENCE_UNFLAT_MXU"; 00533 output_tag = "RECTIFIED_ALL_SCI_MXU"; 00534 } 00535 else if (scif_mos) { 00536 input_tag = "SCIENCE_UNFLAT_MOS"; 00537 output_tag = "RECTIFIED_ALL_SCI_MOS"; 00538 } 00539 else if (stab_mxu) { 00540 input_tag = "STANDARD_UNBIAS_MXU"; 00541 output_tag = "RECTIFIED_ALL_STD_MXU"; 00542 } 00543 else if (stab_mos) { 00544 input_tag = "STANDARD_UNBIAS_MOS"; 00545 output_tag = "RECTIFIED_ALL_STD_MOS"; 00546 } 00547 else if (staf_mxu) { 00548 input_tag = "STANDARD_UNFLAT_MXU"; 00549 output_tag = "RECTIFIED_ALL_STD_MXU"; 00550 } 00551 else if (staf_mos) { 00552 input_tag = "STANDARD_UNFLAT_MOS"; 00553 output_tag = "RECTIFIED_ALL_STD_MOS"; 00554 } 00555 else if (sciu_mxu) { 00556 input_tag = "UNMAPPED_SCI_MXU"; 00557 output_tag = "RECTIFIED_SCI_MXU"; 00558 } 00559 else if (sciu_mos) { 00560 input_tag = "UNMAPPED_SCI_MOS"; 00561 output_tag = "RECTIFIED_SCI_MOS"; 00562 } 00563 else if (stau_mxu) { 00564 input_tag = "UNMAPPED_STD_MXU"; 00565 output_tag = "RECTIFIED_STD_MXU"; 00566 } 00567 else if (stau_mos) { 00568 input_tag = "UNMAPPED_STD_MOS"; 00569 output_tag = "RECTIFIED_STD_MOS"; 00570 } 00571 else if (scis_mxu) { 00572 input_tag = "UNMAPPED_SKY_SCI_MXU"; 00573 output_tag = "RECTIFIED_SKY_SCI_MXU"; 00574 } 00575 else if (scis_mos) { 00576 input_tag = "UNMAPPED_SKY_SCI_MOS"; 00577 output_tag = "RECTIFIED_SKY_SCI_MOS"; 00578 } 00579 else if (stas_mxu) { 00580 input_tag = "UNMAPPED_SKY_STD_MXU"; 00581 output_tag = "RECTIFIED_SKY_STD_MXU"; 00582 } 00583 else if (stas_mos) { 00584 input_tag = "UNMAPPED_SKY_STD_MOS"; 00585 output_tag = "RECTIFIED_SKY_STD_MOS"; 00586 } 00587 00588 header = dfs_load_header(frameset, input_tag, 0); 00589 00590 if (header == NULL) 00591 fors_extract_slits_exit("Cannot load master flat frame header"); 00592 00593 if (mos) 00594 maskslits = mos_load_slits_fors_mos(header, &nslits_out_det); 00595 else 00596 maskslits = mos_load_slits_fors_mxu(header); 00597 00598 /* 00599 * Check if all slits have the same X offset: in such case, abort! 00600 */ 00601 00602 treat_as_lss = fors_mos_is_lss_like(maskslits, nslits_out_det); 00603 00604 cpl_table_delete(maskslits); maskslits = NULL; 00605 00606 if (treat_as_lss) { 00607 cpl_msg_error(recipe, "All slits have the same offset: %.2f mm\n" 00608 "The LSS data reduction strategy must be applied.", 00609 mxpos); 00610 fors_extract_slits_exit(NULL); 00611 } 00612 00613 if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID")) 00614 fors_extract_slits_exit("Input frames are not from the same grism"); 00615 00616 if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID")) 00617 fors_extract_slits_exit("Input frames are not from the same filter"); 00618 00619 if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID")) 00620 fors_extract_slits_exit("Input frames are not from the same chip"); 00621 00622 00623 /* 00624 * Get the reference wavelength and the rebin factor along the 00625 * dispersion direction from the master flat frame 00626 */ 00627 00628 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME"); 00629 if (instrume == NULL) 00630 fors_extract_slits_exit("Missing keyword INSTRUME in master " 00631 "flat header"); 00632 00633 if (instrume[4] == '1') 00634 snprintf(version, 80, "%s/%s", "fors1", VERSION); 00635 if (instrume[4] == '2') 00636 snprintf(version, 80, "%s/%s", "fors2", VERSION); 00637 00638 reference = cpl_propertylist_get_double(header, "ESO INS GRIS1 WLEN"); 00639 00640 if (cpl_error_get_code() != CPL_ERROR_NONE) 00641 fors_extract_slits_exit("Missing keyword ESO INS GRIS1 WLEN " 00642 "in master flat frame header"); 00643 00644 if (reference < 3000.0) /* Perhaps in nanometers... */ 00645 reference *= 10; 00646 00647 if (reference < 3000.0 || reference > 13000.0) { 00648 cpl_msg_error(recipe, "Invalid central wavelength %.2f read from " 00649 "keyword ESO INS GRIS1 WLEN in master flat header", 00650 reference); 00651 fors_extract_slits_exit(NULL); 00652 } 00653 00654 cpl_msg_info(recipe, "The central wavelength is: %.2f", reference); 00655 00656 rebin = cpl_propertylist_get_int(header, "ESO DET WIN1 BINX"); 00657 00658 if (cpl_error_get_code() != CPL_ERROR_NONE) 00659 fors_extract_slits_exit("Missing keyword ESO DET WIN1 BINX " 00660 "in master flat header"); 00661 00662 if (rebin != 1) { 00663 dispersion *= rebin; 00664 cpl_msg_warning(recipe, "The rebin factor is %d, and therefore the " 00665 "working dispersion used is %f A/pixel", rebin, 00666 dispersion); 00667 } 00668 00669 cpl_msg_indent_less(); 00670 cpl_msg_info(recipe, "Load input frames..."); 00671 cpl_msg_indent_more(); 00672 00673 spectra = dfs_load_image(frameset, input_tag, CPL_TYPE_FLOAT, 0, 0); 00674 if (spectra == NULL) 00675 fors_extract_slits_exit("Cannot load input spectral frame"); 00676 00677 slits = dfs_load_table(frameset, slit_location_tag, 1); 00678 if (slits == NULL) 00679 fors_extract_slits_exit("Cannot load slits location table"); 00680 00681 polytraces = dfs_load_table(frameset, curv_coeff_tag, 1); 00682 if (slits == NULL) 00683 fors_extract_slits_exit("Cannot load spectral curvature table"); 00684 00685 spatial = mos_spatial_calibration(spectra, slits, polytraces, reference, 00686 startwavelength, endwavelength, 00687 dispersion, flux, NULL); 00688 00689 cpl_image_delete(spectra); spectra = NULL; 00690 cpl_table_delete(polytraces); polytraces = NULL; 00691 cpl_table_delete(slits); slits = NULL; 00692 00693 cpl_propertylist_delete(header); header = NULL; 00694 header = cpl_propertylist_new(); 00695 00696 cpl_propertylist_update_double(header, "CRPIX2", 1.0); 00697 cpl_propertylist_update_double(header, "CRVAL2", 1.0); 00698 /* cpl_propertylist_update_double(header, "CDELT2", 1.0); */ 00699 cpl_propertylist_update_double(header, "CD1_1", 1.0); 00700 cpl_propertylist_update_double(header, "CD1_2", 0.0); 00701 cpl_propertylist_update_double(header, "CD2_1", 0.0); 00702 cpl_propertylist_update_double(header, "CD2_2", 1.0); 00703 cpl_propertylist_update_string(header, "CTYPE1", "LINEAR"); 00704 cpl_propertylist_update_string(header, "CTYPE2", "PIXEL"); 00705 00706 if (dfs_save_image(frameset, spatial, output_tag, 00707 header, parlist, recipe, version)) 00708 fors_extract_slits_exit(NULL); 00709 00710 cpl_image_delete(spatial); spatial = NULL; 00711 cpl_propertylist_delete(header); header = NULL; 00712 00713 return 0; 00714 }