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