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