|
KMOS Pipeline Reference Manual
1.1.4
|
00001 /* $Id: kmo_reconstruct.c,v 1.53 2013/05/23 14:48:09 erw Exp $ 00002 * 00003 * This file is part of the KMOS Pipeline 00004 * Copyright (C) 2002,2003 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 */ 00020 00021 /* 00022 * $Author: erw $ 00023 * $Date: 2013/05/23 14:48:09 $ 00024 * $Revision: 1.53 $ 00025 * $Name: HEAD $ 00026 */ 00027 00028 #ifdef HAVE_CONFIG_H 00029 #include <config.h> 00030 #endif 00031 00032 /*----------------------------------------------------------------------------- 00033 * Includes 00034 *----------------------------------------------------------------------------*/ 00035 00036 #include <string.h> 00037 #include <math.h> 00038 00039 #include <cpl.h> 00040 00041 #include "kmo_utils.h" 00042 #include "kmo_functions.h" 00043 #include "kmo_priv_reconstruct.h" 00044 #include "kmo_priv_functions.h" 00045 #include "kmo_priv_lcorr.h" 00046 #include "kmo_cpl_extensions.h" 00047 #include "kmo_dfs.h" 00048 #include "kmo_error.h" 00049 #include "kmo_utils.h" 00050 #include "kmo_constants.h" 00051 #include "kmo_debug.h" 00052 00053 /*----------------------------------------------------------------------------- 00054 * Functions prototypes 00055 *----------------------------------------------------------------------------*/ 00056 00057 static int kmo_reconstruct_create(cpl_plugin *); 00058 static int kmo_reconstruct_exec(cpl_plugin *); 00059 static int kmo_reconstruct_destroy(cpl_plugin *); 00060 static int kmo_reconstruct(cpl_parameterlist *, cpl_frameset *); 00061 00062 /*----------------------------------------------------------------------------- 00063 * Static variables 00064 *----------------------------------------------------------------------------*/ 00065 00066 static char kmo_reconstruct_description[] = 00067 "Data with or without noise is reconstructed into a cube using the calibration\n" 00068 "frames XCAL, YCAL and LCAL. XCAL and YCAL are generated using recipe kmo_flat,\n" 00069 "LCAL is generated using recipe kmo_wave_cal.\n" 00070 "The input data can contain noise extensions and will be reconstructed into\n" 00071 "additional extensions.\n" 00072 "If an OH spectrum is given in the SOF file the lambda axis will be corrected\n" 00073 "using the OH lines as reference.\n" 00074 "\n" 00075 "BASIC PARAMETERS:\n" 00076 "-----------------\n" 00077 "--imethod\n" 00078 "The interpolation method used for reconstruction.\n" 00079 "\n" 00080 "--detimg\n" 00081 "Specify if the resampled image of the input frame should be generated. There-\n" 00082 "fore all slitlets of all IFUs are aligned one next to the other. This frame\n" 00083 "serves for quality control. One can immediately see if the reconstruction was\n" 00084 "successful.\n" 00085 "\n" 00086 "--file_extension" 00087 "Set this parameter to TRUE if the EXPTIME keyword should be appended to\n" 00088 "the output filenames.\n" 00089 "\n" 00090 "ADVANCED PARAMETERS\n" 00091 "-------------------\n" 00092 "--flux\n" 00093 "Specify if flux conservation should be applied.\n" 00094 "\n" 00095 "--neighborhoodRange\n" 00096 "Defines the range to search for neighbors during reconstruction\n" 00097 "\n" 00098 "--b_samples\n" 00099 "The number of samples in spectral direction for the reconstructed cube. Ideal-\n" 00100 "ly this number should be greater than 2048, the detector size.\n" 00101 "\n" 00102 "--b_start\n" 00103 "--b_end\n" 00104 "Used to define manually the start and end wavelength for the reconstructed\n" 00105 "cube. By default the internally defined values are used.\n" 00106 "\n" 00107 "--file_extension" 00108 "Set to TRUE if OBS_ID (from input frame header) should be appended to the\n" 00109 "output frame.\n" 00110 "\n" 00111 "--pix_scale\n" 00112 "Change the pixel scale [arcsec]. Default of 0.2\" results into cubes of\n" 00113 "14x14pix, a scale of 0.1\" results into cubes of 28x28pix, etc.\n" 00114 "\n" 00115 "--xcal_interpolation\n" 00116 "If true interpolate the pixel position in the slitlet (xcal) using the two\n" 00117 "closest rotator angles in the calibration file. Otherwise take the values\n" 00118 "of the closest rotator angle\n" 00119 "\n" 00120 "-------------------------------------------------------------------------------\n" 00121 " Input files:\n" 00122 "\n" 00123 " DO KMOS \n" 00124 " category Type Explanation Required #Frames\n" 00125 " -------- ----- ----------- -------- -------\n" 00126 " DARK or RAW/F2D data with Y 1 \n" 00127 " FLAT_ON or RAW/F2D or without noise \n" 00128 " ARC_ON or RAW/F2D \n" 00129 " OBJECT or RAW \n" 00130 " STD or RAW \n" 00131 " SCIENCE RAW \n" 00132 " XCAL F2D x-direction calib. frame Y 1 \n" 00133 " YCAL F2D y-direction calib. frame Y 1 \n" 00134 " LCAL F2D Wavelength calib. frame Y 1 \n" 00135 " WAVE_BAND F2L Table with start-/end-wavelengths Y 1 \n" 00136 " OH_SPEC F1S Vector holding OH lines N 1 \n" 00137 "\n" 00138 " Output files:\n" 00139 "\n" 00140 " DO KMOS\n" 00141 " category Type Explanation\n" 00142 " -------- ----- -----------\n" 00143 " CUBE_DARK or F3I Reconstructed cube \n" 00144 " CUBE_FLAT or RAW/F2D with or without noise\n" 00145 " CUBE_ARC or \n" 00146 " CUBE_OBJECT or \n" 00147 " CUBE_STD or \n" 00148 " CUBE_SCIENCE \n" 00149 "-------------------------------------------------------------------------------\n" 00150 "\n"; 00151 00152 /*----------------------------------------------------------------------------- 00153 * Functions code 00154 *----------------------------------------------------------------------------*/ 00155 00172 int cpl_plugin_get_info(cpl_pluginlist *list) 00173 { 00174 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00175 cpl_plugin *plugin = &recipe->interface; 00176 00177 cpl_plugin_init(plugin, 00178 CPL_PLUGIN_API, 00179 KMOS_BINARY_VERSION, 00180 CPL_PLUGIN_TYPE_RECIPE, 00181 "kmo_reconstruct", 00182 "Performs the cube reconstruction " 00183 "using different interpolation methods.", 00184 kmo_reconstruct_description, 00185 "Alex Agudo Berbel", 00186 "kmos-spark@mpe.mpg.de", 00187 kmos_get_license(), 00188 kmo_reconstruct_create, 00189 kmo_reconstruct_exec, 00190 kmo_reconstruct_destroy); 00191 00192 cpl_pluginlist_append(list, plugin); 00193 00194 return 0; 00195 } 00196 00204 static int kmo_reconstruct_create(cpl_plugin *plugin) 00205 { 00206 cpl_recipe *recipe; 00207 cpl_parameter *p; 00208 00209 /* Check that the plugin is part of a valid recipe */ 00210 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00211 recipe = (cpl_recipe *)plugin; 00212 else 00213 return -1; 00214 00215 /* Create the parameters list in the cpl_recipe object */ 00216 recipe->parameters = cpl_parameterlist_new(); 00217 00218 /* Fill the parameters list */ 00219 /* --imethod */ 00220 p = cpl_parameter_new_value("kmos.kmo_reconstruct.imethod", 00221 CPL_TYPE_STRING, 00222 "Method to use for interpolation. " 00223 "[\"NN\" (nearest neighbour), " 00224 "\"lwNN\" (linear weighted nearest neighbor), " 00225 "\"swNN\" (square weighted nearest neighbor), " 00226 "\"MS\" (Modified Shepard's method)" 00227 "\"CS\" (Cubic spline)]", 00228 "kmos.kmo_reconstruct", 00229 "CS"); 00230 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "imethod"); 00231 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00232 cpl_parameterlist_append(recipe->parameters, p); 00233 00234 /* --neighborhoodRange */ 00235 p = cpl_parameter_new_value("kmos.kmo_reconstruct.neighborhoodRange", 00236 CPL_TYPE_DOUBLE, 00237 "Defines the range to search for neighbors. " 00238 "in pixels", 00239 "kmos.kmo_reconstruct", 00240 1.001); 00241 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "neighborhoodRange"); 00242 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00243 cpl_parameterlist_append(recipe->parameters, p); 00244 00245 /* --flux */ 00246 p = cpl_parameter_new_value("kmos.kmo_reconstruct.flux", 00247 CPL_TYPE_BOOL, 00248 "TRUE: Apply flux conservation. FALSE: otherwise", 00249 "kmos.kmo_reconstruct", 00250 FALSE); 00251 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "flux"); 00252 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00253 cpl_parameterlist_append(recipe->parameters, p); 00254 00255 /* --detectorimage */ 00256 p = cpl_parameter_new_value("kmos.kmo_reconstruct.detectorimage", 00257 CPL_TYPE_BOOL, 00258 "TRUE: if resampled detector frame should be " 00259 "created, FALSE: otherwise", 00260 "kmos.kmo_reconstruct", 00261 FALSE); 00262 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "detimg"); 00263 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00264 cpl_parameterlist_append(recipe->parameters, p); 00265 00266 /* --file_extension */ 00267 p = cpl_parameter_new_value("kmos.kmo_reconstruct.file_extension", 00268 CPL_TYPE_BOOL, 00269 "TRUE: if OBS_ID keyword should be appended to " 00270 "output frames, FALSE: otherwise", 00271 "kmos.kmo_reconstruct", 00272 FALSE); 00273 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "file_extension"); 00274 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00275 cpl_parameterlist_append(recipe->parameters, p); 00276 00277 /* --pix_scale */ 00278 p = cpl_parameter_new_value("kmos.kmo_reconstruct.pix_scale", 00279 CPL_TYPE_DOUBLE, 00280 "Change the pixel scale [arcsec]. " 00281 "Default of 0.2\" results into cubes of 14x14pix, " 00282 "a scale of 0.1\" results into cubes of 28x28pix, " 00283 "etc.", 00284 "kmos.kmo_reconstruct", 00285 KMOS_PIX_RESOLUTION); 00286 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "pix_scale"); 00287 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00288 cpl_parameterlist_append(recipe->parameters, p); 00289 00290 /* --dev_flip */ 00291 p = cpl_parameter_new_value("kmos.kmo_reconstruct.dev_flip", 00292 CPL_TYPE_BOOL, 00293 "INTENDED FOR PIPELINE DEVELOPERS ONLY: " 00294 "Set this parameter to TRUE if the wavelengths " 00295 "are ascending on the detector from bottom to " 00296 "top (only for old simulation data).", 00297 "kmos.kmo_reconstruct", 00298 FALSE); 00299 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dev_flip"); 00300 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00301 cpl_parameterlist_append(recipe->parameters, p); 00302 00303 /* --xcal_interpolation */ 00304 p = cpl_parameter_new_value("kmos.kmo_reconstruct.xcal_interpolation", 00305 CPL_TYPE_BOOL, 00306 "TRUE: Interpolate xcal between rotator angles. FALSE: otherwise", 00307 "kmos.kmo_reconstruct", 00308 TRUE); 00309 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "xcal_interpolation"); 00310 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00311 cpl_parameterlist_append(recipe->parameters, p); 00312 00313 // add parameters for band-definition 00314 kmo_band_pars_create(recipe->parameters, 00315 "kmos.kmo_reconstruct"); 00316 00317 return 0; 00318 } 00319 00325 static int kmo_reconstruct_exec(cpl_plugin *plugin) 00326 { 00327 cpl_recipe *recipe; 00328 00329 /* Get the recipe out of the plugin */ 00330 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00331 recipe = (cpl_recipe *)plugin; 00332 else return -1; 00333 00334 return kmo_reconstruct(recipe->parameters, recipe->frames); 00335 } 00336 00342 static int kmo_reconstruct_destroy(cpl_plugin *plugin) 00343 { 00344 cpl_recipe *recipe; 00345 00346 /* Get the recipe out of the plugin */ 00347 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00348 recipe = (cpl_recipe *)plugin; 00349 else return -1 ; 00350 00351 cpl_parameterlist_delete(recipe->parameters); 00352 return 0 ; 00353 } 00354 00369 static int kmo_reconstruct(cpl_parameterlist *parlist, cpl_frameset *frameset) 00370 { 00371 int ret_val = 0, 00372 nr_devices = 0, 00373 i = 0, 00374 j = 0, 00375 flux = FALSE, 00376 background = FALSE, 00377 index = 0, 00378 detectorimage = 0, 00379 *bounds = NULL, 00380 ifu_nr = 0, 00381 obs_id = 0, 00382 file_extension = FALSE, 00383 dev_flip = FALSE, 00384 xcal_interpolation = FALSE, 00385 detImgCube = FALSE; 00386 float *pdet_img_data = NULL, 00387 *pdet_img_noise = NULL, 00388 *slice = NULL; 00389 double neighborhoodRange = 1.001, 00390 pix_scale = 0.0; 00391 00392 const char *imethod = NULL, 00393 *input_frame_name = NULL, 00394 *output_frame_name = NULL, 00395 *filter_id = NULL, 00396 *filter_id_tmp = NULL; 00397 char *keyword = NULL, 00398 *filename_cube = NULL, 00399 *filename_img = NULL, 00400 // *fn_lut = NULL, 00401 *suffix = NULL, 00402 *obs_suffix = NULL, 00403 *my_filter_id = NULL, 00404 *extname = NULL; 00405 cpl_image *lcal = NULL, 00406 *det_img_data[KMOS_NR_DETECTORS], 00407 *det_img_noise[KMOS_NR_DETECTORS], 00408 *tmp_img = NULL; 00409 cpl_imagelist *cube_data = NULL, 00410 *cube_noise = NULL; 00411 cpl_frame *rec_frame = NULL, 00412 *xcal_frame = NULL, 00413 *ycal_frame = NULL, 00414 *lcal_frame = NULL, 00415 *ref_spectrum_frame = NULL; 00416 cpl_propertylist *main_header = NULL, 00417 *sub_header = NULL, 00418 *sub_header_orig = NULL, 00419 *actual_sub_header = NULL, 00420 *tmp_header = NULL; 00421 cpl_table *band_table = NULL; 00422 gridDefinition gd; 00423 main_fits_desc desc1, 00424 desc2; 00425 cpl_bivector *obj_spectrum = NULL, 00426 *ref_spectrum = NULL; 00427 cpl_vector *peaks = NULL, 00428 *range = NULL; 00429 cpl_polynomial *lcorr_coeffs = NULL; 00430 00431 for (int i=0; i<KMOS_NR_DETECTORS; i++) { 00432 det_img_data[i] = NULL; 00433 det_img_noise[i] = NULL; 00434 } 00435 00436 KMO_TRY 00437 { 00438 kmo_init_fits_desc(&desc1); 00439 kmo_init_fits_desc(&desc2); 00440 00441 // --- check input --- 00442 KMO_TRY_ASSURE((parlist != NULL) && 00443 (frameset != NULL), 00444 CPL_ERROR_NULL_INPUT, 00445 "Not all input data is provided!"); 00446 00447 KMO_TRY_ASSURE((cpl_frameset_count_tags(frameset, DARK) == 1) || 00448 (cpl_frameset_count_tags(frameset, FLAT_ON) == 1) || 00449 (cpl_frameset_count_tags(frameset, ARC_ON) == 1) || 00450 (cpl_frameset_count_tags(frameset, OBJECT) == 1) || 00451 (cpl_frameset_count_tags(frameset, STD) == 1) || 00452 (cpl_frameset_count_tags(frameset, SCIENCE) == 1), 00453 CPL_ERROR_NULL_INPUT, 00454 "A data frame (DARK, FLAT_ON, ARC_ON, OBJECT, STD or SCIENCE) must " 00455 "be provided!"); 00456 00457 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, XCAL) == 1, 00458 CPL_ERROR_FILE_NOT_FOUND, 00459 "XCAL frame missing in frameset!!"); 00460 00461 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, YCAL) == 1, 00462 CPL_ERROR_FILE_NOT_FOUND, 00463 "YCAL frame missing in frameset!!"); 00464 00465 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, LCAL) == 1, 00466 CPL_ERROR_FILE_NOT_FOUND, 00467 "LCAL frame missing in frameset!!"); 00468 00469 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, WAVE_BAND) == 1, 00470 CPL_ERROR_FILE_NOT_FOUND, 00471 "WAVE_BAND frame missing in frameset!!"); 00472 00473 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_reconstruct") == 1, 00474 CPL_ERROR_ILLEGAL_INPUT, 00475 "Cannot identify RAW and CALIB frames!"); 00476 00477 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, OH_SPEC) == 0 || 00478 cpl_frameset_count_tags(frameset, OH_SPEC) == 1, 00479 CPL_ERROR_ILLEGAL_INPUT, 00480 "Only a single reference spectrum can be provided!"); 00481 00482 // --- get parameters --- 00483 cpl_msg_info("", "--- Parameter setup for kmo_reconstruct ---"); 00484 00485 KMO_TRY_EXIT_IF_NULL( 00486 imethod = kmo_dfs_get_parameter_string(parlist, 00487 "kmos.kmo_reconstruct.imethod")); 00488 00489 KMO_TRY_ASSURE((strcmp(imethod, "NN") == 0) || 00490 (strcmp(imethod, "lwNN") == 0) || 00491 (strcmp(imethod, "swNN") == 0) || 00492 (strcmp(imethod, "MS") == 0) || 00493 (strcmp(imethod, "CS") == 0), 00494 CPL_ERROR_ILLEGAL_INPUT, 00495 "imethod must be either \"NN\", \"lwNN\", " 00496 "\"swNN\", \"MS\" or \"CS\"!"); 00497 00498 KMO_TRY_EXIT_IF_ERROR( 00499 kmo_dfs_print_parameter_help(parlist, 00500 "kmos.kmo_reconstruct.imethod")); 00501 00502 flux = kmo_dfs_get_parameter_bool(parlist, 00503 "kmos.kmo_reconstruct.flux"); 00504 00505 KMO_TRY_ASSURE((flux == 0) || 00506 (flux == 1), 00507 CPL_ERROR_ILLEGAL_INPUT, 00508 "flux must be either FALSE or TRUE!"); 00509 00510 KMO_TRY_EXIT_IF_ERROR( 00511 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_reconstruct.flux")); 00512 00513 detectorimage = kmo_dfs_get_parameter_bool(parlist, 00514 "kmos.kmo_reconstruct.detectorimage"); 00515 00516 KMO_TRY_ASSURE((detectorimage == 0) || 00517 (detectorimage == 1), 00518 CPL_ERROR_ILLEGAL_INPUT, 00519 "detectorimage must be either 0 or 1 !"); 00520 00521 KMO_TRY_EXIT_IF_ERROR( 00522 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_reconstruct.detectorimage")); 00523 00524 neighborhoodRange = kmo_dfs_get_parameter_double(parlist, 00525 "kmos.kmo_reconstruct.neighborhoodRange"); 00526 KMO_TRY_CHECK_ERROR_STATE(); 00527 KMO_TRY_ASSURE(neighborhoodRange > 0.0, 00528 CPL_ERROR_ILLEGAL_INPUT, 00529 "neighborhoodRange must be greater than 0.0"); 00530 KMO_TRY_EXIT_IF_ERROR( 00531 kmo_dfs_print_parameter_help(parlist, 00532 "kmos.kmo_reconstruct.neighborhoodRange")); 00533 00534 kmo_band_pars_load(parlist, "kmos.kmo_reconstruct"); 00535 00536 file_extension = kmo_dfs_get_parameter_bool(parlist, 00537 "kmos.kmo_reconstruct.file_extension"); 00538 KMO_TRY_CHECK_ERROR_STATE(); 00539 KMO_TRY_EXIT_IF_ERROR( 00540 kmo_dfs_print_parameter_help(parlist, 00541 "kmos.kmo_reconstruct.file_extension")); 00542 00543 pix_scale = kmo_dfs_get_parameter_double(parlist, 00544 "kmos.kmo_reconstruct.pix_scale"); 00545 KMO_TRY_CHECK_ERROR_STATE(); 00546 KMO_TRY_EXIT_IF_ERROR( 00547 kmo_dfs_print_parameter_help(parlist, 00548 "kmos.kmo_reconstruct.pix_scale")); 00549 KMO_TRY_ASSURE((pix_scale >= 0.01) && 00550 (pix_scale <= 0.4), 00551 CPL_ERROR_ILLEGAL_INPUT, 00552 "pix_scale must be between 0.01 and 0.4 (results in cubes " 00553 "with 7x7 to 280x280 pixels)!"); 00554 00555 dev_flip = kmo_dfs_get_parameter_bool(parlist, 00556 "kmos.kmo_reconstruct.dev_flip"); 00557 KMO_TRY_CHECK_ERROR_STATE(); 00558 KMO_TRY_EXIT_IF_ERROR( 00559 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_reconstruct.dev_flip")); 00560 KMO_TRY_ASSURE((dev_flip == TRUE) || 00561 (dev_flip == FALSE), 00562 CPL_ERROR_ILLEGAL_INPUT, 00563 "dev_flip must be TRUE or FALSE!"); 00564 00565 xcal_interpolation = kmo_dfs_get_parameter_bool(parlist, 00566 "kmos.kmo_reconstruct.xcal_interpolation"); 00567 KMO_TRY_CHECK_ERROR_STATE(); 00568 KMO_TRY_EXIT_IF_ERROR( 00569 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_reconstruct.xcal_interpolation")); 00570 KMO_TRY_ASSURE((xcal_interpolation == TRUE) || 00571 (xcal_interpolation == FALSE), 00572 CPL_ERROR_ILLEGAL_INPUT, 00573 "xcal_interpolation must be TRUE or FALSE!"); 00574 00575 00576 cpl_msg_info("", "-------------------------------------------"); 00577 00578 // load descriptor and header of data frame to reconstruct 00579 if (cpl_frameset_count_tags(frameset, DARK) == 1) { 00580 input_frame_name = DARK; 00581 output_frame_name = CUBE_DARK; 00582 } else if (cpl_frameset_count_tags(frameset, FLAT_ON) == 1) { 00583 input_frame_name = FLAT_ON; 00584 output_frame_name = CUBE_FLAT; 00585 } else if (cpl_frameset_count_tags(frameset, ARC_ON) == 1) { 00586 input_frame_name = ARC_ON; 00587 output_frame_name = CUBE_ARC; 00588 } else if (cpl_frameset_count_tags(frameset, OBJECT) == 1) { 00589 input_frame_name = OBJECT; 00590 output_frame_name = CUBE_OBJECT; 00591 } else if (cpl_frameset_count_tags(frameset, STD) == 1) { 00592 input_frame_name = STD; 00593 output_frame_name = CUBE_STD; 00594 } else if (cpl_frameset_count_tags(frameset, SCIENCE) == 1) { 00595 input_frame_name = SCIENCE; 00596 output_frame_name = CUBE_SCIENCE; 00597 } 00598 00599 // assure that filters, grating and rotation offsets match for 00600 // XCAL, YCAL, LCAL and for data frame to reconstruct (except DARK 00601 // frames) 00602 // check if filter_id and grating_id match for all detectors 00603 KMO_TRY_EXIT_IF_ERROR( 00604 kmo_check_frame_setup(frameset, XCAL, YCAL, 00605 TRUE, FALSE, TRUE)); 00606 KMO_TRY_EXIT_IF_ERROR( 00607 kmo_check_frame_setup(frameset, XCAL, LCAL, 00608 TRUE, FALSE, TRUE)); 00609 00610 // This check doesn't make sense here since OCS.ROT.NAANGLE is compared. 00611 // When creating the calibration files the RAW exposures needn't have been 00612 // provided in the same order 00613 // KMO_TRY_EXIT_IF_ERROR( 00614 // kmo_check_cal_frames_rotangle(frameset, XCAL, YCAL)); 00615 // KMO_TRY_EXIT_IF_ERROR( 00616 // kmo_check_cal_frames_rotangle(frameset, XCAL, LCAL)); 00617 00618 if (cpl_frameset_count_tags(frameset, DARK) != 1) { 00619 00620 // check if filters, gratings and rotator offset match 00621 // (except for DARK frames) 00622 KMO_TRY_EXIT_IF_ERROR( 00623 kmo_check_frame_setup(frameset, XCAL, input_frame_name, 00624 TRUE, FALSE, FALSE)); 00625 /* 00626 // check if rotator offset don't differ to much 00627 cpl_frame *f1 = NULL, *f2 = NULL; 00628 cpl_propertylist *h1 = NULL, *h2 = NULL; 00629 char *kw = NULL; 00630 double tmp_dbl1 = 0.0, tmp_dbl2 = 0.0; 00631 00632 KMO_TRY_EXIT_IF_NULL( 00633 f1 = kmo_dfs_get_frame(frameset, XCAL)); 00634 00635 KMO_TRY_EXIT_IF_NULL( 00636 f2 = kmo_dfs_get_frame(frameset, input_frame_name)); 00637 h1 = kmclipm_propertylist_load(cpl_frame_get_filename(f1), 0); 00638 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00639 cpl_msg_error("","File not found: %s!", 00640 cpl_frame_get_filename(f1)); 00641 KMO_TRY_CHECK_ERROR_STATE(); 00642 } 00643 00644 h2 = kmclipm_propertylist_load(cpl_frame_get_filename(f2), 0); 00645 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00646 cpl_msg_error("","File not found: %s!", 00647 cpl_frame_get_filename(f2)); 00648 KMO_TRY_CHECK_ERROR_STATE(); 00649 } 00650 KMO_TRY_EXIT_IF_NULL( 00651 kw = cpl_sprintf("%s", ROTANGLE)); 00652 tmp_dbl1 = cpl_propertylist_get_double(h1, kw); 00653 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00654 KMO_TRY_ASSURE(1 == 0, 00655 CPL_ERROR_ILLEGAL_INPUT, 00656 "keyword \n%s\n of frame %s is missing!", 00657 keyword, XCAL); 00658 } 00659 00660 tmp_dbl2 = cpl_propertylist_get_double(h2, kw); 00661 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00662 KMO_TRY_ASSURE(1 == 0, 00663 CPL_ERROR_ILLEGAL_INPUT, 00664 "keyword \n%s\n of frame %s is missing!", 00665 keyword, input_frame_name); 00666 } 00667 00668 // strip angles below 0 deg and above 360 deg 00669 kmclipm_strip_angle(&tmp_dbl1); 00670 kmclipm_strip_angle(&tmp_dbl2); 00671 00672 if (fabs(tmp_dbl1 - tmp_dbl2) > 30.) { 00673 if ((fabs(tmp_dbl1) < 0.001) && (tmp_dbl2>330) && (tmp_dbl2<360)) { 00674 // singularity! 00675 // we have rot=0 for XCAL and rot>330 | rot<360 for input frame 00676 } else { 00677 cpl_msg_warning("","The angle of the calibration files (%g deg) " 00678 "and the angle of the frame to reconstruct" 00679 " (%g deg) differ by %g deg! Think about using " 00680 "calibration files matching better the actual " 00681 "rotator offset (ESO OCS ROT NAANGLE)", 00682 tmp_dbl1, tmp_dbl2, 00683 fabs(tmp_dbl1 - tmp_dbl2)); 00684 } 00685 } 00686 00687 cpl_propertylist_delete(h1); h1 = NULL; 00688 cpl_propertylist_delete(h2); h2 = NULL; 00689 cpl_free(kw); kw = NULL; 00690 */ 00691 } 00692 00693 if (cpl_frameset_count_tags(frameset, OH_SPEC) != 0) { 00694 KMO_TRY_EXIT_IF_NULL( 00695 ref_spectrum_frame = kmo_dfs_get_frame(frameset, OH_SPEC)); 00696 } 00697 00698 KMO_TRY_EXIT_IF_NULL( 00699 xcal_frame = kmo_dfs_get_frame(frameset, XCAL)); 00700 KMO_TRY_EXIT_IF_NULL( 00701 rec_frame = kmo_dfs_get_frame(frameset, input_frame_name)); 00702 KMO_TRY_EXIT_IF_NULL( 00703 suffix = kmo_dfs_get_suffix(rec_frame, TRUE, TRUE)); 00704 00705 KMO_TRY_EXIT_IF_ERROR( 00706 kmo_check_frame_setup_md5_xycal(frameset)); 00707 KMO_TRY_EXIT_IF_ERROR( 00708 kmo_check_frame_setup_md5(frameset)); 00709 00710 cpl_msg_info("", "Detected instrument setup: %s", suffix+1); 00711 cpl_msg_info("", "(grating 1, 2 & 3, rotation angle)"); 00712 cpl_msg_info("", "-------------------------------------------"); 00713 00714 00715 desc1 = kmo_identify_fits_header(cpl_frame_get_filename(rec_frame)); 00716 KMO_TRY_CHECK_ERROR_STATE(); 00717 00718 KMO_TRY_ASSURE(((desc1.nr_ext == KMOS_NR_DETECTORS) || 00719 ((desc1.nr_ext == 2*KMOS_NR_DETECTORS))) && 00720 (desc1.ex_badpix == FALSE) && 00721 ((desc1.fits_type == raw_fits) || 00722 (desc1.fits_type == f2d_fits)) && 00723 (desc1.frame_type == detector_frame), 00724 CPL_ERROR_ILLEGAL_INPUT, 00725 "The frame to reconstruct isn't in the correct format!!!" 00726 "Exactly 3 frames, or 6 with noise are expected!"); 00727 00728 if (!desc1.ex_noise) { 00729 nr_devices = desc1.nr_ext; 00730 } else { 00731 nr_devices = desc1.nr_ext / 2; 00732 } 00733 00734 // compare descriptor of XCAL and data frame to reconstruct 00735 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(xcal_frame)); 00736 KMO_TRY_CHECK_ERROR_STATE(); 00737 00738 KMO_TRY_ASSURE((desc2.nr_ext % 3 == 0) && 00739 (desc1.ex_badpix == desc2.ex_badpix) && 00740 (desc1.frame_type == desc2.frame_type), 00741 CPL_ERROR_ILLEGAL_INPUT, 00742 "XCAL isn't in the correct format!!!"); 00743 00744 kmo_free_fits_desc(&desc2); 00745 00746 // compare descriptor of YCAL and data frame to reconstruct 00747 kmo_init_fits_desc(&desc2); 00748 00749 KMO_TRY_EXIT_IF_NULL( 00750 ycal_frame = kmo_dfs_get_frame(frameset, YCAL)); 00751 00752 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(ycal_frame)); 00753 KMO_TRY_CHECK_ERROR_STATE(); 00754 00755 KMO_TRY_ASSURE((desc2.nr_ext % 3 == 0) && 00756 (desc1.ex_badpix == desc2.ex_badpix) && 00757 (desc1.frame_type == desc2.frame_type), 00758 CPL_ERROR_ILLEGAL_INPUT, 00759 "YCAL isn't in the correct format!!!"); 00760 00761 kmo_free_fits_desc(&desc2); 00762 00763 // compare descriptor of LCAL and data frame to reconstruct 00764 kmo_init_fits_desc(&desc2); 00765 00766 KMO_TRY_EXIT_IF_NULL( 00767 lcal_frame = kmo_dfs_get_frame(frameset, LCAL)); 00768 00769 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(lcal_frame)); 00770 KMO_TRY_CHECK_ERROR_STATE(); 00771 00772 KMO_TRY_ASSURE((desc2.nr_ext % 3 == 0) && 00773 (desc1.ex_badpix == desc2.ex_badpix) && 00774 (desc1.frame_type == desc2.frame_type), 00775 CPL_ERROR_ILLEGAL_INPUT, 00776 "LCAL isn't in the correct format!!!"); 00777 00778 kmo_free_fits_desc(&desc2); 00779 00780 // 00781 // --- load, update & save primary header --- 00782 // 00783 KMO_TRY_EXIT_IF_NULL( 00784 main_header = kmo_dfs_load_primary_header(frameset, 00785 input_frame_name)); 00786 00787 KMO_TRY_EXIT_IF_NULL( 00788 tmp_header = kmo_dfs_load_primary_header(frameset, LCAL)); 00789 00790 // assert that filters have correct IDs and that all detectors of all 00791 // input frames have the same filter set 00792 for (i = 1; i <= nr_devices; i++) { 00793 // ESO INS FILTi ID 00794 KMO_TRY_EXIT_IF_NULL( 00795 keyword = cpl_sprintf("%s%d%s", IFU_FILTID_PREFIX, i, 00796 IFU_FILTID_POSTFIX)); 00797 00798 KMO_TRY_EXIT_IF_NULL( 00799 filter_id = cpl_propertylist_get_string(tmp_header, keyword)); 00800 00801 KMO_TRY_ASSURE((strcmp(filter_id, "IZ") == 0) || 00802 (strcmp(filter_id, "YJ") == 0) || 00803 (strcmp(filter_id, "H") == 0) || 00804 (strcmp(filter_id, "K") == 0) || 00805 (strcmp(filter_id, "HK") == 0), 00806 CPL_ERROR_ILLEGAL_INPUT, 00807 "Filter ID in primary header of LCAL frame must " 00808 "be either \"IZ\", \"YJ\", \"H\", \"K\" or " 00809 "\"HK\" !"); 00810 00811 if (strcmp(input_frame_name, DARK) != 0) { 00812 // dark needn't to be taken with filter! 00813 00814 KMO_TRY_EXIT_IF_NULL( 00815 filter_id_tmp = cpl_propertylist_get_string(main_header, 00816 keyword)); 00817 KMO_TRY_ASSURE(strcmp(filter_id, filter_id_tmp) == 0, 00818 CPL_ERROR_ILLEGAL_INPUT, 00819 "Filter IDs must be the same for LCAL frame and " 00820 "the frame to reconstruct!" 00821 "Detector No.: %d\nLCAL: %s\n%s: %s\n", 00822 i, filter_id, input_frame_name, filter_id_tmp); 00823 } 00824 cpl_free(keyword); keyword = NULL; 00825 } 00826 KMO_TRY_EXIT_IF_NULL( 00827 my_filter_id = cpl_strdup(filter_id)); 00828 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00829 00830 obs_id = cpl_propertylist_get_int(main_header, OBS_ID); 00831 KMO_TRY_CHECK_ERROR_STATE(); 00832 00833 KMO_TRY_EXIT_IF_NULL( 00834 filename_cube = cpl_sprintf("%s", output_frame_name)); 00835 KMO_TRY_EXIT_IF_NULL( 00836 filename_img = cpl_sprintf("%s", DET_IMG_REC)); 00837 if (file_extension) { 00838 KMO_TRY_EXIT_IF_NULL( 00839 obs_suffix = cpl_sprintf("%s%d", "_", obs_id)); 00840 } else { 00841 KMO_TRY_EXIT_IF_NULL( 00842 obs_suffix = cpl_sprintf("%s", "")); 00843 } 00844 00845 KMO_TRY_EXIT_IF_ERROR( 00846 kmo_dfs_save_main_header(frameset, filename_cube, obs_suffix, 00847 rec_frame, NULL, parlist, cpl_func)); 00848 00849 // setup grid definition, wavelength start and end points will be set 00850 // in the detector loop 00851 KMO_TRY_EXIT_IF_ERROR( 00852 kmclipm_setup_grid(&gd, imethod, neighborhoodRange, pix_scale)); 00853 00854 KMO_TRY_EXIT_IF_NULL( 00855 tmp_header = kmo_dfs_load_primary_header(frameset, XCAL)); 00856 00857 KMO_TRY_EXIT_IF_NULL( 00858 bounds = kmclipm_extract_bounds(tmp_header)); 00859 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00860 00861 if (detectorimage == TRUE) { 00862 KMO_TRY_EXIT_IF_ERROR( 00863 kmo_dfs_save_main_header(frameset, filename_img, obs_suffix, 00864 rec_frame, NULL, parlist, cpl_func)); 00865 } 00866 00867 /* loop through all detectors */ 00868 for (i = 1; i <= nr_devices; i++) { 00869 cpl_msg_info("","Processing detector No. %d", i); 00870 00871 // load lcal 00872 // extract LCAL image close to ROTANGLE 0. assuming that the wavelength range 00873 // doesn't differ too much with different ROTANGLEs. 00874 double rotangle_found; 00875 KMO_TRY_EXIT_IF_NULL( 00876 lcal = kmo_dfs_load_cal_image(frameset, LCAL, i, FALSE, 0., 00877 FALSE, NULL, &rotangle_found, -1, 0, 0)); 00878 00879 char *tmp_band_method = getenv("KMO_BAND_METHOD"); 00880 int band_method = 0; 00881 if (tmp_band_method != NULL) { 00882 band_method = atoi(tmp_band_method); 00883 } 00884 00885 KMO_TRY_EXIT_IF_NULL( 00886 band_table = kmo_dfs_load_table(frameset, WAVE_BAND, 1, FALSE)); 00887 00888 KMO_TRY_EXIT_IF_ERROR( 00889 kmclipm_setup_grid_band_lcal(&gd, lcal, my_filter_id, 00890 band_method, band_table)); 00891 cpl_table_delete(band_table); band_table = NULL; 00892 00893 cpl_image_delete(lcal); lcal = NULL; 00894 00895 if (detectorimage == TRUE) { 00896 KMO_TRY_EXIT_IF_NULL( 00897 det_img_data[i-1] = cpl_image_new(gd.x.dim*gd.y.dim*KMOS_IFUS_PER_DETECTOR, 00898 gd.l.dim, CPL_TYPE_FLOAT)); 00899 KMO_TRY_EXIT_IF_NULL( 00900 pdet_img_data = cpl_image_get_data_float(det_img_data[i-1])); 00901 00902 KMO_TRY_EXIT_IF_NULL( 00903 det_img_noise[i-1] = cpl_image_new(gd.x.dim*gd.y.dim*KMOS_IFUS_PER_DETECTOR, 00904 gd.l.dim, CPL_TYPE_FLOAT)); 00905 KMO_TRY_EXIT_IF_NULL( 00906 pdet_img_noise = cpl_image_get_data_float(det_img_noise[i-1])); 00907 } 00908 00909 00910 for (j = 0; j < KMOS_IFUS_PER_DETECTOR; j++) { 00911 /* update sub-header */ 00912 ifu_nr = (i-1)*KMOS_IFUS_PER_DETECTOR + j + 1; 00913 00914 /* load raw image and sub-header*/ 00915 KMO_TRY_EXIT_IF_NULL( 00916 sub_header = kmo_dfs_load_sub_header(frameset, input_frame_name, 00917 i, FALSE)); 00918 KMO_TRY_EXIT_IF_NULL( 00919 sub_header_orig = cpl_propertylist_duplicate(sub_header)); 00920 00921 // check if IFU is valid according to main header keywords & 00922 // calibration files 00923 00924 if (getenv("KMOS_RECONSTRUCT_ALL") == NULL) { 00925 KMO_TRY_EXIT_IF_NULL( 00926 keyword = cpl_sprintf("%s%d%s", IFU_VALID_PREFIX, ifu_nr, 00927 IFU_VALID_POSTFIX)); 00928 KMO_TRY_CHECK_ERROR_STATE(); 00929 cpl_propertylist_get_string(main_header, keyword); 00930 cpl_free(keyword); keyword = NULL; 00931 } else { 00932 // if KMOS_RECONSTRUCT_ALL is set all IFUs should be 00933 // reconstructed 00934 cpl_propertylist_get_string(main_header, "ggg"); 00935 } 00936 00937 if ((cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) && 00938 (bounds[2*(ifu_nr-1)] != -1) && 00939 (bounds[2*(ifu_nr-1)+1] != -1)) 00940 { 00941 cpl_error_reset(); 00942 // IFU is valid 00943 actual_sub_header = sub_header; 00944 00945 // calculate WCS 00946 KMO_TRY_EXIT_IF_ERROR( 00947 kmo_calc_wcs_gd(main_header, actual_sub_header, ifu_nr, gd)); 00948 00949 // reconstruct data and noise (if available) 00950 if (j == 0) { 00951 sat_mode_msg = FALSE; 00952 } else { 00953 sat_mode_msg = TRUE; 00954 } 00955 KMO_TRY_EXIT_IF_ERROR( 00956 kmo_reconstruct_sci(ifu_nr, 00957 bounds[2*(ifu_nr-1)], 00958 bounds[2*(ifu_nr-1)+1], 00959 rec_frame, 00960 input_frame_name, 00961 NULL, 00962 NULL, 00963 NULL, 00964 xcal_frame, 00965 ycal_frame, 00966 lcal_frame, 00967 NULL, 00968 &gd, 00969 &cube_data, 00970 &cube_noise, 00971 flux, 00972 background, 00973 xcal_interpolation)); 00974 00975 if (ref_spectrum_frame != NULL && cube_data != NULL) { 00976 if (peaks == NULL) { 00977 KMO_TRY_EXIT_IF_NULL( 00978 range = cpl_vector_new(2)); 00979 KMO_TRY_EXIT_IF_ERROR( 00980 cpl_vector_set(range, 0, gd.l.start)); 00981 KMO_TRY_EXIT_IF_ERROR( 00982 cpl_vector_set(range, 1, gd.l.start + gd.l.delta * gd.l.dim)); 00983 KMO_TRY_EXIT_IF_NULL( 00984 ref_spectrum = kmo_lcorr_read_reference_spectrum( 00985 cpl_frame_get_filename(ref_spectrum_frame),NULL)); 00986 KMO_TRY_EXIT_IF_NULL( 00987 peaks = kmo_lcorr_get_peak_lambdas(ref_spectrum, 0.2, range)); 00988 00989 cpl_vector_delete(range); 00990 } 00991 00992 KMO_TRY_EXIT_IF_ERROR( 00993 cpl_propertylist_set_int(actual_sub_header,NAXIS,3)); 00994 KMO_TRY_EXIT_IF_NULL( 00995 tmp_img = cpl_imagelist_get(cube_data, 0)); 00996 KMO_TRY_EXIT_IF_ERROR( 00997 cpl_propertylist_set_int(actual_sub_header,NAXIS1, 00998 cpl_image_get_size_x(tmp_img))); 00999 KMO_TRY_EXIT_IF_ERROR( 01000 cpl_propertylist_set_int(actual_sub_header,NAXIS2, 01001 cpl_image_get_size_y(tmp_img))); 01002 KMO_TRY_EXIT_IF_ERROR( 01003 cpl_propertylist_append_int(actual_sub_header,NAXIS3, 01004 cpl_imagelist_get_size(cube_data))); 01005 KMO_TRY_EXIT_IF_NULL( 01006 obj_spectrum = kmo_lcorr_extract_spectrum( 01007 cube_data, actual_sub_header, 0.8, NULL)); 01008 01009 /* 01010 // enables additional debugging output 01011 char *idlfilename = cpl_sprintf("idl_%2.2d.dat",ifu_nr); 01012 kmo_lcorr_open_debug_file(idlfilename); 01013 cpl_free(idlfilename); 01014 */ 01015 01016 KMO_TRY_EXIT_IF_NULL( 01017 lcorr_coeffs = kmo_lcorr_crosscorrelate_spectra( 01018 obj_spectrum, ref_spectrum, peaks, my_filter_id)); 01019 /* 01020 // debugging output is a single file for each IFU, so close it now 01021 kmo_lcorr_close_debug_file(); 01022 */ 01023 01024 cpl_bivector_delete(obj_spectrum); 01025 01026 const int format_width = 14; 01027 const int max_coeffs = 6; 01028 char *coeff_string = NULL; 01029 char coeff_dump[format_width * max_coeffs + 1]; 01030 cpl_size pows[1]; 01031 coeff_dump[0] = 0; 01032 for (int ic=0; ic<=cpl_polynomial_get_degree(lcorr_coeffs) && ic < max_coeffs; ic++) { 01033 pows[0] = ic; 01034 coeff_string = cpl_sprintf(" %*g,", 01035 format_width-2, cpl_polynomial_get_coeff(lcorr_coeffs,pows)); 01036 strncat(coeff_dump, coeff_string, format_width); 01037 cpl_free(coeff_string); 01038 } 01039 cpl_msg_debug("","Lambda correction coeffs for IFU %d %s",ifu_nr, coeff_dump); 01040 01041 cpl_imagelist_delete(cube_data); cube_data = NULL; 01042 if (cube_noise != NULL) { 01043 cpl_imagelist_delete(cube_noise); cube_noise = NULL; 01044 } 01045 KMO_TRY_EXIT_IF_ERROR( 01046 kmo_reconstruct_sci(ifu_nr, 01047 bounds[2*(ifu_nr-1)], 01048 bounds[2*(ifu_nr-1)+1], 01049 rec_frame, 01050 input_frame_name, 01051 NULL, 01052 NULL, 01053 NULL, 01054 xcal_frame, 01055 ycal_frame, 01056 lcal_frame, 01057 lcorr_coeffs, 01058 &gd, 01059 &cube_data, 01060 &cube_noise, 01061 flux, 01062 background, 01063 xcal_interpolation)); 01064 /* 01065 // show that lambda correction improved the data cube, a second one would improve even more 01066 01067 cpl_bivector *obj_spectrum2, *obj_spectrum3; 01068 cpl_polynomial *lcorr_coeffs2, *lcorr_coeffs3; 01069 KMO_TRY_EXIT_IF_NULL( 01070 obj_spectrum2 = kmo_lcorr_extract_spectrum( 01071 cube_data, actual_sub_header, 0.8, NULL)); 01072 01073 KMO_TRY_EXIT_IF_NULL( 01074 lcorr_coeffs2 = kmo_lcorr_crosscorrelate_spectra( 01075 obj_spectrum2, ref_spectrum, peaks, 0.002)); 01076 01077 cpl_bivector_delete(obj_spectrum2); 01078 01079 coeff_dump[0] = 0; 01080 for (int ic=0; ic<=cpl_polynomial_get_degree(lcorr_coeffs2) && ic < max_coeffs; ic++) { 01081 pows[0] = ic; 01082 coeff_string = cpl_sprintf(" %*g,", 01083 format_width-2, cpl_polynomial_get_coeff(lcorr_coeffs2,pows)); 01084 strncat(coeff_dump, coeff_string, format_width); 01085 cpl_free(coeff_string); 01086 double c1 = cpl_polynomial_get_coeff(lcorr_coeffs,pows); 01087 double c2 = cpl_polynomial_get_coeff(lcorr_coeffs2,pows); 01088 cpl_polynomial_set_coeff(lcorr_coeffs, pows, c1+c2); 01089 } 01090 cpl_msg_debug("","Lambda correction coeffs for ifu %d %s",ifu_nr, coeff_dump); 01091 cpl_polynomial_delete(lcorr_coeffs2); lcorr_coeffs2=NULL; 01092 01093 cpl_imagelist_delete(cube_data); cube_data = NULL; 01094 cpl_imagelist_delete(cube_noise); cube_noise = NULL; 01095 KMO_TRY_EXIT_IF_ERROR( 01096 kmo_reconstruct_sci(ifu_nr, 01097 bounds[2*(ifu_nr-1)], 01098 bounds[2*(ifu_nr-1)+1], 01099 rec_frame, 01100 input_frame_name, 01101 NULL, 01102 NULL, 01103 NULL, 01104 xcal_frame, 01105 ycal_frame, 01106 lcal_frame, 01107 lcorr_coeffs, 01108 &gd, 01109 &cube_data, 01110 &cube_noise, 01111 flux, 01112 background, 01113 xcal_interpolation)); 01114 01115 KMO_TRY_EXIT_IF_NULL( 01116 obj_spectrum3 = kmo_lcorr_extract_spectrum( 01117 cube_data, actual_sub_header, 0.8, NULL)); 01118 01119 KMO_TRY_EXIT_IF_NULL( 01120 lcorr_coeffs3 = kmo_lcorr_crosscorrelate_spectra( 01121 obj_spectrum3, ref_spectrum, peaks, 0.002)); 01122 01123 cpl_bivector_delete(obj_spectrum3); 01124 01125 coeff_dump[0] = 0; 01126 for (int ic=0; ic<=cpl_polynomial_get_degree(lcorr_coeffs3) && ic < max_coeffs; ic++) { 01127 pows[0] = ic; 01128 coeff_string = cpl_sprintf(" %*g,", 01129 format_width-2, cpl_polynomial_get_coeff(lcorr_coeffs3,pows)); 01130 strncat(coeff_dump, coeff_string, format_width); 01131 cpl_free(coeff_string); 01132 } 01133 cpl_msg_debug("","Lambda correction coeffs for iFu %d %s",ifu_nr, coeff_dump); 01134 cpl_polynomial_delete(lcorr_coeffs3); lcorr_coeffs3=NULL; 01135 */ 01136 cpl_polynomial_delete(lcorr_coeffs); lcorr_coeffs = NULL; 01137 01138 } 01139 01140 // scale flux according to pixel_scale 01141 KMO_TRY_EXIT_IF_NULL( 01142 tmp_img = cpl_imagelist_get(cube_data, 0)); 01143 double scaling = (cpl_image_get_size_x(tmp_img)*cpl_image_get_size_y(tmp_img)) / 01144 (KMOS_SLITLET_X*KMOS_SLITLET_Y); 01145 KMO_TRY_EXIT_IF_ERROR( 01146 cpl_imagelist_divide_scalar(cube_data, scaling)); 01147 if (cube_noise != NULL) { 01148 KMO_TRY_EXIT_IF_ERROR( 01149 cpl_imagelist_divide_scalar(cube_noise, scaling)); 01150 } 01151 } else { 01152 // IFU is invalid 01153 actual_sub_header = sub_header_orig; 01154 cpl_error_reset(); 01155 } // if ((cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) .. 01156 01157 if (detectorimage) { 01158 if (cube_data != NULL) { 01159 for (int l=0; l<gd.l.dim; l++) { 01160 KMO_TRY_EXIT_IF_NULL( 01161 slice = cpl_image_get_data_float(cpl_imagelist_get(cube_data, l))); 01162 for (int y=0; y<gd.y.dim; y++) { 01163 for (int x=0; x<gd.x.dim; x++) { 01164 int ix = x + 01165 y * gd.x.dim + 01166 j * gd.x.dim*gd.y.dim + //IFU offset 01167 l * gd.x.dim*gd.y.dim*KMOS_IFUS_PER_DETECTOR; 01168 pdet_img_data[ix] = slice[x + y*gd.x.dim]; 01169 } 01170 } 01171 } 01172 } 01173 if (cube_noise != NULL) { 01174 if (detectorimage) { 01175 detImgCube = TRUE; 01176 } 01177 for (int l=0; l<gd.l.dim; l++) { 01178 KMO_TRY_EXIT_IF_NULL( 01179 slice = cpl_image_get_data_float(cpl_imagelist_get(cube_noise, l))); 01180 for (int y=0; y<gd.y.dim; y++) { 01181 for (int x=0; x<gd.x.dim; x++) { 01182 int ix = x + 01183 y * gd.x.dim + 01184 j * gd.x.dim*gd.y.dim + //IFU offset 01185 l * gd.x.dim*gd.y.dim*KMOS_IFUS_PER_DETECTOR; 01186 pdet_img_noise[ix] = slice[x + y*gd.x.dim]; 01187 } 01188 } 01189 } 01190 } 01191 } 01192 01193 // save output 01194 KMO_TRY_EXIT_IF_NULL( 01195 extname = kmo_extname_creator(ifu_frame, ifu_nr, 01196 EXT_DATA)); 01197 01198 KMO_TRY_EXIT_IF_ERROR( 01199 kmclipm_update_property_string(actual_sub_header, 01200 EXTNAME, 01201 extname, 01202 "FITS extension name")); 01203 01204 cpl_free(extname); extname = NULL; 01205 01206 KMO_TRY_EXIT_IF_ERROR( 01207 kmo_dfs_save_cube(cube_data, filename_cube, obs_suffix, 01208 actual_sub_header, 0./0.)); 01209 01210 if (cube_noise != NULL) { 01211 KMO_TRY_EXIT_IF_NULL( 01212 extname = kmo_extname_creator(ifu_frame, ifu_nr, 01213 EXT_NOISE)); 01214 01215 KMO_TRY_EXIT_IF_ERROR( 01216 kmclipm_update_property_string(actual_sub_header, 01217 EXTNAME, 01218 extname, 01219 "FITS extension name")); 01220 01221 cpl_free(extname); extname = NULL; 01222 01223 KMO_TRY_EXIT_IF_ERROR( 01224 kmo_dfs_save_cube(cube_noise, filename_cube, obs_suffix, 01225 actual_sub_header, 0./0.)); 01226 } 01227 01228 cpl_imagelist_delete(cube_data); cube_data = NULL; 01229 cpl_imagelist_delete(cube_noise); cube_noise = NULL; 01230 cpl_propertylist_delete(sub_header); sub_header = NULL; 01231 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 01232 } // for j IFUs 01233 01234 if (detectorimage) { 01235 index = kmo_identify_index(cpl_frame_get_filename(rec_frame), 01236 i, FALSE); 01237 KMO_TRY_CHECK_ERROR_STATE(); 01238 01239 KMO_TRY_EXIT_IF_NULL( 01240 tmp_header = kmclipm_propertylist_load( 01241 cpl_frame_get_filename(rec_frame), index)); 01242 KMO_TRY_EXIT_IF_ERROR( 01243 kmo_save_det_img_ext(det_img_data[i-1], gd, i, filename_img, 01244 obs_suffix, tmp_header, dev_flip, FALSE)); 01245 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01246 01247 if (detImgCube) { 01248 if (desc1.ex_noise) { 01249 index = kmo_identify_index(cpl_frame_get_filename(rec_frame), 01250 i, TRUE); 01251 KMO_TRY_CHECK_ERROR_STATE(); 01252 } else { 01253 // use same index as for data frame, since input frame 01254 // has just 3 extensions 01255 } 01256 KMO_TRY_EXIT_IF_NULL( 01257 tmp_header = kmclipm_propertylist_load( 01258 cpl_frame_get_filename(rec_frame), index)); 01259 KMO_TRY_EXIT_IF_ERROR( 01260 kmo_save_det_img_ext(det_img_noise[i-1], gd, i, filename_img, 01261 obs_suffix, tmp_header, dev_flip, TRUE)); 01262 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01263 } 01264 } 01265 01266 // free memory 01267 cpl_imagelist_delete(cube_data); cube_data = NULL; 01268 cpl_imagelist_delete(cube_noise); cube_noise = NULL; 01269 cpl_propertylist_delete(sub_header); sub_header = NULL; 01270 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 01271 } // for i devices 01272 } 01273 KMO_CATCH 01274 { 01275 KMO_CATCH_MSG(); 01276 ret_val = -1; 01277 } 01278 01279 kmo_free_fits_desc(&desc1); 01280 kmo_free_fits_desc(&desc2); 01281 for (int i=0; i<KMOS_NR_DETECTORS; i++) { 01282 cpl_image_delete(det_img_data[i]); det_img_data[i] = NULL; 01283 cpl_image_delete(det_img_noise[i]); det_img_noise[i] = NULL; 01284 } 01285 cpl_free(my_filter_id); my_filter_id = NULL; 01286 cpl_free(bounds); bounds = NULL; 01287 cpl_propertylist_delete(main_header); main_header = NULL; 01288 cpl_propertylist_delete(sub_header); sub_header = NULL; 01289 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 01290 cpl_imagelist_delete(cube_data); cube_data = NULL; 01291 cpl_imagelist_delete(cube_noise); cube_noise = NULL; 01292 cpl_free(obs_suffix); obs_suffix = NULL; 01293 cpl_free(suffix); suffix = NULL; 01294 cpl_free(filename_img); filename_img = NULL; 01295 cpl_free(filename_cube); filename_cube = NULL; 01296 if (peaks != NULL ) {cpl_vector_delete(peaks);} 01297 if (ref_spectrum != NULL ) {cpl_bivector_delete(ref_spectrum);} 01298 sat_mode_msg = FALSE; 01299 01300 return ret_val; 01301 } 01302
1.7.6.1