00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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 ((const char *)message != NULL) 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 ((const char *)message != NULL) 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
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
00200
00201
00202 recipe->parameters = cpl_parameterlist_new();
00203
00204
00205
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
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
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
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
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
00336
00337
00338 double dispersion;
00339 double startwavelength;
00340 double endwavelength;
00341 int skyalign;
00342 const char *wcolumn;
00343
00344
00345
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
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 nlines;
00378 int nx;
00379 int highres;
00380 int treat_as_lss;
00381 int i;
00382 double reference;
00383 double mxpos;
00384 double *line;
00385 int mxu, mos;
00386 int rec_scia;
00387 int rec_stda;
00388 int rec_scis;
00389 int rec_stds;
00390 int nslits_out_det = 0;
00391
00392
00393 char *instrume = NULL;
00394
00395
00396 cpl_msg_set_indentation(2);
00397
00398
00399
00400
00401
00402
00403 cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe);
00404 cpl_msg_indent_more();
00405
00406 if (cpl_frameset_count_tags(frameset, "GRISM_TABLE") > 1)
00407 fors_align_sky_exit("Too many in input: GRISM_TABLE");
00408
00409 grism_table = dfs_load_table(frameset, "GRISM_TABLE", 1);
00410
00411 dispersion = dfs_get_parameter_double(parlist,
00412 "fors.fors_align_sky.dispersion", grism_table);
00413
00414 if (dispersion <= 0.0)
00415 fors_align_sky_exit("Invalid spectral dispersion value");
00416
00417 startwavelength = dfs_get_parameter_double(parlist,
00418 "fors.fors_align_sky.startwavelength", grism_table);
00419 if (startwavelength > 1.0)
00420 if (startwavelength < 3000.0 || startwavelength > 13000.0)
00421 fors_align_sky_exit("Invalid wavelength");
00422
00423 endwavelength = dfs_get_parameter_double(parlist,
00424 "fors.fors_align_sky.endwavelength", grism_table);
00425 if (endwavelength > 1.0) {
00426 if (endwavelength < 3000.0 || endwavelength > 13000.0)
00427 fors_align_sky_exit("Invalid wavelength");
00428 if (startwavelength < 1.0)
00429 fors_align_sky_exit("Invalid wavelength interval");
00430 }
00431
00432 if (startwavelength > 1.0)
00433 if (endwavelength - startwavelength <= 0.0)
00434 fors_align_sky_exit("Invalid wavelength interval");
00435
00436 skyalign = dfs_get_parameter_int(parlist,
00437 "fors.fors_align_sky.skyalign", NULL);
00438
00439 if (skyalign < 0)
00440 fors_align_sky_exit("Invalid polynomial degree");
00441 if (skyalign > 2)
00442 fors_align_sky_exit("Max polynomial degree for sky alignment is 2");
00443
00444 wcolumn = dfs_get_parameter_string(parlist,
00445 "fors.fors_align_sky.wcolumn", NULL);
00446
00447 cpl_table_delete(grism_table); grism_table = NULL;
00448
00449 if (cpl_error_get_code())
00450 fors_align_sky_exit("Failure reading the configuration parameters");
00451
00452
00453 cpl_msg_indent_less();
00454 cpl_msg_info(recipe, "Check input set-of-frames:");
00455 cpl_msg_indent_more();
00456
00457 mxu = cpl_frameset_count_tags(frameset, "SPATIAL_MAP_MXU");
00458 mos = cpl_frameset_count_tags(frameset, "SPATIAL_MAP_MOS");
00459
00460 nframes = mos + mxu;
00461
00462 if (nframes == 0) {
00463 fors_align_sky_exit("Missing input spatial map");
00464 }
00465 if (nframes > 1) {
00466 cpl_msg_error(recipe,
00467 "Too many input spatial maps (%d > 1)", nframes);
00468 fors_align_sky_exit(NULL);
00469 }
00470
00471 if (mxu) {
00472 rec_scia = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_SCI_MXU");
00473 rec_stda = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_STD_MXU");
00474 rec_scis = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_SCI_MXU");
00475 rec_stds = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_STD_MXU");
00476 }
00477 else {
00478 rec_scia = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_SCI_MOS");
00479 rec_stda = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_STD_MOS");
00480 rec_scis = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_SCI_MOS");
00481 rec_stds = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_STD_MOS");
00482 }
00483
00484 nframes = rec_scia + rec_stda + rec_scis + rec_stds;
00485
00486 if (nframes == 0) {
00487 fors_align_sky_exit("Missing input rectified scientific spectra");
00488 }
00489 if (nframes > 1) {
00490 cpl_msg_error(recipe,
00491 "Too many input rectified scientific spectra (%d > 1)",
00492 nframes);
00493 fors_align_sky_exit(NULL);
00494 }
00495
00496 if (cpl_frameset_count_tags(frameset, "MASTER_SKYLINECAT") > 1)
00497 fors_align_sky_exit("Too many in input: MASTER_SKYLINECAT");
00498
00499 if (rec_scia) {
00500 if (mxu) {
00501 rectified_tag = "RECTIFIED_ALL_SCI_MXU";
00502 wavemap_tag = "WAVELENGTH_MAP_SCI_MXU";
00503 shifts_tag = "SKY_SHIFTS_SLIT_SCI_MXU";
00504 disp_ali_tag = "DISP_COEFF_SCI_MXU";
00505 }
00506 else {
00507 rectified_tag = "RECTIFIED_ALL_SCI_MOS";
00508 wavemap_tag = "WAVELENGTH_MAP_SCI_MOS";
00509 shifts_tag = "SKY_SHIFTS_SLIT_SCI_MOS";
00510 disp_ali_tag = "DISP_COEFF_SCI_MOS";
00511 }
00512 }
00513 else if (rec_stda) {
00514 if (mxu) {
00515 rectified_tag = "RECTIFIED_ALL_STD_MXU";
00516 wavemap_tag = "WAVELENGTH_MAP_STD_MXU";
00517 shifts_tag = "SKY_SHIFTS_SLIT_STD_MXU";
00518 disp_ali_tag = "DISP_COEFF_STD_MXU";
00519 }
00520 else {
00521 rectified_tag = "RECTIFIED_ALL_STD_MOS";
00522 wavemap_tag = "WAVELENGTH_MAP_STD_MOS";
00523 shifts_tag = "SKY_SHIFTS_SLIT_STD_MOS";
00524 disp_ali_tag = "DISP_COEFF_STD_MOS";
00525 }
00526 }
00527 else if (rec_scis) {
00528 if (mxu) {
00529 rectified_tag = "RECTIFIED_SKY_SCI_MXU";
00530 wavemap_tag = "WAVELENGTH_MAP_SCI_MXU";
00531 shifts_tag = "SKY_SHIFTS_SLIT_SCI_MXU";
00532 disp_ali_tag = "DISP_COEFF_SCI_MXU";
00533 }
00534 else {
00535 rectified_tag = "RECTIFIED_SKY_SCI_MOS";
00536 wavemap_tag = "WAVELENGTH_MAP_SCI_MOS";
00537 shifts_tag = "SKY_SHIFTS_SLIT_SCI_MOS";
00538 disp_ali_tag = "DISP_COEFF_SCI_MOS";
00539 }
00540 }
00541 else if (rec_stds) {
00542 if (mxu) {
00543 rectified_tag = "RECTIFIED_SKY_STD_MXU";
00544 wavemap_tag = "WAVELENGTH_MAP_STD_MXU";
00545 shifts_tag = "SKY_SHIFTS_SLIT_STD_MXU";
00546 disp_ali_tag = "DISP_COEFF_STD_MXU";
00547 }
00548 else {
00549 rectified_tag = "RECTIFIED_SKY_STD_MOS";
00550 wavemap_tag = "WAVELENGTH_MAP_STD_MOS";
00551 shifts_tag = "SKY_SHIFTS_SLIT_STD_MOS";
00552 disp_ali_tag = "DISP_COEFF_STD_MOS";
00553 }
00554 }
00555
00556
00557 if (mxu) {
00558 disp_coeff_tag = "DISP_COEFF_MXU";
00559 curv_coeff_tag = "CURV_COEFF_MXU";
00560 slit_location_tag = "SLIT_LOCATION_MXU";
00561 spatial_map_tag = "SPATIAL_MAP_MXU";
00562 }
00563 else {
00564 disp_coeff_tag = "DISP_COEFF_MOS";
00565 curv_coeff_tag = "CURV_COEFF_MOS";
00566 slit_location_tag = "SLIT_LOCATION_MOS";
00567 spatial_map_tag = "SPATIAL_MAP_MOS";
00568 }
00569
00570 nframes = cpl_frameset_count_tags(frameset, disp_coeff_tag);
00571
00572 if (nframes == 0) {
00573 cpl_msg_error(recipe, "Missing input %s\n", disp_coeff_tag);
00574 fors_align_sky_exit(NULL);
00575 }
00576 if (nframes > 1) {
00577 cpl_msg_error(recipe,
00578 "Too many input %s (%d > 1)", disp_coeff_tag, nframes);
00579 fors_align_sky_exit(NULL);
00580 }
00581
00582 nframes = cpl_frameset_count_tags(frameset, curv_coeff_tag);
00583
00584 if (nframes == 0) {
00585 cpl_msg_error(recipe, "Missing input %s\n", curv_coeff_tag);
00586 fors_align_sky_exit(NULL);
00587 }
00588 if (nframes > 1) {
00589 cpl_msg_error(recipe,
00590 "Too many input %s (%d > 1)", curv_coeff_tag, nframes);
00591 fors_align_sky_exit(NULL);
00592 }
00593
00594 nframes = cpl_frameset_count_tags(frameset, spatial_map_tag);
00595
00596 if (nframes == 0) {
00597 cpl_msg_error(recipe, "Missing input %s\n", spatial_map_tag);
00598 fors_align_sky_exit(NULL);
00599 }
00600 if (nframes > 1) {
00601 cpl_msg_error(recipe,
00602 "Too many input %s (%d > 1)", spatial_map_tag, nframes);
00603 fors_align_sky_exit(NULL);
00604 }
00605
00606
00607 header = dfs_load_header(frameset, spatial_map_tag, 0);
00608
00609 if (header == NULL)
00610 fors_align_sky_exit("Cannot load spatial map header");
00611
00612 if (mos)
00613 maskslits = mos_load_slits_fors_mos(header, &nslits_out_det);
00614 else
00615 maskslits = mos_load_slits_fors_mxu(header);
00616
00617
00618
00619
00620
00621 treat_as_lss = fors_mos_is_lss_like(maskslits, nslits_out_det);
00622
00623 cpl_table_delete(maskslits); maskslits = NULL;
00624
00625 if (treat_as_lss) {
00626 cpl_msg_error(recipe, "All slits have the same offset: %.2f mm\n"
00627 "The LSS data reduction strategy must be applied. "
00628 "Please use recipe fors_align_sky_lss.", mxpos);
00629 fors_align_sky_exit(NULL);
00630 }
00631
00632 if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
00633 cpl_msg_warning(cpl_func,"Input frames are not from the same grism");
00634
00635 if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
00636 cpl_msg_warning(cpl_func,"Input frames are not from the same filter");
00637
00638 if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
00639 cpl_msg_warning(cpl_func,"Input frames are not from the same chip");
00640
00641
00642
00643
00644
00645
00646
00647 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00648 if (instrume == NULL)
00649 fors_align_sky_exit("Missing keyword INSTRUME in reference frame "
00650 "header");
00651
00652 if (instrume[4] == '1')
00653 snprintf(version, 80, "%s/%s", "fors1", VERSION);
00654 if (instrume[4] == '2')
00655 snprintf(version, 80, "%s/%s", "fors2", VERSION);
00656
00657 reference = cpl_propertylist_get_double(header, "ESO INS GRIS1 WLEN");
00658
00659 if (cpl_error_get_code() != CPL_ERROR_NONE)
00660 fors_align_sky_exit("Missing keyword ESO INS GRIS1 WLEN "
00661 "in reference frame header");
00662
00663 if (reference < 3000.0)
00664 reference *= 10;
00665
00666 if (reference < 3000.0 || reference > 13000.0) {
00667 cpl_msg_error(recipe, "Invalid central wavelength %.2f read from "
00668 "keyword ESO INS GRIS1 WLEN in reference frame header",
00669 reference);
00670 fors_align_sky_exit(NULL);
00671 }
00672
00673 cpl_msg_info(recipe, "The central wavelength is: %.2f", reference);
00674
00675 rebin = cpl_propertylist_get_int(header, "ESO DET WIN1 BINX");
00676
00677 if (cpl_error_get_code() != CPL_ERROR_NONE)
00678 fors_align_sky_exit("Missing keyword ESO DET WIN1 BINX "
00679 "in reference frame header");
00680
00681 if (rebin != 1) {
00682 dispersion *= rebin;
00683 cpl_msg_warning(recipe, "The rebin factor is %d, and therefore the "
00684 "working dispersion used is %f A/pixel", rebin,
00685 dispersion);
00686 }
00687
00688 cpl_msg_indent_less();
00689 cpl_msg_info(recipe, "Load input frames...");
00690 cpl_msg_indent_more();
00691
00692 coordinate = dfs_load_image(frameset, spatial_map_tag,
00693 CPL_TYPE_FLOAT, 0, 0);
00694 if (coordinate == NULL)
00695 fors_align_sky_exit("Cannot load input reference frame");
00696
00697 slits = dfs_load_table(frameset, slit_location_tag, 1);
00698 if (slits == NULL)
00699 fors_align_sky_exit("Cannot load slits location table");
00700
00701 polytraces = dfs_load_table(frameset, curv_coeff_tag, 1);
00702 if (polytraces == NULL)
00703 fors_align_sky_exit("Cannot load spectral curvature table");
00704
00705 idscoeff = dfs_load_table(frameset, disp_coeff_tag, 1);
00706 if (idscoeff == NULL)
00707 fors_align_sky_exit("Cannot load dispersion solution");
00708
00709 smapped = dfs_load_image(frameset, rectified_tag, CPL_TYPE_FLOAT, 0, 0);
00710 if (smapped == NULL)
00711 fors_align_sky_exit("Cannot load input rectified frame");
00712
00713 wavelengths = dfs_load_table(frameset, "MASTER_SKYLINECAT", 1);
00714
00715 if (wavelengths) {
00716
00717
00718
00719
00720
00721 nlines = cpl_table_get_nrow(wavelengths);
00722
00723 if (nlines == 0)
00724 fors_align_sky_exit("Empty input sky line catalog");
00725
00726 if (cpl_table_has_column(wavelengths, wcolumn) != 1) {
00727 cpl_msg_error(recipe, "Missing column %s in input line "
00728 "catalog table", wcolumn);
00729 fors_align_sky_exit(NULL);
00730 }
00731
00732 line = cpl_malloc(nlines * sizeof(double));
00733
00734 for (i = 0; i < nlines; i++)
00735 line[i] = cpl_table_get(wavelengths, wcolumn, i, NULL);
00736
00737 cpl_table_delete(wavelengths); wavelengths = NULL;
00738
00739 lines = cpl_vector_wrap(nlines, line);
00740 }
00741 else {
00742 cpl_msg_info(recipe, "No sky line catalog found in input - fine!");
00743 }
00744
00745 if (skyalign) {
00746 cpl_msg_info(recipe, "Align wavelength solution to reference "
00747 "skylines applying %d order residual fit...", skyalign);
00748 }
00749 else {
00750 cpl_msg_info(recipe, "Align wavelength solution to reference "
00751 "skylines applying median offset...");
00752 }
00753
00754 if (dispersion > 1.0)
00755 highres = 0;
00756 else
00757 highres = 1;
00758
00759 nx = cpl_image_get_size_x(coordinate);
00760
00761 rainbow = mos_map_idscoeff(idscoeff, nx, reference, startwavelength,
00762 endwavelength);
00763
00764 offsets = mos_wavelength_align(smapped, slits, reference,
00765 startwavelength, endwavelength,
00766 idscoeff, lines, highres, skyalign,
00767 rainbow, 4);
00768
00769 cpl_vector_delete(lines); lines = NULL;
00770 cpl_image_delete(smapped); smapped = NULL;
00771
00772 if (offsets) {
00773 if (dfs_save_table(frameset, offsets, shifts_tag, NULL,
00774 parlist, recipe, version))
00775 fors_align_sky_exit(NULL);
00776
00777 cpl_table_delete(offsets); offsets = NULL;
00778 }
00779 else
00780 fors_align_sky_exit("Alignment of the wavelength solution "
00781 "to reference sky lines could not be done!");
00782
00783 if (dfs_save_table(frameset, idscoeff, disp_ali_tag, NULL,
00784 parlist, recipe, version))
00785 fors_align_sky_exit(NULL);
00786
00787 cpl_table_delete(idscoeff); idscoeff = NULL;
00788
00789 wavemap = mos_map_wavelengths(coordinate, rainbow, slits,
00790 polytraces, reference,
00791 startwavelength, endwavelength,
00792 dispersion);
00793
00794 cpl_image_delete(rainbow); rainbow = NULL;
00795 cpl_image_delete(coordinate); coordinate = NULL;
00796 cpl_table_delete(polytraces); polytraces = NULL;
00797 cpl_table_delete(slits); slits = NULL;
00798
00799 if (dfs_save_image(frameset, wavemap, wavemap_tag,
00800 header, parlist, recipe, version))
00801 fors_align_sky_exit(NULL);
00802
00803 cpl_image_delete(wavemap); wavemap = NULL;
00804 cpl_propertylist_delete(header); header = NULL;
00805
00806 return 0;
00807 }