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