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 <vimos_science_impl.h>
00033
00034 #include <math.h>
00035 #include <cpl.h>
00036 #include <moses.h>
00037 #include <fors_tools.h>
00038 #include <fors_dfs.h>
00039 #include <fors_qc.h>
00040
00041 #define vimos_science_exit(message) \
00042 { \
00043 if (message) cpl_msg_error(recipe, message); \
00044 cpl_free(exptime); \
00045 cpl_image_delete(dummy); \
00046 cpl_image_delete(mapped); \
00047 cpl_image_delete(mapped_sky); \
00048 cpl_image_delete(mapped_cleaned); \
00049 cpl_image_delete(skylocalmap); \
00050 cpl_image_delete(skymap); \
00051 cpl_image_delete(smapped); \
00052 cpl_table_delete(offsets); \
00053 cpl_table_delete(sky); \
00054 cpl_image_delete(bias); \
00055 cpl_image_delete(spectra); \
00056 cpl_image_delete(coordinate); \
00057 cpl_image_delete(norm_flat); \
00058 cpl_image_delete(rainbow); \
00059 cpl_image_delete(rectified); \
00060 cpl_image_delete(wavemap); \
00061 cpl_propertylist_delete(header); \
00062 cpl_propertylist_delete(save_header); \
00063 cpl_table_delete(grism_table); \
00064 cpl_table_delete(idscoeff); \
00065 cpl_table_delete(maskslits); \
00066 cpl_table_delete(overscans); \
00067 cpl_table_delete(polytraces); \
00068 cpl_table_delete(slits); \
00069 cpl_table_delete(wavelengths); \
00070 cpl_vector_delete(lines); \
00071 cpl_msg_indent_less(); \
00072 return -1; \
00073 }
00074
00081 int vimos_science_impl(cpl_frameset *frameset, cpl_parameterlist *parlist)
00082 {
00083 const char *recipe = "vimos_science";
00084
00085
00086
00087
00088
00089
00090 double dispersion;
00091 int skyalign;
00092 const char *wcolumn;
00093 double startwavelength;
00094 double endwavelength;
00095 double reference;
00096 int flux;
00097 int flatfield;
00098 int skyglobal;
00099 int skylocal;
00100 int skymedian;
00101 int cosmics;
00102 int slit_margin;
00103 int ext_radius;
00104 int cont_radius;
00105 int ext_mode;
00106 int time_normalise;
00107 int anyframe;
00108 int res_order;
00109 int qc;
00110
00111
00112
00113
00114
00115 cpl_imagelist *all_science;
00116 cpl_image **images;
00117
00118 cpl_image *bias = NULL;
00119 cpl_image *norm_flat = NULL;
00120 cpl_image *spectra = NULL;
00121 cpl_image *rectified = NULL;
00122 cpl_image *coordinate = NULL;
00123 cpl_image *rainbow = NULL;
00124 cpl_image *mapped = NULL;
00125 cpl_image *mapped_sky = NULL;
00126 cpl_image *mapped_cleaned = NULL;
00127 cpl_image *smapped = NULL;
00128 cpl_image *wavemap = NULL;
00129 cpl_image *skymap = NULL;
00130 cpl_image *skylocalmap = NULL;
00131 cpl_image *dummy = NULL;
00132
00133 cpl_table *grism_table = NULL;
00134 cpl_table *overscans = NULL;
00135 cpl_table *wavelengths = NULL;
00136 cpl_table *idscoeff = NULL;
00137 cpl_table *slits = NULL;
00138 cpl_table *maskslits = NULL;
00139 cpl_table *polytraces = NULL;
00140 cpl_table *offsets = NULL;
00141 cpl_table *sky = NULL;
00142
00143 cpl_vector *lines = NULL;
00144
00145 cpl_propertylist *header = NULL;
00146 cpl_propertylist *save_header = NULL;
00147 cpl_propertylist *qclist = NULL;
00148
00149
00150
00151
00152
00153 char version[80];
00154 char *instrume = NULL;
00155 const char *science_tag;
00156 const char *master_norm_flat_tag;
00157 const char *disp_coeff_tag;
00158 const char *disp_coeff_sky_tag;
00159 const char *wavelength_map_tag;
00160 const char *wavelength_map_sky_tag;
00161 const char *curv_coeff_tag;
00162 const char *slit_location_tag;
00163 const char *reduced_science_tag;
00164 const char *reduced_sky_tag;
00165 const char *reduced_error_tag;
00166 const char *mapped_science_tag;
00167 const char *unmapped_science_tag;
00168 const char *mapped_science_sky_tag;
00169 const char *mapped_sky_tag;
00170 const char *unmapped_sky_tag;
00171 const char *global_sky_spectrum_tag;
00172 const char *object_table_tag;
00173 const char *skylines_offsets_tag;
00174 const char *specphot_tag;
00175 const char *key_gris_name;
00176 const char *key_gris_id;
00177 const char *key_filt_name;
00178 const char *key_filt_id;
00179 int mos;
00180 int nexp, expno;
00181 int treat_as_lss = 0;
00182 int nslits;
00183 int nscience;
00184 int quadrant;
00185 double *xpos;
00186 double *exptime = NULL;
00187 double airmass;
00188 double alltime;
00189 double mxpos;
00190 double mean_rms;
00191 int nlines;
00192 double *line;
00193 int nx, ny;
00194 double gain;
00195 double ron;
00196 int standard;
00197 int highres;
00198 int rotate = 1;
00199 int rotate_back = -1;
00200 int i;
00201 double wstart;
00202 double wstep;
00203 int wcount;
00204
00205
00206 snprintf(version, 80, "%s-%s", PACKAGE, PACKAGE_VERSION);
00207
00208 cpl_msg_set_indentation(2);
00209
00210 if (dfs_files_dont_exist(frameset))
00211 vimos_science_exit(NULL);
00212
00213
00214
00215
00216
00217
00218 cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe);
00219 cpl_msg_indent_more();
00220
00221 if (cpl_frameset_count_tags(frameset, "GRISM_TABLE") > 1)
00222 vimos_science_exit("Too many in input: GRISM_TABLE");
00223
00224 grism_table = dfs_load_table(frameset, "GRISM_TABLE", 1);
00225
00226 dispersion = dfs_get_parameter_double(parlist,
00227 "fors.vimos_science.dispersion", grism_table);
00228
00229 if (dispersion <= 0.0)
00230 vimos_science_exit("Invalid resampling step");
00231
00232 skyalign = dfs_get_parameter_int(parlist,
00233 "fors.vimos_science.skyalign", NULL);
00234
00235 if (skyalign > 2)
00236 vimos_science_exit("Max polynomial degree for sky alignment is 2");
00237
00238 wcolumn = dfs_get_parameter_string(parlist,
00239 "fors.vimos_science.wcolumn", NULL);
00240
00241 startwavelength = dfs_get_parameter_double(parlist,
00242 "fors.vimos_science.startwavelength", grism_table);
00243 if (startwavelength < 3000.0 || startwavelength > 13000.0)
00244 vimos_science_exit("Invalid wavelength");
00245
00246 endwavelength = dfs_get_parameter_double(parlist,
00247 "fors.vimos_science.endwavelength", grism_table);
00248 if (endwavelength < 3000.0 || endwavelength > 13000.0)
00249 vimos_science_exit("Invalid wavelength");
00250
00251 if (endwavelength - startwavelength <= 0.0)
00252 vimos_science_exit("Invalid wavelength interval");
00253
00254 reference = dfs_get_parameter_double(parlist,
00255 "fors.vimos_science.reference", grism_table);
00256
00257 if (reference < startwavelength || reference > endwavelength)
00258 vimos_science_exit("Invalid reference wavelength");
00259
00260 flux = dfs_get_parameter_bool(parlist, "fors.vimos_science.flux", NULL);
00261
00262 flatfield = dfs_get_parameter_bool(parlist, "fors.vimos_science.flatfield",
00263 NULL);
00264
00265 skyglobal = dfs_get_parameter_bool(parlist, "fors.vimos_science.skyglobal",
00266 NULL);
00267 skylocal = dfs_get_parameter_bool(parlist, "fors.vimos_science.skylocal",
00268 NULL);
00269 skymedian = dfs_get_parameter_bool(parlist, "fors.vimos_science.skymedian",
00270 NULL);
00271
00272 if (skylocal && skyglobal)
00273 vimos_science_exit("Cannot do both local and global sky subtraction");
00274
00275 if (skylocal && skymedian)
00276 vimos_science_exit("Cannot do sky subtraction both on extracted "
00277 "and non-extracted spectra");
00278
00279 cosmics = dfs_get_parameter_bool(parlist,
00280 "fors.vimos_science.cosmics", NULL);
00281
00282 if (cosmics)
00283 if (!(skyglobal || skylocal))
00284 vimos_science_exit("Cosmic rays correction requires "
00285 "either skylocal=true or skyglobal=true");
00286
00287 slit_margin = dfs_get_parameter_int(parlist,
00288 "fors.vimos_science.slit_margin",
00289 NULL);
00290 if (slit_margin < 0)
00291 vimos_science_exit("Value must be zero or positive");
00292
00293 ext_radius = dfs_get_parameter_int(parlist,
00294 "fors.vimos_science.ext_radius",
00295 NULL);
00296 if (ext_radius < 0)
00297 vimos_science_exit("Value must be zero or positive");
00298
00299 cont_radius = dfs_get_parameter_int(parlist,
00300 "fors.vimos_science.cont_radius",
00301 NULL);
00302 if (cont_radius < 0)
00303 vimos_science_exit("Value must be zero or positive");
00304
00305 ext_mode = dfs_get_parameter_int(parlist, "fors.vimos_science.ext_mode",
00306 NULL);
00307 if (ext_mode < 0 || ext_mode > 1)
00308 vimos_science_exit("Invalid object extraction mode");
00309
00310 time_normalise = dfs_get_parameter_bool(parlist,
00311 "fors.vimos_science.time_normalise", NULL);
00312
00313 res_order = dfs_get_parameter_int(parlist, "fors.vimos_science.response",
00314 NULL);
00315 if (res_order < 2 || res_order > 10)
00316 vimos_science_exit("Invalid instrument response modeling polynomial");
00317
00318 anyframe = dfs_get_parameter_bool(parlist, "fors.vimos_science.anyframe",
00319 NULL);
00320
00321 qc = dfs_get_parameter_bool(parlist, "fors.vimos_science.qc", NULL);
00322
00323 cpl_table_delete(grism_table); grism_table = NULL;
00324
00325 if (cpl_error_get_code())
00326 vimos_science_exit("Failure getting the configuration parameters");
00327
00328
00329
00330
00331
00332
00333 cpl_msg_indent_less();
00334 cpl_msg_info(recipe, "Check input set-of-frames:");
00335 cpl_msg_indent_more();
00336
00337 if (!dfs_equal_keyword(frameset, "ESO OCS CON QUAD"))
00338 vimos_science_exit("Input frames are not from the same quadrant");
00339
00340 mos = cpl_frameset_count_tags(frameset, "MOS_SCIENCE");
00341 standard = 0;
00342
00343 if (mos == 0) {
00344 mos = cpl_frameset_count_tags(frameset, "MOS_STANDARD");
00345 standard = 1;
00346 }
00347
00348 if (mos == 0)
00349 vimos_science_exit("Missing input scientific frame");
00350
00351 nscience = mos;
00352
00353 if (standard) {
00354 science_tag = "MOS_STANDARD";
00355 reduced_science_tag = "MOS_STANDARD_REDUCED";
00356 unmapped_science_tag = "MOS_UNMAPPED_STANDARD";
00357 mapped_science_tag = "MOS_STANDARD_EXTRACTED";
00358 mapped_science_sky_tag = "MOS_STANDARD_SKY_EXTRACTED";
00359 mapped_sky_tag = "MOS_STANDARD_SKY";
00360 specphot_tag = "MOS_SPECPHOT_TABLE";
00361
00362 }
00363 else {
00364 science_tag = "MOS_SCIENCE";
00365 reduced_science_tag = "MOS_SCIENCE_REDUCED";
00366 unmapped_science_tag = "MOS_UNMAPPED_SCIENCE";
00367 mapped_science_tag = "MOS_SCIENCE_EXTRACTED";
00368 mapped_science_sky_tag = "MOS_SCIENCE_SKY_EXTRACTED";
00369 mapped_sky_tag = "MOS_SCIENCE_SKY";
00370 }
00371
00372 reduced_sky_tag = "MOS_SKY_REDUCED";
00373 reduced_error_tag = "MOS_ERROR_REDUCED";
00374 master_norm_flat_tag = "MOS_MASTER_SCREEN_FLAT";
00375 disp_coeff_sky_tag = "MOS_DISP_COEFF_SKY";
00376 wavelength_map_sky_tag = "MOS_WAVELENGTH_MAP_SKY";
00377 disp_coeff_tag = "MOS_DISP_COEFF";
00378 wavelength_map_tag = "WAVELENGTH_MAP_MXU";
00379 curv_coeff_tag = "MOS_CURV_COEFF";
00380 slit_location_tag = "MOS_SLIT_LOCATION";
00381 skylines_offsets_tag = "MOS_SKYLINES_OFFSETS_SLIT";
00382 unmapped_sky_tag = "MOS_UNMAPPED_SKY";
00383 global_sky_spectrum_tag = "MOS_GLOBAL_SKY_SPECTRUM";
00384 object_table_tag = "OBJECT_TABLE";
00385
00386 if (cpl_frameset_count_tags(frameset, "MASTER_BIAS") == 0)
00387 vimos_science_exit("Missing required input: MASTER_BIAS");
00388
00389 if (cpl_frameset_count_tags(frameset, "MASTER_BIAS") > 1)
00390 vimos_science_exit("Too many in input: MASTER_BIAS");
00391
00392 if (skyalign >= 0)
00393 if (cpl_frameset_count_tags(frameset, "SKY_LINE_CATALOG") > 1)
00394 vimos_science_exit("Too many in input: SKY_LINE_CATALOG");
00395
00396 if (cpl_frameset_count_tags(frameset, disp_coeff_tag) == 0) {
00397 cpl_msg_error(recipe, "Missing required input: %s", disp_coeff_tag);
00398 vimos_science_exit(NULL);
00399 }
00400
00401 if (cpl_frameset_count_tags(frameset, disp_coeff_tag) > 1) {
00402 cpl_msg_error(recipe, "Too many in input: %s", disp_coeff_tag);
00403 vimos_science_exit(NULL);
00404 }
00405
00406 if (cpl_frameset_count_tags(frameset, master_norm_flat_tag) > 1) {
00407 if (flatfield) {
00408 cpl_msg_error(recipe, "Too many in input: %s",
00409 master_norm_flat_tag);
00410 vimos_science_exit(NULL);
00411 }
00412 else {
00413 cpl_msg_warning(recipe, "%s in input are ignored, "
00414 "since flat field correction was not requested",
00415 master_norm_flat_tag);
00416 }
00417 }
00418
00419 if (cpl_frameset_count_tags(frameset, master_norm_flat_tag) == 1) {
00420 if (!flatfield) {
00421 cpl_msg_warning(recipe, "%s in input is ignored, "
00422 "since flat field correction was not requested",
00423 master_norm_flat_tag);
00424 }
00425 }
00426
00427 if (cpl_frameset_count_tags(frameset, master_norm_flat_tag) == 0) {
00428 if (flatfield) {
00429 cpl_msg_error(recipe, "Flat field correction was requested, "
00430 "but no %s are found in input",
00431 master_norm_flat_tag);
00432 vimos_science_exit(NULL);
00433 }
00434 }
00435
00436 if (standard) {
00437
00438 if (cpl_frameset_count_tags(frameset, "EXTINCT_TABLE") == 0) {
00439 cpl_msg_warning(recipe, "An EXTINCT_TABLE was not found in input: "
00440 "instrument response curve will not be produced.");
00441 standard = 0;
00442 }
00443
00444 if (cpl_frameset_count_tags(frameset, "EXTINCT_TABLE") > 1)
00445 vimos_science_exit("Too many in input: EXTINCT_TABLE");
00446
00447 if (cpl_frameset_count_tags(frameset, "STD_FLUX_TABLE") == 0) {
00448 cpl_msg_warning(recipe, "A STD_FLUX_TABLE was not found in input: "
00449 "instrument response curve will not be produced.");
00450 standard = 0;
00451 }
00452
00453 if (cpl_frameset_count_tags(frameset, "STD_FLUX_TABLE") > 1)
00454 vimos_science_exit("Too many in input: STD_FLUX_TABLE");
00455
00456 if (!dfs_equal_keyword(frameset, "ESO OBS TARG NAME")) {
00457 cpl_msg_warning(recipe, "The target name of observation does not "
00458 "match the standard star catalog: "
00459 "instrument response curve will not be produced.");
00460 standard = 0;
00461 }
00462 }
00463
00464 cpl_msg_indent_less();
00465
00466
00467
00468
00469
00470
00471 exptime = cpl_calloc(nscience, sizeof(double));
00472
00473 if (nscience > 1) {
00474
00475 cpl_msg_info(recipe, "Load %d scientific frames and median them...",
00476 nscience);
00477 cpl_msg_indent_more();
00478
00479 all_science = cpl_imagelist_new();
00480
00481 header = dfs_load_header(frameset, science_tag, 0);
00482
00483 if (header == NULL)
00484 vimos_science_exit("Cannot load scientific frame header");
00485
00486 alltime = exptime[0] = cpl_propertylist_get_double(header, "EXPTIME");
00487
00488 if (cpl_error_get_code() != CPL_ERROR_NONE)
00489 vimos_science_exit("Missing keyword EXPTIME in scientific "
00490 "frame header");
00491
00492 if (standard) {
00493 airmass = fors_get_airmass(header);
00494 if (airmass < 0.0)
00495 vimos_science_exit("Missing airmass information in "
00496 "scientific frame header");
00497 }
00498
00499 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00500 if (instrume == NULL)
00501 vimos_science_exit("Missing keyword INSTRUME "
00502 "in scientific frame header");
00503
00504 cpl_propertylist_delete(header); header = NULL;
00505
00506 cpl_msg_info(recipe, "Scientific frame 1 exposure time: %.2f s",
00507 exptime[0]);
00508
00509 for (i = 1; i < nscience; i++) {
00510
00511 header = dfs_load_header(frameset, NULL, 0);
00512
00513 if (header == NULL)
00514 vimos_science_exit("Cannot load scientific frame header");
00515
00516 exptime[i] = cpl_propertylist_get_double(header, "EXPTIME");
00517
00518 alltime += exptime[i];
00519
00520 if (cpl_error_get_code() != CPL_ERROR_NONE)
00521 vimos_science_exit("Missing keyword EXPTIME in scientific "
00522 "frame header");
00523
00524 cpl_propertylist_delete(header); header = NULL;
00525
00526 cpl_msg_info(recipe, "Scientific frame %d exposure time: %.2f s",
00527 i+1, exptime[i]);
00528 }
00529
00530 spectra = dfs_load_image(frameset, science_tag, CPL_TYPE_FLOAT, 0, 0);
00531
00532 if (spectra == NULL)
00533 vimos_science_exit("Cannot load scientific frame");
00534
00535 cpl_image_divide_scalar(spectra, exptime[0]);
00536 cpl_imagelist_set(all_science, spectra, 0);
00537
00538 for (i = 1; i < nscience; i++) {
00539
00540 spectra = dfs_load_image(frameset, NULL, CPL_TYPE_FLOAT, 0, 0);
00541
00542 if (spectra) {
00543 cpl_image_divide_scalar(spectra, exptime[i]);
00544 cpl_imagelist_set(all_science, spectra, i);
00545 }
00546 else
00547 vimos_science_exit("Cannot load scientific frame");
00548
00549 }
00550
00551 spectra = cpl_imagelist_collapse_median_create(all_science);
00552 cpl_image_multiply_scalar(spectra, alltime);
00553
00554 cpl_imagelist_delete(all_science);
00555 }
00556 else {
00557 cpl_msg_info(recipe, "Load scientific exposure...");
00558 cpl_msg_indent_more();
00559
00560 header = dfs_load_header(frameset, science_tag, 0);
00561
00562 if (header == NULL)
00563 vimos_science_exit("Cannot load scientific frame header");
00564
00565 alltime = exptime[0] = cpl_propertylist_get_double(header, "EXPTIME");
00566
00567 if (cpl_error_get_code() != CPL_ERROR_NONE)
00568 vimos_science_exit("Missing keyword EXPTIME in scientific "
00569 "frame header");
00570
00571 if (standard) {
00572 airmass = fors_get_airmass(header);
00573 if (airmass < 0.0)
00574 vimos_science_exit("Missing airmass information in "
00575 "scientific frame header");
00576 }
00577
00578 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00579 if (instrume == NULL)
00580 vimos_science_exit("Missing keyword INSTRUME "
00581 "in scientific frame header");
00582
00583 cpl_propertylist_delete(header); header = NULL;
00584
00585 cpl_msg_info(recipe, "Scientific frame exposure time: %.2f s",
00586 exptime[0]);
00587
00588 spectra = dfs_load_image(frameset, science_tag, CPL_TYPE_FLOAT, 0, 0);
00589 }
00590
00591 if (spectra == NULL)
00592 vimos_science_exit("Cannot load scientific frame");
00593
00594 cpl_free(exptime); exptime = NULL;
00595
00596 cpl_msg_indent_less();
00597
00598
00599
00600
00601
00602
00603 header = dfs_load_header(frameset, science_tag, 0);
00604
00605 if (header == NULL)
00606 vimos_science_exit("Cannot load scientific frame header");
00607
00608 quadrant = cpl_propertylist_get_int(header, "ESO OCS CON QUAD");
00609
00610 switch (quadrant) {
00611 case 1:
00612 key_gris_name = "ESO INS GRIS1 NAME";
00613 key_gris_id = "ESO INS GRIS1 ID";
00614 key_filt_name = "ESO INS FILT1 NAME";
00615 key_filt_id = "ESO INS FILT1 ID";
00616 break;
00617 case 2:
00618 key_gris_name = "ESO INS GRIS2 NAME";
00619 key_gris_id = "ESO INS GRIS2 ID";
00620 key_filt_name = "ESO INS FILT2 NAME";
00621 key_filt_id = "ESO INS FILT2 ID";
00622 break;
00623 case 3:
00624 key_gris_name = "ESO INS GRIS3 NAME";
00625 key_gris_id = "ESO INS GRIS3 ID";
00626 key_filt_name = "ESO INS FILT3 NAME";
00627 key_filt_id = "ESO INS FILT3 ID";
00628 break;
00629 case 4:
00630 key_gris_name = "ESO INS GRIS4 NAME";
00631 key_gris_id = "ESO INS GRIS4 ID";
00632 key_filt_name = "ESO INS FILT4 NAME";
00633 key_filt_id = "ESO INS FILT4 ID";
00634 break;
00635 }
00636
00637 if (standard) {
00638 if (!anyframe) {
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654 nexp = cpl_propertylist_get_int(header, "ESO TPL NEXP");
00655
00656 if (cpl_error_get_code() != CPL_ERROR_NONE)
00657 vimos_science_exit("Missing keyword ESO TPL NEXP in "
00658 "scientific frame header");
00659
00660 if (nexp == 4) {
00661 expno = cpl_propertylist_get_int(header, "ESO TPL EXPNO");
00662
00663 if (cpl_error_get_code() != CPL_ERROR_NONE)
00664 vimos_science_exit("Missing keyword ESO TPL EXPNO in "
00665 "scientific frame header");
00666 }
00667
00668 if (quadrant != expno) {
00669 cpl_msg_warning(recipe, "The MOS_STANDARD frame is not "
00670 "expected to contain a standard star: "
00671 "instrument response curve will not be "
00672 "produced. Set --anyframe=true to skip "
00673 "this check.");
00674 standard = 0;
00675 }
00676 }
00677 }
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687 gain = cpl_propertylist_get_double(header, "ESO DET OUT1 CONAD");
00688
00689 if (cpl_error_get_code() != CPL_ERROR_NONE)
00690 vimos_science_exit("Missing keyword ESO DET OUT1 CONAD in scientific "
00691 "frame header");
00692
00693 cpl_msg_info(recipe, "The gain factor is: %.2f e-/ADU", gain);
00694
00695 ron = cpl_propertylist_get_double(header, "ESO DET OUT1 RON");
00696
00697 if (cpl_error_get_code() != CPL_ERROR_NONE)
00698 vimos_science_exit("Missing keyword ESO DET OUT1 RON in scientific "
00699 "frame header");
00700
00701 ron /= gain;
00702
00703 cpl_msg_info(recipe, "The read-out-noise is: %.2f ADU", ron);
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740 if (treat_as_lss) {
00741 if (skylocal) {
00742 if (cosmics)
00743 vimos_science_exit("Cosmic rays correction for long-slit-like "
00744 "data requires --skyglobal=true");
00745 skymedian = skylocal;
00746 skylocal = 0;
00747 }
00748 }
00749 else {
00750 if (cpl_frameset_count_tags(frameset, curv_coeff_tag) == 0) {
00751 cpl_msg_error(recipe, "Missing required input: %s", curv_coeff_tag);
00752 vimos_science_exit(NULL);
00753 }
00754
00755 if (cpl_frameset_count_tags(frameset, curv_coeff_tag) > 1) {
00756 cpl_msg_error(recipe, "Too many in input: %s", curv_coeff_tag);
00757 vimos_science_exit(NULL);
00758 }
00759
00760 if (cpl_frameset_count_tags(frameset, slit_location_tag) == 0) {
00761 cpl_msg_error(recipe, "Missing required input: %s",
00762 slit_location_tag);
00763 vimos_science_exit(NULL);
00764 }
00765
00766 if (cpl_frameset_count_tags(frameset, slit_location_tag) > 1) {
00767 cpl_msg_error(recipe, "Too many in input: %s", slit_location_tag);
00768 vimos_science_exit(NULL);
00769 }
00770 }
00771
00772
00773
00774
00775
00776
00777
00778
00779 cpl_msg_info(recipe, "Remove the master bias...");
00780
00781 bias = dfs_load_image(frameset, "MASTER_BIAS", CPL_TYPE_FLOAT, 0, 1);
00782
00783 if (bias == NULL)
00784 vimos_science_exit("Cannot load master bias");
00785
00786 overscans = mos_load_overscans_vimos(header, 1);
00787 cpl_propertylist_delete(header); header = NULL;
00788 dummy = mos_remove_bias(spectra, bias, overscans);
00789 cpl_image_delete(spectra); spectra = dummy; dummy = NULL;
00790 cpl_image_delete(bias); bias = NULL;
00791 cpl_table_delete(overscans); overscans = NULL;
00792
00793 if (spectra == NULL)
00794 vimos_science_exit("Cannot remove bias from scientific frame");
00795
00796
00797
00798
00799
00800 cpl_image_turn(spectra, rotate);
00801
00802 nx = cpl_image_get_size_x(spectra);
00803 ny = cpl_image_get_size_y(spectra);
00804
00805 cpl_msg_indent_less();
00806 cpl_msg_info(recipe, "Load normalised flat field (if present)...");
00807 cpl_msg_indent_more();
00808
00809 if (flatfield) {
00810
00811 norm_flat = dfs_load_image(frameset, master_norm_flat_tag,
00812 CPL_TYPE_FLOAT, 0, 1);
00813
00814 if (norm_flat) {
00815 cpl_image_turn(norm_flat, rotate);
00816 cpl_msg_info(recipe, "Apply flat field correction...");
00817 if (cpl_image_divide(spectra, norm_flat) != CPL_ERROR_NONE) {
00818 cpl_msg_error(recipe, "Failure of flat field correction: %s",
00819 cpl_error_get_message());
00820 vimos_science_exit(NULL);
00821 }
00822 cpl_image_delete(norm_flat); norm_flat = NULL;
00823 }
00824 else {
00825 cpl_msg_error(recipe, "Cannot load input %s for flat field "
00826 "correction", master_norm_flat_tag);
00827 vimos_science_exit(NULL);
00828 }
00829
00830 }
00831
00832
00833 if (skyalign >= 0) {
00834 cpl_msg_indent_less();
00835 cpl_msg_info(recipe, "Load input sky line catalog...");
00836 cpl_msg_indent_more();
00837
00838 wavelengths = dfs_load_table(frameset, "SKY_LINE_CATALOG", 1);
00839
00840 if (wavelengths) {
00841
00842
00843
00844
00845
00846 nlines = cpl_table_get_nrow(wavelengths);
00847
00848 if (nlines == 0)
00849 vimos_science_exit("Empty input sky line catalog");
00850
00851 if (cpl_table_has_column(wavelengths, wcolumn) != 1) {
00852 cpl_msg_error(recipe, "Missing column %s in input line "
00853 "catalog table", wcolumn);
00854 vimos_science_exit(NULL);
00855 }
00856
00857 line = cpl_malloc(nlines * sizeof(double));
00858
00859 for (i = 0; i < nlines; i++)
00860 line[i] = cpl_table_get(wavelengths, wcolumn, i, NULL);
00861
00862 cpl_table_delete(wavelengths); wavelengths = NULL;
00863
00864 lines = cpl_vector_wrap(nlines, line);
00865 }
00866 else {
00867 cpl_msg_info(recipe, "No sky line catalog found in input - fine!");
00868 }
00869 }
00870
00871
00872
00873
00874
00875
00876
00877 if (!treat_as_lss) {
00878 polytraces = dfs_load_table(frameset, curv_coeff_tag, 1);
00879 if (polytraces == NULL)
00880 vimos_science_exit("Cannot load spectral curvature table");
00881 }
00882
00883
00884
00885
00886
00887
00888
00889 if (treat_as_lss) {
00890 slits = cpl_table_new(1);
00891 cpl_table_new_column(slits, "slit_id", CPL_TYPE_INT);
00892 cpl_table_set_int(slits, "slit_id", 0, 1);
00893 cpl_table_new_column(slits, "position", CPL_TYPE_INT);
00894 cpl_table_set_int(slits, "position", 0, 0);
00895 cpl_table_new_column(slits, "length", CPL_TYPE_INT);
00896 cpl_table_set_int(slits, "length", 0, ny);
00897 }
00898 else {
00899 slits = dfs_load_table(frameset, slit_location_tag, 1);
00900 if (slits == NULL)
00901 vimos_science_exit("Cannot load slits location table");
00902 mos_rotate_slits(slits, -rotate, nx, ny);
00903 }
00904
00905
00906
00907
00908
00909
00910 idscoeff = dfs_load_table(frameset, disp_coeff_tag, 1);
00911 if (idscoeff == NULL)
00912 vimos_science_exit("Cannot load wavelength calibration table");
00913
00914 cpl_msg_indent_less();
00915 cpl_msg_info(recipe, "Processing scientific spectra...");
00916 cpl_msg_indent_more();
00917
00918
00919
00920
00921
00922
00923 if (treat_as_lss) {
00924 smapped = cpl_image_duplicate(spectra);
00925 }
00926 else {
00927 coordinate = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
00928
00929 smapped = mos_spatial_calibration(spectra, slits, polytraces, reference,
00930 startwavelength, endwavelength,
00931 dispersion, flux, coordinate);
00932 }
00933
00934
00935
00936
00937
00938
00939
00940 rainbow = mos_map_idscoeff(idscoeff, nx, reference, startwavelength,
00941 endwavelength);
00942
00943 if (dispersion > 1.0)
00944 highres = 0;
00945 else
00946 highres = 1;
00947
00948 if (skyalign >= 0) {
00949 if (skyalign) {
00950 cpl_msg_info(recipe, "Align wavelength solution to reference "
00951 "skylines applying %d order residual fit...", skyalign);
00952 }
00953 else {
00954 cpl_msg_info(recipe, "Align wavelength solution to reference "
00955 "skylines applying median offset...");
00956 }
00957
00958 if (treat_as_lss) {
00959 offsets = mos_wavelength_align_lss(smapped, reference,
00960 startwavelength, endwavelength,
00961 idscoeff, lines, highres,
00962 skyalign, rainbow, 4);
00963 }
00964 else {
00965 offsets = mos_wavelength_align(smapped, slits, reference,
00966 startwavelength, endwavelength,
00967 idscoeff, lines, highres, skyalign,
00968 rainbow, 4);
00969 }
00970
00971 cpl_vector_delete(lines); lines = NULL;
00972
00973 if (offsets) {
00974 if (standard)
00975 cpl_msg_warning(recipe, "Alignment of the wavelength solution "
00976 "to reference sky lines may be unreliable in "
00977 "this case!");
00978
00979 if (dfs_save_table(frameset, offsets, skylines_offsets_tag, NULL,
00980 parlist, recipe, version))
00981 vimos_science_exit(NULL);
00982
00983 cpl_table_delete(offsets); offsets = NULL;
00984 }
00985 else {
00986 cpl_msg_warning(recipe, "Alignment of the wavelength solution "
00987 "to reference sky lines could not be done!");
00988 skyalign = -1;
00989 }
00990
00991 }
00992
00993 if (treat_as_lss) {
00994 wavemap = rainbow;
00995 rainbow = NULL;
00996 }
00997 else {
00998 wavemap = mos_map_wavelengths(coordinate, rainbow, slits,
00999 polytraces, reference,
01000 startwavelength, endwavelength,
01001 dispersion);
01002 }
01003
01004 cpl_image_delete(rainbow); rainbow = NULL;
01005 cpl_image_delete(coordinate); coordinate = NULL;
01006
01007
01008
01009
01010
01011
01012 mapped_sky = mos_wavelength_calibration(smapped, reference,
01013 startwavelength, endwavelength,
01014 dispersion, idscoeff, flux);
01015
01016 cpl_msg_indent_less();
01017 cpl_msg_info(recipe, "Check applied wavelength against skylines...");
01018 cpl_msg_indent_more();
01019
01020 mean_rms = mos_distortions_rms(mapped_sky, NULL, startwavelength,
01021 dispersion, 6, highres);
01022
01023 cpl_msg_info(recipe, "Mean residual: %f", mean_rms);
01024
01025 mean_rms = cpl_table_get_column_mean(idscoeff, "error");
01026
01027 cpl_msg_info(recipe, "Mean model accuracy: %f pixel (%f A)",
01028 mean_rms, mean_rms * dispersion);
01029
01030 header = cpl_propertylist_new();
01031 cpl_propertylist_update_double(header, "CRPIX1", 1.0);
01032 cpl_propertylist_update_double(header, "CRPIX2", 1.0);
01033 cpl_propertylist_update_double(header, "CRVAL1",
01034 startwavelength + dispersion/2);
01035 cpl_propertylist_update_double(header, "CRVAL2", 1.0);
01036
01037
01038 cpl_propertylist_update_double(header, "CD1_1", dispersion);
01039 cpl_propertylist_update_double(header, "CD1_2", 0.0);
01040 cpl_propertylist_update_double(header, "CD2_1", 0.0);
01041 cpl_propertylist_update_double(header, "CD2_2", 1.0);
01042 cpl_propertylist_update_string(header, "CTYPE1", "LINEAR");
01043 cpl_propertylist_update_string(header, "CTYPE2", "PIXEL");
01044
01045 if (time_normalise) {
01046 dummy = cpl_image_divide_scalar_create(mapped_sky, alltime);
01047 if (dfs_save_image(frameset, dummy, mapped_science_sky_tag, header,
01048 parlist, recipe, version))
01049 vimos_science_exit(NULL);
01050 cpl_image_delete(dummy); dummy = NULL;
01051 }
01052 else {
01053 if (dfs_save_image(frameset, mapped_sky, mapped_science_sky_tag,
01054 header, parlist, recipe, version))
01055 vimos_science_exit(NULL);
01056 }
01057
01058 if (skyglobal == 0 && skymedian == 0 && skylocal == 0) {
01059 cpl_image_delete(mapped_sky); mapped_sky = NULL;
01060 }
01061
01062 if (skyglobal || skylocal) {
01063
01064 cpl_msg_indent_less();
01065
01066 if (skyglobal) {
01067 cpl_msg_info(recipe, "Global sky determination...");
01068 cpl_msg_indent_more();
01069 skymap = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
01070 sky = mos_sky_map_super(spectra, wavemap, dispersion,
01071 2.0, 50, skymap);
01072 if (sky)
01073 cpl_image_subtract(spectra, skymap);
01074 else
01075 cpl_image_delete(skymap); skymap = NULL;
01076 }
01077 else {
01078 cpl_msg_info(recipe, "Local sky determination...");
01079 cpl_msg_indent_more();
01080 skymap = mos_subtract_sky(spectra, slits, polytraces, reference,
01081 startwavelength, endwavelength, dispersion);
01082 }
01083
01084 if (skymap) {
01085 if (skyglobal) {
01086 if (time_normalise)
01087 cpl_table_divide_scalar(sky, "sky", alltime);
01088 if (dfs_save_table(frameset, sky, global_sky_spectrum_tag,
01089 NULL, parlist, recipe, version))
01090 vimos_science_exit(NULL);
01091
01092 cpl_table_delete(sky); sky = NULL;
01093 }
01094
01095 save_header = dfs_load_header(frameset, science_tag, 0);
01096
01097 if (time_normalise)
01098 cpl_image_divide_scalar(skymap, alltime);
01099 cpl_image_turn(skymap, rotate_back);
01100 if (dfs_save_image(frameset, skymap, unmapped_sky_tag,
01101 save_header, parlist, recipe, version))
01102 vimos_science_exit(NULL);
01103
01104 cpl_image_delete(skymap); skymap = NULL;
01105
01106 cpl_image_turn(spectra, rotate_back);
01107
01108 if (cosmics) {
01109 cpl_msg_info(recipe, "Removing cosmic rays...");
01110 mos_clean_cosmics(spectra, gain, -1., -1.);
01111 }
01112
01113 if (dfs_save_image(frameset, spectra, unmapped_science_tag,
01114 save_header, parlist, recipe, version))
01115 vimos_science_exit(NULL);
01116 cpl_image_turn(spectra, rotate);
01117
01118 cpl_propertylist_delete(save_header); save_header = NULL;
01119
01120
01121
01122
01123
01124
01125 cpl_image_delete(smapped); smapped = NULL;
01126
01127 if (treat_as_lss) {
01128 smapped = cpl_image_duplicate(spectra);
01129 }
01130 else {
01131 smapped = mos_spatial_calibration(spectra, slits, polytraces,
01132 reference, startwavelength,
01133 endwavelength, dispersion,
01134 flux, NULL);
01135 }
01136 }
01137 else {
01138 cpl_msg_warning(recipe, "Sky subtraction failure");
01139 if (cosmics)
01140 cpl_msg_warning(recipe, "Cosmic rays removal not performed!");
01141 cosmics = skylocal = skyglobal = 0;
01142 }
01143 }
01144
01145 cpl_image_delete(spectra); spectra = NULL;
01146 cpl_table_delete(polytraces); polytraces = NULL;
01147
01148 if (skyalign >= 0) {
01149 save_header = dfs_load_header(frameset, science_tag, 0);
01150 cpl_image_turn(wavemap, rotate_back);
01151 if (dfs_save_image(frameset, wavemap, wavelength_map_sky_tag,
01152 save_header, parlist, recipe, version))
01153 vimos_science_exit(NULL);
01154 cpl_propertylist_delete(save_header); save_header = NULL;
01155 }
01156
01157 cpl_image_delete(wavemap); wavemap = NULL;
01158
01159 mapped = mos_wavelength_calibration(smapped, reference,
01160 startwavelength, endwavelength,
01161 dispersion, idscoeff, flux);
01162
01163 cpl_image_delete(smapped); smapped = NULL;
01164
01165 if (skymedian) {
01166 cpl_msg_indent_less();
01167 cpl_msg_info(recipe, "Local sky determination...");
01168 cpl_msg_indent_more();
01169
01170 skylocalmap = mos_sky_local_old(mapped, slits);
01171 cpl_image_subtract(mapped, skylocalmap);
01172 cpl_image_delete(skylocalmap); skylocalmap = NULL;
01173 }
01174
01175 if (skyglobal || skymedian || skylocal) {
01176
01177 skylocalmap = cpl_image_subtract_create(mapped_sky, mapped);
01178
01179 cpl_image_delete(mapped_sky); mapped_sky = NULL;
01180
01181 if (time_normalise) {
01182 dummy = cpl_image_divide_scalar_create(skylocalmap, alltime);
01183 if (dfs_save_image(frameset, dummy, mapped_sky_tag, header,
01184 parlist, recipe, version))
01185 vimos_science_exit(NULL);
01186 cpl_image_delete(dummy); dummy = NULL;
01187 }
01188 else {
01189 if (dfs_save_image(frameset, skylocalmap, mapped_sky_tag, header,
01190 parlist, recipe, version))
01191 vimos_science_exit(NULL);
01192 }
01193
01194 cpl_msg_indent_less();
01195 cpl_msg_info(recipe, "Object detection...");
01196 cpl_msg_indent_more();
01197
01198 if (cosmics || nscience > 1) {
01199 dummy = mos_detect_objects(mapped, slits, slit_margin, ext_radius,
01200 cont_radius);
01201 }
01202 else {
01203 mapped_cleaned = cpl_image_duplicate(mapped);
01204 mos_clean_cosmics(mapped_cleaned, gain, -1., -1.);
01205 dummy = mos_detect_objects(mapped_cleaned, slits, slit_margin,
01206 ext_radius, cont_radius);
01207
01208 cpl_image_delete(mapped_cleaned); mapped_cleaned = NULL;
01209 }
01210
01211 cpl_image_delete(dummy); dummy = NULL;
01212
01213 mos_rotate_slits(slits, rotate, ny, nx);
01214 if (dfs_save_table(frameset, slits, object_table_tag, NULL, parlist,
01215 recipe, version))
01216 vimos_science_exit(NULL);
01217
01218 cpl_msg_indent_less();
01219 cpl_msg_info(recipe, "Object extraction...");
01220 cpl_msg_indent_more();
01221
01222 images = mos_extract_objects(mapped, skylocalmap, slits,
01223 ext_mode, ron, gain, 1);
01224
01225 cpl_image_delete(skylocalmap); skylocalmap = NULL;
01226
01227 if (images) {
01228 if (standard) {
01229 cpl_table *photcal = NULL;
01230 cpl_table *ext_table = NULL;
01231 cpl_table *flux_table = NULL;
01232
01233 ext_table = dfs_load_table(frameset, "EXTINCT_TABLE", 1);
01234 flux_table = dfs_load_table(frameset, "STD_FLUX_TABLE", 1);
01235
01236 photcal = mos_photometric_calibration(images[0],
01237 startwavelength,
01238 dispersion, gain,
01239 alltime, ext_table,
01240 airmass, flux_table,
01241 res_order);
01242
01243 cpl_table_delete(ext_table);
01244 cpl_table_delete(flux_table);
01245
01246 if (photcal) {
01247
01248 if (qc) {
01249
01250 float *data;
01251 char *pipefile = NULL;
01252 char keyname[30];
01253
01254 qclist = dfs_load_header(frameset, science_tag, 0);
01255
01256 if (qclist == NULL)
01257 vimos_science_exit("Cannot reload scientific "
01258 "frame header");
01259
01260 fors_qc_start_group(qclist, "2.0", instrume);
01261
01262
01263
01264
01265
01266
01267 if (fors_qc_write_string("PRO.CATG", specphot_tag,
01268 "Product category", instrume))
01269 vimos_science_exit("Cannot write product category "
01270 "to QC log file");
01271
01272 if (fors_qc_keyword_to_paf(qclist, "ESO DPR TYPE", NULL,
01273 "DPR type", instrume))
01274 vimos_science_exit("Missing keyword DPR TYPE in "
01275 "scientific frame header");
01276
01277 if (fors_qc_keyword_to_paf(qclist, "ESO TPL ID", NULL,
01278 "Template", instrume))
01279 vimos_science_exit("Missing keyword TPL ID in "
01280 "scientific frame header");
01281
01282 if (fors_qc_keyword_to_paf(qclist,
01283 key_gris_name, NULL,
01284 "Grism name", instrume)) {
01285 cpl_msg_error(recipe, "Missing keyword %s in "
01286 "scientific frame header",
01287 key_gris_name);
01288 vimos_science_exit(NULL);
01289 }
01290
01291 if (fors_qc_keyword_to_paf(qclist,
01292 "ESO INS GRIS1 ID", NULL,
01293 "Grism identifier",
01294 instrume)) {
01295 cpl_msg_error(recipe, "Missing keyword %s in "
01296 "scientific frame header",
01297 key_gris_id);
01298 vimos_science_exit(NULL);
01299 }
01300
01301 if (cpl_propertylist_has(qclist, key_filt_name))
01302 fors_qc_keyword_to_paf(qclist, key_filt_name, NULL,
01303 "Filter name", instrume);
01304
01305 if (fors_qc_keyword_to_paf(qclist,
01306 "ESO DET CHIP1 ID", NULL,
01307 "Chip identifier",
01308 instrume))
01309 vimos_science_exit("Missing keyword DET CHIP1 ID "
01310 "in scientific frame header");
01311
01312 if (fors_qc_keyword_to_paf(qclist, "ARCFILE", NULL,
01313 "Archive name of input data",
01314 instrume))
01315 vimos_science_exit("Missing keyword ARCFILE in "
01316 "scientific frame header");
01317
01318 pipefile = dfs_generate_filename_tfits(specphot_tag);
01319
01320 if (fors_qc_write_string("PIPEFILE", pipefile,
01321 "Pipeline product name",
01322 instrume))
01323 vimos_science_exit("Cannot write PIPEFILE to "
01324 "QC log file");
01325 cpl_free(pipefile);
01326
01327
01328
01329
01330
01331
01332 wstart = 3700.;
01333 wstep = 400.;
01334 wcount = 15;
01335
01336 dummy = cpl_image_new(wcount, 1, CPL_TYPE_FLOAT);
01337 data = cpl_image_get_data_float(dummy);
01338 map_table(dummy, wstart, wstep, photcal,
01339 "WAVE", "EFFICIENCY");
01340
01341 for (i = 0; i < wcount; i++) {
01342 sprintf(keyname, "QC.MOS.EFFICIENCY%d.LAMBDA",
01343 i + 1);
01344 if (fors_qc_write_qc_double(qclist,
01345 wstart + wstep * i,
01346 keyname, "Angstrom",
01347 "Wavelength of "
01348 "efficiency evaluation",
01349 instrume)) {
01350 vimos_science_exit("Cannot write wavelength of "
01351 "efficiency evaluation");
01352 }
01353
01354 sprintf(keyname, "QC.MOS.EFFICIENCY%d", i + 1);
01355 if (fors_qc_write_qc_double(qclist,
01356 data[i],
01357 keyname, "e-/photon",
01358 "Efficiency",
01359 instrume)) {
01360 vimos_science_exit("Cannot write wavelength of "
01361 "efficiency evaluation");
01362 }
01363 }
01364
01365 cpl_image_delete(dummy); dummy = NULL;
01366
01367 fors_qc_end_group();
01368
01369 }
01370
01371 if (dfs_save_table(frameset, photcal, specphot_tag, qclist,
01372 parlist, recipe, version)) {
01373 cpl_table_delete(photcal);
01374 vimos_science_exit(NULL);
01375 }
01376 cpl_propertylist_delete(qclist); qclist = NULL;
01377 cpl_table_delete(photcal);
01378 }
01379 }
01380
01381 if (time_normalise)
01382 cpl_image_divide_scalar(images[0], alltime);
01383
01384 if (dfs_save_image(frameset, images[0], reduced_science_tag, header,
01385 parlist, recipe, version))
01386 vimos_science_exit(NULL);
01387
01388 cpl_image_delete(images[0]);
01389
01390 if (time_normalise)
01391 cpl_image_divide_scalar(images[1], alltime);
01392
01393 if (dfs_save_image(frameset, images[1], reduced_sky_tag, header,
01394 parlist, recipe, version))
01395 vimos_science_exit(NULL);
01396
01397 cpl_image_delete(images[1]);
01398
01399 if (time_normalise)
01400 cpl_image_divide_scalar(images[2], alltime);
01401
01402 if (dfs_save_image(frameset, images[2], reduced_error_tag, header,
01403 parlist, recipe, version))
01404 vimos_science_exit(NULL);
01405
01406 cpl_image_delete(images[2]);
01407
01408 cpl_free(images);
01409 }
01410 else {
01411 cpl_msg_warning(recipe, "No objects found: the products "
01412 "%s, %s, and %s are not created",
01413 reduced_science_tag, reduced_sky_tag,
01414 reduced_error_tag);
01415 }
01416
01417 }
01418
01419 cpl_table_delete(slits); slits = NULL;
01420
01421 if (skyalign >= 0) {
01422 if (dfs_save_table(frameset, idscoeff, disp_coeff_sky_tag, NULL,
01423 parlist, recipe, version))
01424 vimos_science_exit(NULL);
01425 }
01426
01427 cpl_table_delete(idscoeff); idscoeff = NULL;
01428
01429 if (skyglobal || skymedian || skylocal) {
01430 if (time_normalise)
01431 cpl_image_divide_scalar(mapped, alltime);
01432 if (dfs_save_image(frameset, mapped, mapped_science_tag, header,
01433 parlist, recipe, version))
01434 vimos_science_exit(NULL);
01435 }
01436
01437 cpl_image_delete(mapped); mapped = NULL;
01438 cpl_propertylist_delete(header); header = NULL;
01439
01440 if (cpl_error_get_code()) {
01441 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01442 vimos_science_exit(NULL);
01443 }
01444 else
01445 return 0;
01446 }