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 ((const char *)message != NULL) 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 ((const char *)message != NULL) 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 nlines;
00369 int nx;
00370 int ccd_xsize, ccd_ysize;
00371 int first_row, last_row;
00372 int ylow, yhig;
00373 int highres;
00374 int treat_as_lss;
00375 int i;
00376 double reference;
00377 double *line;
00378 int mxu, mos, lss;
00379 int rec_scib;
00380 int rec_stdb;
00381 int rec_scif;
00382 int rec_stdf;
00383 int nslits_out_det = 0;
00384
00385 char *instrume = NULL;
00386
00387
00388 cpl_msg_set_indentation(2);
00389
00390
00391
00392
00393
00394
00395 cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe);
00396 cpl_msg_indent_more();
00397
00398 if (cpl_frameset_count_tags(frameset, "GRISM_TABLE") > 1)
00399 fors_align_sky_lss_exit("Too many in input: GRISM_TABLE");
00400
00401 grism_table = dfs_load_table(frameset, "GRISM_TABLE", 1);
00402
00403 dispersion = dfs_get_parameter_double(parlist,
00404 "fors.fors_align_sky_lss.dispersion", grism_table);
00405
00406 if (dispersion <= 0.0)
00407 fors_align_sky_lss_exit("Invalid spectral dispersion value");
00408
00409 startwavelength = dfs_get_parameter_double(parlist,
00410 "fors.fors_align_sky_lss.startwavelength", grism_table);
00411 if (startwavelength > 1.0)
00412 if (startwavelength < 3000.0 || startwavelength > 13000.0)
00413 fors_align_sky_lss_exit("Invalid wavelength");
00414
00415 endwavelength = dfs_get_parameter_double(parlist,
00416 "fors.fors_align_sky_lss.endwavelength", grism_table);
00417 if (endwavelength > 1.0) {
00418 if (endwavelength < 3000.0 || endwavelength > 13000.0)
00419 fors_align_sky_lss_exit("Invalid wavelength");
00420 if (startwavelength < 1.0)
00421 fors_align_sky_lss_exit("Invalid wavelength interval");
00422 }
00423
00424 if (startwavelength > 1.0)
00425 if (endwavelength - startwavelength <= 0.0)
00426 fors_align_sky_lss_exit("Invalid wavelength interval");
00427
00428 skyalign = dfs_get_parameter_int(parlist,
00429 "fors.fors_align_sky_lss.skyalign", NULL);
00430
00431 if (skyalign < 0)
00432 fors_align_sky_lss_exit("Invalid polynomial degree");
00433 if (skyalign > 2)
00434 fors_align_sky_lss_exit("Max polynomial degree for sky alignment is 2");
00435
00436 wcolumn = dfs_get_parameter_string(parlist,
00437 "fors.fors_align_sky_lss.wcolumn", NULL);
00438
00439 cpl_table_delete(grism_table); grism_table = NULL;
00440
00441 if (cpl_error_get_code())
00442 fors_align_sky_lss_exit("Failure reading the configuration parameters");
00443
00444
00445 cpl_msg_indent_less();
00446 cpl_msg_info(recipe, "Check input set-of-frames:");
00447 cpl_msg_indent_more();
00448
00449 mxu = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_MXU");
00450 mos = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_MOS");
00451 lss = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_LSS");
00452
00453 nframes = mos + mxu + lss;
00454
00455 if (nframes == 0) {
00456 fors_align_sky_lss_exit("Missing input slit location table");
00457 }
00458 if (nframes > 1) {
00459 cpl_msg_error(recipe,
00460 "Too many input slit location tables (%d > 1)", nframes);
00461 fors_align_sky_lss_exit(NULL);
00462 }
00463
00464 if (mxu) {
00465 rec_scib = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_MXU");
00466 rec_stdb = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_MXU");
00467 rec_scif = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_MXU");
00468 rec_stdf = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_MXU");
00469 }
00470 else if (mos) {
00471 rec_scib = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_MOS");
00472 rec_stdb = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_MOS");
00473 rec_scif = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_MOS");
00474 rec_stdf = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_MOS");
00475 }
00476 else {
00477 rec_scib = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_LSS");
00478 rec_stdb = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_LSS");
00479 rec_scif = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_LSS");
00480 rec_stdf = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_LSS");
00481 }
00482
00483 nframes = rec_scib + rec_stdb + rec_scif + rec_stdf;
00484
00485 if (nframes == 0) {
00486 fors_align_sky_lss_exit("Missing input scientific spectra");
00487 }
00488 if (nframes > 1) {
00489 cpl_msg_error(recipe, "Too many input scientific spectra (%d > 1)",
00490 nframes);
00491 fors_align_sky_lss_exit(NULL);
00492 }
00493
00494 if (cpl_frameset_count_tags(frameset, "MASTER_SKYLINECAT") > 1)
00495 fors_align_sky_lss_exit("Too many in input: MASTER_SKYLINECAT");
00496
00497 if (rec_scib) {
00498 if (mxu) {
00499 rectified_tag = "SCIENCE_UNBIAS_MXU";
00500 wavemap_tag = "WAVELENGTH_MAP_SCI_MXU";
00501 shifts_tag = "SKY_SHIFTS_LONG_SCI_MXU";
00502 disp_ali_tag = "DISP_COEFF_SCI_MXU";
00503 }
00504 else if (mos) {
00505 rectified_tag = "SCIENCE_UNBIAS_MOS";
00506 wavemap_tag = "WAVELENGTH_MAP_SCI_MOS";
00507 shifts_tag = "SKY_SHIFTS_LONG_SCI_MOS";
00508 disp_ali_tag = "DISP_COEFF_SCI_MOS";
00509 }
00510 else {
00511 rectified_tag = "SCIENCE_UNBIAS_LSS";
00512 wavemap_tag = "WAVELENGTH_MAP_SCI_LSS";
00513 shifts_tag = "SKY_SHIFTS_LONG_SCI_LSS";
00514 disp_ali_tag = "DISP_COEFF_SCI_LSS";
00515 }
00516 }
00517 else if (rec_stdb) {
00518 if (mxu) {
00519 rectified_tag = "STANDARD_UNBIAS_MXU";
00520 wavemap_tag = "WAVELENGTH_MAP_STD_MXU";
00521 shifts_tag = "SKY_SHIFTS_LONG_STD_MXU";
00522 disp_ali_tag = "DISP_COEFF_STD_MXU";
00523 }
00524 else if (mos) {
00525 rectified_tag = "STANDARD_UNBIAS_MOS";
00526 wavemap_tag = "WAVELENGTH_MAP_STD_MOS";
00527 shifts_tag = "SKY_SHIFTS_LONG_STD_MOS";
00528 disp_ali_tag = "DISP_COEFF_STD_MOS";
00529 }
00530 else {
00531 rectified_tag = "STANDARD_UNBIAS_LSS";
00532 wavemap_tag = "WAVELENGTH_MAP_STD_LSS";
00533 shifts_tag = "SKY_SHIFTS_LONG_STD_LSS";
00534 disp_ali_tag = "DISP_COEFF_STD_LSS";
00535 }
00536 }
00537 else if (rec_scif) {
00538 if (mxu) {
00539 rectified_tag = "SCIENCE_UNFLAT_MXU";
00540 wavemap_tag = "WAVELENGTH_MAP_SCI_MXU";
00541 shifts_tag = "SKY_SHIFTS_LONG_SCI_MXU";
00542 disp_ali_tag = "DISP_COEFF_SCI_MXU";
00543 }
00544 else if (mos) {
00545 rectified_tag = "SCIENCE_UNFLAT_MOS";
00546 wavemap_tag = "WAVELENGTH_MAP_SCI_MOS";
00547 shifts_tag = "SKY_SHIFTS_LONG_SCI_MOS";
00548 disp_ali_tag = "DISP_COEFF_SCI_MOS";
00549 }
00550 else {
00551 rectified_tag = "SCIENCE_UNFLAT_LSS";
00552 wavemap_tag = "WAVELENGTH_MAP_SCI_LSS";
00553 shifts_tag = "SKY_SHIFTS_LONG_SCI_LSS";
00554 disp_ali_tag = "DISP_COEFF_SCI_LSS";
00555 }
00556 }
00557 else if (rec_stdf) {
00558 if (mxu) {
00559 rectified_tag = "STANDARD_UNFLAT_MXU";
00560 wavemap_tag = "WAVELENGTH_MAP_STD_MXU";
00561 shifts_tag = "SKY_SHIFTS_LONG_STD_MXU";
00562 disp_ali_tag = "DISP_COEFF_STD_MXU";
00563 }
00564 else if (mos) {
00565 rectified_tag = "STANDARD_UNFLAT_MOS";
00566 wavemap_tag = "WAVELENGTH_MAP_STD_MOS";
00567 shifts_tag = "SKY_SHIFTS_LONG_STD_MOS";
00568 disp_ali_tag = "DISP_COEFF_STD_MOS";
00569 }
00570 else {
00571 rectified_tag = "STANDARD_UNFLAT_LSS";
00572 wavemap_tag = "WAVELENGTH_MAP_STD_LSS";
00573 shifts_tag = "SKY_SHIFTS_LONG_STD_LSS";
00574 disp_ali_tag = "DISP_COEFF_STD_LSS";
00575 }
00576 }
00577
00578 nframes = cpl_frameset_count_tags(frameset, rectified_tag);
00579
00580 if (nframes == 0) {
00581 cpl_msg_error(recipe, "Missing input %s", rectified_tag);
00582 fors_align_sky_lss_exit(NULL);
00583 }
00584 if (nframes > 1) {
00585 cpl_msg_error(recipe, "Too many input %s (%d > 1)", rectified_tag,
00586 nframes);
00587 fors_align_sky_lss_exit(NULL);
00588 }
00589
00590
00591 if (mxu) {
00592 disp_coeff_tag = "DISP_COEFF_MXU";
00593 slit_location_tag = "SLIT_LOCATION_MXU";
00594 }
00595 else if (mos) {
00596 disp_coeff_tag = "DISP_COEFF_MOS";
00597 slit_location_tag = "SLIT_LOCATION_MOS";
00598 }
00599 else {
00600 disp_coeff_tag = "DISP_COEFF_LSS";
00601 slit_location_tag = "SLIT_LOCATION_LSS";
00602 }
00603
00604 nframes = cpl_frameset_count_tags(frameset, disp_coeff_tag);
00605
00606 if (nframes == 0) {
00607 cpl_msg_error(recipe, "Missing input %s", disp_coeff_tag);
00608 fors_align_sky_lss_exit(NULL);
00609 }
00610 if (nframes > 1) {
00611 cpl_msg_error(recipe, "Too many input %s (%d > 1)", disp_coeff_tag,
00612 nframes);
00613 fors_align_sky_lss_exit(NULL);
00614 }
00615
00616
00617 header = dfs_load_header(frameset, rectified_tag, 0);
00618
00619 if (header == NULL)
00620 fors_align_sky_lss_exit("Cannot load scientific frame header");
00621
00622 if (mos || mxu) {
00623 if (mos)
00624 maskslits = mos_load_slits_fors_mos(header, &nslits_out_det);
00625 else
00626 maskslits = mos_load_slits_fors_mxu(header);
00627
00628
00629
00630
00631
00632 treat_as_lss = fors_mos_is_lss_like(maskslits, nslits_out_det);
00633
00634 cpl_table_delete(maskslits); maskslits = NULL;
00635
00636 if (!treat_as_lss)
00637 fors_align_sky_lss_exit("This is not an LSS observation. "
00638 "Please use recipe fors_align_sky");
00639 }
00640
00641 if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
00642 cpl_msg_warning(cpl_func,"Input frames are not from the same grism");
00643
00644 if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
00645 cpl_msg_warning(cpl_func,"Input frames are not from the same filter");
00646
00647 if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
00648 cpl_msg_warning(cpl_func,"Input frames are not from the same chip");
00649
00650
00651
00652
00653
00654
00655
00656 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00657 if (instrume == NULL)
00658 fors_align_sky_lss_exit("Missing keyword INSTRUME in reference frame "
00659 "header");
00660
00661 if (instrume[4] == '1')
00662 snprintf(version, 80, "%s/%s", "fors1", VERSION);
00663 if (instrume[4] == '2')
00664 snprintf(version, 80, "%s/%s", "fors2", VERSION);
00665
00666 reference = cpl_propertylist_get_double(header, "ESO INS GRIS1 WLEN");
00667
00668 if (cpl_error_get_code() != CPL_ERROR_NONE)
00669 fors_align_sky_lss_exit("Missing keyword ESO INS GRIS1 WLEN "
00670 "in reference frame header");
00671
00672 if (reference < 3000.0)
00673 reference *= 10;
00674
00675 if (reference < 3000.0 || reference > 13000.0) {
00676 cpl_msg_error(recipe, "Invalid central wavelength %.2f read from "
00677 "keyword ESO INS GRIS1 WLEN in reference frame header",
00678 reference);
00679 fors_align_sky_lss_exit(NULL);
00680 }
00681
00682 cpl_msg_info(recipe, "The central wavelength is: %.2f", reference);
00683
00684 rebin = cpl_propertylist_get_int(header, "ESO DET WIN1 BINX");
00685
00686 if (cpl_error_get_code() != CPL_ERROR_NONE)
00687 fors_align_sky_lss_exit("Missing keyword ESO DET WIN1 BINX "
00688 "in reference frame header");
00689
00690 if (rebin != 1) {
00691 dispersion *= rebin;
00692 cpl_msg_warning(recipe, "The rebin factor is %d, and therefore the "
00693 "working dispersion used is %f A/pixel", rebin,
00694 dispersion);
00695 }
00696
00697
00698 cpl_msg_indent_less();
00699 cpl_msg_info(recipe, "Load input frames...");
00700 cpl_msg_indent_more();
00701
00702 smapped = dfs_load_image(frameset, rectified_tag, CPL_TYPE_FLOAT, 0, 0);
00703 if (smapped == NULL)
00704 fors_align_sky_lss_exit("Cannot load input scientific frame");
00705
00706 slits = dfs_load_table(frameset, slit_location_tag, 1);
00707 if (slits == NULL)
00708 fors_align_sky_lss_exit("Cannot load slits location table");
00709
00710 first_row = cpl_table_get_double(slits, "ybottom", 0, NULL);
00711 last_row = cpl_table_get_double(slits, "ytop", 0, NULL);
00712
00713 ylow = first_row + 1;
00714 yhig = last_row + 1;
00715
00716 ccd_xsize = cpl_image_get_size_x(smapped);
00717 ccd_ysize = cpl_image_get_size_x(smapped);
00718 dummy = cpl_image_extract(smapped, 1, ylow, ccd_xsize, yhig);
00719 cpl_image_delete(smapped); smapped = dummy;
00720 nx = ccd_xsize;
00721
00722 cpl_table_delete(slits); slits = NULL;
00723
00724 idscoeff = dfs_load_table(frameset, disp_coeff_tag, 1);
00725 if (idscoeff == NULL)
00726 fors_align_sky_lss_exit("Cannot load dispersion solution");
00727
00728 wavelengths = dfs_load_table(frameset, "MASTER_SKYLINECAT", 1);
00729
00730 if (wavelengths) {
00731
00732
00733
00734
00735
00736 nlines = cpl_table_get_nrow(wavelengths);
00737
00738 if (nlines == 0)
00739 fors_align_sky_lss_exit("Empty input sky line catalog");
00740
00741 if (cpl_table_has_column(wavelengths, wcolumn) != 1) {
00742 cpl_msg_error(recipe, "Missing column %s in input line "
00743 "catalog table", wcolumn);
00744 fors_align_sky_lss_exit(NULL);
00745 }
00746
00747 line = cpl_malloc(nlines * sizeof(double));
00748
00749 for (i = 0; i < nlines; i++)
00750 line[i] = cpl_table_get(wavelengths, wcolumn, i, NULL);
00751
00752 cpl_table_delete(wavelengths); wavelengths = NULL;
00753
00754 lines = cpl_vector_wrap(nlines, line);
00755 }
00756 else {
00757 cpl_msg_info(recipe, "No sky line catalog found in input - fine!");
00758 }
00759
00760 if (skyalign) {
00761 cpl_msg_info(recipe, "Align wavelength solution to reference "
00762 "skylines applying %d order residual fit...", skyalign);
00763 }
00764 else {
00765 cpl_msg_info(recipe, "Align wavelength solution to reference "
00766 "skylines applying median offset...");
00767 }
00768
00769 if (dispersion > 1.0)
00770 highres = 0;
00771 else
00772 highres = 1;
00773
00774 rainbow = mos_map_idscoeff(idscoeff, nx, reference, startwavelength,
00775 endwavelength);
00776
00777 offsets = mos_wavelength_align_lss(smapped, reference,
00778 startwavelength, endwavelength,
00779 idscoeff, lines, highres,
00780 skyalign, 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_lss_exit(NULL);
00789
00790 cpl_table_delete(offsets); offsets = NULL;
00791 }
00792 else
00793 fors_align_sky_lss_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_lss_exit(NULL);
00799
00800 cpl_table_delete(idscoeff); idscoeff = NULL;
00801
00802 wavemap = cpl_image_new(ccd_xsize, ccd_ysize, CPL_TYPE_FLOAT);
00803 cpl_image_copy(wavemap, rainbow, 1, ylow);
00804
00805 cpl_image_delete(rainbow); rainbow = NULL;
00806
00807 if (dfs_save_image(frameset, wavemap, wavemap_tag,
00808 header, parlist, recipe, version))
00809 fors_align_sky_lss_exit(NULL);
00810
00811 cpl_image_delete(wavemap); wavemap = NULL;
00812 cpl_propertylist_delete(header); header = NULL;
00813
00814 return 0;
00815 }