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 ((const char *)message != NULL) 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 ((const char *)message != NULL) 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 treat_as_lss;
00340 double reference;
00341 double mxpos;
00342 int mxu, mos, lss;
00343 int slit_l, slit_d;
00344 int lamp_mxu;
00345 int lamp_mos;
00346 int lamp_lss;
00347 int scib_mxu;
00348 int scib_mos;
00349 int scib_lss;
00350 int scif_mxu;
00351 int scif_mos;
00352 int scif_lss;
00353 int stab_mxu;
00354 int stab_mos;
00355 int stab_lss;
00356 int staf_mxu;
00357 int staf_mos;
00358 int staf_lss;
00359 int sciu_mxu;
00360 int sciu_mos;
00361 int sciu_lss;
00362 int stau_mxu;
00363 int stau_mos;
00364 int stau_lss;
00365 int scis_mxu;
00366 int scis_mos;
00367 int scis_lss;
00368 int stas_mxu;
00369 int stas_mos;
00370 int stas_lss;
00371 int nslits_out_det = 0;
00372
00373 char *instrume = NULL;
00374
00375
00376 cpl_msg_set_indentation(2);
00377
00378
00379
00380
00381
00382
00383 cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe);
00384 cpl_msg_indent_more();
00385
00386 if (cpl_frameset_count_tags(frameset, "GRISM_TABLE") > 1)
00387 fors_extract_slits_exit("Too many in input: GRISM_TABLE");
00388
00389 grism_table = dfs_load_table(frameset, "GRISM_TABLE", 1);
00390
00391 dispersion = dfs_get_parameter_double(parlist,
00392 "fors.fors_extract_slits.dispersion", grism_table);
00393
00394 if (dispersion <= 0.0)
00395 fors_extract_slits_exit("Invalid spectral dispersion value");
00396
00397 startwavelength = dfs_get_parameter_double(parlist,
00398 "fors.fors_extract_slits.startwavelength", grism_table);
00399 if (startwavelength > 1.0)
00400 if (startwavelength < 3000.0 || startwavelength > 13000.0)
00401 fors_extract_slits_exit("Invalid wavelength");
00402
00403 endwavelength = dfs_get_parameter_double(parlist,
00404 "fors.fors_extract_slits.endwavelength", grism_table);
00405 if (endwavelength > 1.0) {
00406 if (endwavelength < 3000.0 || endwavelength > 13000.0)
00407 fors_extract_slits_exit("Invalid wavelength");
00408 if (startwavelength < 1.0)
00409 fors_extract_slits_exit("Invalid wavelength interval");
00410 }
00411
00412 if (startwavelength > 1.0)
00413 if (endwavelength - startwavelength <= 0.0)
00414 fors_extract_slits_exit("Invalid wavelength interval");
00415
00416 flux = dfs_get_parameter_bool(parlist,
00417 "fors.fors_extract_slits.flux", NULL);
00418
00419 cpl_table_delete(grism_table); grism_table = NULL;
00420
00421 if (cpl_error_get_code())
00422 fors_extract_slits_exit("Failure reading the configuration parameters");
00423
00424
00425 cpl_msg_indent_less();
00426 cpl_msg_info(recipe, "Check input set-of-frames:");
00427 cpl_msg_indent_more();
00428
00429 mxu = lamp_mxu = cpl_frameset_count_tags(frameset, "LAMP_UNBIAS_MXU");
00430 mos = lamp_mos = cpl_frameset_count_tags(frameset, "LAMP_UNBIAS_MOS");
00431 lss = lamp_lss = cpl_frameset_count_tags(frameset, "LAMP_UNBIAS_LSS");
00432 mxu += scib_mxu = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_MXU");
00433 mos += scib_mos = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_MOS");
00434 lss += scib_lss = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_LSS");
00435 mxu += scif_mxu = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_MXU");
00436 mos += scif_mos = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_MOS");
00437 lss += scif_lss = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_LSS");
00438 mxu += stab_mxu = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_MXU");
00439 mos += stab_mos = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_MOS");
00440 lss += stab_lss = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_LSS");
00441 mxu += staf_mxu = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_MXU");
00442 mos += staf_mos = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_MOS");
00443 lss += staf_lss = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_LSS");
00444 mxu += sciu_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_SCI_MXU");
00445 mos += sciu_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_SCI_MOS");
00446 lss += sciu_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_SCI_LSS");
00447 mxu += stau_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_STD_MXU");
00448 mos += stau_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_STD_MOS");
00449 lss += stau_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_STD_LSS");
00450 mxu += scis_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_SCI_MXU");
00451 mos += scis_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_SCI_MOS");
00452 lss += scis_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_SCI_LSS");
00453 mxu += stas_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_STD_MXU");
00454 mos += stas_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_STD_MOS");
00455 lss += stas_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_STD_LSS");
00456
00457 nframes = mos + mxu + lss;
00458
00459 if (nframes == 0) {
00460 fors_extract_slits_exit("Missing input spectral frame");
00461 }
00462 if (nframes > 1) {
00463 cpl_msg_error(recipe,
00464 "Too many input spectral frames (%d > 1)", nframes);
00465 fors_extract_slits_exit(NULL);
00466 }
00467
00468 if (lss)
00469 fors_extract_slits_exit("Use this recipe just with MOS/MXU data.");
00470
00471 if (mxu) {
00472 slit_l = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_MXU");
00473 slit_d = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_DETECT_MXU");
00474 }
00475 else {
00476 slit_l = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_MOS");
00477 slit_d = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_DETECT_MOS");
00478 }
00479
00480 nframes = slit_l + slit_d;
00481
00482 if (nframes == 0) {
00483 fors_extract_slits_exit("Missing input slit location table");
00484 }
00485 if (nframes > 1) {
00486 cpl_msg_error(recipe,
00487 "Too many input slit location tables (%d > 1)", nframes);
00488 fors_extract_slits_exit(NULL);
00489 }
00490
00491 if (slit_l) {
00492 if (mxu)
00493 slit_location_tag = "SLIT_LOCATION_MXU";
00494 else
00495 slit_location_tag = "SLIT_LOCATION_MOS";
00496 }
00497 else {
00498 if (mxu)
00499 slit_location_tag = "SLIT_LOCATION_DETECT_MXU";
00500 else
00501 slit_location_tag = "SLIT_LOCATION_DETECT_MOS";
00502 }
00503
00504 if (mxu)
00505 curv_coeff_tag = "CURV_COEFF_MXU";
00506 else
00507 curv_coeff_tag = "CURV_COEFF_MOS";
00508
00509 if (lamp_mxu) {
00510 input_tag = "LAMP_UNBIAS_MXU";
00511 output_tag = "RECTIFIED_LAMP_MXU";
00512 }
00513 else if (lamp_mos) {
00514 input_tag = "LAMP_UNBIAS_MOS";
00515 output_tag = "RECTIFIED_LAMP_MOS";
00516 }
00517 else if (scib_mxu) {
00518 input_tag = "SCIENCE_UNBIAS_MXU";
00519 output_tag = "RECTIFIED_ALL_SCI_MXU";
00520 }
00521 else if (scib_mos) {
00522 input_tag = "SCIENCE_UNBIAS_MOS";
00523 output_tag = "RECTIFIED_ALL_SCI_MOS";
00524 }
00525 else if (scif_mxu) {
00526 input_tag = "SCIENCE_UNFLAT_MXU";
00527 output_tag = "RECTIFIED_ALL_SCI_MXU";
00528 }
00529 else if (scif_mos) {
00530 input_tag = "SCIENCE_UNFLAT_MOS";
00531 output_tag = "RECTIFIED_ALL_SCI_MOS";
00532 }
00533 else if (stab_mxu) {
00534 input_tag = "STANDARD_UNBIAS_MXU";
00535 output_tag = "RECTIFIED_ALL_STD_MXU";
00536 }
00537 else if (stab_mos) {
00538 input_tag = "STANDARD_UNBIAS_MOS";
00539 output_tag = "RECTIFIED_ALL_STD_MOS";
00540 }
00541 else if (staf_mxu) {
00542 input_tag = "STANDARD_UNFLAT_MXU";
00543 output_tag = "RECTIFIED_ALL_STD_MXU";
00544 }
00545 else if (staf_mos) {
00546 input_tag = "STANDARD_UNFLAT_MOS";
00547 output_tag = "RECTIFIED_ALL_STD_MOS";
00548 }
00549 else if (sciu_mxu) {
00550 input_tag = "UNMAPPED_SCI_MXU";
00551 output_tag = "RECTIFIED_SCI_MXU";
00552 }
00553 else if (sciu_mos) {
00554 input_tag = "UNMAPPED_SCI_MOS";
00555 output_tag = "RECTIFIED_SCI_MOS";
00556 }
00557 else if (stau_mxu) {
00558 input_tag = "UNMAPPED_STD_MXU";
00559 output_tag = "RECTIFIED_STD_MXU";
00560 }
00561 else if (stau_mos) {
00562 input_tag = "UNMAPPED_STD_MOS";
00563 output_tag = "RECTIFIED_STD_MOS";
00564 }
00565 else if (scis_mxu) {
00566 input_tag = "UNMAPPED_SKY_SCI_MXU";
00567 output_tag = "RECTIFIED_SKY_SCI_MXU";
00568 }
00569 else if (scis_mos) {
00570 input_tag = "UNMAPPED_SKY_SCI_MOS";
00571 output_tag = "RECTIFIED_SKY_SCI_MOS";
00572 }
00573 else if (stas_mxu) {
00574 input_tag = "UNMAPPED_SKY_STD_MXU";
00575 output_tag = "RECTIFIED_SKY_STD_MXU";
00576 }
00577 else if (stas_mos) {
00578 input_tag = "UNMAPPED_SKY_STD_MOS";
00579 output_tag = "RECTIFIED_SKY_STD_MOS";
00580 }
00581
00582 header = dfs_load_header(frameset, input_tag, 0);
00583
00584 if (header == NULL)
00585 fors_extract_slits_exit("Cannot load master flat frame header");
00586
00587 if (mos)
00588 maskslits = mos_load_slits_fors_mos(header, &nslits_out_det);
00589 else
00590 maskslits = mos_load_slits_fors_mxu(header);
00591
00592
00593
00594
00595
00596 treat_as_lss = fors_mos_is_lss_like(maskslits, nslits_out_det);
00597
00598 cpl_table_delete(maskslits); maskslits = NULL;
00599
00600 if (treat_as_lss) {
00601 cpl_msg_error(recipe, "All slits have the same offset: %.2f mm\n"
00602 "The LSS data reduction strategy must be applied.",
00603 mxpos);
00604 fors_extract_slits_exit(NULL);
00605 }
00606
00607 if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
00608 fors_extract_slits_exit("Input frames are not from the same grism");
00609
00610 if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
00611 fors_extract_slits_exit("Input frames are not from the same filter");
00612
00613 if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
00614 fors_extract_slits_exit("Input frames are not from the same chip");
00615
00616
00617
00618
00619
00620
00621
00622 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00623 if (instrume == NULL)
00624 fors_extract_slits_exit("Missing keyword INSTRUME in master "
00625 "flat header");
00626
00627 if (instrume[4] == '1')
00628 snprintf(version, 80, "%s/%s", "fors1", VERSION);
00629 if (instrume[4] == '2')
00630 snprintf(version, 80, "%s/%s", "fors2", VERSION);
00631
00632 reference = cpl_propertylist_get_double(header, "ESO INS GRIS1 WLEN");
00633
00634 if (cpl_error_get_code() != CPL_ERROR_NONE)
00635 fors_extract_slits_exit("Missing keyword ESO INS GRIS1 WLEN "
00636 "in master flat frame header");
00637
00638 if (reference < 3000.0)
00639 reference *= 10;
00640
00641 if (reference < 3000.0 || reference > 13000.0) {
00642 cpl_msg_error(recipe, "Invalid central wavelength %.2f read from "
00643 "keyword ESO INS GRIS1 WLEN in master flat header",
00644 reference);
00645 fors_extract_slits_exit(NULL);
00646 }
00647
00648 cpl_msg_info(recipe, "The central wavelength is: %.2f", reference);
00649
00650 rebin = cpl_propertylist_get_int(header, "ESO DET WIN1 BINX");
00651
00652 if (cpl_error_get_code() != CPL_ERROR_NONE)
00653 fors_extract_slits_exit("Missing keyword ESO DET WIN1 BINX "
00654 "in master flat header");
00655
00656 if (rebin != 1) {
00657 dispersion *= rebin;
00658 cpl_msg_warning(recipe, "The rebin factor is %d, and therefore the "
00659 "working dispersion used is %f A/pixel", rebin,
00660 dispersion);
00661 }
00662
00663 cpl_msg_indent_less();
00664 cpl_msg_info(recipe, "Load input frames...");
00665 cpl_msg_indent_more();
00666
00667 spectra = dfs_load_image(frameset, input_tag, CPL_TYPE_FLOAT, 0, 0);
00668 if (spectra == NULL)
00669 fors_extract_slits_exit("Cannot load input spectral frame");
00670
00671 slits = dfs_load_table(frameset, slit_location_tag, 1);
00672 if (slits == NULL)
00673 fors_extract_slits_exit("Cannot load slits location table");
00674
00675 polytraces = dfs_load_table(frameset, curv_coeff_tag, 1);
00676 if (slits == NULL)
00677 fors_extract_slits_exit("Cannot load spectral curvature table");
00678
00679 spatial = mos_spatial_calibration(spectra, slits, polytraces, reference,
00680 startwavelength, endwavelength,
00681 dispersion, flux, NULL);
00682
00683 cpl_image_delete(spectra); spectra = NULL;
00684 cpl_table_delete(polytraces); polytraces = NULL;
00685 cpl_table_delete(slits); slits = NULL;
00686
00687 cpl_propertylist_delete(header); header = NULL;
00688 header = cpl_propertylist_new();
00689
00690 cpl_propertylist_update_double(header, "CRPIX2", 1.0);
00691 cpl_propertylist_update_double(header, "CRVAL2", 1.0);
00692
00693 cpl_propertylist_update_double(header, "CD1_1", 1.0);
00694 cpl_propertylist_update_double(header, "CD1_2", 0.0);
00695 cpl_propertylist_update_double(header, "CD2_1", 0.0);
00696 cpl_propertylist_update_double(header, "CD2_2", 1.0);
00697 cpl_propertylist_update_string(header, "CTYPE1", "LINEAR");
00698 cpl_propertylist_update_string(header, "CTYPE2", "PIXEL");
00699
00700 if (dfs_save_image(frameset, spatial, output_tag,
00701 header, parlist, recipe, version))
00702 fors_extract_slits_exit(NULL);
00703
00704 cpl_image_delete(spatial); spatial = NULL;
00705 cpl_propertylist_delete(header); header = NULL;
00706
00707 return 0;
00708 }