FORS Pipeline Reference Manual 4.9.9
|
00001 /* $Id: fors_align_sky.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_align_sky_create(cpl_plugin *); 00038 static int fors_align_sky_exec(cpl_plugin *); 00039 static int fors_align_sky_destroy(cpl_plugin *); 00040 static int fors_align_sky(cpl_parameterlist *, cpl_frameset *); 00041 00042 static char fors_align_sky_description[] = 00043 "This recipe is used to align the wavelength solution based on the arc\n" 00044 "lamp exposure on a set of sky lines observed on a scientific exposure.\n" 00045 "The input rectified frames are produced by the recipe fors_extract_slits.\n" 00046 "An input catalog of sky lines can be specified, otherwise an internal one\n" 00047 "is used.\n" 00048 "\n" 00049 "This recipe should be applied to multi-slit MOS/MXU data: for LSS or\n" 00050 "long-slit like data (MOS/MXU with all slits at the same offset) use recipe\n" 00051 "fors_align_sky_lss instead. Please refer to the FORS Pipeline User's Manual\n" 00052 "for more details.\n" 00053 "\n" 00054 "In the table below the MXU acronym can be alternatively read as MOS, and\n" 00055 "SCI as STD.\n\n" 00056 "Input files:\n\n" 00057 " DO category: Type: Explanation: Required:\n" 00058 " RECTIFIED_ALL_SCI_MXU\n" 00059 " or RECTIFIED_SKY_SCI_MXU Calib Frame with sky lines Y\n" 00060 " SPATIAL_MAP_MXU Calib Spatial coordinate map Y\n" 00061 " CURV_COEFF_MXU Calib Spectral curvature Y\n" 00062 " SLIT_LOCATION_MXU Calib Slit location on CCD Y\n" 00063 " DISP_COEFF_MXU Calib Dispersion solution Y\n" 00064 " MASTER_SKYLINECAT Calib Catalog of sky lines .\n" 00065 " GRISM_TABLE Calib Grism table .\n\n" 00066 "Output files:\n\n" 00067 " DO category: Data type: Explanation:\n" 00068 " SKY_SHIFTS_SLIT_SCI_MXU FITS table Observed sky lines offsets\n" 00069 " WAVELENGTH_MAP_SCI_MXU FITS image Wavelength mapped on CCD\n" 00070 " DISP_COEFF_SCI_MXU FITS image Upgraded dispersion solution\n\n"; 00071 00072 #define fors_align_sky_exit(message) \ 00073 { \ 00074 if (message) cpl_msg_error(recipe, message); \ 00075 cpl_image_delete(wavemap); \ 00076 cpl_image_delete(coordinate); \ 00077 cpl_image_delete(rainbow); \ 00078 cpl_image_delete(smapped); \ 00079 cpl_table_delete(grism_table); \ 00080 cpl_table_delete(maskslits); \ 00081 cpl_table_delete(wavelengths); \ 00082 cpl_table_delete(offsets); \ 00083 cpl_table_delete(slits); \ 00084 cpl_table_delete(polytraces); \ 00085 cpl_table_delete(idscoeff); \ 00086 cpl_vector_delete(lines); \ 00087 cpl_propertylist_delete(header); \ 00088 cpl_msg_indent_less(); \ 00089 return -1; \ 00090 } 00091 00092 #define fors_align_sky_exit_memcheck(message) \ 00093 { \ 00094 if (message) cpl_msg_info(recipe, message); \ 00095 printf("free wavemap (%p)\n", wavemap); \ 00096 cpl_image_delete(wavemap); \ 00097 printf("free coordinate (%p)\n", coordinate); \ 00098 cpl_image_delete(coordinate); \ 00099 printf("free rainbow (%p)\n", rainbow); \ 00100 cpl_image_delete(rainbow); \ 00101 printf("free smapped (%p)\n", smapped); \ 00102 cpl_image_delete(smapped); \ 00103 printf("free grism_table (%p)\n", grism_table); \ 00104 cpl_table_delete(grism_table); \ 00105 printf("free maskslits (%p)\n", maskslits); \ 00106 cpl_table_delete(maskslits); \ 00107 printf("free wavelengths (%p)\n", wavelengths); \ 00108 cpl_table_delete(wavelengths); \ 00109 printf("free offsets (%p)\n", offsets); \ 00110 cpl_table_delete(offsets); \ 00111 printf("free idscoeff (%p)\n", idscoeff); \ 00112 cpl_table_delete(idscoeff); \ 00113 printf("free slits (%p)\n", slits); \ 00114 cpl_table_delete(slits); \ 00115 printf("free polytraces (%p)\n", polytraces); \ 00116 cpl_table_delete(polytraces); \ 00117 printf("free lines (%p)\n", lines); \ 00118 cpl_vector_delete(lines); \ 00119 printf("free header (%p)\n", header); \ 00120 cpl_propertylist_delete(header); \ 00121 cpl_msg_indent_less(); \ 00122 return 0; \ 00123 } 00124 00125 00137 int cpl_plugin_get_info(cpl_pluginlist *list) 00138 { 00139 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe ); 00140 cpl_plugin *plugin = &recipe->interface; 00141 00142 cpl_plugin_init(plugin, 00143 CPL_PLUGIN_API, 00144 FORS_BINARY_VERSION, 00145 CPL_PLUGIN_TYPE_RECIPE, 00146 "fors_align_sky", 00147 "Upgrade wavelength solution using sky lines", 00148 fors_align_sky_description, 00149 "Carlo Izzo", 00150 PACKAGE_BUGREPORT, 00151 "This file is currently part of the FORS Instrument Pipeline\n" 00152 "Copyright (C) 2002-2010 European Southern Observatory\n\n" 00153 "This program is free software; you can redistribute it and/or modify\n" 00154 "it under the terms of the GNU General Public License as published by\n" 00155 "the Free Software Foundation; either version 2 of the License, or\n" 00156 "(at your option) any later version.\n\n" 00157 "This program is distributed in the hope that it will be useful,\n" 00158 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" 00159 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" 00160 "GNU General Public License for more details.\n\n" 00161 "You should have received a copy of the GNU General Public License\n" 00162 "along with this program; if not, write to the Free Software Foundation,\n" 00163 "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n", 00164 fors_align_sky_create, 00165 fors_align_sky_exec, 00166 fors_align_sky_destroy); 00167 00168 cpl_pluginlist_append(list, plugin); 00169 00170 return 0; 00171 } 00172 00173 00184 static int fors_align_sky_create(cpl_plugin *plugin) 00185 { 00186 cpl_recipe *recipe; 00187 cpl_parameter *p; 00188 00189 /* 00190 * Check that the plugin is part of a valid recipe 00191 */ 00192 00193 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00194 recipe = (cpl_recipe *)plugin; 00195 else 00196 return -1; 00197 00198 /* 00199 * Create the (empty) parameters list in the cpl_recipe object 00200 */ 00201 00202 recipe->parameters = cpl_parameterlist_new(); 00203 00204 /* 00205 * Dispersion 00206 */ 00207 00208 p = cpl_parameter_new_value("fors.fors_align_sky.dispersion", 00209 CPL_TYPE_DOUBLE, 00210 "Expected spectral dispersion (Angstrom/pixel)", 00211 "fors.fors_align_sky", 00212 0.0); 00213 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dispersion"); 00214 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00215 cpl_parameterlist_append(recipe->parameters, p); 00216 00217 /* 00218 * Start wavelength for spectral extraction 00219 */ 00220 00221 p = cpl_parameter_new_value("fors.fors_align_sky.startwavelength", 00222 CPL_TYPE_DOUBLE, 00223 "Start wavelength in spectral extraction", 00224 "fors.fors_align_sky", 00225 0.0); 00226 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "startwavelength"); 00227 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00228 cpl_parameterlist_append(recipe->parameters, p); 00229 00230 /* 00231 * End wavelength for spectral extraction 00232 */ 00233 00234 p = cpl_parameter_new_value("fors.fors_align_sky.endwavelength", 00235 CPL_TYPE_DOUBLE, 00236 "End wavelength in spectral extraction", 00237 "fors.fors_align_sky", 00238 0.0); 00239 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "endwavelength"); 00240 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00241 cpl_parameterlist_append(recipe->parameters, p); 00242 00243 /* 00244 * Sky lines alignment 00245 */ 00246 00247 p = cpl_parameter_new_value("fors.fors_align_sky.skyalign", 00248 CPL_TYPE_INT, 00249 "Polynomial order for sky lines alignment", 00250 "fors.fors_align_sky", 00251 0); 00252 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "skyalign"); 00253 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00254 cpl_parameterlist_append(recipe->parameters, p); 00255 00256 /* 00257 * Line catalog table column containing the sky reference wavelengths 00258 */ 00259 00260 p = cpl_parameter_new_value("fors.fors_align_sky.wcolumn", 00261 CPL_TYPE_STRING, 00262 "Name of sky line catalog table column " 00263 "with wavelengths", 00264 "fors.fors_align_sky", 00265 "WLEN"); 00266 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wcolumn"); 00267 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00268 cpl_parameterlist_append(recipe->parameters, p); 00269 00270 return 0; 00271 } 00272 00273 00282 static int fors_align_sky_exec(cpl_plugin *plugin) 00283 { 00284 cpl_recipe *recipe; 00285 00286 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00287 recipe = (cpl_recipe *)plugin; 00288 else 00289 return -1; 00290 00291 return fors_align_sky(recipe->parameters, recipe->frames); 00292 } 00293 00294 00303 static int fors_align_sky_destroy(cpl_plugin *plugin) 00304 { 00305 cpl_recipe *recipe; 00306 00307 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00308 recipe = (cpl_recipe *)plugin; 00309 else 00310 return -1; 00311 00312 cpl_parameterlist_delete(recipe->parameters); 00313 00314 return 0; 00315 } 00316 00317 00327 static int fors_align_sky(cpl_parameterlist *parlist, 00328 cpl_frameset *frameset) 00329 { 00330 00331 const char *recipe = "fors_align_sky"; 00332 00333 00334 /* 00335 * Input parameters 00336 */ 00337 00338 double dispersion; 00339 double startwavelength; 00340 double endwavelength; 00341 int skyalign; 00342 const char *wcolumn; 00343 00344 /* 00345 * CPL objects 00346 */ 00347 00348 cpl_image *rainbow = NULL; 00349 cpl_image *wavemap = NULL; 00350 cpl_image *smapped = NULL; 00351 cpl_image *coordinate = NULL; 00352 cpl_table *grism_table = NULL; 00353 cpl_table *wavelengths = NULL; 00354 cpl_table *slits = NULL; 00355 cpl_table *idscoeff = NULL; 00356 cpl_table *polytraces = NULL; 00357 cpl_table *maskslits = NULL; 00358 cpl_table *offsets = NULL; 00359 cpl_vector *lines = NULL; 00360 cpl_propertylist *header = NULL; 00361 00362 /* 00363 * Auxiliary variables 00364 */ 00365 00366 char version[80]; 00367 const char *slit_location_tag; 00368 const char *curv_coeff_tag; 00369 const char *rectified_tag; 00370 const char *wavemap_tag; 00371 const char *shifts_tag; 00372 const char *disp_ali_tag; 00373 const char *disp_coeff_tag; 00374 const char *spatial_map_tag; 00375 int nframes; 00376 int rebin; 00377 int nslits; 00378 int nlines; 00379 int nx; 00380 int highres; 00381 int treat_as_lss; 00382 int i; 00383 double reference; 00384 double *xpos; 00385 double mxpos; 00386 double *line; 00387 int mxu, mos; 00388 int rec_scia; 00389 int rec_stda; 00390 int rec_scis; 00391 int rec_stds; 00392 00393 char *instrume = NULL; 00394 00395 00396 cpl_msg_set_indentation(2); 00397 00398 if (dfs_files_dont_exist(frameset)) 00399 fors_align_sky_exit(NULL); 00400 00401 00402 /* 00403 * Get configuration parameters 00404 */ 00405 00406 cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe); 00407 cpl_msg_indent_more(); 00408 00409 if (cpl_frameset_count_tags(frameset, "GRISM_TABLE") > 1) 00410 fors_align_sky_exit("Too many in input: GRISM_TABLE"); 00411 00412 grism_table = dfs_load_table(frameset, "GRISM_TABLE", 1); 00413 00414 dispersion = dfs_get_parameter_double(parlist, 00415 "fors.fors_align_sky.dispersion", grism_table); 00416 00417 if (dispersion <= 0.0) 00418 fors_align_sky_exit("Invalid spectral dispersion value"); 00419 00420 startwavelength = dfs_get_parameter_double(parlist, 00421 "fors.fors_align_sky.startwavelength", grism_table); 00422 if (startwavelength > 1.0) 00423 if (startwavelength < 3000.0 || startwavelength > 13000.0) 00424 fors_align_sky_exit("Invalid wavelength"); 00425 00426 endwavelength = dfs_get_parameter_double(parlist, 00427 "fors.fors_align_sky.endwavelength", grism_table); 00428 if (endwavelength > 1.0) { 00429 if (endwavelength < 3000.0 || endwavelength > 13000.0) 00430 fors_align_sky_exit("Invalid wavelength"); 00431 if (startwavelength < 1.0) 00432 fors_align_sky_exit("Invalid wavelength interval"); 00433 } 00434 00435 if (startwavelength > 1.0) 00436 if (endwavelength - startwavelength <= 0.0) 00437 fors_align_sky_exit("Invalid wavelength interval"); 00438 00439 skyalign = dfs_get_parameter_int(parlist, 00440 "fors.fors_align_sky.skyalign", NULL); 00441 00442 if (skyalign < 0) 00443 fors_align_sky_exit("Invalid polynomial degree"); 00444 if (skyalign > 2) 00445 fors_align_sky_exit("Max polynomial degree for sky alignment is 2"); 00446 00447 wcolumn = dfs_get_parameter_string(parlist, 00448 "fors.fors_align_sky.wcolumn", NULL); 00449 00450 cpl_table_delete(grism_table); grism_table = NULL; 00451 00452 if (cpl_error_get_code()) 00453 fors_align_sky_exit("Failure reading the configuration parameters"); 00454 00455 00456 cpl_msg_indent_less(); 00457 cpl_msg_info(recipe, "Check input set-of-frames:"); 00458 cpl_msg_indent_more(); 00459 00460 mxu = cpl_frameset_count_tags(frameset, "SPATIAL_MAP_MXU"); 00461 mos = cpl_frameset_count_tags(frameset, "SPATIAL_MAP_MOS"); 00462 00463 nframes = mos + mxu; 00464 00465 if (nframes == 0) { 00466 fors_align_sky_exit("Missing input spatial map"); 00467 } 00468 if (nframes > 1) { 00469 cpl_msg_error(recipe, 00470 "Too many input spatial maps (%d > 1)", nframes); 00471 fors_align_sky_exit(NULL); 00472 } 00473 00474 if (mxu) { 00475 rec_scia = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_SCI_MXU"); 00476 rec_stda = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_STD_MXU"); 00477 rec_scis = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_SCI_MXU"); 00478 rec_stds = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_STD_MXU"); 00479 } 00480 else { 00481 rec_scia = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_SCI_MOS"); 00482 rec_stda = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_STD_MOS"); 00483 rec_scis = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_SCI_MOS"); 00484 rec_stds = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_STD_MOS"); 00485 } 00486 00487 nframes = rec_scia + rec_stda + rec_scis + rec_stds; 00488 00489 if (nframes == 0) { 00490 fors_align_sky_exit("Missing input rectified scientific spectra"); 00491 } 00492 if (nframes > 1) { 00493 cpl_msg_error(recipe, 00494 "Too many input rectified scientific spectra (%d > 1)", 00495 nframes); 00496 fors_align_sky_exit(NULL); 00497 } 00498 00499 if (cpl_frameset_count_tags(frameset, "MASTER_SKYLINECAT") > 1) 00500 fors_align_sky_exit("Too many in input: MASTER_SKYLINECAT"); 00501 00502 if (rec_scia) { 00503 if (mxu) { 00504 rectified_tag = "RECTIFIED_ALL_SCI_MXU"; 00505 wavemap_tag = "WAVELENGTH_MAP_SCI_MXU"; 00506 shifts_tag = "SKY_SHIFTS_SLIT_SCI_MXU"; 00507 disp_ali_tag = "DISP_COEFF_SCI_MXU"; 00508 } 00509 else { 00510 rectified_tag = "RECTIFIED_ALL_SCI_MOS"; 00511 wavemap_tag = "WAVELENGTH_MAP_SCI_MOS"; 00512 shifts_tag = "SKY_SHIFTS_SLIT_SCI_MOS"; 00513 disp_ali_tag = "DISP_COEFF_SCI_MOS"; 00514 } 00515 } 00516 else if (rec_stda) { 00517 if (mxu) { 00518 rectified_tag = "RECTIFIED_ALL_STD_MXU"; 00519 wavemap_tag = "WAVELENGTH_MAP_STD_MXU"; 00520 shifts_tag = "SKY_SHIFTS_SLIT_STD_MXU"; 00521 disp_ali_tag = "DISP_COEFF_STD_MXU"; 00522 } 00523 else { 00524 rectified_tag = "RECTIFIED_ALL_STD_MOS"; 00525 wavemap_tag = "WAVELENGTH_MAP_STD_MOS"; 00526 shifts_tag = "SKY_SHIFTS_SLIT_STD_MOS"; 00527 disp_ali_tag = "DISP_COEFF_STD_MOS"; 00528 } 00529 } 00530 else if (rec_scis) { 00531 if (mxu) { 00532 rectified_tag = "RECTIFIED_SKY_SCI_MXU"; 00533 wavemap_tag = "WAVELENGTH_MAP_SCI_MXU"; 00534 shifts_tag = "SKY_SHIFTS_SLIT_SCI_MXU"; 00535 disp_ali_tag = "DISP_COEFF_SCI_MXU"; 00536 } 00537 else { 00538 rectified_tag = "RECTIFIED_SKY_SCI_MOS"; 00539 wavemap_tag = "WAVELENGTH_MAP_SCI_MOS"; 00540 shifts_tag = "SKY_SHIFTS_SLIT_SCI_MOS"; 00541 disp_ali_tag = "DISP_COEFF_SCI_MOS"; 00542 } 00543 } 00544 else if (rec_stds) { 00545 if (mxu) { 00546 rectified_tag = "RECTIFIED_SKY_STD_MXU"; 00547 wavemap_tag = "WAVELENGTH_MAP_STD_MXU"; 00548 shifts_tag = "SKY_SHIFTS_SLIT_STD_MXU"; 00549 disp_ali_tag = "DISP_COEFF_STD_MXU"; 00550 } 00551 else { 00552 rectified_tag = "RECTIFIED_SKY_STD_MOS"; 00553 wavemap_tag = "WAVELENGTH_MAP_STD_MOS"; 00554 shifts_tag = "SKY_SHIFTS_SLIT_STD_MOS"; 00555 disp_ali_tag = "DISP_COEFF_STD_MOS"; 00556 } 00557 } 00558 00559 00560 if (mxu) { 00561 disp_coeff_tag = "DISP_COEFF_MXU"; 00562 curv_coeff_tag = "CURV_COEFF_MXU"; 00563 slit_location_tag = "SLIT_LOCATION_MXU"; 00564 spatial_map_tag = "SPATIAL_MAP_MXU"; 00565 } 00566 else { 00567 disp_coeff_tag = "DISP_COEFF_MOS"; 00568 curv_coeff_tag = "CURV_COEFF_MOS"; 00569 slit_location_tag = "SLIT_LOCATION_MOS"; 00570 spatial_map_tag = "SPATIAL_MAP_MOS"; 00571 } 00572 00573 nframes = cpl_frameset_count_tags(frameset, disp_coeff_tag); 00574 00575 if (nframes == 0) { 00576 cpl_msg_error(recipe, "Missing input %s\n", disp_coeff_tag); 00577 fors_align_sky_exit(NULL); 00578 } 00579 if (nframes > 1) { 00580 cpl_msg_error(recipe, 00581 "Too many input %s (%d > 1)", disp_coeff_tag, nframes); 00582 fors_align_sky_exit(NULL); 00583 } 00584 00585 nframes = cpl_frameset_count_tags(frameset, curv_coeff_tag); 00586 00587 if (nframes == 0) { 00588 cpl_msg_error(recipe, "Missing input %s\n", curv_coeff_tag); 00589 fors_align_sky_exit(NULL); 00590 } 00591 if (nframes > 1) { 00592 cpl_msg_error(recipe, 00593 "Too many input %s (%d > 1)", curv_coeff_tag, nframes); 00594 fors_align_sky_exit(NULL); 00595 } 00596 00597 nframes = cpl_frameset_count_tags(frameset, spatial_map_tag); 00598 00599 if (nframes == 0) { 00600 cpl_msg_error(recipe, "Missing input %s\n", spatial_map_tag); 00601 fors_align_sky_exit(NULL); 00602 } 00603 if (nframes > 1) { 00604 cpl_msg_error(recipe, 00605 "Too many input %s (%d > 1)", spatial_map_tag, nframes); 00606 fors_align_sky_exit(NULL); 00607 } 00608 00609 00610 header = dfs_load_header(frameset, spatial_map_tag, 0); 00611 00612 if (header == NULL) 00613 fors_align_sky_exit("Cannot load spatial map header"); 00614 00615 if (mos) 00616 maskslits = mos_load_slits_fors_mos(header); 00617 else 00618 maskslits = mos_load_slits_fors_mxu(header); 00619 00620 /* 00621 * Check if all slits have the same X offset: in such case, abort! 00622 */ 00623 00624 mxpos = cpl_table_get_column_median(maskslits, "xtop"); 00625 xpos = cpl_table_get_data_double(maskslits, "xtop"); 00626 nslits = cpl_table_get_nrow(maskslits); 00627 00628 treat_as_lss = 1; 00629 for (i = 0; i < nslits; i++) { 00630 if (fabs(mxpos-xpos[i]) > 0.01) { 00631 treat_as_lss = 0; 00632 break; 00633 } 00634 } 00635 00636 cpl_table_delete(maskslits); maskslits = NULL; 00637 00638 if (treat_as_lss) { 00639 cpl_msg_error(recipe, "All slits have the same offset: %.2f mm\n" 00640 "The LSS data reduction strategy must be applied. " 00641 "Please use recipe fors_align_sky_lss.", mxpos); 00642 fors_align_sky_exit(NULL); 00643 } 00644 00645 if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID")) 00646 fors_align_sky_exit("Input frames are not from the same grism"); 00647 00648 if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID")) 00649 fors_align_sky_exit("Input frames are not from the same filter"); 00650 00651 if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID")) 00652 fors_align_sky_exit("Input frames are not from the same chip"); 00653 00654 00655 /* 00656 * Get the reference wavelength and the rebin factor along the 00657 * dispersion direction from the reference frame 00658 */ 00659 00660 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME"); 00661 if (instrume == NULL) 00662 fors_align_sky_exit("Missing keyword INSTRUME in reference frame " 00663 "header"); 00664 00665 if (instrume[4] == '1') 00666 snprintf(version, 80, "%s/%s", "fors1", VERSION); 00667 if (instrume[4] == '2') 00668 snprintf(version, 80, "%s/%s", "fors2", VERSION); 00669 00670 reference = cpl_propertylist_get_double(header, "ESO INS GRIS1 WLEN"); 00671 00672 if (cpl_error_get_code() != CPL_ERROR_NONE) 00673 fors_align_sky_exit("Missing keyword ESO INS GRIS1 WLEN " 00674 "in reference frame header"); 00675 00676 if (reference < 3000.0) /* Perhaps in nanometers... */ 00677 reference *= 10; 00678 00679 if (reference < 3000.0 || reference > 13000.0) { 00680 cpl_msg_error(recipe, "Invalid central wavelength %.2f read from " 00681 "keyword ESO INS GRIS1 WLEN in reference frame header", 00682 reference); 00683 fors_align_sky_exit(NULL); 00684 } 00685 00686 cpl_msg_info(recipe, "The central wavelength is: %.2f", reference); 00687 00688 rebin = cpl_propertylist_get_int(header, "ESO DET WIN1 BINX"); 00689 00690 if (cpl_error_get_code() != CPL_ERROR_NONE) 00691 fors_align_sky_exit("Missing keyword ESO DET WIN1 BINX " 00692 "in reference frame header"); 00693 00694 if (rebin != 1) { 00695 dispersion *= rebin; 00696 cpl_msg_warning(recipe, "The rebin factor is %d, and therefore the " 00697 "working dispersion used is %f A/pixel", rebin, 00698 dispersion); 00699 } 00700 00701 cpl_msg_indent_less(); 00702 cpl_msg_info(recipe, "Load input frames..."); 00703 cpl_msg_indent_more(); 00704 00705 coordinate = dfs_load_image(frameset, spatial_map_tag, 00706 CPL_TYPE_FLOAT, 0, 0); 00707 if (coordinate == NULL) 00708 fors_align_sky_exit("Cannot load input reference frame"); 00709 00710 slits = dfs_load_table(frameset, slit_location_tag, 1); 00711 if (slits == NULL) 00712 fors_align_sky_exit("Cannot load slits location table"); 00713 00714 polytraces = dfs_load_table(frameset, curv_coeff_tag, 1); 00715 if (polytraces == NULL) 00716 fors_align_sky_exit("Cannot load spectral curvature table"); 00717 00718 idscoeff = dfs_load_table(frameset, disp_coeff_tag, 1); 00719 if (idscoeff == NULL) 00720 fors_align_sky_exit("Cannot load dispersion solution"); 00721 00722 smapped = dfs_load_image(frameset, rectified_tag, CPL_TYPE_FLOAT, 0, 0); 00723 if (smapped == NULL) 00724 fors_align_sky_exit("Cannot load input rectified frame"); 00725 00726 wavelengths = dfs_load_table(frameset, "MASTER_SKYLINECAT", 1); 00727 00728 if (wavelengths) { 00729 00730 /* 00731 * Cast the wavelengths into a (double precision) CPL vector 00732 */ 00733 00734 nlines = cpl_table_get_nrow(wavelengths); 00735 00736 if (nlines == 0) 00737 fors_align_sky_exit("Empty input sky line catalog"); 00738 00739 if (cpl_table_has_column(wavelengths, wcolumn) != 1) { 00740 cpl_msg_error(recipe, "Missing column %s in input line " 00741 "catalog table", wcolumn); 00742 fors_align_sky_exit(NULL); 00743 } 00744 00745 line = cpl_malloc(nlines * sizeof(double)); 00746 00747 for (i = 0; i < nlines; i++) 00748 line[i] = cpl_table_get(wavelengths, wcolumn, i, NULL); 00749 00750 cpl_table_delete(wavelengths); wavelengths = NULL; 00751 00752 lines = cpl_vector_wrap(nlines, line); 00753 } 00754 else { 00755 cpl_msg_info(recipe, "No sky line catalog found in input - fine!"); 00756 } 00757 00758 if (skyalign) { 00759 cpl_msg_info(recipe, "Align wavelength solution to reference " 00760 "skylines applying %d order residual fit...", skyalign); 00761 } 00762 else { 00763 cpl_msg_info(recipe, "Align wavelength solution to reference " 00764 "skylines applying median offset..."); 00765 } 00766 00767 if (dispersion > 1.0) 00768 highres = 0; 00769 else 00770 highres = 1; 00771 00772 nx = cpl_image_get_size_x(coordinate); 00773 00774 rainbow = mos_map_idscoeff(idscoeff, nx, reference, startwavelength, 00775 endwavelength); 00776 00777 offsets = mos_wavelength_align(smapped, slits, reference, 00778 startwavelength, endwavelength, 00779 idscoeff, lines, highres, skyalign, 00780 rainbow, 4); 00781 00782 cpl_vector_delete(lines); lines = NULL; 00783 cpl_image_delete(smapped); smapped = NULL; 00784 00785 if (offsets) { 00786 if (dfs_save_table(frameset, offsets, shifts_tag, NULL, 00787 parlist, recipe, version)) 00788 fors_align_sky_exit(NULL); 00789 00790 cpl_table_delete(offsets); offsets = NULL; 00791 } 00792 else 00793 fors_align_sky_exit("Alignment of the wavelength solution " 00794 "to reference sky lines could not be done!"); 00795 00796 if (dfs_save_table(frameset, idscoeff, disp_ali_tag, NULL, 00797 parlist, recipe, version)) 00798 fors_align_sky_exit(NULL); 00799 00800 cpl_table_delete(idscoeff); idscoeff = NULL; 00801 00802 wavemap = mos_map_wavelengths(coordinate, rainbow, slits, 00803 polytraces, reference, 00804 startwavelength, endwavelength, 00805 dispersion); 00806 00807 cpl_image_delete(rainbow); rainbow = NULL; 00808 cpl_image_delete(coordinate); coordinate = NULL; 00809 cpl_table_delete(polytraces); polytraces = NULL; 00810 cpl_table_delete(slits); slits = NULL; 00811 00812 if (dfs_save_image(frameset, wavemap, wavemap_tag, 00813 header, parlist, recipe, version)) 00814 fors_align_sky_exit(NULL); 00815 00816 cpl_image_delete(wavemap); wavemap = NULL; 00817 cpl_propertylist_delete(header); header = NULL; 00818 00819 return 0; 00820 }