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_extract_slits_create(cpl_plugin *);
00038 static int fors_extract_slits_exec(cpl_plugin *);
00039 static int fors_extract_slits_destroy(cpl_plugin *);
00040 static int fors_extract_slits(cpl_parameterlist *, cpl_frameset *);
00041
00042 static char fors_extract_slits_description[] =
00043 "This recipe is used to extract MOS/MXU slit spectra, following their\n"
00044 "curvature, and to remap them into a spatially rectified image.\n"
00045 "Please refer to the FORS Pipeline User's Manual for details about\n"
00046 "the spectra remapping technique. Note however that the interpolation\n"
00047 "is done exclusively along the spatial direction, and therefore the\n"
00048 "output rectified image will have the same x size of the input spectral\n"
00049 "image.\n"
00050 "\n"
00051 "In the table below the MXU acronym can be alternatively read as MOS.\n\n"
00052 "Input files:\n\n"
00053 " DO category: Type: Explanation: Required:\n"
00054 " LAMP_UNBIAS_MXU\n"
00055 " or SCIENCE_UNBIAS_MXU\n"
00056 " or SCIENCE_UNFLAT_MXU\n"
00057 " or STANDARD_UNBIAS_MXU\n"
00058 " or STANDARD_UNFLAT_MXU\n"
00059 " or UNMAPPED_SCI_MXU\n"
00060 " or UNMAPPED_STD_MXU\n"
00061 " or UNMAPPED_SKY_SCI_MXU\n"
00062 " or UNMAPPED_SKY_STD_MXU Calib Spectral frame Y\n"
00063 " SLIT_LOCATION_DETECT_MXU\n"
00064 " or SLIT_LOCATION_MXU Calib Master flat frame Y\n"
00065 " CURV_COEFF_MXU Calib Spectral curvature Y\n"
00066 " GRISM_TABLE Calib Grism table .\n\n"
00067 "Output files:\n\n"
00068 " DO category: Data type: Explanation:\n"
00069 " RECTIFIED_LAMP_MXU\n"
00070 " or RECTIFIED_ALL_SCI_MXU\n"
00071 " or RECTIFIED_ALL_STD_MXU\n"
00072 " or RECTIFIED_SCI_MXU\n"
00073 " or RECTIFIED_STD_MXU\n"
00074 " or RECTIFIED_SKY_SCI_MXU\n"
00075 " or RECTIFIED_SKY_STD_MXU FITS image Rectified slit spectra\n\n";
00076
00077 #define fors_extract_slits_exit(message) \
00078 { \
00079 if (message) cpl_msg_error(recipe, message); \
00080 cpl_image_delete(spectra); \
00081 cpl_image_delete(spatial); \
00082 cpl_table_delete(grism_table); \
00083 cpl_table_delete(maskslits); \
00084 cpl_table_delete(slits); \
00085 cpl_table_delete(polytraces); \
00086 cpl_propertylist_delete(header); \
00087 cpl_msg_indent_less(); \
00088 return -1; \
00089 }
00090
00091 #define fors_extract_slits_exit_memcheck(message) \
00092 { \
00093 if (message) cpl_msg_info(recipe, message); \
00094 printf("free spectra (%p)\n", spectra); \
00095 cpl_image_delete(spectra); \
00096 printf("free spatial (%p)\n", spatial); \
00097 cpl_image_delete(spatial); \
00098 printf("free grism_table (%p)\n", grism_table); \
00099 cpl_table_delete(grism_table); \
00100 printf("free maskslits (%p)\n", maskslits); \
00101 cpl_table_delete(maskslits); \
00102 printf("free slits (%p)\n", slits); \
00103 cpl_table_delete(slits); \
00104 printf("free polytraces (%p)\n", polytraces); \
00105 cpl_table_delete(polytraces); \
00106 printf("free header (%p)\n", header); \
00107 cpl_propertylist_delete(header); \
00108 cpl_msg_indent_less(); \
00109 return 0; \
00110 }
00111
00112
00124 int cpl_plugin_get_info(cpl_pluginlist *list)
00125 {
00126 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe );
00127 cpl_plugin *plugin = &recipe->interface;
00128
00129 cpl_plugin_init(plugin,
00130 CPL_PLUGIN_API,
00131 FORS_BINARY_VERSION,
00132 CPL_PLUGIN_TYPE_RECIPE,
00133 "fors_extract_slits",
00134 "Spatial rectification of spectral image",
00135 fors_extract_slits_description,
00136 "Carlo Izzo",
00137 PACKAGE_BUGREPORT,
00138 "This file is currently part of the FORS Instrument Pipeline\n"
00139 "Copyright (C) 2002-2010 European Southern Observatory\n\n"
00140 "This program is free software; you can redistribute it and/or modify\n"
00141 "it under the terms of the GNU General Public License as published by\n"
00142 "the Free Software Foundation; either version 2 of the License, or\n"
00143 "(at your option) any later version.\n\n"
00144 "This program is distributed in the hope that it will be useful,\n"
00145 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00146 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00147 "GNU General Public License for more details.\n\n"
00148 "You should have received a copy of the GNU General Public License\n"
00149 "along with this program; if not, write to the Free Software Foundation,\n"
00150 "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n",
00151 fors_extract_slits_create,
00152 fors_extract_slits_exec,
00153 fors_extract_slits_destroy);
00154
00155 cpl_pluginlist_append(list, plugin);
00156
00157 return 0;
00158 }
00159
00160
00171 static int fors_extract_slits_create(cpl_plugin *plugin)
00172 {
00173 cpl_recipe *recipe;
00174 cpl_parameter *p;
00175
00176
00177
00178
00179
00180 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00181 recipe = (cpl_recipe *)plugin;
00182 else
00183 return -1;
00184
00185
00186
00187
00188
00189 recipe->parameters = cpl_parameterlist_new();
00190
00191
00192
00193
00194
00195 p = cpl_parameter_new_value("fors.fors_extract_slits.dispersion",
00196 CPL_TYPE_DOUBLE,
00197 "Expected spectral dispersion (Angstrom/pixel)",
00198 "fors.fors_extract_slits",
00199 0.0);
00200 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dispersion");
00201 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00202 cpl_parameterlist_append(recipe->parameters, p);
00203
00204
00205
00206
00207
00208 p = cpl_parameter_new_value("fors.fors_extract_slits.startwavelength",
00209 CPL_TYPE_DOUBLE,
00210 "Start wavelength in spectral extraction",
00211 "fors.fors_extract_slits",
00212 0.0);
00213 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "startwavelength");
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_extract_slits.endwavelength",
00222 CPL_TYPE_DOUBLE,
00223 "End wavelength in spectral extraction",
00224 "fors.fors_extract_slits",
00225 0.0);
00226 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "endwavelength");
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_extract_slits.flux",
00235 CPL_TYPE_BOOL,
00236 "Apply flux conservation",
00237 "fors.fors_extract_slits",
00238 TRUE);
00239 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "flux");
00240 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00241 cpl_parameterlist_append(recipe->parameters, p);
00242
00243 return 0;
00244 }
00245
00246
00255 static int fors_extract_slits_exec(cpl_plugin *plugin)
00256 {
00257 cpl_recipe *recipe;
00258
00259 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00260 recipe = (cpl_recipe *)plugin;
00261 else
00262 return -1;
00263
00264 return fors_extract_slits(recipe->parameters, recipe->frames);
00265 }
00266
00267
00276 static int fors_extract_slits_destroy(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 cpl_parameterlist_delete(recipe->parameters);
00286
00287 return 0;
00288 }
00289
00290
00300 static int fors_extract_slits(cpl_parameterlist *parlist,
00301 cpl_frameset *frameset)
00302 {
00303
00304 const char *recipe = "fors_extract_slits";
00305
00306
00307
00308
00309
00310
00311 double dispersion;
00312 double startwavelength;
00313 double endwavelength;
00314 int flux;
00315
00316
00317
00318
00319
00320 cpl_image *spectra = NULL;
00321 cpl_image *spatial = NULL;
00322 cpl_table *grism_table = NULL;
00323 cpl_table *slits = NULL;
00324 cpl_table *polytraces = NULL;
00325 cpl_table *maskslits = NULL;
00326 cpl_propertylist *header = NULL;
00327
00328
00329
00330
00331
00332 char version[80];
00333 const char *input_tag;
00334 const char *output_tag;
00335 const char *slit_location_tag;
00336 const char *curv_coeff_tag;
00337 int nframes;
00338 int rebin;
00339 int nslits;
00340 int treat_as_lss;
00341 int i;
00342 double reference;
00343 double *xpos;
00344 double mxpos;
00345 int mxu, mos, lss;
00346 int slit_l, slit_d;
00347 int lamp_mxu;
00348 int lamp_mos;
00349 int lamp_lss;
00350 int scib_mxu;
00351 int scib_mos;
00352 int scib_lss;
00353 int scif_mxu;
00354 int scif_mos;
00355 int scif_lss;
00356 int stab_mxu;
00357 int stab_mos;
00358 int stab_lss;
00359 int staf_mxu;
00360 int staf_mos;
00361 int staf_lss;
00362 int sciu_mxu;
00363 int sciu_mos;
00364 int sciu_lss;
00365 int stau_mxu;
00366 int stau_mos;
00367 int stau_lss;
00368 int scis_mxu;
00369 int scis_mos;
00370 int scis_lss;
00371 int stas_mxu;
00372 int stas_mos;
00373 int stas_lss;
00374
00375 char *instrume = NULL;
00376
00377
00378 cpl_msg_set_indentation(2);
00379
00380 if (dfs_files_dont_exist(frameset))
00381 fors_extract_slits_exit(NULL);
00382
00383
00384
00385
00386
00387
00388 cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe);
00389 cpl_msg_indent_more();
00390
00391 if (cpl_frameset_count_tags(frameset, "GRISM_TABLE") > 1)
00392 fors_extract_slits_exit("Too many in input: GRISM_TABLE");
00393
00394 grism_table = dfs_load_table(frameset, "GRISM_TABLE", 1);
00395
00396 dispersion = dfs_get_parameter_double(parlist,
00397 "fors.fors_extract_slits.dispersion", grism_table);
00398
00399 if (dispersion <= 0.0)
00400 fors_extract_slits_exit("Invalid spectral dispersion value");
00401
00402 startwavelength = dfs_get_parameter_double(parlist,
00403 "fors.fors_extract_slits.startwavelength", grism_table);
00404 if (startwavelength > 1.0)
00405 if (startwavelength < 3000.0 || startwavelength > 13000.0)
00406 fors_extract_slits_exit("Invalid wavelength");
00407
00408 endwavelength = dfs_get_parameter_double(parlist,
00409 "fors.fors_extract_slits.endwavelength", grism_table);
00410 if (endwavelength > 1.0) {
00411 if (endwavelength < 3000.0 || endwavelength > 13000.0)
00412 fors_extract_slits_exit("Invalid wavelength");
00413 if (startwavelength < 1.0)
00414 fors_extract_slits_exit("Invalid wavelength interval");
00415 }
00416
00417 if (startwavelength > 1.0)
00418 if (endwavelength - startwavelength <= 0.0)
00419 fors_extract_slits_exit("Invalid wavelength interval");
00420
00421 flux = dfs_get_parameter_bool(parlist,
00422 "fors.fors_extract_slits.flux", NULL);
00423
00424 cpl_table_delete(grism_table); grism_table = NULL;
00425
00426 if (cpl_error_get_code())
00427 fors_extract_slits_exit("Failure reading the configuration parameters");
00428
00429
00430 cpl_msg_indent_less();
00431 cpl_msg_info(recipe, "Check input set-of-frames:");
00432 cpl_msg_indent_more();
00433
00434 mxu = lamp_mxu = cpl_frameset_count_tags(frameset, "LAMP_UNBIAS_MXU");
00435 mos = lamp_mos = cpl_frameset_count_tags(frameset, "LAMP_UNBIAS_MOS");
00436 lss = lamp_lss = cpl_frameset_count_tags(frameset, "LAMP_UNBIAS_LSS");
00437 mxu += scib_mxu = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_MXU");
00438 mos += scib_mos = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_MOS");
00439 lss += scib_lss = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_LSS");
00440 mxu += scif_mxu = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_MXU");
00441 mos += scif_mos = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_MOS");
00442 lss += scif_lss = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_LSS");
00443 mxu += stab_mxu = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_MXU");
00444 mos += stab_mos = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_MOS");
00445 lss += stab_lss = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_LSS");
00446 mxu += staf_mxu = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_MXU");
00447 mos += staf_mos = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_MOS");
00448 lss += staf_lss = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_LSS");
00449 mxu += sciu_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_SCI_MXU");
00450 mos += sciu_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_SCI_MOS");
00451 lss += sciu_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_SCI_LSS");
00452 mxu += stau_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_STD_MXU");
00453 mos += stau_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_STD_MOS");
00454 lss += stau_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_STD_LSS");
00455 mxu += scis_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_SCI_MXU");
00456 mos += scis_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_SCI_MOS");
00457 lss += scis_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_SCI_LSS");
00458 mxu += stas_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_STD_MXU");
00459 mos += stas_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_STD_MOS");
00460 lss += stas_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_STD_LSS");
00461
00462 nframes = mos + mxu + lss;
00463
00464 if (nframes == 0) {
00465 fors_extract_slits_exit("Missing input spectral frame");
00466 }
00467 if (nframes > 1) {
00468 cpl_msg_error(recipe,
00469 "Too many input spectral frames (%d > 1)", nframes);
00470 fors_extract_slits_exit(NULL);
00471 }
00472
00473 if (lss)
00474 fors_extract_slits_exit("Use this recipe just with MOS/MXU data.");
00475
00476 if (mxu) {
00477 slit_l = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_MXU");
00478 slit_d = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_DETECT_MXU");
00479 }
00480 else {
00481 slit_l = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_MOS");
00482 slit_d = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_DETECT_MOS");
00483 }
00484
00485 nframes = slit_l + slit_d;
00486
00487 if (nframes == 0) {
00488 fors_extract_slits_exit("Missing input slit location table");
00489 }
00490 if (nframes > 1) {
00491 cpl_msg_error(recipe,
00492 "Too many input slit location tables (%d > 1)", nframes);
00493 fors_extract_slits_exit(NULL);
00494 }
00495
00496 if (slit_l) {
00497 if (mxu)
00498 slit_location_tag = "SLIT_LOCATION_MXU";
00499 else
00500 slit_location_tag = "SLIT_LOCATION_MOS";
00501 }
00502 else {
00503 if (mxu)
00504 slit_location_tag = "SLIT_LOCATION_DETECT_MXU";
00505 else
00506 slit_location_tag = "SLIT_LOCATION_DETECT_MOS";
00507 }
00508
00509 if (mxu)
00510 curv_coeff_tag = "CURV_COEFF_MXU";
00511 else
00512 curv_coeff_tag = "CURV_COEFF_MOS";
00513
00514 if (lamp_mxu) {
00515 input_tag = "LAMP_UNBIAS_MXU";
00516 output_tag = "RECTIFIED_LAMP_MXU";
00517 }
00518 else if (lamp_mos) {
00519 input_tag = "LAMP_UNBIAS_MOS";
00520 output_tag = "RECTIFIED_LAMP_MOS";
00521 }
00522 else if (scib_mxu) {
00523 input_tag = "SCIENCE_UNBIAS_MXU";
00524 output_tag = "RECTIFIED_ALL_SCI_MXU";
00525 }
00526 else if (scib_mos) {
00527 input_tag = "SCIENCE_UNBIAS_MOS";
00528 output_tag = "RECTIFIED_ALL_SCI_MOS";
00529 }
00530 else if (scif_mxu) {
00531 input_tag = "SCIENCE_UNFLAT_MXU";
00532 output_tag = "RECTIFIED_ALL_SCI_MXU";
00533 }
00534 else if (scif_mos) {
00535 input_tag = "SCIENCE_UNFLAT_MOS";
00536 output_tag = "RECTIFIED_ALL_SCI_MOS";
00537 }
00538 else if (stab_mxu) {
00539 input_tag = "STANDARD_UNBIAS_MXU";
00540 output_tag = "RECTIFIED_ALL_STD_MXU";
00541 }
00542 else if (stab_mos) {
00543 input_tag = "STANDARD_UNBIAS_MOS";
00544 output_tag = "RECTIFIED_ALL_STD_MOS";
00545 }
00546 else if (staf_mxu) {
00547 input_tag = "STANDARD_UNFLAT_MXU";
00548 output_tag = "RECTIFIED_ALL_STD_MXU";
00549 }
00550 else if (staf_mos) {
00551 input_tag = "STANDARD_UNFLAT_MOS";
00552 output_tag = "RECTIFIED_ALL_STD_MOS";
00553 }
00554 else if (sciu_mxu) {
00555 input_tag = "UNMAPPED_SCI_MXU";
00556 output_tag = "RECTIFIED_SCI_MXU";
00557 }
00558 else if (sciu_mos) {
00559 input_tag = "UNMAPPED_SCI_MOS";
00560 output_tag = "RECTIFIED_SCI_MOS";
00561 }
00562 else if (stau_mxu) {
00563 input_tag = "UNMAPPED_STD_MXU";
00564 output_tag = "RECTIFIED_STD_MXU";
00565 }
00566 else if (stau_mos) {
00567 input_tag = "UNMAPPED_STD_MOS";
00568 output_tag = "RECTIFIED_STD_MOS";
00569 }
00570 else if (scis_mxu) {
00571 input_tag = "UNMAPPED_SKY_SCI_MXU";
00572 output_tag = "RECTIFIED_SKY_SCI_MXU";
00573 }
00574 else if (scis_mos) {
00575 input_tag = "UNMAPPED_SKY_SCI_MOS";
00576 output_tag = "RECTIFIED_SKY_SCI_MOS";
00577 }
00578 else if (stas_mxu) {
00579 input_tag = "UNMAPPED_SKY_STD_MXU";
00580 output_tag = "RECTIFIED_SKY_STD_MXU";
00581 }
00582 else if (stas_mos) {
00583 input_tag = "UNMAPPED_SKY_STD_MOS";
00584 output_tag = "RECTIFIED_SKY_STD_MOS";
00585 }
00586
00587 header = dfs_load_header(frameset, input_tag, 0);
00588
00589 if (header == NULL)
00590 fors_extract_slits_exit("Cannot load master flat frame header");
00591
00592 if (mos)
00593 maskslits = mos_load_slits_fors_mos(header);
00594 else
00595 maskslits = mos_load_slits_fors_mxu(header);
00596
00597
00598
00599
00600
00601 mxpos = cpl_table_get_column_median(maskslits, "xtop");
00602 xpos = cpl_table_get_data_double(maskslits, "xtop");
00603 nslits = cpl_table_get_nrow(maskslits);
00604
00605 treat_as_lss = 1;
00606 for (i = 0; i < nslits; i++) {
00607 if (fabs(mxpos-xpos[i]) > 0.01) {
00608 treat_as_lss = 0;
00609 break;
00610 }
00611 }
00612
00613 cpl_table_delete(maskslits); maskslits = NULL;
00614
00615 if (treat_as_lss) {
00616 cpl_msg_error(recipe, "All slits have the same offset: %.2f mm\n"
00617 "The LSS data reduction strategy must be applied.",
00618 mxpos);
00619 fors_extract_slits_exit(NULL);
00620 }
00621
00622 if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
00623 fors_extract_slits_exit("Input frames are not from the same grism");
00624
00625 if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
00626 fors_extract_slits_exit("Input frames are not from the same filter");
00627
00628 if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
00629 fors_extract_slits_exit("Input frames are not from the same chip");
00630
00631
00632
00633
00634
00635
00636
00637 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00638 if (instrume == NULL)
00639 fors_extract_slits_exit("Missing keyword INSTRUME in master "
00640 "flat header");
00641
00642 if (instrume[4] == '1')
00643 snprintf(version, 80, "%s/%s", "fors1", VERSION);
00644 if (instrume[4] == '2')
00645 snprintf(version, 80, "%s/%s", "fors2", VERSION);
00646
00647 reference = cpl_propertylist_get_double(header, "ESO INS GRIS1 WLEN");
00648
00649 if (cpl_error_get_code() != CPL_ERROR_NONE)
00650 fors_extract_slits_exit("Missing keyword ESO INS GRIS1 WLEN "
00651 "in master flat frame header");
00652
00653 if (reference < 3000.0)
00654 reference *= 10;
00655
00656 if (reference < 3000.0 || reference > 13000.0) {
00657 cpl_msg_error(recipe, "Invalid central wavelength %.2f read from "
00658 "keyword ESO INS GRIS1 WLEN in master flat header",
00659 reference);
00660 fors_extract_slits_exit(NULL);
00661 }
00662
00663 cpl_msg_info(recipe, "The central wavelength is: %.2f", reference);
00664
00665 rebin = cpl_propertylist_get_int(header, "ESO DET WIN1 BINX");
00666
00667 if (cpl_error_get_code() != CPL_ERROR_NONE)
00668 fors_extract_slits_exit("Missing keyword ESO DET WIN1 BINX "
00669 "in master flat header");
00670
00671 if (rebin != 1) {
00672 dispersion *= rebin;
00673 cpl_msg_warning(recipe, "The rebin factor is %d, and therefore the "
00674 "working dispersion used is %f A/pixel", rebin,
00675 dispersion);
00676 }
00677
00678 cpl_msg_indent_less();
00679 cpl_msg_info(recipe, "Load input frames...");
00680 cpl_msg_indent_more();
00681
00682 spectra = dfs_load_image(frameset, input_tag, CPL_TYPE_FLOAT, 0, 0);
00683 if (spectra == NULL)
00684 fors_extract_slits_exit("Cannot load input spectral frame");
00685
00686 slits = dfs_load_table(frameset, slit_location_tag, 1);
00687 if (slits == NULL)
00688 fors_extract_slits_exit("Cannot load slits location table");
00689
00690 polytraces = dfs_load_table(frameset, curv_coeff_tag, 1);
00691 if (slits == NULL)
00692 fors_extract_slits_exit("Cannot load spectral curvature table");
00693
00694 spatial = mos_spatial_calibration(spectra, slits, polytraces, reference,
00695 startwavelength, endwavelength,
00696 dispersion, flux, NULL);
00697
00698 cpl_image_delete(spectra); spectra = NULL;
00699 cpl_table_delete(polytraces); polytraces = NULL;
00700 cpl_table_delete(slits); slits = NULL;
00701
00702 cpl_propertylist_delete(header); header = NULL;
00703 header = cpl_propertylist_new();
00704
00705 cpl_propertylist_update_double(header, "CRPIX2", 1.0);
00706 cpl_propertylist_update_double(header, "CRVAL2", 1.0);
00707
00708 cpl_propertylist_update_double(header, "CD1_1", 1.0);
00709 cpl_propertylist_update_double(header, "CD1_2", 0.0);
00710 cpl_propertylist_update_double(header, "CD2_1", 0.0);
00711 cpl_propertylist_update_double(header, "CD2_2", 1.0);
00712 cpl_propertylist_update_string(header, "CTYPE1", "LINEAR");
00713 cpl_propertylist_update_string(header, "CTYPE2", "PIXEL");
00714
00715 if (dfs_save_image(frameset, spatial, output_tag,
00716 header, parlist, recipe, version))
00717 fors_extract_slits_exit(NULL);
00718
00719 cpl_image_delete(spatial); spatial = NULL;
00720 cpl_propertylist_delete(header); header = NULL;
00721
00722 return 0;
00723 }