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