|
KMOS Pipeline Reference Manual
1.0.8
|
00001 /* $Id: kmo_reconstruct.c,v 1.37 2013/02/19 10:51:42 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/02/19 10:51:42 $ 00024 * $Revision: 1.37 $ 00025 * $Name: kmosp_v1_0_8__20130220 $ 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_cpl_extensions.h" 00046 #include "kmo_dfs.h" 00047 #include "kmo_error.h" 00048 #include "kmo_utils.h" 00049 #include "kmo_constants.h" 00050 #include "kmo_debug.h" 00051 00052 /*----------------------------------------------------------------------------- 00053 * Functions prototypes 00054 *----------------------------------------------------------------------------*/ 00055 00056 static int kmo_reconstruct_create(cpl_plugin *); 00057 static int kmo_reconstruct_exec(cpl_plugin *); 00058 static int kmo_reconstruct_destroy(cpl_plugin *); 00059 static int kmo_reconstruct(cpl_parameterlist *, cpl_frameset *); 00060 00061 /*----------------------------------------------------------------------------- 00062 * Static variables 00063 *----------------------------------------------------------------------------*/ 00064 00065 static char kmo_reconstruct_description[] = 00066 "Data with or without noise is reconstructed into a cube using the calibration\n" 00067 "frames XCAL, YCAL and LCAL. XCAL and YCAL are generated using recipe kmo_flat,\n" 00068 "LCAL is generated using recipe kmo_wave_cal.\n" 00069 "The input data can contain noise extensions and will be reconstructed into\n" 00070 "additional extensions.\n" 00071 "\n" 00072 "BASIC PARAMETERS:\n" 00073 "-----------------\n" 00074 "--imethod\n" 00075 "The interpolation method used for reconstruction.\n" 00076 "\n" 00077 "--detimg\n" 00078 "Specify if the resampled image of the input frame should be generated. There-\n" 00079 "fore all slitlets of all IFUs are aligned one next to the other. This frame\n" 00080 "serves for quality control. One can immediately see if the reconstruction was\n" 00081 "successful.\n" 00082 "\n" 00083 "--file_extension" 00084 "Set this parameter to TRUE if the EXPTIME keyword should be appended to\n" 00085 "the output filenames.\n" 00086 "\n" 00087 "ADVANCED PARAMETERS\n" 00088 "-------------------\n" 00089 "--flux\n" 00090 "Specify if flux conservation should be applied.\n" 00091 "\n" 00092 "--neighborhoodRange\n" 00093 "Defines the range to search for neighbors during reconstruction\n" 00094 "\n" 00095 "--b_samples\n" 00096 "The number of samples in spectral direction for the reconstructed cube. Ideal-\n" 00097 "ly this number should be greater than 2048, the detector size.\n" 00098 "\n" 00099 "--b_start\n" 00100 "--b_end\n" 00101 "Used to define manually the start and end wavelength for the reconstructed\n" 00102 "cube. By default the internally defined values are used.\n" 00103 "\n" 00104 "--file_extension" 00105 "Set to TRUE if OBS_ID (from input frame header) should be appended to the\n" 00106 "output frame.\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 "\n" 00125 " Output files:\n" 00126 "\n" 00127 " DO KMOS\n" 00128 " category Type Explanation\n" 00129 " -------- ----- -----------\n" 00130 " CUBE_DARK or F3I Reconstructed cube \n" 00131 " CUBE_FLAT or RAW/F2D with or without noise\n" 00132 " CUBE_ARC or \n" 00133 " CUBE_OBJECT or \n" 00134 " CUBE_STD or \n" 00135 " CUBE_SCIENCE \n" 00136 "-------------------------------------------------------------------------------\n" 00137 "\n"; 00138 00139 /*----------------------------------------------------------------------------- 00140 * Functions code 00141 *----------------------------------------------------------------------------*/ 00142 00159 int cpl_plugin_get_info(cpl_pluginlist *list) 00160 { 00161 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00162 cpl_plugin *plugin = &recipe->interface; 00163 00164 cpl_plugin_init(plugin, 00165 CPL_PLUGIN_API, 00166 KMOS_BINARY_VERSION, 00167 CPL_PLUGIN_TYPE_RECIPE, 00168 "kmo_reconstruct", 00169 "Performs the cube reconstruction " 00170 "using different interpolation methods.", 00171 kmo_reconstruct_description, 00172 "Alex Agudo Berbel", 00173 "agudo@mpe.mpg.de", 00174 kmos_get_license(), 00175 kmo_reconstruct_create, 00176 kmo_reconstruct_exec, 00177 kmo_reconstruct_destroy); 00178 00179 cpl_pluginlist_append(list, plugin); 00180 00181 return 0; 00182 } 00183 00191 static int kmo_reconstruct_create(cpl_plugin *plugin) 00192 { 00193 cpl_recipe *recipe; 00194 cpl_parameter *p; 00195 00196 /* Check that the plugin is part of a valid recipe */ 00197 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00198 recipe = (cpl_recipe *)plugin; 00199 else 00200 return -1; 00201 00202 /* Create the parameters list in the cpl_recipe object */ 00203 recipe->parameters = cpl_parameterlist_new(); 00204 00205 /* Fill the parameters list */ 00206 /* --imethod */ 00207 p = cpl_parameter_new_value("kmos.kmo_reconstruct.imethod", 00208 CPL_TYPE_STRING, 00209 "Method to use for interpolation. " 00210 "[\"NN\" (nearest neighbour), " 00211 "\"lwNN\" (linear weighted nearest neighbor), " 00212 "\"swNN\" (square weighted nearest neighbor), " 00213 "\"MS\" (Modified Shepard's method)" 00214 "\"CS\" (Cubic spline)]", 00215 "kmos.kmo_reconstruct", 00216 "CS"); 00217 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "imethod"); 00218 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00219 cpl_parameterlist_append(recipe->parameters, p); 00220 00221 /* --neighborhoodRange */ 00222 p = cpl_parameter_new_value("kmos.kmo_reconstruct.neighborhoodRange", 00223 CPL_TYPE_DOUBLE, 00224 "Defines the range to search for neighbors. " 00225 "in pixels", 00226 "kmos.kmo_reconstruct", 00227 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", 00234 CPL_TYPE_BOOL, 00235 "TRUE: Apply flux conservation. FALSE: otherwise", 00236 "kmos.kmo_reconstruct", 00237 FALSE); 00238 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "flux"); 00239 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00240 cpl_parameterlist_append(recipe->parameters, p); 00241 00242 /* --detectorimage */ 00243 p = cpl_parameter_new_value("kmos.kmo_reconstruct.detectorimage", 00244 CPL_TYPE_BOOL, 00245 "TRUE: if resampled detector frame should be " 00246 "created, FALSE: otherwise", 00247 "kmos.kmo_reconstruct", 00248 FALSE); 00249 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "detimg"); 00250 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00251 cpl_parameterlist_append(recipe->parameters, p); 00252 00253 /* --file_extension */ 00254 p = cpl_parameter_new_value("kmos.kmo_reconstruct.file_extension", 00255 CPL_TYPE_BOOL, 00256 "TRUE: if OBS_ID keyword should be appended to " 00257 "output frames, FALSE: otherwise", 00258 "kmos.kmo_reconstruct", 00259 FALSE); 00260 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "file_extension"); 00261 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00262 cpl_parameterlist_append(recipe->parameters, p); 00263 00264 /* --dev_flip */ 00265 p = cpl_parameter_new_value("kmos.kmo_reconstruct.dev_flip", 00266 CPL_TYPE_BOOL, 00267 "INTENDED FOR PIPELINE DEVELOPERS ONLY: " 00268 "Set this parameter to TRUE if the wavelengths " 00269 "are ascending on the detector from bottom to " 00270 "top (only for old simulation data).", 00271 "kmos.kmo_reconstruct", 00272 FALSE); 00273 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dev_flip"); 00274 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00275 cpl_parameterlist_append(recipe->parameters, p); 00276 00277 // add parameters for band-definition 00278 kmo_band_pars_create(recipe->parameters, 00279 "kmos.kmo_reconstruct"); 00280 00281 return 0; 00282 } 00283 00289 static int kmo_reconstruct_exec(cpl_plugin *plugin) 00290 { 00291 cpl_recipe *recipe; 00292 00293 /* Get the recipe out of the plugin */ 00294 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00295 recipe = (cpl_recipe *)plugin; 00296 else return -1; 00297 00298 return kmo_reconstruct(recipe->parameters, recipe->frames); 00299 } 00300 00306 static int kmo_reconstruct_destroy(cpl_plugin *plugin) 00307 { 00308 cpl_recipe *recipe; 00309 00310 /* Get the recipe out of the plugin */ 00311 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00312 recipe = (cpl_recipe *)plugin; 00313 else return -1 ; 00314 00315 cpl_parameterlist_delete(recipe->parameters); 00316 return 0 ; 00317 } 00318 00333 static int kmo_reconstruct(cpl_parameterlist *parlist, cpl_frameset *frameset) 00334 { 00335 int ret_val = 0, 00336 nr_devices = 0, 00337 i = 0, 00338 j = 0, 00339 flux = 0, 00340 index = 0, 00341 detectorimage = 0, 00342 *bounds = NULL, 00343 ifu_nr = 0, 00344 obs_id = 0, 00345 file_extension = FALSE, 00346 dev_flip = FALSE, 00347 detImgCube = FALSE; 00348 float *pdet_img_data = NULL, 00349 *pdet_img_noise = NULL, 00350 *slice = NULL; 00351 double neighborhoodRange = 1.001; 00352 00353 const char *imethod = NULL, 00354 *input_frame_name = NULL, 00355 *output_frame_name = NULL, 00356 *filter_id = NULL, 00357 *filter_id_tmp = NULL; 00358 char *keyword = NULL, 00359 *filename_cube = NULL, 00360 *filename_img = NULL, 00361 // *fn_lut = NULL, 00362 *suffix = NULL, 00363 *obs_suffix = NULL, 00364 *my_filter_id = NULL, 00365 *extname = NULL; 00366 cpl_image *lcal = NULL, 00367 *det_img_data[KMOS_NR_DETECTORS], 00368 *det_img_noise[KMOS_NR_DETECTORS]; 00369 cpl_imagelist *cube_data = NULL, 00370 *cube_noise = NULL; 00371 cpl_frame *rec_frame = NULL, 00372 *xcal_frame = NULL, 00373 *ycal_frame = NULL, 00374 *lcal_frame = NULL; 00375 cpl_propertylist *main_header = NULL, 00376 *sub_header = NULL, 00377 *sub_header_orig = NULL, 00378 *actual_sub_header = NULL, 00379 *tmp_header = NULL; 00380 cpl_table *band_table = NULL; 00381 gridDefinition gd; 00382 main_fits_desc desc1, 00383 desc2; 00384 00385 for (int i=0; i<KMOS_NR_DETECTORS; i++) { 00386 det_img_data[i] = NULL; 00387 det_img_noise[i] = NULL; 00388 } 00389 00390 KMO_TRY 00391 { 00392 kmo_init_fits_desc(&desc1); 00393 kmo_init_fits_desc(&desc2); 00394 00395 // --- check input --- 00396 KMO_TRY_ASSURE((parlist != NULL) && 00397 (frameset != NULL), 00398 CPL_ERROR_NULL_INPUT, 00399 "Not all input data is provided!"); 00400 00401 KMO_TRY_ASSURE((cpl_frameset_count_tags(frameset, DARK) == 1) || 00402 (cpl_frameset_count_tags(frameset, FLAT_ON) == 1) || 00403 (cpl_frameset_count_tags(frameset, ARC_ON) == 1) || 00404 (cpl_frameset_count_tags(frameset, OBJECT) == 1) || 00405 (cpl_frameset_count_tags(frameset, STD) == 1) || 00406 (cpl_frameset_count_tags(frameset, SCIENCE) == 1), 00407 CPL_ERROR_NULL_INPUT, 00408 "A data frame (DARK, FLAT_ON, ARC_ON, OBJECT, STD or SCIENCE) must " 00409 "be provided!"); 00410 00411 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, XCAL) == 1, 00412 CPL_ERROR_FILE_NOT_FOUND, 00413 "XCAL frame missing in frameset!!"); 00414 00415 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, YCAL) == 1, 00416 CPL_ERROR_FILE_NOT_FOUND, 00417 "YCAL frame missing in frameset!!"); 00418 00419 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, LCAL) == 1, 00420 CPL_ERROR_FILE_NOT_FOUND, 00421 "LCAL frame missing in frameset!!"); 00422 00423 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, WAVE_BAND) == 1, 00424 CPL_ERROR_FILE_NOT_FOUND, 00425 "WAVE_BAND frame missing in frameset!!"); 00426 00427 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_reconstruct") == 1, 00428 CPL_ERROR_ILLEGAL_INPUT, 00429 "Cannot identify RAW and CALIB frames!"); 00430 00431 // --- get parameters --- 00432 cpl_msg_info("", "--- Parameter setup for kmo_reconstruct ---"); 00433 00434 KMO_TRY_EXIT_IF_NULL( 00435 imethod = kmo_dfs_get_parameter_string(parlist, 00436 "kmos.kmo_reconstruct.imethod")); 00437 00438 KMO_TRY_ASSURE((strcmp(imethod, "NN") == 0) || 00439 (strcmp(imethod, "lwNN") == 0) || 00440 (strcmp(imethod, "swNN") == 0) || 00441 (strcmp(imethod, "MS") == 0) || 00442 (strcmp(imethod, "CS") == 0), 00443 CPL_ERROR_ILLEGAL_INPUT, 00444 "imethod must be either \"NN\", \"lwNN\", " 00445 "\"swNN\", \"MS\" or \"CS\"!"); 00446 00447 KMO_TRY_EXIT_IF_ERROR( 00448 kmo_dfs_print_parameter_help(parlist, 00449 "kmos.kmo_reconstruct.imethod")); 00450 00451 flux = kmo_dfs_get_parameter_bool(parlist, 00452 "kmos.kmo_reconstruct.flux"); 00453 00454 KMO_TRY_ASSURE((flux == 0) || 00455 (flux == 1), 00456 CPL_ERROR_ILLEGAL_INPUT, 00457 "flux must be either FALSE or TRUE!"); 00458 00459 KMO_TRY_EXIT_IF_ERROR( 00460 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_reconstruct.flux")); 00461 00462 detectorimage = kmo_dfs_get_parameter_bool(parlist, 00463 "kmos.kmo_reconstruct.detectorimage"); 00464 00465 KMO_TRY_ASSURE((detectorimage == 0) || 00466 (detectorimage == 1), 00467 CPL_ERROR_ILLEGAL_INPUT, 00468 "detectorimage must be either 0 or 1 !"); 00469 00470 KMO_TRY_EXIT_IF_ERROR( 00471 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_reconstruct.detectorimage")); 00472 00473 neighborhoodRange = kmo_dfs_get_parameter_double(parlist, 00474 "kmos.kmo_reconstruct.neighborhoodRange"); 00475 KMO_TRY_CHECK_ERROR_STATE(); 00476 00477 KMO_TRY_ASSURE(neighborhoodRange > 0.0, 00478 CPL_ERROR_ILLEGAL_INPUT, 00479 "neighborhoodRange must be greater than 0.0"); 00480 00481 KMO_TRY_EXIT_IF_ERROR( 00482 kmo_dfs_print_parameter_help(parlist, 00483 "kmos.kmo_reconstruct.neighborhoodRange")); 00484 00485 kmo_band_pars_load(parlist, "kmos.kmo_reconstruct"); 00486 00487 file_extension = kmo_dfs_get_parameter_bool(parlist, 00488 "kmos.kmo_reconstruct.file_extension"); 00489 KMO_TRY_CHECK_ERROR_STATE(); 00490 00491 KMO_TRY_EXIT_IF_ERROR( 00492 kmo_dfs_print_parameter_help(parlist, 00493 "kmos.kmo_reconstruct.file_extension")); 00494 00495 dev_flip = kmo_dfs_get_parameter_bool(parlist, 00496 "kmos.kmo_reconstruct.dev_flip"); 00497 KMO_TRY_CHECK_ERROR_STATE(); 00498 KMO_TRY_EXIT_IF_ERROR( 00499 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_reconstruct.dev_flip")); 00500 KMO_TRY_ASSURE((dev_flip == TRUE) || 00501 (dev_flip == FALSE), 00502 CPL_ERROR_ILLEGAL_INPUT, 00503 "dev_flip must be TRUE or FALSE!"); 00504 00505 00506 cpl_msg_info("", "-------------------------------------------"); 00507 00508 // load descriptor and header of data frame to reconstruct 00509 if (cpl_frameset_count_tags(frameset, DARK) == 1) { 00510 input_frame_name = DARK; 00511 output_frame_name = CUBE_DARK; 00512 } else if (cpl_frameset_count_tags(frameset, FLAT_ON) == 1) { 00513 input_frame_name = FLAT_ON; 00514 output_frame_name = CUBE_FLAT; 00515 } else if (cpl_frameset_count_tags(frameset, ARC_ON) == 1) { 00516 input_frame_name = ARC_ON; 00517 output_frame_name = CUBE_ARC; 00518 } else if (cpl_frameset_count_tags(frameset, OBJECT) == 1) { 00519 input_frame_name = OBJECT; 00520 output_frame_name = CUBE_OBJECT; 00521 } else if (cpl_frameset_count_tags(frameset, STD) == 1) { 00522 input_frame_name = STD; 00523 output_frame_name = CUBE_STD; 00524 } else if (cpl_frameset_count_tags(frameset, SCIENCE) == 1) { 00525 input_frame_name = SCIENCE; 00526 output_frame_name = CUBE_SCIENCE; 00527 } 00528 00529 // assure that filters, grating and rotation offsets match for 00530 // XCAL, YCAL, LCAL and for data frame to reconstruct (except DARK 00531 // frames) 00532 // check if filter_id and grating_id match for all detectors 00533 KMO_TRY_EXIT_IF_ERROR( 00534 kmo_check_frame_setup(frameset, XCAL, YCAL, 00535 TRUE, FALSE, TRUE)); 00536 KMO_TRY_EXIT_IF_ERROR( 00537 kmo_check_frame_setup(frameset, XCAL, LCAL, 00538 TRUE, FALSE, TRUE)); 00539 00540 // This check doesn't make sense here since OCS.ROT.NAANGLE is compared. 00541 // When creating the calibration files the RAW exposures needn't have been 00542 // provided in the same order 00543 // KMO_TRY_EXIT_IF_ERROR( 00544 // kmo_check_cal_frames_rotangle(frameset, XCAL, YCAL)); 00545 // KMO_TRY_EXIT_IF_ERROR( 00546 // kmo_check_cal_frames_rotangle(frameset, XCAL, LCAL)); 00547 00548 if (cpl_frameset_count_tags(frameset, DARK) != 1) { 00549 00550 // check if filters, gratings and rotator offset match 00551 // (except for DARK frames) 00552 KMO_TRY_EXIT_IF_ERROR( 00553 kmo_check_frame_setup(frameset, XCAL, input_frame_name, 00554 TRUE, FALSE, FALSE)); 00555 /* 00556 // check if rotator offset don't differ to much 00557 cpl_frame *f1 = NULL, *f2 = NULL; 00558 cpl_propertylist *h1 = NULL, *h2 = NULL; 00559 char *kw = NULL; 00560 double tmp_dbl1 = 0.0, tmp_dbl2 = 0.0; 00561 00562 KMO_TRY_EXIT_IF_NULL( 00563 f1 = kmo_dfs_get_frame(frameset, XCAL)); 00564 00565 KMO_TRY_EXIT_IF_NULL( 00566 f2 = kmo_dfs_get_frame(frameset, input_frame_name)); 00567 h1 = kmclipm_propertylist_load(cpl_frame_get_filename(f1), 0); 00568 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00569 cpl_msg_error("","File not found: %s!", 00570 cpl_frame_get_filename(f1)); 00571 KMO_TRY_CHECK_ERROR_STATE(); 00572 } 00573 00574 h2 = kmclipm_propertylist_load(cpl_frame_get_filename(f2), 0); 00575 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00576 cpl_msg_error("","File not found: %s!", 00577 cpl_frame_get_filename(f2)); 00578 KMO_TRY_CHECK_ERROR_STATE(); 00579 } 00580 KMO_TRY_EXIT_IF_NULL( 00581 kw = cpl_sprintf("%s", ROTANGLE)); 00582 tmp_dbl1 = cpl_propertylist_get_double(h1, kw); 00583 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00584 KMO_TRY_ASSURE(1 == 0, 00585 CPL_ERROR_ILLEGAL_INPUT, 00586 "keyword \n%s\n of frame %s is missing!", 00587 keyword, XCAL); 00588 } 00589 00590 tmp_dbl2 = cpl_propertylist_get_double(h2, kw); 00591 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00592 KMO_TRY_ASSURE(1 == 0, 00593 CPL_ERROR_ILLEGAL_INPUT, 00594 "keyword \n%s\n of frame %s is missing!", 00595 keyword, input_frame_name); 00596 } 00597 00598 // strip angles below 0 deg and above 360 deg 00599 kmclipm_strip_angle(&tmp_dbl1); 00600 kmclipm_strip_angle(&tmp_dbl2); 00601 00602 if (fabs(tmp_dbl1 - tmp_dbl2) > 30.) { 00603 if ((fabs(tmp_dbl1) < 0.001) && (tmp_dbl2>330) && (tmp_dbl2<360)) { 00604 // singularity! 00605 // we have rot=0 for XCAL and rot>330 | rot<360 for input frame 00606 } else { 00607 cpl_msg_warning("","The angle of the calibration files (%g deg) " 00608 "and the angle of the frame to reconstruct" 00609 " (%g deg) differ by %g deg! Think about using " 00610 "calibration files matching better the actual " 00611 "rotator offset (ESO OCS ROT NAANGLE)", 00612 tmp_dbl1, tmp_dbl2, 00613 fabs(tmp_dbl1 - tmp_dbl2)); 00614 } 00615 } 00616 00617 cpl_propertylist_delete(h1); h1 = NULL; 00618 cpl_propertylist_delete(h2); h2 = NULL; 00619 cpl_free(kw); kw = NULL; 00620 */ 00621 } 00622 00623 KMO_TRY_EXIT_IF_NULL( 00624 xcal_frame = kmo_dfs_get_frame(frameset, XCAL)); 00625 KMO_TRY_EXIT_IF_NULL( 00626 rec_frame = kmo_dfs_get_frame(frameset, input_frame_name)); 00627 KMO_TRY_EXIT_IF_NULL( 00628 suffix = kmo_dfs_get_suffix(rec_frame, TRUE, TRUE)); 00629 00630 cpl_msg_info("", "Detected instrument setup: %s", suffix+1); 00631 cpl_msg_info("", "(grating 1, 2 & 3, rotation angle)"); 00632 cpl_msg_info("", "-------------------------------------------"); 00633 00634 00635 desc1 = kmo_identify_fits_header(cpl_frame_get_filename(rec_frame)); 00636 KMO_TRY_CHECK_ERROR_STATE(); 00637 00638 KMO_TRY_ASSURE(((desc1.nr_ext == KMOS_NR_DETECTORS) || 00639 ((desc1.nr_ext == 2*KMOS_NR_DETECTORS))) && 00640 (desc1.ex_badpix == FALSE) && 00641 ((desc1.fits_type == raw_fits) || 00642 (desc1.fits_type == f2d_fits)) && 00643 (desc1.frame_type == detector_frame), 00644 CPL_ERROR_ILLEGAL_INPUT, 00645 "The frame to reconstruct isn't in the correct format!!!" 00646 "Exactly 3 frames, or 6 with noise are expected!"); 00647 00648 if (!desc1.ex_noise) { 00649 nr_devices = desc1.nr_ext; 00650 } else { 00651 nr_devices = desc1.nr_ext / 2; 00652 } 00653 00654 // compare descriptor of XCAL and data frame to reconstruct 00655 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(xcal_frame)); 00656 KMO_TRY_CHECK_ERROR_STATE(); 00657 00658 KMO_TRY_ASSURE((desc2.nr_ext % 3 == 0) && 00659 (desc1.ex_badpix == desc2.ex_badpix) && 00660 (desc1.frame_type == desc2.frame_type), 00661 CPL_ERROR_ILLEGAL_INPUT, 00662 "XCAL isn't in the correct format!!!"); 00663 00664 kmo_free_fits_desc(&desc2); 00665 00666 // compare descriptor of YCAL and data frame to reconstruct 00667 kmo_init_fits_desc(&desc2); 00668 00669 KMO_TRY_EXIT_IF_NULL( 00670 ycal_frame = kmo_dfs_get_frame(frameset, YCAL)); 00671 00672 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(ycal_frame)); 00673 KMO_TRY_CHECK_ERROR_STATE(); 00674 00675 KMO_TRY_ASSURE((desc2.nr_ext % 3 == 0) && 00676 (desc1.ex_badpix == desc2.ex_badpix) && 00677 (desc1.frame_type == desc2.frame_type), 00678 CPL_ERROR_ILLEGAL_INPUT, 00679 "YCAL isn't in the correct format!!!"); 00680 00681 kmo_free_fits_desc(&desc2); 00682 00683 // compare descriptor of LCAL and data frame to reconstruct 00684 kmo_init_fits_desc(&desc2); 00685 00686 KMO_TRY_EXIT_IF_NULL( 00687 lcal_frame = kmo_dfs_get_frame(frameset, LCAL)); 00688 00689 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(lcal_frame)); 00690 KMO_TRY_CHECK_ERROR_STATE(); 00691 00692 KMO_TRY_ASSURE((desc2.nr_ext % 3 == 0) && 00693 (desc1.ex_badpix == desc2.ex_badpix) && 00694 (desc1.frame_type == desc2.frame_type), 00695 CPL_ERROR_ILLEGAL_INPUT, 00696 "LCAL isn't in the correct format!!!"); 00697 00698 kmo_free_fits_desc(&desc2); 00699 00700 // 00701 // --- load, update & save primary header --- 00702 // 00703 KMO_TRY_EXIT_IF_NULL( 00704 main_header = kmo_dfs_load_primary_header(frameset, 00705 input_frame_name)); 00706 00707 KMO_TRY_EXIT_IF_NULL( 00708 tmp_header = kmo_dfs_load_primary_header(frameset, LCAL)); 00709 00710 // assert that filters have correct IDs and that all detectors of all 00711 // input frames have the same filter set 00712 for (i = 1; i <= nr_devices; i++) { 00713 // ESO INS FILTi ID 00714 KMO_TRY_EXIT_IF_NULL( 00715 keyword = cpl_sprintf("%s%d%s", IFU_FILTID_PREFIX, i, 00716 IFU_FILTID_POSTFIX)); 00717 00718 KMO_TRY_EXIT_IF_NULL( 00719 filter_id = cpl_propertylist_get_string(tmp_header, keyword)); 00720 00721 KMO_TRY_ASSURE((strcmp(filter_id, "IZ") == 0) || 00722 (strcmp(filter_id, "YJ") == 0) || 00723 (strcmp(filter_id, "H") == 0) || 00724 (strcmp(filter_id, "K") == 0) || 00725 (strcmp(filter_id, "HK") == 0), 00726 CPL_ERROR_ILLEGAL_INPUT, 00727 "Filter ID in primary header of LCAL frame must " 00728 "be either \"IZ\", \"YJ\", \"H\", \"K\" or " 00729 "\"HK\" !"); 00730 00731 if (strcmp(input_frame_name, DARK) != 0) { 00732 // dark needn't to be taken with filter! 00733 00734 KMO_TRY_EXIT_IF_NULL( 00735 filter_id_tmp = cpl_propertylist_get_string(main_header, 00736 keyword)); 00737 KMO_TRY_ASSURE(strcmp(filter_id, filter_id_tmp) == 0, 00738 CPL_ERROR_ILLEGAL_INPUT, 00739 "Filter IDs must be the same for LCAL frame and " 00740 "the frame to reconstruct!" 00741 "Detector No.: %d\nLCAL: %s\n%s: %s\n", 00742 i, filter_id, input_frame_name, filter_id_tmp); 00743 } 00744 cpl_free(keyword); keyword = NULL; 00745 } 00746 KMO_TRY_EXIT_IF_NULL( 00747 my_filter_id = cpl_strdup(filter_id)); 00748 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00749 00750 obs_id = cpl_propertylist_get_int(main_header, OBS_ID); 00751 KMO_TRY_CHECK_ERROR_STATE(); 00752 00753 KMO_TRY_EXIT_IF_NULL( 00754 filename_cube = cpl_sprintf("%s", output_frame_name)); 00755 KMO_TRY_EXIT_IF_NULL( 00756 filename_img = cpl_sprintf("%s", DET_IMG_REC)); 00757 if (file_extension) { 00758 KMO_TRY_EXIT_IF_NULL( 00759 obs_suffix = cpl_sprintf("%s%d", "_", obs_id)); 00760 } else { 00761 KMO_TRY_EXIT_IF_NULL( 00762 obs_suffix = cpl_sprintf("%s", "")); 00763 } 00764 00765 KMO_TRY_EXIT_IF_ERROR( 00766 kmo_dfs_save_main_header(frameset, filename_cube, obs_suffix, 00767 rec_frame, NULL, parlist, cpl_func)); 00768 00769 // setup grid definition, wavelength start and end points will be set 00770 // in the detector loop 00771 KMO_TRY_EXIT_IF_ERROR( 00772 kmclipm_setup_grid(&gd, imethod, neighborhoodRange)); 00773 00774 KMO_TRY_EXIT_IF_NULL( 00775 tmp_header = kmo_dfs_load_primary_header(frameset, XCAL)); 00776 00777 KMO_TRY_EXIT_IF_NULL( 00778 bounds = kmclipm_extract_bounds(tmp_header)); 00779 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00780 00781 if (detectorimage == TRUE) { 00782 KMO_TRY_EXIT_IF_ERROR( 00783 kmo_dfs_save_main_header(frameset, filename_img, obs_suffix, 00784 rec_frame, NULL, parlist, cpl_func)); 00785 } 00786 00787 /* loop through all detectors */ 00788 for (i = 1; i <= nr_devices; i++) { 00789 cpl_msg_info("","Processing detector No. %d", i); 00790 00791 // load lcal 00792 // extract LCAL image close to ROTANGLE 0. assuming that the wavelength range 00793 // doesn't differ too much with different ROTANGLEs. 00794 double rotangle_found; 00795 KMO_TRY_EXIT_IF_NULL( 00796 lcal = kmo_dfs_load_cal_image(frameset, LCAL, i, FALSE, 0., 00797 FALSE, NULL, &rotangle_found)); 00798 00799 char *tmp_band_method = getenv("KMO_BAND_METHOD"); 00800 int band_method = 0; 00801 if (tmp_band_method != NULL) { 00802 band_method = atoi(tmp_band_method); 00803 } 00804 00805 KMO_TRY_EXIT_IF_NULL( 00806 band_table = kmo_dfs_load_table(frameset, WAVE_BAND, 1, FALSE)); 00807 00808 KMO_TRY_EXIT_IF_ERROR( 00809 kmclipm_setup_grid_band_lcal(&gd, lcal, my_filter_id, 00810 band_method, band_table)); 00811 cpl_table_delete(band_table); band_table = NULL; 00812 00813 cpl_image_delete(lcal); lcal = NULL; 00814 00815 if (detectorimage == TRUE) { 00816 KMO_TRY_EXIT_IF_NULL( 00817 det_img_data[i-1] = cpl_image_new(gd.x.dim*gd.y.dim*KMOS_IFUS_PER_DETECTOR, 00818 gd.l.dim, CPL_TYPE_FLOAT)); 00819 KMO_TRY_EXIT_IF_NULL( 00820 pdet_img_data = cpl_image_get_data_float(det_img_data[i-1])); 00821 00822 KMO_TRY_EXIT_IF_NULL( 00823 det_img_noise[i-1] = cpl_image_new(gd.x.dim*gd.y.dim*KMOS_IFUS_PER_DETECTOR, 00824 gd.l.dim, CPL_TYPE_FLOAT)); 00825 KMO_TRY_EXIT_IF_NULL( 00826 pdet_img_noise = cpl_image_get_data_float(det_img_noise[i-1])); 00827 } 00828 00829 00830 for (j = 0; j < KMOS_IFUS_PER_DETECTOR; j++) { 00831 /* update sub-header */ 00832 ifu_nr = (i-1)*KMOS_IFUS_PER_DETECTOR + j + 1; 00833 00834 /* load raw image and sub-header*/ 00835 KMO_TRY_EXIT_IF_NULL( 00836 sub_header = kmo_dfs_load_sub_header(frameset, input_frame_name, 00837 i, FALSE)); 00838 KMO_TRY_EXIT_IF_NULL( 00839 sub_header_orig = cpl_propertylist_duplicate(sub_header)); 00840 00841 // check if IFU is valid according to main header keywords & 00842 // calibration files 00843 00844 if (getenv("KMOS_RECONSTRUCT_ALL") == NULL) { 00845 KMO_TRY_EXIT_IF_NULL( 00846 keyword = cpl_sprintf("%s%d%s", IFU_VALID_PREFIX, ifu_nr, 00847 IFU_VALID_POSTFIX)); 00848 KMO_TRY_CHECK_ERROR_STATE(); 00849 cpl_propertylist_get_string(main_header, keyword); 00850 cpl_free(keyword); keyword = NULL; 00851 } else { 00852 // if KMOS_RECONSTRUCT_ALL is set all IFUs should be 00853 // reconstructed 00854 cpl_propertylist_get_string(main_header, "ggg"); 00855 } 00856 00857 if ((cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) && 00858 (bounds[2*(ifu_nr-1)] != -1) && 00859 (bounds[2*(ifu_nr-1)+1] != -1)) 00860 { 00861 cpl_error_reset(); 00862 // IFU is valid 00863 actual_sub_header = sub_header; 00864 00865 // calculate WCS 00866 KMO_TRY_EXIT_IF_ERROR( 00867 kmo_calc_wcs(main_header, actual_sub_header, ifu_nr, 00868 gd.l.start, gd.l.delta)); 00869 00870 // reconstruct data and noise (if available) 00871 if (j == 0) { 00872 sat_mode_msg = FALSE; 00873 } else { 00874 sat_mode_msg = TRUE; 00875 } 00876 KMO_TRY_EXIT_IF_ERROR( 00877 kmo_reconstruct_sci(ifu_nr, 00878 bounds[2*(ifu_nr-1)], 00879 bounds[2*(ifu_nr-1)+1], 00880 rec_frame, 00881 input_frame_name, 00882 NULL, 00883 NULL, 00884 NULL, 00885 xcal_frame, 00886 ycal_frame, 00887 lcal_frame, 00888 &gd, 00889 &cube_data, 00890 &cube_noise, 00891 flux)); 00892 } else { 00893 // IFU is invalid 00894 actual_sub_header = sub_header_orig; 00895 cpl_error_reset(); 00896 } // if ((cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) .. 00897 00898 if (detectorimage) { 00899 if (cube_data != NULL) { 00900 for (int l=0; l<gd.l.dim; l++) { 00901 KMO_TRY_EXIT_IF_NULL( 00902 slice = cpl_image_get_data_float(cpl_imagelist_get(cube_data, l))); 00903 for (int y=0; y<gd.y.dim; y++) { 00904 for (int x=0; x<gd.x.dim; x++) { 00905 int ix = x + 00906 y * gd.x.dim + 00907 j * gd.x.dim*gd.y.dim + //IFU offset 00908 l * gd.x.dim*gd.y.dim*KMOS_IFUS_PER_DETECTOR; 00909 pdet_img_data[ix] = slice[x + y*gd.x.dim]; 00910 } 00911 } 00912 } 00913 } 00914 if (cube_noise != NULL) { 00915 if (detectorimage) { 00916 detImgCube = TRUE; 00917 } 00918 for (int l=0; l<gd.l.dim; l++) { 00919 KMO_TRY_EXIT_IF_NULL( 00920 slice = cpl_image_get_data_float(cpl_imagelist_get(cube_noise, l))); 00921 for (int y=0; y<gd.y.dim; y++) { 00922 for (int x=0; x<gd.x.dim; x++) { 00923 int ix = x + 00924 y * gd.x.dim + 00925 j * gd.x.dim*gd.y.dim + //IFU offset 00926 l * gd.x.dim*gd.y.dim*KMOS_IFUS_PER_DETECTOR; 00927 pdet_img_noise[ix] = slice[x + y*gd.x.dim]; 00928 } 00929 } 00930 } 00931 } 00932 } 00933 00934 // save output 00935 KMO_TRY_EXIT_IF_NULL( 00936 extname = kmo_extname_creator(ifu_frame, ifu_nr, 00937 EXT_DATA)); 00938 00939 KMO_TRY_EXIT_IF_ERROR( 00940 kmclipm_update_property_string(actual_sub_header, 00941 EXTNAME, 00942 extname, 00943 "FITS extension name")); 00944 00945 cpl_free(extname); extname = NULL; 00946 00947 KMO_TRY_EXIT_IF_ERROR( 00948 kmo_dfs_save_cube(cube_data, filename_cube, obs_suffix, 00949 actual_sub_header, 0./0.)); 00950 00951 if (cube_noise != NULL) { 00952 KMO_TRY_EXIT_IF_NULL( 00953 extname = kmo_extname_creator(ifu_frame, ifu_nr, 00954 EXT_NOISE)); 00955 00956 KMO_TRY_EXIT_IF_ERROR( 00957 kmclipm_update_property_string(actual_sub_header, 00958 EXTNAME, 00959 extname, 00960 "FITS extension name")); 00961 00962 cpl_free(extname); extname = NULL; 00963 00964 KMO_TRY_EXIT_IF_ERROR( 00965 kmo_dfs_save_cube(cube_noise, filename_cube, obs_suffix, 00966 actual_sub_header, 0./0.)); 00967 } 00968 00969 cpl_imagelist_delete(cube_data); cube_data = NULL; 00970 cpl_imagelist_delete(cube_noise); cube_noise = NULL; 00971 cpl_propertylist_delete(sub_header); sub_header = NULL; 00972 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 00973 } // for j IFUs 00974 00975 if (detectorimage) { 00976 index = kmo_identify_index(cpl_frame_get_filename(rec_frame), 00977 i, FALSE); 00978 KMO_TRY_CHECK_ERROR_STATE(); 00979 00980 KMO_TRY_EXIT_IF_NULL( 00981 tmp_header = kmclipm_propertylist_load( 00982 cpl_frame_get_filename(rec_frame), index)); 00983 KMO_TRY_EXIT_IF_ERROR( 00984 kmo_save_det_img_ext(det_img_data[i-1], gd, i, filename_img, 00985 obs_suffix, tmp_header, dev_flip, FALSE)); 00986 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00987 00988 if (detImgCube) { 00989 if (desc1.ex_noise) { 00990 index = kmo_identify_index(cpl_frame_get_filename(rec_frame), 00991 i, TRUE); 00992 KMO_TRY_CHECK_ERROR_STATE(); 00993 } else { 00994 // use same index as for data frame, since input frame 00995 // has just 3 extensions 00996 } 00997 KMO_TRY_EXIT_IF_NULL( 00998 tmp_header = kmclipm_propertylist_load( 00999 cpl_frame_get_filename(rec_frame), index)); 01000 KMO_TRY_EXIT_IF_ERROR( 01001 kmo_save_det_img_ext(det_img_noise[i-1], gd, i, filename_img, 01002 obs_suffix, tmp_header, dev_flip, TRUE)); 01003 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01004 } 01005 } 01006 01007 // free memory 01008 cpl_imagelist_delete(cube_data); cube_data = NULL; 01009 cpl_imagelist_delete(cube_noise); cube_noise = NULL; 01010 cpl_propertylist_delete(sub_header); sub_header = NULL; 01011 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 01012 } // for i devices 01013 } 01014 KMO_CATCH 01015 { 01016 KMO_CATCH_MSG(); 01017 ret_val = -1; 01018 } 01019 01020 kmo_free_fits_desc(&desc1); 01021 kmo_free_fits_desc(&desc2); 01022 for (int i=0; i<KMOS_NR_DETECTORS; i++) { 01023 cpl_image_delete(det_img_data[i]); det_img_data[i] = NULL; 01024 cpl_image_delete(det_img_noise[i]); det_img_noise[i] = NULL; 01025 } 01026 cpl_free(my_filter_id); my_filter_id = NULL; 01027 cpl_free(bounds); bounds = NULL; 01028 cpl_propertylist_delete(main_header); main_header = NULL; 01029 cpl_propertylist_delete(sub_header); sub_header = NULL; 01030 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 01031 cpl_imagelist_delete(cube_data); cube_data = NULL; 01032 cpl_imagelist_delete(cube_noise); cube_noise = NULL; 01033 cpl_free(obs_suffix); obs_suffix = NULL; 01034 cpl_free(suffix); suffix = NULL; 01035 cpl_free(filename_img); filename_img = NULL; 01036 cpl_free(filename_cube); filename_cube = NULL; 01037 sat_mode_msg = FALSE; 01038 01039 return ret_val; 01040 } 01041
1.7.6.1