|
KMOS Pipeline Reference Manual
1.2.8
|
00001 /* $Id: kmo_reconstruct.c,v 1.61 2013/10/08 14:55:01 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/10/08 14:55:01 $ 00024 * $Revision: 1.61 $ 00025 * $Name: $ 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 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 *tmp_str = NULL; 00395 char *keyword = NULL, 00396 *filename_cube = NULL, 00397 *filename_img = NULL, 00398 // *fn_lut = NULL, 00399 *suffix = NULL, 00400 *obs_suffix = NULL, 00401 *my_filter_id = NULL, 00402 *extname = NULL; 00403 cpl_image *lcal = NULL, 00404 *det_img_data[KMOS_NR_DETECTORS], 00405 *det_img_noise[KMOS_NR_DETECTORS], 00406 *tmp_img = NULL; 00407 cpl_imagelist *cube_data = NULL, 00408 *cube_noise = NULL; 00409 cpl_frame *rec_frame = NULL, 00410 *xcal_frame = NULL, 00411 *ycal_frame = NULL, 00412 *lcal_frame = NULL, 00413 *ref_spectrum_frame = NULL; 00414 cpl_propertylist *main_header = NULL, 00415 *sub_header = NULL, 00416 *sub_header_orig = NULL, 00417 *actual_sub_header = NULL, 00418 *tmp_header = NULL; 00419 cpl_table *band_table = NULL; 00420 gridDefinition gd; 00421 main_fits_desc desc1, 00422 desc2; 00423 cpl_polynomial *lcorr_coeffs = NULL; 00424 00425 for (i = 0; i < KMOS_NR_DETECTORS; i++) { 00426 det_img_data[i] = NULL; 00427 det_img_noise[i] = NULL; 00428 } 00429 00430 KMO_TRY 00431 { 00432 kmo_init_fits_desc(&desc1); 00433 kmo_init_fits_desc(&desc2); 00434 00435 // --- check input --- 00436 KMO_TRY_ASSURE((parlist != NULL) && 00437 (frameset != NULL), 00438 CPL_ERROR_NULL_INPUT, 00439 "Not all input data is provided!"); 00440 00441 KMO_TRY_ASSURE((cpl_frameset_count_tags(frameset, DARK) == 1) || 00442 (cpl_frameset_count_tags(frameset, FLAT_ON) == 1) || 00443 (cpl_frameset_count_tags(frameset, ARC_ON) == 1) || 00444 (cpl_frameset_count_tags(frameset, OBJECT) == 1) || 00445 (cpl_frameset_count_tags(frameset, STD) == 1) || 00446 (cpl_frameset_count_tags(frameset, SCIENCE) == 1), 00447 CPL_ERROR_NULL_INPUT, 00448 "A data frame (DARK, FLAT_ON, ARC_ON, OBJECT, STD or SCIENCE) must " 00449 "be provided!"); 00450 00451 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, XCAL) == 1, 00452 CPL_ERROR_FILE_NOT_FOUND, 00453 "XCAL frame missing in frameset!!"); 00454 00455 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, YCAL) == 1, 00456 CPL_ERROR_FILE_NOT_FOUND, 00457 "YCAL frame missing in frameset!!"); 00458 00459 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, LCAL) == 1, 00460 CPL_ERROR_FILE_NOT_FOUND, 00461 "LCAL frame missing in frameset!!"); 00462 00463 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, WAVE_BAND) == 1, 00464 CPL_ERROR_FILE_NOT_FOUND, 00465 "WAVE_BAND frame missing in frameset!!"); 00466 00467 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_reconstruct") == 1, 00468 CPL_ERROR_ILLEGAL_INPUT, 00469 "Cannot identify RAW and CALIB frames!"); 00470 00471 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, OH_SPEC) == 0 || 00472 cpl_frameset_count_tags(frameset, OH_SPEC) == 1, 00473 CPL_ERROR_ILLEGAL_INPUT, 00474 "Only a single reference spectrum can be provided!"); 00475 00476 // --- get parameters --- 00477 cpl_msg_info("", "--- Parameter setup for kmo_reconstruct ---"); 00478 00479 KMO_TRY_EXIT_IF_NULL( 00480 imethod = kmo_dfs_get_parameter_string(parlist, 00481 "kmos.kmo_reconstruct.imethod")); 00482 00483 KMO_TRY_ASSURE((strcmp(imethod, "NN") == 0) || 00484 (strcmp(imethod, "lwNN") == 0) || 00485 (strcmp(imethod, "swNN") == 0) || 00486 (strcmp(imethod, "MS") == 0) || 00487 (strcmp(imethod, "CS") == 0), 00488 CPL_ERROR_ILLEGAL_INPUT, 00489 "imethod must be either \"NN\", \"lwNN\", " 00490 "\"swNN\", \"MS\" or \"CS\"!"); 00491 00492 KMO_TRY_EXIT_IF_ERROR( 00493 kmo_dfs_print_parameter_help(parlist, 00494 "kmos.kmo_reconstruct.imethod")); 00495 00496 flux = kmo_dfs_get_parameter_bool(parlist, 00497 "kmos.kmo_reconstruct.flux"); 00498 00499 KMO_TRY_ASSURE((flux == 0) || 00500 (flux == 1), 00501 CPL_ERROR_ILLEGAL_INPUT, 00502 "flux must be either FALSE or TRUE!"); 00503 00504 KMO_TRY_EXIT_IF_ERROR( 00505 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_reconstruct.flux")); 00506 00507 detectorimage = kmo_dfs_get_parameter_bool(parlist, 00508 "kmos.kmo_reconstruct.detectorimage"); 00509 00510 KMO_TRY_ASSURE((detectorimage == 0) || 00511 (detectorimage == 1), 00512 CPL_ERROR_ILLEGAL_INPUT, 00513 "detectorimage must be either 0 or 1 !"); 00514 00515 KMO_TRY_EXIT_IF_ERROR( 00516 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_reconstruct.detectorimage")); 00517 00518 neighborhoodRange = kmo_dfs_get_parameter_double(parlist, 00519 "kmos.kmo_reconstruct.neighborhoodRange"); 00520 KMO_TRY_CHECK_ERROR_STATE(); 00521 KMO_TRY_ASSURE(neighborhoodRange > 0.0, 00522 CPL_ERROR_ILLEGAL_INPUT, 00523 "neighborhoodRange must be greater than 0.0"); 00524 KMO_TRY_EXIT_IF_ERROR( 00525 kmo_dfs_print_parameter_help(parlist, 00526 "kmos.kmo_reconstruct.neighborhoodRange")); 00527 00528 kmo_band_pars_load(parlist, "kmos.kmo_reconstruct"); 00529 00530 file_extension = kmo_dfs_get_parameter_bool(parlist, 00531 "kmos.kmo_reconstruct.file_extension"); 00532 KMO_TRY_CHECK_ERROR_STATE(); 00533 KMO_TRY_EXIT_IF_ERROR( 00534 kmo_dfs_print_parameter_help(parlist, 00535 "kmos.kmo_reconstruct.file_extension")); 00536 00537 pix_scale = kmo_dfs_get_parameter_double(parlist, 00538 "kmos.kmo_reconstruct.pix_scale"); 00539 KMO_TRY_CHECK_ERROR_STATE(); 00540 KMO_TRY_EXIT_IF_ERROR( 00541 kmo_dfs_print_parameter_help(parlist, 00542 "kmos.kmo_reconstruct.pix_scale")); 00543 KMO_TRY_ASSURE((pix_scale >= 0.01) && 00544 (pix_scale <= 0.4), 00545 CPL_ERROR_ILLEGAL_INPUT, 00546 "pix_scale must be between 0.01 and 0.4 (results in cubes " 00547 "with 7x7 to 280x280 pixels)!"); 00548 00549 dev_flip = kmo_dfs_get_parameter_bool(parlist, 00550 "kmos.kmo_reconstruct.dev_flip"); 00551 KMO_TRY_CHECK_ERROR_STATE(); 00552 KMO_TRY_EXIT_IF_ERROR( 00553 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_reconstruct.dev_flip")); 00554 KMO_TRY_ASSURE((dev_flip == TRUE) || 00555 (dev_flip == FALSE), 00556 CPL_ERROR_ILLEGAL_INPUT, 00557 "dev_flip must be TRUE or FALSE!"); 00558 00559 xcal_interpolation = kmo_dfs_get_parameter_bool(parlist, 00560 "kmos.kmo_reconstruct.xcal_interpolation"); 00561 KMO_TRY_CHECK_ERROR_STATE(); 00562 KMO_TRY_EXIT_IF_ERROR( 00563 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_reconstruct.xcal_interpolation")); 00564 KMO_TRY_ASSURE((xcal_interpolation == TRUE) || 00565 (xcal_interpolation == FALSE), 00566 CPL_ERROR_ILLEGAL_INPUT, 00567 "xcal_interpolation must be TRUE or FALSE!"); 00568 00569 00570 cpl_msg_info("", "-------------------------------------------"); 00571 00572 // load descriptor and header of data frame to reconstruct 00573 if (cpl_frameset_count_tags(frameset, DARK) == 1) { 00574 input_frame_name = DARK; 00575 output_frame_name = CUBE_DARK; 00576 } else if (cpl_frameset_count_tags(frameset, FLAT_ON) == 1) { 00577 input_frame_name = FLAT_ON; 00578 output_frame_name = CUBE_FLAT; 00579 } else if (cpl_frameset_count_tags(frameset, ARC_ON) == 1) { 00580 input_frame_name = ARC_ON; 00581 output_frame_name = CUBE_ARC; 00582 } else if (cpl_frameset_count_tags(frameset, OBJECT) == 1) { 00583 input_frame_name = OBJECT; 00584 output_frame_name = CUBE_OBJECT; 00585 } else if (cpl_frameset_count_tags(frameset, STD) == 1) { 00586 input_frame_name = STD; 00587 output_frame_name = CUBE_STD; 00588 } else if (cpl_frameset_count_tags(frameset, SCIENCE) == 1) { 00589 input_frame_name = SCIENCE; 00590 output_frame_name = CUBE_SCIENCE; 00591 } 00592 00593 // assure that filters, grating and rotation offsets match for 00594 // XCAL, YCAL, LCAL and for data frame to reconstruct (except DARK 00595 // frames) 00596 // check if filter_id and grating_id match for all detectors 00597 KMO_TRY_EXIT_IF_ERROR( 00598 kmo_check_frame_setup(frameset, XCAL, YCAL, 00599 TRUE, FALSE, TRUE)); 00600 KMO_TRY_EXIT_IF_ERROR( 00601 kmo_check_frame_setup(frameset, XCAL, LCAL, 00602 TRUE, FALSE, TRUE)); 00603 00604 if (cpl_frameset_count_tags(frameset, DARK) != 1) { 00605 00606 // check if filters, gratings and rotator offset match 00607 // (except for DARK frames) 00608 KMO_TRY_EXIT_IF_ERROR( 00609 kmo_check_frame_setup(frameset, XCAL, input_frame_name, 00610 TRUE, FALSE, FALSE)); 00611 /* 00612 // check if rotator offset don't differ to much 00613 cpl_frame *f1 = NULL, *f2 = NULL; 00614 cpl_propertylist *h1 = NULL, *h2 = NULL; 00615 char *kw = NULL; 00616 double tmp_dbl1 = 0.0, tmp_dbl2 = 0.0; 00617 00618 KMO_TRY_EXIT_IF_NULL( 00619 f1 = kmo_dfs_get_frame(frameset, XCAL)); 00620 00621 KMO_TRY_EXIT_IF_NULL( 00622 f2 = kmo_dfs_get_frame(frameset, input_frame_name)); 00623 h1 = kmclipm_propertylist_load(cpl_frame_get_filename(f1), 0); 00624 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00625 cpl_msg_error("","File not found: %s!", 00626 cpl_frame_get_filename(f1)); 00627 KMO_TRY_CHECK_ERROR_STATE(); 00628 } 00629 00630 h2 = kmclipm_propertylist_load(cpl_frame_get_filename(f2), 0); 00631 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00632 cpl_msg_error("","File not found: %s!", 00633 cpl_frame_get_filename(f2)); 00634 KMO_TRY_CHECK_ERROR_STATE(); 00635 } 00636 KMO_TRY_EXIT_IF_NULL( 00637 kw = cpl_sprintf("%s", ROTANGLE)); 00638 tmp_dbl1 = cpl_propertylist_get_double(h1, kw); 00639 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00640 KMO_TRY_ASSURE(1 == 0, 00641 CPL_ERROR_ILLEGAL_INPUT, 00642 "keyword \n%s\n of frame %s is missing!", 00643 keyword, XCAL); 00644 } 00645 00646 tmp_dbl2 = cpl_propertylist_get_double(h2, kw); 00647 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00648 KMO_TRY_ASSURE(1 == 0, 00649 CPL_ERROR_ILLEGAL_INPUT, 00650 "keyword \n%s\n of frame %s is missing!", 00651 keyword, input_frame_name); 00652 } 00653 00654 // strip angles below 0 deg and above 360 deg 00655 kmclipm_strip_angle(&tmp_dbl1); 00656 kmclipm_strip_angle(&tmp_dbl2); 00657 00658 if (fabs(tmp_dbl1 - tmp_dbl2) > 30.) { 00659 if ((fabs(tmp_dbl1) < 0.001) && (tmp_dbl2>330) && (tmp_dbl2<360)) { 00660 // singularity! 00661 // we have rot=0 for XCAL and rot>330 | rot<360 for input frame 00662 } else { 00663 cpl_msg_warning("","The angle of the calibration files (%g deg) " 00664 "and the angle of the frame to reconstruct" 00665 " (%g deg) differ by %g deg! Think about using " 00666 "calibration files matching better the actual " 00667 "rotator offset (ESO OCS ROT NAANGLE)", 00668 tmp_dbl1, tmp_dbl2, 00669 fabs(tmp_dbl1 - tmp_dbl2)); 00670 } 00671 } 00672 00673 cpl_propertylist_delete(h1); h1 = NULL; 00674 cpl_propertylist_delete(h2); h2 = NULL; 00675 cpl_free(kw); kw = NULL; 00676 */ 00677 } 00678 00679 KMO_TRY_EXIT_IF_NULL( 00680 xcal_frame = kmo_dfs_get_frame(frameset, XCAL)); 00681 KMO_TRY_EXIT_IF_NULL( 00682 rec_frame = kmo_dfs_get_frame(frameset, input_frame_name)); 00683 KMO_TRY_EXIT_IF_NULL( 00684 suffix = kmo_dfs_get_suffix(rec_frame, TRUE, TRUE)); 00685 00686 KMO_TRY_EXIT_IF_ERROR( 00687 kmo_check_frame_setup_md5_xycal(frameset)); 00688 KMO_TRY_EXIT_IF_ERROR( 00689 kmo_check_frame_setup_md5(frameset)); 00690 00691 cpl_msg_info("", "Detected instrument setup: %s", suffix+1); 00692 cpl_msg_info("", "(grating 1, 2 & 3, rotation angle)"); 00693 cpl_msg_info("", "-------------------------------------------"); 00694 00695 KMO_TRY_EXIT_IF_NULL( 00696 main_header = kmo_dfs_load_primary_header(frameset, 00697 input_frame_name)); 00698 00699 if (cpl_frameset_count_tags(frameset, OH_SPEC) != 0) { 00700 if (cpl_propertylist_has(main_header, ORIGFILE)) { 00701 KMO_TRY_EXIT_IF_NULL( 00702 tmp_str = cpl_propertylist_get_string(main_header, ORIGFILE)); 00703 if (strstr(tmp_str, "OBS") != NULL) { 00704 // we are reconstructing an OBS-frame, allow OH_SPEC correction 00705 KMO_TRY_EXIT_IF_NULL( 00706 ref_spectrum_frame = kmo_dfs_get_frame(frameset, OH_SPEC)); 00707 } else { 00708 cpl_msg_warning("", "Supplied OH_SPEC is ignored since a calibration frame is being reconstructed."); 00709 } 00710 } else { 00711 cpl_msg_warning("", "The supplied frame %s is assumed to be a science frame. If it is a calibration frame, omit OH_SPEC from sof-file", input_frame_name); 00712 KMO_TRY_EXIT_IF_NULL( 00713 ref_spectrum_frame = kmo_dfs_get_frame(frameset, OH_SPEC)); 00714 } 00715 } 00716 00717 desc1 = kmo_identify_fits_header(cpl_frame_get_filename(rec_frame)); 00718 KMO_TRY_CHECK_ERROR_STATE(); 00719 00720 KMO_TRY_ASSURE(((desc1.nr_ext == KMOS_NR_DETECTORS) || 00721 ((desc1.nr_ext == 2*KMOS_NR_DETECTORS))) && 00722 (desc1.ex_badpix == FALSE) && 00723 ((desc1.fits_type == raw_fits) || 00724 (desc1.fits_type == f2d_fits)) && 00725 (desc1.frame_type == detector_frame), 00726 CPL_ERROR_ILLEGAL_INPUT, 00727 "The frame to reconstruct isn't in the correct format!!!" 00728 "Exactly 3 frames, or 6 with noise are expected!"); 00729 00730 if (!desc1.ex_noise) { 00731 nr_devices = desc1.nr_ext; 00732 } else { 00733 nr_devices = desc1.nr_ext / 2; 00734 } 00735 00736 // compare descriptor of XCAL and data frame to reconstruct 00737 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(xcal_frame)); 00738 KMO_TRY_CHECK_ERROR_STATE(); 00739 00740 KMO_TRY_ASSURE((desc2.nr_ext % 3 == 0) && 00741 (desc1.ex_badpix == desc2.ex_badpix) && 00742 (desc1.frame_type == desc2.frame_type), 00743 CPL_ERROR_ILLEGAL_INPUT, 00744 "XCAL isn't in the correct format!!!"); 00745 00746 kmo_free_fits_desc(&desc2); 00747 00748 // compare descriptor of YCAL and data frame to reconstruct 00749 kmo_init_fits_desc(&desc2); 00750 00751 KMO_TRY_EXIT_IF_NULL( 00752 ycal_frame = kmo_dfs_get_frame(frameset, YCAL)); 00753 00754 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(ycal_frame)); 00755 KMO_TRY_CHECK_ERROR_STATE(); 00756 00757 KMO_TRY_ASSURE((desc2.nr_ext % 3 == 0) && 00758 (desc1.ex_badpix == desc2.ex_badpix) && 00759 (desc1.frame_type == desc2.frame_type), 00760 CPL_ERROR_ILLEGAL_INPUT, 00761 "YCAL isn't in the correct format!!!"); 00762 00763 kmo_free_fits_desc(&desc2); 00764 00765 // compare descriptor of LCAL and data frame to reconstruct 00766 kmo_init_fits_desc(&desc2); 00767 00768 KMO_TRY_EXIT_IF_NULL( 00769 lcal_frame = kmo_dfs_get_frame(frameset, LCAL)); 00770 00771 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(lcal_frame)); 00772 KMO_TRY_CHECK_ERROR_STATE(); 00773 00774 KMO_TRY_ASSURE((desc2.nr_ext % 3 == 0) && 00775 (desc1.ex_badpix == desc2.ex_badpix) && 00776 (desc1.frame_type == desc2.frame_type), 00777 CPL_ERROR_ILLEGAL_INPUT, 00778 "LCAL isn't in the correct format!!!"); 00779 00780 kmo_free_fits_desc(&desc2); 00781 00782 // 00783 // --- update & save primary header --- 00784 // 00785 KMO_TRY_EXIT_IF_NULL( 00786 tmp_header = kmo_dfs_load_primary_header(frameset, LCAL)); 00787 00788 // assert that filters have correct IDs and that all detectors of all 00789 // input frames have the same filter set 00790 for (i = 1; i <= nr_devices; i++) { 00791 // ESO INS FILTi ID 00792 KMO_TRY_EXIT_IF_NULL( 00793 keyword = cpl_sprintf("%s%d%s", IFU_FILTID_PREFIX, i, 00794 IFU_FILTID_POSTFIX)); 00795 00796 KMO_TRY_EXIT_IF_NULL( 00797 filter_id = cpl_propertylist_get_string(tmp_header, keyword)); 00798 00799 KMO_TRY_ASSURE((strcmp(filter_id, "IZ") == 0) || 00800 (strcmp(filter_id, "YJ") == 0) || 00801 (strcmp(filter_id, "H") == 0) || 00802 (strcmp(filter_id, "K") == 0) || 00803 (strcmp(filter_id, "HK") == 0), 00804 CPL_ERROR_ILLEGAL_INPUT, 00805 "Filter ID in primary header of LCAL frame must " 00806 "be either \"IZ\", \"YJ\", \"H\", \"K\" or " 00807 "\"HK\" !"); 00808 00809 if (strcmp(input_frame_name, DARK) != 0) { 00810 // dark needn't to be taken with filter! 00811 00812 KMO_TRY_EXIT_IF_NULL( 00813 filter_id_tmp = cpl_propertylist_get_string(main_header, 00814 keyword)); 00815 KMO_TRY_ASSURE(strcmp(filter_id, filter_id_tmp) == 0, 00816 CPL_ERROR_ILLEGAL_INPUT, 00817 "Filter IDs must be the same for LCAL frame and " 00818 "the frame to reconstruct!" 00819 "Detector No.: %d\nLCAL: %s\n%s: %s\n", 00820 i, filter_id, input_frame_name, filter_id_tmp); 00821 } 00822 cpl_free(keyword); keyword = NULL; 00823 } 00824 KMO_TRY_EXIT_IF_NULL( 00825 my_filter_id = cpl_strdup(filter_id)); 00826 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00827 00828 obs_id = cpl_propertylist_get_int(main_header, OBS_ID); 00829 KMO_TRY_CHECK_ERROR_STATE(); 00830 00831 KMO_TRY_EXIT_IF_NULL( 00832 filename_cube = cpl_sprintf("%s", output_frame_name)); 00833 KMO_TRY_EXIT_IF_NULL( 00834 filename_img = cpl_sprintf("%s", DET_IMG_REC)); 00835 if (file_extension) { 00836 KMO_TRY_EXIT_IF_NULL( 00837 obs_suffix = cpl_sprintf("%s%d", "_", obs_id)); 00838 } else { 00839 KMO_TRY_EXIT_IF_NULL( 00840 obs_suffix = cpl_sprintf("%s", "")); 00841 } 00842 00843 KMO_TRY_EXIT_IF_ERROR( 00844 kmo_dfs_save_main_header(frameset, filename_cube, obs_suffix, 00845 rec_frame, NULL, parlist, cpl_func)); 00846 00847 // setup grid definition, wavelength start and end points will be set 00848 // in the detector loop 00849 KMO_TRY_EXIT_IF_ERROR( 00850 kmclipm_setup_grid(&gd, imethod, neighborhoodRange, pix_scale, 0.)); 00851 00852 KMO_TRY_EXIT_IF_NULL( 00853 tmp_header = kmo_dfs_load_primary_header(frameset, XCAL)); 00854 00855 KMO_TRY_EXIT_IF_NULL( 00856 bounds = kmclipm_extract_bounds(tmp_header)); 00857 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00858 00859 if (detectorimage == TRUE) { 00860 KMO_TRY_EXIT_IF_ERROR( 00861 kmo_dfs_save_main_header(frameset, filename_img, obs_suffix, 00862 rec_frame, NULL, parlist, cpl_func)); 00863 } 00864 00865 /* loop through all detectors */ 00866 for (i = 1; i <= nr_devices; i++) { 00867 cpl_msg_info("","Processing detector No. %d", i); 00868 00869 // load lcal 00870 // extract LCAL image close to ROTANGLE 0. assuming that the wavelength range 00871 // doesn't differ too much with different ROTANGLEs. 00872 double rotangle_found; 00873 print_cal_angle_msg_once = FALSE; 00874 print_xcal_angle_msg_once = FALSE; 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 if (i==1) { 00879 print_cal_angle_msg_once = TRUE; 00880 print_xcal_angle_msg_once = TRUE; 00881 } 00882 char *tmp_band_method = getenv("KMO_BAND_METHOD"); 00883 int band_method = 0; 00884 if (tmp_band_method != NULL) { 00885 band_method = atoi(tmp_band_method); 00886 } 00887 00888 KMO_TRY_EXIT_IF_NULL( 00889 band_table = kmo_dfs_load_table(frameset, WAVE_BAND, 1, FALSE)); 00890 00891 KMO_TRY_EXIT_IF_ERROR( 00892 kmclipm_setup_grid_band_lcal(&gd, lcal, my_filter_id, 00893 band_method, band_table)); 00894 cpl_table_delete(band_table); band_table = NULL; 00895 00896 cpl_image_delete(lcal); lcal = NULL; 00897 00898 if (detectorimage == TRUE) { 00899 KMO_TRY_EXIT_IF_NULL( 00900 det_img_data[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_data = cpl_image_get_data_float(det_img_data[i-1])); 00904 00905 KMO_TRY_EXIT_IF_NULL( 00906 det_img_noise[i-1] = cpl_image_new(gd.x.dim*gd.y.dim*KMOS_IFUS_PER_DETECTOR, 00907 gd.l.dim, CPL_TYPE_FLOAT)); 00908 KMO_TRY_EXIT_IF_NULL( 00909 pdet_img_noise = cpl_image_get_data_float(det_img_noise[i-1])); 00910 } 00911 00912 00913 for (j = 0; j < KMOS_IFUS_PER_DETECTOR; j++) { 00914 /* update sub-header */ 00915 ifu_nr = (i-1)*KMOS_IFUS_PER_DETECTOR + j + 1; 00916 00917 /* load raw image and sub-header*/ 00918 KMO_TRY_EXIT_IF_NULL( 00919 sub_header = kmo_dfs_load_sub_header(frameset, input_frame_name, 00920 i, FALSE)); 00921 KMO_TRY_EXIT_IF_NULL( 00922 sub_header_orig = cpl_propertylist_duplicate(sub_header)); 00923 00924 // check if IFU is valid according to main header keywords & 00925 // calibration files 00926 00927 if (getenv("KMOS_RECONSTRUCT_ALL") == NULL) { 00928 KMO_TRY_EXIT_IF_NULL( 00929 keyword = cpl_sprintf("%s%d%s", IFU_VALID_PREFIX, ifu_nr, 00930 IFU_VALID_POSTFIX)); 00931 KMO_TRY_CHECK_ERROR_STATE(); 00932 cpl_propertylist_get_string(main_header, keyword); 00933 cpl_free(keyword); keyword = NULL; 00934 } else { 00935 // if KMOS_RECONSTRUCT_ALL is set all IFUs should be 00936 // reconstructed 00937 cpl_propertylist_get_string(main_header, "ggg"); 00938 } 00939 00940 if ((cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) && 00941 (bounds[2*(ifu_nr-1)] != -1) && 00942 (bounds[2*(ifu_nr-1)+1] != -1)) 00943 { 00944 cpl_error_reset(); 00945 // IFU is valid 00946 actual_sub_header = sub_header; 00947 00948 // 00949 // calc WCS & update subheader 00950 // 00951 KMO_TRY_EXIT_IF_ERROR( 00952 kmo_calc_wcs_gd(main_header, actual_sub_header, ifu_nr, gd)); 00953 00954 KMO_TRY_EXIT_IF_ERROR( 00955 kmclipm_update_property_int(actual_sub_header, 00956 NAXIS, 3, 00957 "number of data axes")); 00958 KMO_TRY_EXIT_IF_ERROR( 00959 kmclipm_update_property_int(actual_sub_header, 00960 NAXIS1, gd.x.dim, 00961 "length of data axis 1")); 00962 KMO_TRY_EXIT_IF_ERROR( 00963 kmclipm_update_property_int(actual_sub_header, 00964 NAXIS2, gd.y.dim, 00965 "length of data axis 2")); 00966 KMO_TRY_EXIT_IF_ERROR( 00967 kmclipm_update_property_int(actual_sub_header, 00968 NAXIS3, gd.l.dim, 00969 "length of data axis 3")); 00970 00971 // reconstruct data and noise (if available) 00972 // if (j == 0) { 00973 // sat_mode_msg = FALSE; 00974 // } else { 00975 // sat_mode_msg = TRUE; 00976 // } 00977 KMO_TRY_EXIT_IF_ERROR( 00978 kmo_reconstruct_sci(ifu_nr, 00979 bounds[2*(ifu_nr-1)], 00980 bounds[2*(ifu_nr-1)+1], 00981 rec_frame, 00982 input_frame_name, 00983 NULL, 00984 NULL, 00985 NULL, 00986 xcal_frame, 00987 ycal_frame, 00988 lcal_frame, 00989 NULL, 00990 NULL, 00991 &gd, 00992 &cube_data, 00993 &cube_noise, 00994 flux, 00995 background, 00996 xcal_interpolation)); 00997 00998 if (ref_spectrum_frame != NULL && cube_data != NULL) { 00999 KMO_TRY_EXIT_IF_NULL( 01000 lcorr_coeffs = kmo_lcorr_get(cube_data, 01001 actual_sub_header, 01002 ref_spectrum_frame, 01003 gd, 01004 my_filter_id, 01005 ifu_nr)); 01006 01007 cpl_imagelist_delete(cube_data); cube_data = NULL; 01008 if (cube_noise != NULL) { 01009 cpl_imagelist_delete(cube_noise); cube_noise = NULL; 01010 } 01011 KMO_TRY_EXIT_IF_ERROR( 01012 kmo_reconstruct_sci(ifu_nr, 01013 bounds[2*(ifu_nr-1)], 01014 bounds[2*(ifu_nr-1)+1], 01015 rec_frame, 01016 input_frame_name, 01017 NULL, 01018 NULL, 01019 NULL, 01020 xcal_frame, 01021 ycal_frame, 01022 lcal_frame, 01023 lcorr_coeffs, 01024 NULL, 01025 &gd, 01026 &cube_data, 01027 &cube_noise, 01028 flux, 01029 background, 01030 xcal_interpolation)); 01031 /* 01032 // show that lambda correction improved the data cube, a second one would improve even more 01033 01034 cpl_bivector *obj_spectrum2, *obj_spectrum3; 01035 cpl_polynomial *lcorr_coeffs2, *lcorr_coeffs3; 01036 KMO_TRY_EXIT_IF_NULL( 01037 obj_spectrum2 = kmo_lcorr_extract_spectrum( 01038 cube_data, actual_sub_header, 0.8, NULL)); 01039 01040 KMO_TRY_EXIT_IF_NULL( 01041 lcorr_coeffs2 = kmo_lcorr_crosscorrelate_spectra( 01042 obj_spectrum2, ref_spectrum, peaks, 0.002)); 01043 01044 cpl_bivector_delete(obj_spectrum2); 01045 01046 coeff_dump[0] = 0; 01047 for (ic=0; ic<=cpl_polynomial_get_degree(lcorr_coeffs2) && ic < max_coeffs; ic++) { 01048 pows[0] = ic; 01049 coeff_string = cpl_sprintf(" %*g,", 01050 format_width-2, cpl_polynomial_get_coeff(lcorr_coeffs2,pows)); 01051 strncat(coeff_dump, coeff_string, format_width); 01052 cpl_free(coeff_string); 01053 double c1 = cpl_polynomial_get_coeff(lcorr_coeffs,pows); 01054 double c2 = cpl_polynomial_get_coeff(lcorr_coeffs2,pows); 01055 cpl_polynomial_set_coeff(lcorr_coeffs, pows, c1+c2); 01056 } 01057 cpl_msg_debug("","Lambda correction coeffs for ifu %d %s",ifu_nr, coeff_dump); 01058 cpl_polynomial_delete(lcorr_coeffs2); lcorr_coeffs2=NULL; 01059 01060 cpl_imagelist_delete(cube_data); cube_data = NULL; 01061 cpl_imagelist_delete(cube_noise); cube_noise = NULL; 01062 KMO_TRY_EXIT_IF_ERROR( 01063 kmo_reconstruct_sci(ifu_nr, 01064 bounds[2*(ifu_nr-1)], 01065 bounds[2*(ifu_nr-1)+1], 01066 rec_frame, 01067 input_frame_name, 01068 NULL, 01069 NULL, 01070 NULL, 01071 xcal_frame, 01072 ycal_frame, 01073 lcal_frame, 01074 lcorr_coeffs, 01075 &gd, 01076 &cube_data, 01077 &cube_noise, 01078 flux, 01079 background, 01080 xcal_interpolation)); 01081 01082 KMO_TRY_EXIT_IF_NULL( 01083 obj_spectrum3 = kmo_lcorr_extract_spectrum( 01084 cube_data, actual_sub_header, 0.8, NULL)); 01085 01086 KMO_TRY_EXIT_IF_NULL( 01087 lcorr_coeffs3 = kmo_lcorr_crosscorrelate_spectra( 01088 obj_spectrum3, ref_spectrum, peaks, 0.002)); 01089 01090 cpl_bivector_delete(obj_spectrum3); 01091 01092 coeff_dump[0] = 0; 01093 for (ic=0; ic<=cpl_polynomial_get_degree(lcorr_coeffs3) && ic < max_coeffs; ic++) { 01094 pows[0] = ic; 01095 coeff_string = cpl_sprintf(" %*g,", 01096 format_width-2, cpl_polynomial_get_coeff(lcorr_coeffs3,pows)); 01097 strncat(coeff_dump, coeff_string, format_width); 01098 cpl_free(coeff_string); 01099 } 01100 cpl_msg_debug("","Lambda correction coeffs for iFu %d %s",ifu_nr, coeff_dump); 01101 cpl_polynomial_delete(lcorr_coeffs3); lcorr_coeffs3=NULL; 01102 */ 01103 cpl_polynomial_delete(lcorr_coeffs); lcorr_coeffs = NULL; 01104 01105 } 01106 01107 // scale flux according to pixel_scale 01108 KMO_TRY_EXIT_IF_NULL( 01109 tmp_img = cpl_imagelist_get(cube_data, 0)); 01110 double scaling = (cpl_image_get_size_x(tmp_img)*cpl_image_get_size_y(tmp_img)) / 01111 (KMOS_SLITLET_X*KMOS_SLITLET_Y); 01112 KMO_TRY_EXIT_IF_ERROR( 01113 cpl_imagelist_divide_scalar(cube_data, scaling)); 01114 if (cube_noise != NULL) { 01115 KMO_TRY_EXIT_IF_ERROR( 01116 cpl_imagelist_divide_scalar(cube_noise, scaling)); 01117 } 01118 } else { 01119 // IFU is invalid 01120 actual_sub_header = sub_header_orig; 01121 cpl_error_reset(); 01122 } // if ((cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) .. 01123 01124 if (detectorimage) { 01125 if (cube_data != NULL) { 01126 for (l = 0; l < gd.l.dim; l++) { 01127 KMO_TRY_EXIT_IF_NULL( 01128 slice = cpl_image_get_data_float(cpl_imagelist_get(cube_data, l))); 01129 for (y = 0; y < gd.y.dim; y++) { 01130 for (x = 0; x < gd.x.dim; x++) { 01131 int ix = x + 01132 y * gd.x.dim + 01133 j * gd.x.dim*gd.y.dim + //IFU offset 01134 l * gd.x.dim*gd.y.dim*KMOS_IFUS_PER_DETECTOR; 01135 pdet_img_data[ix] = slice[x + y*gd.x.dim]; 01136 } 01137 } 01138 } 01139 } 01140 if (cube_noise != NULL) { 01141 if (detectorimage) { 01142 detImgCube = TRUE; 01143 } 01144 for (l = 0; l < gd.l.dim; l++) { 01145 KMO_TRY_EXIT_IF_NULL( 01146 slice = cpl_image_get_data_float(cpl_imagelist_get(cube_noise, l))); 01147 for (y = 0; y < gd.y.dim; y++) { 01148 for (x = 0; x < gd.x.dim; x++) { 01149 int ix = x + 01150 y * gd.x.dim + 01151 j * gd.x.dim*gd.y.dim + //IFU offset 01152 l * gd.x.dim*gd.y.dim*KMOS_IFUS_PER_DETECTOR; 01153 pdet_img_noise[ix] = slice[x + y*gd.x.dim]; 01154 } 01155 } 01156 } 01157 } 01158 } 01159 01160 // save output 01161 KMO_TRY_EXIT_IF_NULL( 01162 extname = kmo_extname_creator(ifu_frame, ifu_nr, 01163 EXT_DATA)); 01164 01165 KMO_TRY_EXIT_IF_ERROR( 01166 kmclipm_update_property_string(actual_sub_header, 01167 EXTNAME, 01168 extname, 01169 "FITS extension name")); 01170 01171 cpl_free(extname); extname = NULL; 01172 01173 KMO_TRY_EXIT_IF_ERROR( 01174 kmo_dfs_save_cube(cube_data, filename_cube, obs_suffix, 01175 actual_sub_header, 0./0.)); 01176 01177 if (cube_noise != NULL) { 01178 KMO_TRY_EXIT_IF_NULL( 01179 extname = kmo_extname_creator(ifu_frame, ifu_nr, 01180 EXT_NOISE)); 01181 01182 KMO_TRY_EXIT_IF_ERROR( 01183 kmclipm_update_property_string(actual_sub_header, 01184 EXTNAME, 01185 extname, 01186 "FITS extension name")); 01187 01188 cpl_free(extname); extname = NULL; 01189 01190 KMO_TRY_EXIT_IF_ERROR( 01191 kmo_dfs_save_cube(cube_noise, filename_cube, obs_suffix, 01192 actual_sub_header, 0./0.)); 01193 } 01194 01195 cpl_imagelist_delete(cube_data); cube_data = NULL; 01196 cpl_imagelist_delete(cube_noise); cube_noise = NULL; 01197 cpl_propertylist_delete(sub_header); sub_header = NULL; 01198 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 01199 } // for j IFUs 01200 01201 if (detectorimage) { 01202 index = kmo_identify_index(cpl_frame_get_filename(rec_frame), 01203 i, FALSE); 01204 KMO_TRY_CHECK_ERROR_STATE(); 01205 01206 KMO_TRY_EXIT_IF_NULL( 01207 tmp_header = kmclipm_propertylist_load( 01208 cpl_frame_get_filename(rec_frame), index)); 01209 KMO_TRY_EXIT_IF_ERROR( 01210 kmo_save_det_img_ext(det_img_data[i-1], gd, i, filename_img, 01211 obs_suffix, tmp_header, dev_flip, FALSE)); 01212 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01213 01214 if (detImgCube) { 01215 if (desc1.ex_noise) { 01216 index = kmo_identify_index(cpl_frame_get_filename(rec_frame), 01217 i, TRUE); 01218 KMO_TRY_CHECK_ERROR_STATE(); 01219 } else { 01220 // use same index as for data frame, since input frame 01221 // has just 3 extensions 01222 } 01223 KMO_TRY_EXIT_IF_NULL( 01224 tmp_header = kmclipm_propertylist_load( 01225 cpl_frame_get_filename(rec_frame), index)); 01226 KMO_TRY_EXIT_IF_ERROR( 01227 kmo_save_det_img_ext(det_img_noise[i-1], gd, i, filename_img, 01228 obs_suffix, tmp_header, dev_flip, TRUE)); 01229 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01230 } 01231 } 01232 01233 // free memory 01234 cpl_imagelist_delete(cube_data); cube_data = NULL; 01235 cpl_imagelist_delete(cube_noise); cube_noise = NULL; 01236 cpl_propertylist_delete(sub_header); sub_header = NULL; 01237 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 01238 } // for i devices 01239 } 01240 KMO_CATCH 01241 { 01242 KMO_CATCH_MSG(); 01243 ret_val = -1; 01244 } 01245 01246 kmo_free_fits_desc(&desc1); 01247 kmo_free_fits_desc(&desc2); 01248 for (i = 0; i < KMOS_NR_DETECTORS; i++) { 01249 cpl_image_delete(det_img_data[i]); det_img_data[i] = NULL; 01250 cpl_image_delete(det_img_noise[i]); det_img_noise[i] = NULL; 01251 } 01252 cpl_free(my_filter_id); my_filter_id = NULL; 01253 cpl_free(bounds); bounds = NULL; 01254 cpl_propertylist_delete(main_header); main_header = NULL; 01255 cpl_propertylist_delete(sub_header); sub_header = NULL; 01256 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 01257 cpl_imagelist_delete(cube_data); cube_data = NULL; 01258 cpl_imagelist_delete(cube_noise); cube_noise = NULL; 01259 cpl_free(obs_suffix); obs_suffix = NULL; 01260 cpl_free(suffix); suffix = NULL; 01261 cpl_free(filename_img); filename_img = NULL; 01262 cpl_free(filename_cube); filename_cube = NULL; 01263 // sat_mode_msg = FALSE; 01264 01265 return ret_val; 01266 } 01267
1.7.6.1