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