FORS Pipeline Reference Manual 4.9.20
|
00001 /* $Id: vimos_science_impl.c,v 1.3 2010/09/14 07:49:30 cizzo Exp $ 00002 * 00003 * This file is part of the FORS Data Reduction Pipeline 00004 * Copyright (C) 2002-2010 European Southern Observatory 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 /* 00022 * $Author: cizzo $ 00023 * $Date: 2010/09/14 07:49:30 $ 00024 * $Revision: 1.3 $ 00025 * $Name: fors-4_9_20 $ 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 * Input parameters 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 * CPL objects 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 * Auxiliary variables 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 * Get configuration parameters 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 * Check input set-of-frames 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 * Loading input data 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 * Get some info from header 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 * As a default this recipe wouldn't reduce a frame belonging 00642 * to a quadrant that is not expected to contain a standard 00643 * star. The current template for getting data for photometric 00644 * calibration consists of a sequence of 4 exposures, where 00645 * the same standard star is moved through all quadrants. 00646 * The first exposure has the standard star in quadrant 1, 00647 * the second exposure in quadrant 2, and so on. So a standard 00648 * star will be reduced only if it is part of a template of 00649 * 4 exposures (i.e., TPL NEXP == 4), and if its sequence 00650 * number in the template is equal to its quadrant number 00651 * (i.e., TPL EXPNO == OCS CON QUAD). 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 if (!dfs_equal_keyword(frameset, key_gris_id)) 00681 vimos_science_exit("Input frames are not from the same grism"); 00682 00683 if (!dfs_equal_keyword(frameset, key_filt_id)) 00684 vimos_science_exit("Input frames are not from the same filter"); 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; /* Convert from electrons to ADU */ 00702 00703 cpl_msg_info(recipe, "The read-out-noise is: %.2f ADU", ron); 00704 00705 /* 00706 * In VIMOS data are "never" LSS. This is why this part is 00707 * commented out. 00708 */ 00709 00710 // maskslits = mos_load_slits_vimos(header); 00711 // 00712 // /* 00713 // * Check if all slits have the same X offset: in such case, 00714 // * treat the observation as a long-slit one! 00715 // */ 00716 // 00717 // mxpos = cpl_table_get_column_median(maskslits, "ytop"); 00718 // xpos = cpl_table_get_data_double(maskslits, "ytop"); 00719 // nslits = cpl_table_get_nrow(maskslits); 00720 // 00721 // treat_as_lss = 1; 00722 // for (i = 0; i < nslits; i++) { 00723 // if (fabs(mxpos-xpos[i]) > 0.01) { 00724 // treat_as_lss = 0; 00725 // break; 00726 // } 00727 // } 00728 // 00729 // treat_as_lss = 0; // FIXME Prevent LSS treatment for the moment!!! 00730 // 00731 // cpl_table_delete(maskslits); maskslits = NULL; 00732 // 00733 // if (treat_as_lss) { 00734 // cpl_msg_warning(recipe, "All MOS slits have the same offset: %.2f\n" 00735 // "The LSS data reduction strategy is applied!", 00736 // mxpos); 00737 // skylines_offsets_tag = "MOS_SKYLINES_OFFSETS_LONG"; 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 /* Leave the header on for the next step... */ 00773 00774 00775 /* 00776 * Remove the master bias 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 * Rotate frames horizontally with red to the right 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 * Cast the wavelengths into a (double precision) CPL vector 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 * Load the spectral curvature table, or provide a dummy one 00874 * in case of LSS-like data (single slit with flat curvature) 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 * Load the slit location table, or provide a dummy one in case 00886 * of LSS-like data (single slit spanning whole image) 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 * Load the wavelength calibration table 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 * This one will also generate the spatial map from the spectral 00920 * curvature table (in the case of multislit data) 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 * Generate a rectified wavelength map from the wavelength calibration 00937 * table 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 * Here the wavelength calibrated slit spectra are created. This frame 01009 * contains sky_science. 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 /* cpl_propertylist_update_double(header, "CDELT1", dispersion); 01037 cpl_propertylist_update_double(header, "CDELT2", 1.0); */ 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 /* Cosmics was here */ 01120 /* 01121 * The spatially rectified image, that contained the sky, 01122 * is replaced by a sky-subtracted spatially rectified image: 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 * QC1 group header 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 * QC1 parameters 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 } /* End of QC1 computation */ 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 }