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 (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
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 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
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
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
00657
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)
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
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 }