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