|
KMOS Pipeline Reference Manual
1.2.3
|
00001 /* $Id: kmo_multi_reconstruct.c,v 1.46 2013/08/02 09:38:57 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/08/02 09:38:57 $ 00024 * $Revision: 1.46 $ 00025 * $Name: HEAD $ 00026 */ 00027 00028 #ifdef HAVE_CONFIG_H 00029 #include <config.h> 00030 #endif 00031 00032 #include <string.h> 00033 #include <math.h> 00034 00035 #include <cpl.h> 00036 #include <cpl_wcs.h> 00037 00038 #include "kmo_debug.h" 00039 #include "kmo_utils.h" 00040 #include "kmo_dfs.h" 00041 #include "kmo_error.h" 00042 #include "kmo_priv_functions.h" 00043 #include "kmo_cpl_extensions.h" 00044 #include "kmo_constants.h" 00045 #include "kmo_priv_multi_reconstruct.h" 00046 #include "kmo_priv_reconstruct.h" 00047 00048 static int kmo_multi_reconstruct_create(cpl_plugin *); 00049 static int kmo_multi_reconstruct_exec(cpl_plugin *); 00050 static int kmo_multi_reconstruct_destroy(cpl_plugin *); 00051 static int kmo_multi_reconstruct(cpl_parameterlist *, cpl_frameset *); 00052 00053 static char kmo_multi_reconstruct_description[] = 00054 "This recipe shifts several exposures of an object and combines them. The diffe-\n" 00055 "rent methods to match the exposures are described below (--method parameter).\n" 00056 "The output cube is larger than the input cubes, according to the shifts to be\n" 00057 "applied. Additionally a border of NaN values is added. The WCS is the same as\n" 00058 "for the first exposure.\n" 00059 "For each spatial/spectral pixel a new value will be calculated (according the\n" 00060 "--cmethod parameter) and written into the output cube.\n" 00061 "Only exposures with equal orientation regarding the WCS can be combined (except\n" 00062 "-–method=”none”), north must point to the same direction. It is recommended to\n" 00063 "apply any rotation possibly after combining.\n" 00064 "The default mapping mode is done via the --name parameter, where the name of\n" 00065 "the object has to be provided. The recipe searches in all input data cubes IFUs\n" 00066 "pointing to that object.\n" 00067 "\n" 00068 "BASIC PARAMETERS:\n" 00069 "-----------------\n" 00070 "--name\n" 00071 "--ifus\n" 00072 "Since an object can be present only once per exposure and since it can be\n" 00073 "located in different IFUs for the existing exposures, there are two modes to\n" 00074 "identify the objects:\n" 00075 " * Combine by object names (default)\n" 00076 " In this case the object name must be provided via the --name parameter. The\n" 00077 " object name will be searched for in all primary headers of all provided frames\n" 00078 " in the keyword ESO OCS ARMx NAME.\n" 00079 "\n" 00080 " * Combine by index (advanced)\n" 00081 " In this case the --ifus parameter must be provided. The parameter must have\n" 00082 " the same number of entries as frames are provided, e.g. \"3;1;24\" for 3 expo-\n" 00083 " sures. The index doesn't reference the extension in the frame but the real\n" 00084 " index of the IFU as defined in the EXTNAME keyword (e.g. 'IFU.3.DATA').\n" 00085 "\n" 00086 "--imethod\n" 00087 "Method to use for interpolation.\n" 00088 "\n" 00089 "--method\n" 00090 "There are following sources to get the shift parameters from:\n" 00091 " * 'none' (default)\n" 00092 " The cubes are directly recombined, not shifting at all. The ouput frame will\n" 00093 " have the same dimensions as the input cubes.\n" 00094 " If the size differs a warning will be emitted and the cubes will be aligned\n" 00095 " to the lower left corner. If the orientation differs a warning will be emit-\n" 00096 " ted, but the cubes are combined anyway.\n" 00097 "\n" 00098 " * 'header'\n" 00099 " The shifts are calculated according to the WCS information stored in the\n" 00100 " header of every IFU. The output frame will get larger, except the object is\n" 00101 " at the exact same position for all exposures. The size of the exposures can\n" 00102 " differ, but the orientation must be the same for all exposures.\n" 00103 "\n" 00104 " * 'user'\n" 00105 " Read the shifts from a user specified file. The path of the file must be pro-\n" 00106 " vided using the --filename parameter. For every exposure (except the first one)\n" 00107 " two shift values are expected per line, they have to be separated with simple\n" 00108 " spaces. The values indicate pixel shifts and are referenced to the first\n" 00109 " frame. The 1st value is the shift in x-direction to the left, the 2nd the\n" 00110 " shift in y-direction upwards. The size of the exposures can differ, but the\n" 00111 " orientation must be the same for all exposures.\n" 00112 "\n" 00113 " * 'center'\n" 00114 " The shifts are calculated using a centering algorithm. The detector exposures\"" 00115 " will be reconstructed and the resulting data cubes will be collapsed to an image.\n" 00116 " A 2D profile of the image will be fitted to it to identify the centre. With \n" 00117 " the parameter --fmethod the function to fit can be provided. The size of the\n" 00118 " exposures can differ, but the orientation must be the same for all exposures.\n" 00119 "\n" 00120 "ADVANCED PARAMETERS\n" 00121 "-------------------\n" 00122 "--size\n" 00123 "Spatial size of the output cube.\n" 00124 "\n" 00125 "--suppress_extension\n" 00126 "If set to TRUE, the arbitrary filename extensions are supressed. If multiple\n" 00127 "products with the same category are produced, they will be numered consecutively\n" 00128 "starting from 0.\n" 00129 "\n" 00130 "--fmethod\n" 00131 "see --method='center'\n" 00132 "The type of function that should be fitted spatially to the collapsed image.\n" 00133 "This fit is used to create a mask to extract the spectrum of the object. Valid\n" 00134 "values are 'gauss' and 'moffat'.\n" 00135 "\n" 00136 "--filename\n" 00137 "see --method='user'\n" 00138 "\n" 00139 " Advanced reconstruction parameters\n" 00140 " ----------------------------------\n" 00141 "--pix_scale\n" 00142 "Change the pixel scale [arcsec]. Default of 0.2\" results into cubes of\n" 00143 "14x14pix, a scale of 0.1\" results into cubes of 28x28pix, etc.\n" 00144 "\n" 00145 "--neighborhoodRange\n" 00146 "Defines the range to search for neighbors during reconstruction\n" 00147 "\n" 00148 "--b_samples\n" 00149 "The number of samples in spectral direction for the reconstructed cube. Ideal-\n" 00150 "ly this number should be greater than 2048, the detector size.\n" 00151 "\n" 00152 "--b_start\n" 00153 "--b_end\n" 00154 "Used to define manually the start and end wavelength for the reconstructed\n" 00155 "cube. By default the internally defined values are used.\n" 00156 "\n" 00157 " Advanced combining parameters\n" 00158 " ----------------------------------\n" 00159 "--cmethod\n" 00160 "Following methods of frame combination are available:\n" 00161 " * 'ksigma' (Default)\n" 00162 " An iterative sigma clipping. For each position all pixels in the spectrum\n" 00163 " are examined. If they deviate significantly, they will be rejected according\n" 00164 " to the conditions:\n" 00165 " val > mean + stdev * cpos_rej\n" 00166 " and\n" 00167 " val < mean - stdev * cneg_rej\n" 00168 " where --cpos_rej, --cneg_rej and --citer are the corresponding configuration\n" 00169 " parameters. In the first iteration median and percentile level are used.\n" 00170 "\n" 00171 " * 'median'\n" 00172 " At each pixel position the median is calculated.\n" 00173 "\n" 00174 " * 'average'\n" 00175 " At each pixel position the average is calculated.\n" 00176 "\n" 00177 " * 'sum'\n" 00178 " At each pixel position the sum is calculated.\n" 00179 "\n" 00180 " * 'min_max'\n" 00181 " The specified number of minimum and maximum pixel values will be rejected.\n" 00182 " --cmax and --cmin apply to this method.\n" 00183 "\n" 00184 "--cpos_rej\n" 00185 "--cneg_rej\n" 00186 "--citer\n" 00187 "see --cmethod='ksigma'\n" 00188 "\n" 00189 "--cmax\n" 00190 "--cmin\n" 00191 "see --cmethod='min_max'\n" 00192 "\n" 00193 "-------------------------------------------------------------------------------\n" 00194 " Input files:\n" 00195 "\n" 00196 " DO DO KMOS \n" 00197 " category group Type Explanation Required #Frames\n" 00198 " -------- ----- ----- ----------- -------- -------\n" 00199 " SCIENCE RAW The science frames Y >=2 \n" 00200 " XCAL F2D x calibration frame Y 1 \n" 00201 " YCAL F2D y calibration frame Y 1 \n" 00202 " LCAL F2D Wavelength calib. frame Y 1 \n" 00203 " WAVE_BAND F2L Table with start-/end-wavelengths Y 1 \n" 00204 "\n" 00205 " Output files:\n" 00206 "\n" 00207 " DO KMOS\n" 00208 " category Type Explanation\n" 00209 " -------- ----- -----------\n" 00210 " CUBE_MULTI_<name/ifu> F3I Combined data cube\n" 00211 "-------------------------------------------------------------------------------\n" 00212 "\n"; 00213 00230 int cpl_plugin_get_info(cpl_pluginlist *list) 00231 { 00232 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00233 cpl_plugin *plugin = &recipe->interface; 00234 00235 cpl_plugin_init(plugin, 00236 CPL_PLUGIN_API, 00237 KMOS_BINARY_VERSION, 00238 CPL_PLUGIN_TYPE_RECIPE, 00239 "kmo_multi_reconstruct", 00240 "Reconstruct and combine cubes in one processing step", 00241 kmo_multi_reconstruct_description, 00242 "Alex Agudo Berbel", 00243 "kmos-spark@mpe.mpg.de", 00244 kmos_get_license(), 00245 kmo_multi_reconstruct_create, 00246 kmo_multi_reconstruct_exec, 00247 kmo_multi_reconstruct_destroy); 00248 00249 cpl_pluginlist_append(list, plugin); 00250 00251 return 0; 00252 } 00253 00261 static int kmo_multi_reconstruct_create(cpl_plugin *plugin) 00262 { 00263 cpl_recipe *recipe; 00264 cpl_parameter *p; 00265 00266 /* Check that the plugin is part of a valid recipe */ 00267 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00268 recipe = (cpl_recipe *)plugin; 00269 else 00270 return -1; 00271 00272 /* Create the parameters list in the cpl_recipe object */ 00273 recipe->parameters = cpl_parameterlist_new(); 00274 00275 /* Fill the parameters list */ 00276 00277 /* --imethod (interpolation method) */ 00278 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.imethod", 00279 CPL_TYPE_STRING, 00280 "Method to use for interpolation. " 00281 "[\"NN\" (nearest neighbour), " 00282 "\"lwNN\" (linear weighted nearest neighbor), " 00283 "\"swNN\" (square weighted nearest neighbor), " 00284 "\"MS\" (Modified Shepard's method)", 00285 "kmos.kmo_multi_reconstruct", 00286 "MS"); 00287 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "imethod"); 00288 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00289 cpl_parameterlist_append(recipe->parameters, p); 00290 00291 /* --method (shift method) */ 00292 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.method", 00293 CPL_TYPE_STRING, 00294 "The shifting method: " 00295 "'none': no shifting, combined directly " 00296 "(default), " 00297 "'header': shift according to WCS, " 00298 "'center': centering algorithm, " 00299 "'user': read shifts from file", 00300 "kmos.kmo_multi_reconstruct", 00301 "header"); 00302 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "method"); 00303 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00304 cpl_parameterlist_append(recipe->parameters, p); 00305 00306 /* --fmethod */ 00307 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.fmethod", 00308 CPL_TYPE_STRING, 00309 "The fitting method (applies only when " 00310 "method='center'): " 00311 "'gauss': fit a gauss function to collapsed " 00312 "image (default), " 00313 "'moffat': fit a moffat function to collapsed" 00314 " image", 00315 "kmos.kmo_combine", 00316 "gauss"); 00317 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fmethod"); 00318 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00319 cpl_parameterlist_append(recipe->parameters, p); 00320 00321 /* --name */ 00322 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.name", 00323 CPL_TYPE_STRING, 00324 "Name of the object to combine.", 00325 "kmos.kmo_multi_reconstruct", 00326 ""); 00327 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "name"); 00328 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00329 cpl_parameterlist_append(recipe->parameters, p); 00330 00331 /* --ifus */ 00332 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.ifus", 00333 CPL_TYPE_STRING, 00334 "The indices of the IFUs to combine. " 00335 "\"ifu1;ifu2;...\"", 00336 "kmos.kmo_multi_reconstruct", 00337 ""); 00338 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ifus"); 00339 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00340 cpl_parameterlist_append(recipe->parameters, p); 00341 00342 /* --pix_scale */ 00343 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.pix_scale", 00344 CPL_TYPE_DOUBLE, 00345 "Change the pixel scale [arcsec]. " 00346 "Default of 0.2\" results into cubes of 14x14pix, " 00347 "a scale of 0.1\" results into cubes of 28x28pix, " 00348 "etc.", 00349 "kmos.kmo_multi_reconstruct", 00350 KMOS_PIX_RESOLUTION); 00351 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "pix_scale"); 00352 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00353 cpl_parameterlist_append(recipe->parameters, p); 00354 00355 /* --suppress_extension */ 00356 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.suppress_extension", 00357 CPL_TYPE_BOOL, 00358 "Suppress arbitrary filename extension." 00359 "(TRUE (apply) or FALSE (don't apply)", 00360 "kmos.kmo_multi_reconstruct", 00361 FALSE); 00362 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "suppress_extension"); 00363 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00364 cpl_parameterlist_append(recipe->parameters, p); 00365 00366 /* --neighborhoodRange */ 00367 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.neighborhoodRange", 00368 CPL_TYPE_DOUBLE, 00369 "Defines the range to search for neighbors. " 00370 "in pixels", 00371 "kmos.kmo_multi_reconstruct", 00372 1.001); 00373 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "neighborhoodRange"); 00374 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00375 cpl_parameterlist_append(recipe->parameters, p); 00376 00377 /* --filename */ 00378 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.filename", 00379 CPL_TYPE_STRING, 00380 "The path to the file with the shift vectors." 00381 "(Applies only to method='user')", 00382 "kmos.kmo_multi_reconstruct", 00383 ""); 00384 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "filename"); 00385 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00386 cpl_parameterlist_append(recipe->parameters, p); 00387 00388 /* --dev_cal */ 00389 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.dev_cal", 00390 CPL_TYPE_BOOL, 00391 "Development only: If calibration data is to be " 00392 "reconstructed the ALPHA/DELTA keywords are " 00393 "missing. Setting this parameter to TRUE prevents " 00394 "according data check", 00395 "kmos.kmo_multi_reconstruct", 00396 FALSE); 00397 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dev_cal"); 00398 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00399 cpl_parameterlist_append(recipe->parameters, p); 00400 00401 /* --size */ 00402 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.size", 00403 CPL_TYPE_STRING, 00404 "Spatial size of the output cube.", 00405 "kmos.kmo_multi_reconstruct", 00406 "max"); 00407 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "size"); 00408 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00409 cpl_parameterlist_append(recipe->parameters, p); 00410 00411 // add parameters for band-definition 00412 kmo_band_pars_create(recipe->parameters, 00413 "kmos.kmo_multi_reconstruct"); 00414 00415 return kmo_combine_pars_create(recipe->parameters, 00416 "kmos.kmo_multi_reconstruct", 00417 DEF_REJ_METHOD, 00418 FALSE); 00419 } 00420 00426 static int kmo_multi_reconstruct_exec(cpl_plugin *plugin) 00427 { 00428 cpl_recipe *recipe; 00429 00430 /* Get the recipe out of the plugin */ 00431 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00432 recipe = (cpl_recipe *)plugin; 00433 else return -1 ; 00434 00435 return kmo_multi_reconstruct(recipe->parameters, recipe->frames); 00436 } 00437 00443 static int kmo_multi_reconstruct_destroy(cpl_plugin *plugin) 00444 { 00445 cpl_recipe *recipe; 00446 00447 /* Get the recipe out of the plugin */ 00448 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00449 recipe = (cpl_recipe *)plugin; 00450 else return -1 ; 00451 00452 cpl_parameterlist_delete(recipe->parameters); 00453 return 0 ; 00454 } 00455 00470 static int kmo_multi_reconstruct(cpl_parameterlist *parlist, cpl_frameset *frameset) 00471 { 00472 const char *method = NULL, 00473 *cmethod = NULL, 00474 *fmethod = NULL, 00475 *imethod = NULL, 00476 *filename = NULL, 00477 *ifus_txt = NULL, 00478 *name = NULL, 00479 *size = NULL, 00480 *filter_id = NULL; 00481 char *tmp_str = NULL, 00482 *filename_output_cube = NULL, 00483 *extname = NULL, 00484 *keyword = NULL, 00485 *suffix = NULL, 00486 *tmp_ocs = NULL, 00487 **exposure_filename = NULL, 00488 **exposure_objectname = NULL; 00489 int ret_val = 0, 00490 device_nr = 0, 00491 citer = 0, 00492 cmin = 0, 00493 cmax = 0, 00494 nr_alloc = 0, 00495 suppress_extension = FALSE, 00496 i = 0, 00497 *exposure_ifus = NULL, 00498 nr_science_frames = 0, 00499 dev_cal = 0; 00500 double neighborhoodRange = 1.001, 00501 cpos_rej = 0.0, 00502 cneg_rej = 0.0, 00503 pix_scale = 0.0, 00504 *xshifts = NULL, 00505 *yshifts = NULL, 00506 cd1_1 = 0.0, 00507 cd1_2 = 0.0, 00508 ang1 = 0.0, 00509 ang2 = 0.0, 00510 exposure_rotangle = 0.0, 00511 rotangle_found = 0.0; 00512 cpl_imagelist **data_cube_list = NULL, 00513 **noise_cube_list = NULL, 00514 *cube_combined_data = NULL, 00515 *cube_combined_noise = NULL; 00516 cpl_vector *ifus = NULL; 00517 cpl_propertylist *pl = NULL, 00518 *main_header = NULL, 00519 *ref_main_header = NULL, 00520 *ref_sub_header = NULL, 00521 *tmp_header = NULL, 00522 **header_data = NULL, 00523 **data_header_list = NULL, 00524 **noise_header_list = NULL; 00525 cpl_frame *frame = NULL, 00526 *lcal_frame = NULL, 00527 **empty_frames = NULL, 00528 *tmp_frame = NULL, 00529 *ref_frame = NULL; 00530 cpl_table *band_table = NULL; 00531 cpl_image *lcalImg = NULL; 00532 cpl_frameset *exposures = NULL; 00533 main_fits_desc desc; 00534 gridDefinition gd; 00535 00536 KMO_TRY 00537 { 00538 // 00539 // check frameset 00540 // 00541 KMO_TRY_ASSURE((parlist != NULL) && 00542 (frameset != NULL), 00543 CPL_ERROR_NULL_INPUT, 00544 "Not all input data is provided!"); 00545 00546 KMO_TRY_ASSURE(! ((cpl_frameset_count_tags(frameset, XCAL) == 0) && 00547 (cpl_frameset_count_tags(frameset, YCAL) == 0) && 00548 (cpl_frameset_count_tags(frameset, LCAL) == 0) && 00549 (cpl_frameset_count_tags(frameset, WAVE_BAND) == 0)), 00550 CPL_ERROR_FILE_NOT_FOUND, 00551 "XCAL, YCAL, LCAL or WAVE_BAND frames missing in " 00552 "frameset!!"); 00553 00554 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, XCAL) == 1, 00555 CPL_ERROR_FILE_NOT_FOUND, 00556 "Exactly one XCAL frame is expected in frameset!"); 00557 00558 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, YCAL) == 1, 00559 CPL_ERROR_FILE_NOT_FOUND, 00560 "Exactly one YCAL frame is expected in frameset!"); 00561 00562 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, LCAL) == 1, 00563 CPL_ERROR_FILE_NOT_FOUND, 00564 "Exactly one LCAL frame is expected in frameset!"); 00565 00566 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, WAVE_BAND) == 1, 00567 CPL_ERROR_FILE_NOT_FOUND, 00568 "Exactly one WAVE_BAND frame is expected in frameset!"); 00569 00570 // assert that at least two SCIENCE frames are available and create 00571 // intermediate frameset just with these science frames 00572 nr_science_frames = cpl_frameset_count_tags(frameset, SCIENCE); 00573 KMO_TRY_CHECK_ERROR_STATE(); 00574 00575 KMO_TRY_ASSURE(nr_science_frames > 1, 00576 CPL_ERROR_ILLEGAL_INPUT, 00577 "At least two SCIENCE frames must be provided to combine!"); 00578 00579 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_multi_reconstruct") == 1, 00580 CPL_ERROR_ILLEGAL_INPUT, 00581 "Cannot identify RAW and CALIB frames!"); 00582 00583 KMO_TRY_EXIT_IF_NULL( 00584 exposures = cpl_frameset_new()); 00585 KMO_TRY_EXIT_IF_NULL( 00586 tmp_frame = kmo_dfs_get_frame(frameset, SCIENCE)); 00587 00588 for (i = 0; i < nr_science_frames; i++) { 00589 KMO_TRY_EXIT_IF_ERROR( 00590 cpl_frameset_insert(exposures, cpl_frame_duplicate(tmp_frame))); 00591 KMO_TRY_CHECK_ERROR_STATE(); 00592 00593 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 00594 } 00595 00596 cpl_msg_info("", "--- Parameter setup for kmo_multi_reconstruct -------"); 00597 00598 KMO_TRY_EXIT_IF_NULL( 00599 imethod = kmo_dfs_get_parameter_string(parlist, 00600 "kmos.kmo_multi_reconstruct.imethod")); 00601 00602 KMO_TRY_ASSURE((strcmp(imethod, "NN") == 0) || 00603 (strcmp(imethod, "lwNN") == 0) || 00604 (strcmp(imethod, "swNN") == 0) || 00605 (strcmp(imethod, "MS") == 0), 00606 CPL_ERROR_ILLEGAL_INPUT, 00607 "imethod must be either \"NN\", \"lwNN\", " 00608 "\"swNN\" or \"MS\"!"); 00609 00610 KMO_TRY_EXIT_IF_ERROR( 00611 kmo_dfs_print_parameter_help(parlist, 00612 "kmos.kmo_multi_reconstruct.imethod")); 00613 00614 pix_scale = kmo_dfs_get_parameter_double(parlist, 00615 "kmos.kmo_multi_reconstruct.pix_scale"); 00616 KMO_TRY_CHECK_ERROR_STATE(); 00617 KMO_TRY_EXIT_IF_ERROR( 00618 kmo_dfs_print_parameter_help(parlist, 00619 "kmos.kmo_multi_reconstruct.pix_scale")); 00620 KMO_TRY_ASSURE((pix_scale >= 0.01) && 00621 (pix_scale <= 0.4), 00622 CPL_ERROR_ILLEGAL_INPUT, 00623 "pix_scale must be between 0.01 and 0.4 (results in cubes " 00624 "with 7x7 to 280x280 pixels)!"); 00625 00626 neighborhoodRange = kmo_dfs_get_parameter_double(parlist, 00627 "kmos.kmo_multi_reconstruct.neighborhoodRange"); 00628 KMO_TRY_CHECK_ERROR_STATE(); 00629 00630 KMO_TRY_ASSURE(neighborhoodRange > 0.0, 00631 CPL_ERROR_ILLEGAL_INPUT, 00632 "neighborhoodRange must be greater than 0.0"); 00633 00634 KMO_TRY_EXIT_IF_ERROR( 00635 kmo_dfs_print_parameter_help(parlist, 00636 "kmos.kmo_multi_reconstruct.neighborhoodRange")); 00637 00638 KMO_TRY_EXIT_IF_NULL( 00639 size = kmo_dfs_get_parameter_string(parlist, 00640 "kmos.kmo_multi_reconstruct.size")); 00641 00642 KMO_TRY_EXIT_IF_NULL( 00643 method = kmo_dfs_get_parameter_string(parlist, 00644 "kmos.kmo_multi_reconstruct.method")); 00645 00646 KMO_TRY_EXIT_IF_NULL( 00647 fmethod = kmo_dfs_get_parameter_string(parlist, 00648 "kmos.kmo_multi_reconstruct.fmethod")); 00649 00650 KMO_TRY_ASSURE((strcmp(size, "max") == 0) || 00651 (strcmp(size, "std") == 0), 00652 CPL_ERROR_ILLEGAL_INPUT, 00653 "Following output cube size specifications are available: " 00654 "'std' or 'max'"); 00655 00656 00657 KMO_TRY_ASSURE((strcmp(method, "none") == 0) || 00658 (strcmp(method, "header") == 0) || 00659 (strcmp(method, "center") == 0) || 00660 (strcmp(method, "user") == 0), 00661 CPL_ERROR_ILLEGAL_INPUT, 00662 "Following shift methods are available : 'none', " 00663 "'header', 'center' or 'user'"); 00664 00665 if (strcmp(method, "user") == 0) { 00666 filename = kmo_dfs_get_parameter_string(parlist, 00667 "kmos.kmo_multi_reconstruct.filename"); 00668 KMO_TRY_CHECK_ERROR_STATE(); 00669 00670 KMO_TRY_ASSURE(strcmp(filename, "") != 0, 00671 CPL_ERROR_ILLEGAL_INPUT, 00672 "path of file with shift information must be " 00673 "provided!"); 00674 00675 KMO_TRY_EXIT_IF_ERROR( 00676 kmo_dfs_print_parameter_help(parlist, 00677 "kmos.kmo_multi_reconstruct.filename")); 00678 } 00679 00680 KMO_TRY_EXIT_IF_ERROR( 00681 kmo_dfs_print_parameter_help(parlist, 00682 "kmos.kmo_multi_reconstruct.method")); 00683 00684 ifus_txt = kmo_dfs_get_parameter_string(parlist, 00685 "kmos.kmo_multi_reconstruct.ifus"); 00686 KMO_TRY_CHECK_ERROR_STATE(); 00687 00688 name = kmo_dfs_get_parameter_string(parlist, 00689 "kmos.kmo_multi_reconstruct.name"); 00690 KMO_TRY_CHECK_ERROR_STATE(); 00691 00692 if (strcmp(ifus_txt, "") != 0) { 00693 KMO_TRY_ASSURE(strcmp(name, "") == 0, 00694 CPL_ERROR_ILLEGAL_INPUT, 00695 "name parameter must be NULL if IFU indices are " 00696 "provided!"); 00697 00698 KMO_TRY_EXIT_IF_NULL( 00699 ifus = kmo_identify_values(ifus_txt)); 00700 00701 KMO_TRY_ASSURE(cpl_vector_get_size(ifus) == nr_science_frames, 00702 CPL_ERROR_ILLEGAL_INPUT, 00703 "ifus parameter must have the same number of values " 00704 "than frames provided ) (%lld!=%d)", 00705 cpl_vector_get_size(ifus), nr_science_frames); 00706 00707 for (i = 0; i < nr_science_frames; i++) { 00708 KMO_TRY_ASSURE((cpl_vector_get(ifus, i) > 0.5 && 00709 cpl_vector_get(ifus, i) < 24.5 ), 00710 CPL_ERROR_ILLEGAL_INPUT, 00711 "IFU numbers must be in the range 1..24"); 00712 } 00713 } 00714 00715 if (strcmp(name, "") != 0) { 00716 KMO_TRY_ASSURE(strcmp(ifus_txt, "") == 0, 00717 CPL_ERROR_ILLEGAL_INPUT, 00718 "ifus parameter must be NULL if name is provided!"); 00719 } 00720 00721 KMO_TRY_ASSURE((strcmp(name, "") != 0) || (strcmp(ifus_txt, "") != 0), 00722 CPL_ERROR_ILLEGAL_INPUT, 00723 "Either the name of the object or the numbers of the " 00724 "IFUs to combine must be provided (--name or --ifus " 00725 "parameters)"); 00726 00727 KMO_TRY_EXIT_IF_ERROR( 00728 kmo_dfs_print_parameter_help(parlist, 00729 "kmos.kmo_multi_reconstruct.ifus")); 00730 00731 KMO_TRY_EXIT_IF_ERROR( 00732 kmo_dfs_print_parameter_help(parlist, 00733 "kmos.kmo_multi_reconstruct.name")); 00734 00735 00736 suppress_extension = kmo_dfs_get_parameter_bool(parlist, 00737 "kmos.kmo_multi_reconstruct.suppress_extension"); 00738 KMO_TRY_CHECK_ERROR_STATE(); 00739 KMO_TRY_EXIT_IF_ERROR( 00740 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_multi_reconstruct.suppress_extension")); 00741 00742 KMO_TRY_ASSURE((suppress_extension == TRUE) || (suppress_extension == FALSE), 00743 CPL_ERROR_ILLEGAL_INPUT, 00744 "suppress_extension must be TRUE or FALSE!"); 00745 00746 dev_cal = kmo_dfs_get_parameter_bool(parlist, 00747 "kmos.kmo_multi_reconstruct.dev_cal"); 00748 KMO_TRY_CHECK_ERROR_STATE(); 00749 KMO_TRY_EXIT_IF_ERROR( 00750 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_multi_reconstruct.dev_cal")); 00751 00752 KMO_TRY_ASSURE((dev_cal == TRUE) || (dev_cal == FALSE), 00753 CPL_ERROR_ILLEGAL_INPUT, 00754 "dev_cal must be TRUE or FALSE!"); 00755 00756 KMO_TRY_EXIT_IF_ERROR( 00757 kmo_combine_pars_load(parlist, 00758 "kmos.kmo_multi_reconstruct", 00759 &cmethod, 00760 &cpos_rej, 00761 &cneg_rej, 00762 &citer, 00763 &cmin, 00764 &cmax, 00765 FALSE)); 00766 00767 kmo_band_pars_load(parlist, "kmos.kmo_multi_reconstruct"); 00768 00769 cpl_msg_info("", "-------------------------------------------"); 00770 00771 KMO_TRY_EXIT_IF_NULL( 00772 tmp_frame = kmo_dfs_get_frame(frameset, SCIENCE)); 00773 00774 KMO_TRY_EXIT_IF_NULL( 00775 suffix = kmo_dfs_get_suffix(tmp_frame, TRUE, FALSE)); 00776 00777 KMO_TRY_EXIT_IF_ERROR( 00778 kmo_check_frame_setup_md5_xycal(frameset)); 00779 KMO_TRY_EXIT_IF_ERROR( 00780 kmo_check_frame_setup_md5(frameset)); 00781 00782 cpl_msg_info("", "Detected instrument setup: %s", suffix+1); 00783 cpl_msg_info("", "(grating 1, 2 & 3)"); 00784 cpl_msg_info("", "-------------------------------------------"); 00785 00786 // assure that filters and grating match for 00787 // XCAL, YCAL, LCAL and for data frames to reconstruct 00788 KMO_TRY_EXIT_IF_ERROR( 00789 kmo_check_frameset_setup(frameset, XCAL, TRUE, FALSE, FALSE)); 00790 KMO_TRY_EXIT_IF_ERROR( 00791 kmo_check_frameset_setup(frameset, YCAL, TRUE, FALSE, FALSE)); 00792 KMO_TRY_EXIT_IF_ERROR( 00793 kmo_check_frameset_setup(frameset, LCAL, TRUE, FALSE, FALSE)); 00794 KMO_TRY_EXIT_IF_ERROR( 00795 kmo_check_frame_setup(frameset, XCAL, YCAL, TRUE, FALSE, TRUE)); 00796 KMO_TRY_EXIT_IF_ERROR( 00797 kmo_check_frame_setup(frameset, XCAL, LCAL, TRUE, FALSE, TRUE)); 00798 KMO_TRY_EXIT_IF_ERROR( 00799 kmo_check_frameset_setup(frameset, SCIENCE, TRUE, FALSE, FALSE)); 00800 KMO_TRY_EXIT_IF_ERROR( 00801 kmo_check_frame_setup(frameset, XCAL, SCIENCE, TRUE, FALSE, TRUE)); 00802 KMO_TRY_EXIT_IF_ERROR( 00803 kmo_check_frame_setup_md5_xycal(frameset)); 00804 KMO_TRY_EXIT_IF_ERROR( 00805 kmo_check_frame_setup_md5(frameset)); 00806 00807 // KMO_TRY_EXIT_IF_ERROR( 00808 // kmo_check_cal_frames_rotangle(frameset, XCAL, YCAL)); 00809 // KMO_TRY_EXIT_IF_ERROR( 00810 // kmo_check_cal_frames_rotangle(frameset, XCAL, LCAL)); 00811 00812 nr_alloc = nr_science_frames; 00813 KMO_TRY_EXIT_IF_NULL( 00814 exposure_filename = cpl_malloc(nr_alloc * sizeof(char *))); 00815 KMO_TRY_EXIT_IF_NULL( 00816 exposure_objectname = cpl_malloc(nr_alloc * sizeof(char *))); 00817 KMO_TRY_EXIT_IF_NULL( 00818 exposure_ifus = cpl_malloc(nr_alloc * sizeof(int))); 00819 00820 // check exposure frames 00821 for (i = 0; i < nr_science_frames; i++) { 00822 KMO_TRY_EXIT_IF_NULL( 00823 tmp_str = cpl_sprintf("%d", i)); 00824 00825 KMO_TRY_EXIT_IF_NULL( 00826 frame = kmo_dfs_get_frame(exposures, tmp_str)); 00827 cpl_free(tmp_str); 00828 00829 KMO_TRY_EXIT_IF_NULL( 00830 exposure_filename[i] = (char*)cpl_frame_get_filename(frame)); 00831 00832 kmo_init_fits_desc(&desc); 00833 00834 desc = kmo_identify_fits_header(exposure_filename[i]); 00835 KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to " 00836 "be in KMOS-format!"); 00837 00838 KMO_TRY_ASSURE(((desc.nr_ext == KMOS_NR_DETECTORS) || 00839 ((desc.nr_ext == 2*KMOS_NR_DETECTORS))) && 00840 (desc.ex_badpix == FALSE) && 00841 ((desc.fits_type == raw_fits) || 00842 (desc.fits_type == f2d_fits)) && 00843 (desc.frame_type == detector_frame), 00844 CPL_ERROR_ILLEGAL_INPUT, 00845 "The frame to reconstruct isn't in the correct " 00846 "format!!!"); 00847 kmo_free_fits_desc(&desc); 00848 } 00849 00850 // select IFU for each exposure 00851 KMO_TRY_EXIT_IF_NULL( 00852 empty_frames = cpl_malloc(nr_alloc * sizeof(cpl_frame *))); 00853 int found=0; 00854 for (i = 0; i < nr_science_frames; i++) { 00855 empty_frames[i] = NULL; 00856 if (strcmp(ifus_txt, "") != 0) { //IFU selected by user given list 00857 found = 1; 00858 // const char *tmpString; 00859 exposure_ifus[i] = (int) (cpl_vector_get(ifus, i) + 0.1); 00860 KMO_TRY_EXIT_IF_NULL( 00861 pl = kmclipm_propertylist_load(exposure_filename[i], 0)); 00862 KMO_TRY_EXIT_IF_NULL( 00863 tmp_ocs = cpl_sprintf("%s%d%s", IFU_NAME_PREFIX, 00864 exposure_ifus[i], IFU_NAME_POSTFIX)); 00865 if (cpl_propertylist_has(pl, tmp_ocs)) { 00866 tmp_str = (char*)cpl_propertylist_get_string(pl, tmp_ocs); 00867 } else { 00868 tmp_str = ""; 00869 } 00870 KMO_TRY_EXIT_IF_NULL( 00871 exposure_objectname[i] = cpl_sprintf("%s", tmp_str)); 00872 cpl_free(tmp_ocs); 00873 cpl_propertylist_delete(pl); pl = NULL; 00874 } else { //IFU selected by user given object name 00875 exposure_objectname[i] = (char*)name; 00876 KMO_TRY_EXIT_IF_NULL( 00877 tmp_str = cpl_sprintf("%d", i)); 00878 00879 KMO_TRY_EXIT_IF_NULL( 00880 frame = kmo_dfs_get_frame(exposures, tmp_str)); 00881 cpl_free(tmp_str); 00882 00883 KMO_TRY_CHECK_ERROR_STATE(); 00884 int this_ifu = kmo_get_index_from_ocs_name(frame, name); 00885 KMO_TRY_CHECK_ERROR_STATE(); 00886 if (this_ifu > 0) { 00887 found = 1; 00888 exposure_ifus[i] = this_ifu; 00889 } else { 00890 empty_frames[i] = frame; 00891 exposure_ifus[i] = -1; 00892 cpl_msg_warning("", 00893 "Could not find any IFU with an object " 00894 "named '%s' in file %s", 00895 name, exposure_filename[i]); 00896 } 00897 } 00898 KMO_TRY_CHECK_ERROR_STATE(); 00899 } 00900 if (! found) { 00901 cpl_msg_error("", 00902 "Could not find any IFU with an object named '%s' in " 00903 "any input file", name); 00904 KMO_TRY_EXIT_WITH_ERROR(CPL_ERROR_ILLEGAL_INPUT); 00905 } 00906 int j = 0; 00907 for (i = 0; i < nr_alloc; i++) { 00908 if (empty_frames[i] != NULL) { 00909 KMO_TRY_EXIT_IF_ERROR( 00910 cpl_frameset_erase_frame(exposures, empty_frames[i])); 00911 nr_science_frames--; 00912 exposure_ifus[j] = exposure_ifus[i]; 00913 } else { 00914 exposure_ifus[j] = exposure_ifus[i]; 00915 j++; 00916 } 00917 } 00918 for (i = 0; i < nr_science_frames; i++) { 00919 KMO_TRY_EXIT_IF_NULL( 00920 tmp_str = cpl_sprintf("%d", i)); 00921 00922 KMO_TRY_EXIT_IF_NULL( 00923 frame = kmo_dfs_get_frame(exposures, tmp_str)); 00924 cpl_free(tmp_str); 00925 00926 KMO_TRY_EXIT_IF_NULL( 00927 exposure_filename[i] = (char*)cpl_frame_get_filename(frame)); 00928 } 00929 00930 cpl_free(empty_frames); empty_frames = NULL; 00931 00932 // get reference header, subheader and set grid definition 00933 device_nr = ((exposure_ifus[0] -1) / KMOS_IFUS_PER_DETECTOR) + 1; 00934 00935 KMO_TRY_EXIT_IF_NULL( 00936 ref_main_header = kmclipm_propertylist_load(exposure_filename[0],0)); 00937 KMO_TRY_EXIT_IF_NULL( 00938 ref_frame = cpl_frameset_get_first(exposures)); 00939 KMO_TRY_EXIT_IF_NULL( 00940 ref_sub_header = kmclipm_propertylist_load(exposure_filename[0], 00941 device_nr)); 00942 KMO_TRY_EXIT_IF_ERROR( 00943 kmclipm_setup_grid(&gd, imethod, neighborhoodRange, pix_scale)); 00944 00945 exposure_rotangle = kmo_mr_get_rot_angle(kmo_dfs_get_frame(exposures, "0")); 00946 00947 KMO_TRY_EXIT_IF_NULL( 00948 lcal_frame = kmo_dfs_get_frame(frameset, LCAL)); 00949 00950 KMO_TRY_EXIT_IF_NULL( 00951 lcalImg = kmo_dfs_load_cal_image_frame(lcal_frame, 00952 1, 0, exposure_rotangle, 00953 FALSE, NULL, 00954 &rotangle_found, -1, 0, 0)); 00955 00956 KMO_TRY_EXIT_IF_NULL( 00957 tmp_header = kmo_dfs_load_primary_header(frameset, LCAL)); 00958 00959 KMO_TRY_EXIT_IF_NULL( 00960 keyword = cpl_sprintf("%s%d%s", IFU_FILTID_PREFIX, device_nr, 00961 IFU_FILTID_POSTFIX)); 00962 KMO_TRY_EXIT_IF_NULL( 00963 filter_id = cpl_propertylist_get_string(tmp_header, keyword)); 00964 00965 int band_method = 0; 00966 KMO_TRY_EXIT_IF_NULL( 00967 band_table = kmo_dfs_load_table(frameset, WAVE_BAND, 1, 0)); 00968 00969 KMO_TRY_EXIT_IF_ERROR( 00970 kmclipm_setup_grid_band_lcal(&gd, lcalImg, filter_id, 00971 band_method, band_table)); 00972 cpl_image_delete(lcalImg); lcalImg = NULL; 00973 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00974 cpl_free(keyword); keyword = NULL; 00975 cpl_table_delete(band_table); band_table = NULL; 00976 00977 //extract sub-headers for each exposures, calculate WCS 00978 KMO_TRY_EXIT_IF_NULL( 00979 header_data = cpl_malloc(nr_science_frames*sizeof(cpl_propertylist*))); 00980 for (i = 0; i < nr_science_frames; i++) { 00981 device_nr = ((exposure_ifus[0] -1) / KMOS_IFUS_PER_DETECTOR) + 1; 00982 KMO_TRY_EXIT_IF_NULL( 00983 header_data[i] = kmclipm_propertylist_load(exposure_filename[i], 00984 device_nr)); 00985 KMO_TRY_EXIT_IF_ERROR( 00986 kmclipm_update_property_int(header_data[i],"NAXIS", 3,"")); 00987 KMO_TRY_EXIT_IF_ERROR( 00988 kmclipm_update_property_int(header_data[i],"NAXIS1",gd.x.dim,"")); 00989 KMO_TRY_EXIT_IF_ERROR( 00990 kmclipm_update_property_int(header_data[i],"NAXIS2",gd.y.dim,"")); 00991 KMO_TRY_EXIT_IF_ERROR( 00992 kmclipm_update_property_int(header_data[i],"NAXIS3",gd.l.dim,"")); 00993 cpl_propertylist *tmpHeader; 00994 KMO_TRY_EXIT_IF_NULL( 00995 tmpHeader = kmclipm_propertylist_load(exposure_filename[i],0)); 00996 KMO_TRY_EXIT_IF_ERROR( 00997 kmo_calc_wcs_gd(tmpHeader, header_data[i], exposure_ifus[i], gd)); 00998 cpl_propertylist_delete(tmpHeader); 00999 } 01000 01001 // check rotation angle 01002 if (dev_cal == FALSE) { 01003 cd1_1 = kmo_dfs_get_property_double(header_data[0], CD1_1); 01004 cd1_2 = kmo_dfs_get_property_double(header_data[0], CD1_2); 01005 KMO_TRY_CHECK_ERROR_STATE(); 01006 ang1 = atan(cd1_2/cd1_1)*180/CPL_MATH_PI; 01007 for (i = 1; i < nr_science_frames; i++) { 01008 cd1_1 = kmo_dfs_get_property_double(header_data[i], CD1_1); 01009 cd1_2 = kmo_dfs_get_property_double(header_data[i], CD1_2); 01010 KMO_TRY_CHECK_ERROR_STATE(); 01011 ang2 = atan(cd1_2/cd1_1)*180/CPL_MATH_PI; 01012 01013 if (strcmp(method, "none") != 0) { 01014 // center, header, user 01015 KMO_TRY_ASSURE(fabs(ang1-ang2) <= 0.5, 01016 CPL_ERROR_ILLEGAL_INPUT, 01017 "Orientation of cube 1 (%gdeg) and cube %d " 01018 "(%gdeg) differ! " 01019 "Align the orientation of this cube with " 01020 "kmo_rotate before applying this recipe.", 01021 ang1, i+1, ang2); 01022 } else { 01023 // none 01024 if (fabs(ang1-ang2) > 0.5) { 01025 cpl_msg_warning("", 01026 "Orientation of cube 1 (%gdeg) and cube %d " 01027 "(%gdeg) differ! Processing anyway.", 01028 ang1, i+1, ang2); 01029 } 01030 } 01031 } 01032 } 01033 01034 // set x/y shifts 01035 KMO_TRY_EXIT_IF_NULL( 01036 xshifts = cpl_malloc(nr_science_frames * sizeof(double))); 01037 KMO_TRY_EXIT_IF_NULL( 01038 yshifts = cpl_malloc(nr_science_frames * sizeof(double))); 01039 KMO_TRY_EXIT_IF_ERROR( 01040 kmo_mr_get_offsets(nr_science_frames, method, imethod, neighborhoodRange, 01041 filename, frameset, exposures, exposure_ifus, 01042 (const cpl_propertylist**)header_data, 01043 fmethod, 01044 cmethod, 01045 cpos_rej, 01046 cneg_rej, 01047 citer, 01048 cmin, 01049 cmax, 01050 pix_scale, 01051 xshifts, yshifts)); 01052 01053 for (i = 0; i < nr_science_frames; i++) { 01054 printf("exposure %d: filename %s, selected IFU %d, object name " 01055 "\"%s\", xshift %f, yshift %f\n", i, exposure_filename[i], 01056 exposure_ifus[i], exposure_objectname[i], xshifts[i], yshifts[i]); 01057 } 01058 01059 // 01060 // set spatial part of the grid 01061 // 01062 // size = "max"; 01063 if (strcmp(size, "max") == 0) { 01064 double xmin=0, xmax=0, ymin=0, ymax=0; 01065 double gxshift, gyshift, gxdim, gydim; 01066 double pixel_resolution = pix_scale; 01067 int xdim, ydim; 01068 01069 for (i = 0; i < nr_science_frames; i++) { 01070 if (xmin > xshifts[i]) { xmin = xshifts[i]; } 01071 if (xmax < xshifts[i]) { xmax = xshifts[i]; } 01072 if (ymin > yshifts[i]) { ymin = yshifts[i]; } 01073 if (ymax < yshifts[i]) { ymax = yshifts[i]; } 01074 } 01075 if (xmax > 0.0001) { 01076 gxshift = - ceil(xmax); 01077 } else { 01078 gxshift = 0.; 01079 } 01080 if (ymin < -0.0001) { 01081 gyshift = floor(ymin); 01082 } else { 01083 gyshift = 0.; 01084 } 01085 if (xmin < -0.0001) { 01086 gxdim = - floor(xmin); 01087 } else { 01088 gxdim = 0.; 01089 } 01090 if (ymax > 0.0001) { 01091 gydim = ceil(ymax); 01092 } else { 01093 gydim = 0.; 01094 } 01095 01096 xdim = (int) (gxdim - gxshift + .5); 01097 ydim = (int) (gydim - gyshift + .5); 01098 gd.x.start += gxshift * pixel_resolution; 01099 gd.y.start += gyshift * pixel_resolution; 01100 gd.x.dim += xdim; 01101 gd.y.dim += ydim; 01102 // printf("X: %f < %f Y: %f < %f \n",xmin,xmax,ymin,ymax); 01103 // printf("gxshift: %f gxdim: %f xdim: %d gyshift: %f gydim: %f ydim: %d \n", 01104 // gxshift, gxdim, xdim, gyshift, gydim, ydim); 01105 // printf("GD: %f %d %f %d\n", gd.x.start, gd.x.dim, gd.y.start, gd.y.dim); 01106 } 01107 01108 // 01109 // reconstruct multiple detector images 01110 // 01111 01112 // printf("GD: %f %f %d %f %f %d %f %f %d\n", 01113 // gd.x.start, gd.x.delta, gd.x.dim, 01114 // gd.y.start, gd.y.delta, gd.y.dim, 01115 // gd.l.start, gd.l.delta, gd.l.dim); 01116 01117 KMO_TRY_EXIT_IF_ERROR( 01118 kmo_priv_multi_reconstruct(frameset, 01119 exposures, 01120 exposure_ifus, 01121 xshifts, 01122 yshifts, 01123 gd, 01124 &cube_combined_data, 01125 &cube_combined_noise, 01126 pix_scale)); 01127 01128 if (!suppress_extension) { 01129 // setup output category COMBINE + ESO PRO CATG 01130 if (strcmp(ifus_txt, "") != 0) { //IFU selected by user given list 01131 KMO_TRY_EXIT_IF_NULL( 01132 tmp_str = cpl_sprintf("IFU")); 01133 } else { 01134 KMO_TRY_EXIT_IF_NULL( 01135 tmp_str = cpl_sprintf("%s", name)); 01136 } 01137 01138 KMO_TRY_EXIT_IF_NULL( 01139 filename_output_cube = cpl_sprintf("%s_%s", CUBE_MULTI, tmp_str)); 01140 cpl_free(tmp_str); tmp_str = NULL; 01141 } else { 01142 KMO_TRY_EXIT_IF_NULL( 01143 filename_output_cube = cpl_sprintf("%s", CUBE_MULTI)); 01144 } 01145 01146 KMO_TRY_EXIT_IF_ERROR( 01147 kmo_dfs_save_main_header(frameset, filename_output_cube, "", 01148 ref_frame, NULL, parlist, cpl_func)); 01149 // save output 01150 KMO_TRY_EXIT_IF_NULL( 01151 extname = kmo_extname_creator(ifu_frame, exposure_ifus[0], 01152 EXT_DATA)); 01153 01154 // calculate WCS 01155 KMO_TRY_EXIT_IF_ERROR( 01156 kmo_calc_wcs_gd(ref_main_header, ref_sub_header, exposure_ifus[0], gd)); 01157 01158 KMO_TRY_EXIT_IF_ERROR( 01159 kmclipm_update_property_string(ref_sub_header, 01160 EXTNAME, 01161 extname, 01162 "FITS extension name")); 01163 cpl_free(extname); extname = NULL; 01164 01165 KMO_TRY_EXIT_IF_ERROR( 01166 kmo_dfs_save_cube(cube_combined_data, filename_output_cube, 01167 "", ref_sub_header, 0./0.)); 01168 01169 if (cube_combined_noise != NULL) { 01170 KMO_TRY_EXIT_IF_NULL( 01171 extname = kmo_extname_creator(ifu_frame, exposure_ifus[0], 01172 EXT_NOISE)); 01173 01174 KMO_TRY_EXIT_IF_ERROR( 01175 kmclipm_update_property_string(ref_sub_header, 01176 EXTNAME, 01177 extname, 01178 "FITS extension name")); 01179 cpl_free(extname); extname = NULL; 01180 01181 KMO_TRY_EXIT_IF_ERROR( 01182 kmo_dfs_save_cube(cube_combined_noise, filename_output_cube, 01183 "", ref_sub_header, 0./0.)); 01184 } 01185 } 01186 KMO_CATCH 01187 { 01188 KMO_CATCH_MSG(); 01189 ret_val = -1; 01190 } 01191 01192 cpl_free(suffix); suffix = NULL; 01193 cpl_free(filename_output_cube); filename_output_cube = NULL; 01194 cpl_propertylist_delete(main_header); main_header = NULL; 01195 cpl_vector_delete(ifus); ifus = NULL; 01196 cpl_imagelist_delete(cube_combined_data); cube_combined_data = NULL; 01197 cpl_imagelist_delete(cube_combined_noise); cube_combined_noise = NULL; 01198 if (exposures != NULL) {cpl_frameset_delete(exposures);} 01199 if (exposure_filename != NULL) {cpl_free(exposure_filename);} 01200 if ((ifus_txt != NULL) && (strcmp(ifus_txt, "") != 0)) { //IFU selected by user given list 01201 for (i = 0; i < nr_alloc; i++) { 01202 cpl_free(exposure_objectname[i]); 01203 } 01204 } 01205 if (exposure_objectname != NULL) {cpl_free(exposure_objectname);} 01206 if (exposure_ifus != NULL) {cpl_free(exposure_ifus);} 01207 if (ref_main_header != NULL) {cpl_propertylist_delete(ref_main_header);} 01208 if (ref_sub_header != NULL) {cpl_propertylist_delete(ref_sub_header);} 01209 if (xshifts != NULL) {cpl_free(xshifts);} 01210 if (yshifts != NULL) {cpl_free(yshifts);} 01211 01212 if (data_cube_list != NULL) { 01213 for (i = 0; i < nr_science_frames; i++) { 01214 cpl_imagelist_delete(data_cube_list[i]); data_cube_list[i] = NULL; 01215 } 01216 cpl_free(data_cube_list); data_cube_list = NULL; 01217 } 01218 01219 if (noise_cube_list != NULL) { 01220 for (i = 0; i < nr_science_frames; i++) { 01221 cpl_imagelist_delete(noise_cube_list[i]); noise_cube_list[i] = NULL; 01222 } 01223 cpl_free(noise_cube_list); noise_cube_list = NULL; 01224 } 01225 01226 if (data_header_list != NULL) { 01227 for (i = 0; i < nr_science_frames; i++) { 01228 cpl_propertylist_delete(data_header_list[i]); 01229 data_header_list[i] = NULL; 01230 } 01231 cpl_free(data_header_list); data_header_list = NULL; 01232 } 01233 01234 if (noise_header_list != NULL) { 01235 for (i = 0; i < nr_science_frames; i++) { 01236 cpl_propertylist_delete(noise_header_list[i]); 01237 noise_header_list[i] = NULL; 01238 } 01239 cpl_free(noise_header_list); noise_header_list = NULL; 01240 } 01241 01242 if (header_data != NULL) { 01243 for (i = 0; i < nr_science_frames; i++) { 01244 cpl_propertylist_delete(header_data[i]); 01245 header_data[i] = NULL; 01246 } 01247 cpl_free(header_data); header_data = NULL; 01248 } 01249 01250 return ret_val; 01251 } 01252
1.7.6.1