|
KMOS Pipeline Reference Manual
1.2.1
|
00001 /* $Id: kmo_multi_reconstruct.c,v 1.39 2013/06/20 09:38:29 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/06/20 09:38:29 $ 00024 * $Revision: 1.39 $ 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 (--smethod 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 "-–smethod=”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 "--smethod\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 --smethod='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 --smethod='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 /* --name */ 00277 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.name", 00278 CPL_TYPE_STRING, 00279 "Name of the object to combine.", 00280 "kmos.kmo_multi_reconstruct", 00281 ""); 00282 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "name"); 00283 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00284 cpl_parameterlist_append(recipe->parameters, p); 00285 00286 /* --ifus */ 00287 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.ifus", 00288 CPL_TYPE_STRING, 00289 "The indices of the IFUs to combine. " 00290 "\"ifu1;ifu2;...\"", 00291 "kmos.kmo_multi_reconstruct", 00292 ""); 00293 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ifus"); 00294 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00295 cpl_parameterlist_append(recipe->parameters, p); 00296 00297 /* --size */ 00298 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.size", 00299 CPL_TYPE_STRING, 00300 "Spatial size of the output cube.", 00301 "kmos.kmo_multi_reconstruct", 00302 "max"); 00303 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "size"); 00304 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00305 cpl_parameterlist_append(recipe->parameters, p); 00306 00307 00308 /* --smethod shift method*/ 00309 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.smethod", 00310 CPL_TYPE_STRING, 00311 "The shifting method: " 00312 "'none': no shifting, combined directly " 00313 "(default), " 00314 "'header': shift according to WCS, " 00315 "'center': centering algorithm, " 00316 "'user': read shifts from file", 00317 "kmos.kmo_multi_reconstruct", 00318 "none"); 00319 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "smethod"); 00320 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00321 cpl_parameterlist_append(recipe->parameters, p); 00322 00323 /* --fmethod */ 00324 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.fmethod", 00325 CPL_TYPE_STRING, 00326 "The fitting method (applies only when " 00327 "method='center'): " 00328 "'gauss': fit a gauss function to collapsed " 00329 "image (default), " 00330 "'moffat': fit a moffat function to collapsed" 00331 " image", 00332 "kmos.kmo_combine", 00333 "gauss"); 00334 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fmethod"); 00335 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00336 cpl_parameterlist_append(recipe->parameters, p); 00337 00338 /* --imethod interpolation method */ 00339 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.imethod", 00340 CPL_TYPE_STRING, 00341 "Method to use for interpolation. " 00342 "[\"NN\" (nearest neighbour), " 00343 "\"lwNN\" (linear weighted nearest neighbor), " 00344 "\"swNN\" (square weighted nearest neighbor), " 00345 "\"MS\" (Modified Shepard's method)" 00346 "\"CS\" (Cubic spline)]", 00347 "kmos.kmo_multi_reconstruct", 00348 "NN"); 00349 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "imethod"); 00350 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00351 cpl_parameterlist_append(recipe->parameters, p); 00352 00353 /* --pix_scale */ 00354 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.pix_scale", 00355 CPL_TYPE_DOUBLE, 00356 "Change the pixel scale [arcsec]. " 00357 "Default of 0.2\" results into cubes of 14x14pix, " 00358 "a scale of 0.1\" results into cubes of 28x28pix, " 00359 "etc.", 00360 "kmos.kmo_multi_reconstruct", 00361 KMOS_PIX_RESOLUTION); 00362 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "pix_scale"); 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 smethod='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 /* --suppress_extension */ 00389 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.suppress_extension", 00390 CPL_TYPE_BOOL, 00391 "Suppress arbitrary filename extension." 00392 "(TRUE (apply) or FALSE (don't apply)", 00393 "kmos.kmo_multi_reconstruct", 00394 FALSE); 00395 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "suppress_extension"); 00396 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00397 cpl_parameterlist_append(recipe->parameters, p); 00398 00399 /* --dev_cal */ 00400 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.dev_cal", 00401 CPL_TYPE_BOOL, 00402 "Development only: If calibration data is to be " 00403 "reconstructed the ALPHA/DELTA keywords are " 00404 "missing. Setting this parameter to TRUE prevents " 00405 "according data check", 00406 "kmos.kmo_multi_reconstruct", 00407 FALSE); 00408 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dev_cal"); 00409 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00410 cpl_parameterlist_append(recipe->parameters, p); 00411 00412 // add parameters for band-definition 00413 kmo_band_pars_create(recipe->parameters, 00414 "kmos.kmo_multi_reconstruct"); 00415 00416 return kmo_combine_pars_create(recipe->parameters, 00417 "kmos.kmo_multi_reconstruct", 00418 DEF_REJ_METHOD, 00419 FALSE); 00420 } 00421 00427 static int kmo_multi_reconstruct_exec(cpl_plugin *plugin) 00428 { 00429 cpl_recipe *recipe; 00430 00431 /* Get the recipe out of the plugin */ 00432 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00433 recipe = (cpl_recipe *)plugin; 00434 else return -1 ; 00435 00436 return kmo_multi_reconstruct(recipe->parameters, recipe->frames); 00437 } 00438 00444 static int kmo_multi_reconstruct_destroy(cpl_plugin *plugin) 00445 { 00446 cpl_recipe *recipe; 00447 00448 /* Get the recipe out of the plugin */ 00449 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00450 recipe = (cpl_recipe *)plugin; 00451 else return -1 ; 00452 00453 cpl_parameterlist_delete(recipe->parameters); 00454 return 0 ; 00455 } 00456 00457 //int kmo_tolerance_round(double x, double tol) 00458 //{ 00459 // int ret = 0; 00460 00461 // KMO_TRY 00462 // { 00463 // if (fabs(x - floor(x)) < tol) { 00464 // // value is slightly greater than the real int value 00465 // ret = floor(x); 00466 // } else { 00467 // if (fabs(x - floor(x+tol)) < tol) { 00468 // // value is slightly greater than the real int value 00469 // ret = floor(x+tol); 00470 // } else { 00471 // // error: sub pixel shift 00472 // KMO_TRY_ASSURE(1 == 0, 00473 // CPL_ERROR_ILLEGAL_INPUT, 00474 // "Please apply only whole pixel shifts here " 00475 // "and no subpixel shifts!"); 00476 // } 00477 // } 00478 // } 00479 // KMO_CATCH 00480 // { 00481 // KMO_CATCH_MSG(); 00482 00483 // ret = 0; 00484 // } 00485 00486 // return ret; 00487 //} 00488 00503 static int kmo_multi_reconstruct(cpl_parameterlist *parlist, cpl_frameset *frameset) 00504 { 00505 const char *smethod = NULL, 00506 *cmethod = NULL, 00507 *fmethod = NULL, 00508 *imethod = NULL, 00509 *filename = NULL, 00510 *ifus_txt = NULL, 00511 *name = NULL, 00512 *size = NULL, 00513 *filter_id = NULL; 00514 char *tmp_str = NULL, 00515 *filename_output_cube = NULL, 00516 *extname = NULL, 00517 *keyword = NULL, 00518 *suffix = NULL, 00519 *tmp_ocs = NULL, 00520 **exposure_filename = NULL, 00521 **exposure_objectname = NULL; 00522 int ret_val = 0, 00523 device_nr = 0, 00524 citer = 0, 00525 cmin = 0, 00526 cmax = 0, 00527 nr_alloc = 0, 00528 suppress_extension = FALSE, 00529 i = 0, 00530 *exposure_ifus = NULL, 00531 nr_science_frames = 0, 00532 dev_cal = 0; 00533 double neighborhoodRange = 1.001, 00534 cpos_rej = 0.0, 00535 cneg_rej = 0.0, 00536 pix_scale = 0.0, 00537 *xshifts = NULL, 00538 *yshifts = NULL, 00539 cd1_1 = 0.0, 00540 cd1_2 = 0.0, 00541 ang1 = 0.0, 00542 ang2 = 0.0, 00543 exposure_rotangle = 0.0, 00544 rotangle_found = 0.0; 00545 cpl_imagelist **data_cube_list = NULL, 00546 **noise_cube_list = NULL, 00547 *cube_combined_data = NULL, 00548 *cube_combined_noise = NULL; 00549 cpl_vector *ifus = NULL; 00550 cpl_propertylist *pl = NULL, 00551 *main_header = NULL, 00552 *ref_main_header = NULL, 00553 *ref_sub_header = NULL, 00554 *tmp_header = NULL, 00555 **header_data = NULL, 00556 **data_header_list = NULL, 00557 **noise_header_list = NULL; 00558 cpl_frame *frame = NULL, 00559 *lcal_frame = NULL, 00560 **empty_frames = NULL, 00561 *tmp_frame = NULL, 00562 *ref_frame = NULL; 00563 cpl_table *band_table = NULL; 00564 cpl_image *lcalImg = NULL; 00565 cpl_frameset *exposures = NULL; 00566 main_fits_desc desc; 00567 gridDefinition gd; 00568 00569 KMO_TRY 00570 { 00571 /* --- check input --- */ 00572 KMO_TRY_ASSURE((parlist != NULL) && 00573 (frameset != NULL), 00574 CPL_ERROR_NULL_INPUT, 00575 "Not all input data is provided!"); 00576 00577 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_multi_reconstruct") == 1, 00578 CPL_ERROR_ILLEGAL_INPUT, 00579 "Cannot identify RAW and CALIB frames!"); 00580 00581 KMO_TRY_ASSURE(! ((cpl_frameset_count_tags(frameset, XCAL) == 0) && 00582 (cpl_frameset_count_tags(frameset, YCAL) == 0) && 00583 (cpl_frameset_count_tags(frameset, LCAL) == 0) && 00584 (cpl_frameset_count_tags(frameset, WAVE_BAND) == 0)), 00585 CPL_ERROR_FILE_NOT_FOUND, 00586 "XCAL, YCAL, LCAL or WAVE_BAND frames missing in " 00587 "frameset!!"); 00588 00589 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, XCAL) == 1, 00590 CPL_ERROR_FILE_NOT_FOUND, 00591 "Exactly one XCAL frame is expected in frameset!"); 00592 00593 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, YCAL) == 1, 00594 CPL_ERROR_FILE_NOT_FOUND, 00595 "Exactly one YCAL frame is expected in frameset!"); 00596 00597 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, LCAL) == 1, 00598 CPL_ERROR_FILE_NOT_FOUND, 00599 "Exactly one LCAL frame is expected in frameset!"); 00600 00601 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, WAVE_BAND) == 1, 00602 CPL_ERROR_FILE_NOT_FOUND, 00603 "Exactly one WAVE_BAND frame is expected in frameset!"); 00604 00605 // assert that at least two SCIENCE frames are available and create 00606 // intermediate frameset just with these science frames 00607 nr_science_frames = cpl_frameset_count_tags(frameset, SCIENCE); 00608 KMO_TRY_CHECK_ERROR_STATE(); 00609 00610 KMO_TRY_ASSURE(nr_science_frames > 1, 00611 CPL_ERROR_ILLEGAL_INPUT, 00612 "At least two SCIENCE frames must be provided to combine!"); 00613 KMO_TRY_EXIT_IF_NULL( 00614 exposures = cpl_frameset_new()); 00615 KMO_TRY_EXIT_IF_NULL( 00616 tmp_frame = kmo_dfs_get_frame(frameset, SCIENCE)); 00617 00618 for (i = 0; i < nr_science_frames; i++) { 00619 KMO_TRY_EXIT_IF_ERROR( 00620 cpl_frameset_insert(exposures, cpl_frame_duplicate(tmp_frame))); 00621 KMO_TRY_CHECK_ERROR_STATE(); 00622 00623 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 00624 } 00625 00626 cpl_msg_info("", "--- Parameter setup for kmo_multi_reconstruct -------"); 00627 00628 KMO_TRY_EXIT_IF_NULL( 00629 imethod = kmo_dfs_get_parameter_string(parlist, 00630 "kmos.kmo_multi_reconstruct.imethod")); 00631 00632 KMO_TRY_ASSURE((strcmp(imethod, "NN") == 0) || 00633 (strcmp(imethod, "lwNN") == 0) || 00634 (strcmp(imethod, "swNN") == 0) || 00635 (strcmp(imethod, "MS") == 0) || 00636 (strcmp(imethod, "CS") == 0), 00637 CPL_ERROR_ILLEGAL_INPUT, 00638 "imethod must be either \"NN\", \"lwNN\", " 00639 "\"swNN\", \"MS\" or \"CS\"!"); 00640 00641 KMO_TRY_EXIT_IF_ERROR( 00642 kmo_dfs_print_parameter_help(parlist, 00643 "kmos.kmo_multi_reconstruct.imethod")); 00644 00645 pix_scale = kmo_dfs_get_parameter_double(parlist, 00646 "kmos.kmo_multi_reconstruct.pix_scale"); 00647 KMO_TRY_CHECK_ERROR_STATE(); 00648 KMO_TRY_EXIT_IF_ERROR( 00649 kmo_dfs_print_parameter_help(parlist, 00650 "kmos.kmo_multi_reconstruct.pix_scale")); 00651 KMO_TRY_ASSURE((pix_scale >= 0.01) && 00652 (pix_scale <= 0.4), 00653 CPL_ERROR_ILLEGAL_INPUT, 00654 "pix_scale must be between 0.01 and 0.4 (results in cubes " 00655 "with 7x7 to 280x280 pixels)!"); 00656 00657 neighborhoodRange = kmo_dfs_get_parameter_double(parlist, 00658 "kmos.kmo_multi_reconstruct.neighborhoodRange"); 00659 KMO_TRY_CHECK_ERROR_STATE(); 00660 00661 KMO_TRY_ASSURE(neighborhoodRange > 0.0, 00662 CPL_ERROR_ILLEGAL_INPUT, 00663 "neighborhoodRange must be greater than 0.0"); 00664 00665 KMO_TRY_EXIT_IF_ERROR( 00666 kmo_dfs_print_parameter_help(parlist, 00667 "kmos.kmo_multi_reconstruct.neighborhoodRange")); 00668 00669 KMO_TRY_EXIT_IF_NULL( 00670 size = kmo_dfs_get_parameter_string(parlist, 00671 "kmos.kmo_multi_reconstruct.size")); 00672 00673 KMO_TRY_EXIT_IF_NULL( 00674 smethod = kmo_dfs_get_parameter_string(parlist, 00675 "kmos.kmo_multi_reconstruct.smethod")); 00676 00677 KMO_TRY_EXIT_IF_NULL( 00678 fmethod = kmo_dfs_get_parameter_string(parlist, 00679 "kmos.kmo_multi_reconstruct.fmethod")); 00680 00681 KMO_TRY_ASSURE((strcmp(size, "max") == 0) || 00682 (strcmp(size, "std") == 0), 00683 CPL_ERROR_ILLEGAL_INPUT, 00684 "Following output cube size specifications are available: " 00685 "'std' or 'max'"); 00686 00687 00688 KMO_TRY_ASSURE((strcmp(smethod, "none") == 0) || 00689 (strcmp(smethod, "header") == 0) || 00690 (strcmp(smethod, "center") == 0) || 00691 (strcmp(smethod, "user") == 0), 00692 CPL_ERROR_ILLEGAL_INPUT, 00693 "Following shift methods are available : 'none', " 00694 "'header', 'center' or 'user'"); 00695 00696 if (strcmp(smethod, "user") == 0) { 00697 filename = kmo_dfs_get_parameter_string(parlist, 00698 "kmos.kmo_multi_reconstruct.filename"); 00699 KMO_TRY_CHECK_ERROR_STATE(); 00700 00701 KMO_TRY_ASSURE(strcmp(filename, "") != 0, 00702 CPL_ERROR_ILLEGAL_INPUT, 00703 "path of file with shift information must be " 00704 "provided!"); 00705 00706 KMO_TRY_EXIT_IF_ERROR( 00707 kmo_dfs_print_parameter_help(parlist, 00708 "kmos.kmo_multi_reconstruct.filename")); 00709 } 00710 00711 KMO_TRY_EXIT_IF_ERROR( 00712 kmo_dfs_print_parameter_help(parlist, 00713 "kmos.kmo_multi_reconstruct.smethod")); 00714 00715 ifus_txt = kmo_dfs_get_parameter_string(parlist, 00716 "kmos.kmo_multi_reconstruct.ifus"); 00717 KMO_TRY_CHECK_ERROR_STATE(); 00718 00719 name = kmo_dfs_get_parameter_string(parlist, 00720 "kmos.kmo_multi_reconstruct.name"); 00721 KMO_TRY_CHECK_ERROR_STATE(); 00722 00723 if (strcmp(ifus_txt, "") != 0) { 00724 KMO_TRY_ASSURE(strcmp(name, "") == 0, 00725 CPL_ERROR_ILLEGAL_INPUT, 00726 "name parameter must be NULL if IFU indices are " 00727 "provided!"); 00728 00729 KMO_TRY_EXIT_IF_NULL( 00730 ifus = kmo_identify_values(ifus_txt)); 00731 00732 KMO_TRY_ASSURE(cpl_vector_get_size(ifus) == nr_science_frames, 00733 CPL_ERROR_ILLEGAL_INPUT, 00734 "ifus parameter must have the same number of values " 00735 "than frames provided ) (%lld!=%d)", 00736 cpl_vector_get_size(ifus), nr_science_frames); 00737 00738 for (i = 0; i < nr_science_frames; i++) { 00739 KMO_TRY_ASSURE((cpl_vector_get(ifus, i) > 0.5 && 00740 cpl_vector_get(ifus, i) < 24.5 ), 00741 CPL_ERROR_ILLEGAL_INPUT, 00742 "IFU numbers must be in the range 1..24"); 00743 } 00744 } 00745 00746 if (strcmp(name, "") != 0) { 00747 KMO_TRY_ASSURE(strcmp(ifus_txt, "") == 0, 00748 CPL_ERROR_ILLEGAL_INPUT, 00749 "ifus parameter must be NULL if name is provided!"); 00750 } 00751 00752 KMO_TRY_ASSURE((strcmp(name, "") != 0) || (strcmp(ifus_txt, "") != 0), 00753 CPL_ERROR_ILLEGAL_INPUT, 00754 "Either the name of the object or the numbers of the " 00755 "IFUs to combine must be provided (--name or --ifus " 00756 "parameters)"); 00757 00758 KMO_TRY_EXIT_IF_ERROR( 00759 kmo_dfs_print_parameter_help(parlist, 00760 "kmos.kmo_multi_reconstruct.ifus")); 00761 00762 KMO_TRY_EXIT_IF_ERROR( 00763 kmo_dfs_print_parameter_help(parlist, 00764 "kmos.kmo_multi_reconstruct.name")); 00765 00766 00767 suppress_extension = kmo_dfs_get_parameter_bool(parlist, 00768 "kmos.kmo_multi_reconstruct.suppress_extension"); 00769 KMO_TRY_CHECK_ERROR_STATE(); 00770 KMO_TRY_EXIT_IF_ERROR( 00771 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_multi_reconstruct.suppress_extension")); 00772 00773 KMO_TRY_ASSURE((suppress_extension == TRUE) || (suppress_extension == FALSE), 00774 CPL_ERROR_ILLEGAL_INPUT, 00775 "suppress_extension must be TRUE or FALSE!"); 00776 00777 dev_cal = kmo_dfs_get_parameter_bool(parlist, 00778 "kmos.kmo_multi_reconstruct.dev_cal"); 00779 KMO_TRY_CHECK_ERROR_STATE(); 00780 KMO_TRY_EXIT_IF_ERROR( 00781 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_multi_reconstruct.dev_cal")); 00782 00783 KMO_TRY_ASSURE((dev_cal == TRUE) || (dev_cal == FALSE), 00784 CPL_ERROR_ILLEGAL_INPUT, 00785 "dev_cal must be TRUE or FALSE!"); 00786 00787 KMO_TRY_EXIT_IF_ERROR( 00788 kmo_combine_pars_load(parlist, 00789 "kmos.kmo_multi_reconstruct", 00790 &cmethod, 00791 &cpos_rej, 00792 &cneg_rej, 00793 &citer, 00794 &cmin, 00795 &cmax, 00796 FALSE)); 00797 00798 kmo_band_pars_load(parlist, "kmos.kmo_multi_reconstruct"); 00799 00800 cpl_msg_info("", "-------------------------------------------"); 00801 00802 KMO_TRY_EXIT_IF_NULL( 00803 tmp_frame = kmo_dfs_get_frame(frameset, SCIENCE)); 00804 00805 KMO_TRY_EXIT_IF_NULL( 00806 suffix = kmo_dfs_get_suffix(tmp_frame, TRUE, FALSE)); 00807 00808 KMO_TRY_EXIT_IF_ERROR( 00809 kmo_check_frame_setup_md5_xycal(frameset)); 00810 KMO_TRY_EXIT_IF_ERROR( 00811 kmo_check_frame_setup_md5(frameset)); 00812 00813 cpl_msg_info("", "Detected instrument setup: %s", suffix+1); 00814 cpl_msg_info("", "(grating 1, 2 & 3)"); 00815 cpl_msg_info("", "-------------------------------------------"); 00816 00817 // assure that filters and grating match for 00818 // XCAL, YCAL, LCAL and for data frames to reconstruct 00819 KMO_TRY_EXIT_IF_ERROR( 00820 kmo_check_frameset_setup(frameset, XCAL, TRUE, FALSE, FALSE)); 00821 KMO_TRY_EXIT_IF_ERROR( 00822 kmo_check_frameset_setup(frameset, YCAL, TRUE, FALSE, FALSE)); 00823 KMO_TRY_EXIT_IF_ERROR( 00824 kmo_check_frameset_setup(frameset, LCAL, TRUE, FALSE, FALSE)); 00825 KMO_TRY_EXIT_IF_ERROR( 00826 kmo_check_frame_setup(frameset, XCAL, YCAL, TRUE, FALSE, TRUE)); 00827 KMO_TRY_EXIT_IF_ERROR( 00828 kmo_check_frame_setup(frameset, XCAL, LCAL, TRUE, FALSE, TRUE)); 00829 KMO_TRY_EXIT_IF_ERROR( 00830 kmo_check_frameset_setup(frameset, SCIENCE, TRUE, FALSE, FALSE)); 00831 KMO_TRY_EXIT_IF_ERROR( 00832 kmo_check_frame_setup(frameset, XCAL, SCIENCE, TRUE, FALSE, TRUE)); 00833 KMO_TRY_EXIT_IF_ERROR( 00834 kmo_check_frame_setup_md5_xycal(frameset)); 00835 KMO_TRY_EXIT_IF_ERROR( 00836 kmo_check_frame_setup_md5(frameset)); 00837 00838 // KMO_TRY_EXIT_IF_ERROR( 00839 // kmo_check_cal_frames_rotangle(frameset, XCAL, YCAL)); 00840 // KMO_TRY_EXIT_IF_ERROR( 00841 // kmo_check_cal_frames_rotangle(frameset, XCAL, LCAL)); 00842 00843 nr_alloc = nr_science_frames; 00844 KMO_TRY_EXIT_IF_NULL( 00845 exposure_filename = cpl_malloc(nr_alloc * sizeof(char *))); 00846 KMO_TRY_EXIT_IF_NULL( 00847 exposure_objectname = cpl_malloc(nr_alloc * sizeof(char *))); 00848 KMO_TRY_EXIT_IF_NULL( 00849 exposure_ifus = cpl_malloc(nr_alloc * sizeof(int))); 00850 00851 // check exposure frames 00852 for (i = 0; i < nr_science_frames; i++) { 00853 KMO_TRY_EXIT_IF_NULL( 00854 tmp_str = cpl_sprintf("%d", i)); 00855 00856 KMO_TRY_EXIT_IF_NULL( 00857 frame = kmo_dfs_get_frame(exposures, tmp_str)); 00858 cpl_free(tmp_str); 00859 00860 KMO_TRY_EXIT_IF_NULL( 00861 exposure_filename[i] = (char*)cpl_frame_get_filename(frame)); 00862 00863 kmo_init_fits_desc(&desc); 00864 00865 desc = kmo_identify_fits_header(exposure_filename[i]); 00866 KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to " 00867 "be in KMOS-format!"); 00868 00869 KMO_TRY_ASSURE(((desc.nr_ext == KMOS_NR_DETECTORS) || 00870 ((desc.nr_ext == 2*KMOS_NR_DETECTORS))) && 00871 (desc.ex_badpix == FALSE) && 00872 ((desc.fits_type == raw_fits) || 00873 (desc.fits_type == f2d_fits)) && 00874 (desc.frame_type == detector_frame), 00875 CPL_ERROR_ILLEGAL_INPUT, 00876 "The frame to reconstruct isn't in the correct " 00877 "format!!!"); 00878 kmo_free_fits_desc(&desc); 00879 } 00880 00881 // select IFU for each exposure 00882 KMO_TRY_EXIT_IF_NULL( 00883 empty_frames = cpl_malloc(nr_alloc * sizeof(cpl_frame *))); 00884 int found=0; 00885 for (i = 0; i < nr_science_frames; i++) { 00886 empty_frames[i] = NULL; 00887 if (strcmp(ifus_txt, "") != 0) { //IFU selected by user given list 00888 found = 1; 00889 // const char *tmpString; 00890 exposure_ifus[i] = (int) (cpl_vector_get(ifus, i) + 0.1); 00891 KMO_TRY_EXIT_IF_NULL( 00892 pl = kmclipm_propertylist_load(exposure_filename[i], 0)); 00893 KMO_TRY_EXIT_IF_NULL( 00894 tmp_ocs = cpl_sprintf("%s%d%s", IFU_NAME_PREFIX, 00895 exposure_ifus[i], IFU_NAME_POSTFIX)); 00896 if (cpl_propertylist_has(pl, tmp_ocs)) { 00897 tmp_str = (char*)cpl_propertylist_get_string(pl, tmp_ocs); 00898 } else { 00899 tmp_str = ""; 00900 } 00901 KMO_TRY_EXIT_IF_NULL( 00902 exposure_objectname[i] = cpl_sprintf("%s", tmp_str)); 00903 cpl_free(tmp_ocs); 00904 cpl_propertylist_delete(pl); pl = NULL; 00905 } else { //IFU selected by user given object name 00906 exposure_objectname[i] = (char*)name; 00907 KMO_TRY_EXIT_IF_NULL( 00908 tmp_str = cpl_sprintf("%d", i)); 00909 00910 KMO_TRY_EXIT_IF_NULL( 00911 frame = kmo_dfs_get_frame(exposures, tmp_str)); 00912 cpl_free(tmp_str); 00913 00914 KMO_TRY_CHECK_ERROR_STATE(); 00915 int this_ifu = kmo_get_index_from_ocs_name(frame, name); 00916 KMO_TRY_CHECK_ERROR_STATE(); 00917 if (this_ifu > 0) { 00918 found = 1; 00919 exposure_ifus[i] = this_ifu; 00920 } else { 00921 empty_frames[i] = frame; 00922 exposure_ifus[i] = -1; 00923 cpl_msg_warning("", 00924 "Could not find any IFU with an object " 00925 "named '%s' in file %s", 00926 name, exposure_filename[i]); 00927 } 00928 } 00929 KMO_TRY_CHECK_ERROR_STATE(); 00930 } 00931 if (! found) { 00932 cpl_msg_error("", 00933 "Could not find any IFU with an object named '%s' in " 00934 "any input file", name); 00935 KMO_TRY_EXIT_WITH_ERROR(CPL_ERROR_ILLEGAL_INPUT); 00936 } 00937 int j = 0; 00938 for (i = 0; i < nr_alloc; i++) { 00939 if (empty_frames[i] != NULL) { 00940 KMO_TRY_EXIT_IF_ERROR( 00941 cpl_frameset_erase_frame(exposures, empty_frames[i])); 00942 nr_science_frames--; 00943 exposure_ifus[j] = exposure_ifus[i]; 00944 } else { 00945 exposure_ifus[j] = exposure_ifus[i]; 00946 j++; 00947 } 00948 } 00949 for (i = 0; i < nr_science_frames; i++) { 00950 KMO_TRY_EXIT_IF_NULL( 00951 tmp_str = cpl_sprintf("%d", i)); 00952 00953 KMO_TRY_EXIT_IF_NULL( 00954 frame = kmo_dfs_get_frame(exposures, tmp_str)); 00955 cpl_free(tmp_str); 00956 00957 KMO_TRY_EXIT_IF_NULL( 00958 exposure_filename[i] = (char*)cpl_frame_get_filename(frame)); 00959 } 00960 00961 cpl_free(empty_frames); empty_frames = NULL; 00962 00963 // get reference header, subheader and set grid definition 00964 device_nr = ((exposure_ifus[0] -1) / KMOS_IFUS_PER_DETECTOR) + 1; 00965 00966 KMO_TRY_EXIT_IF_NULL( 00967 ref_main_header = kmclipm_propertylist_load(exposure_filename[0],0)); 00968 KMO_TRY_EXIT_IF_NULL( 00969 ref_frame = cpl_frameset_get_first(exposures)); 00970 KMO_TRY_EXIT_IF_NULL( 00971 ref_sub_header = kmclipm_propertylist_load(exposure_filename[0], 00972 device_nr)); 00973 KMO_TRY_EXIT_IF_ERROR( 00974 kmclipm_setup_grid(&gd, imethod, neighborhoodRange, pix_scale)); 00975 00976 exposure_rotangle = kmo_mr_get_rot_angle(kmo_dfs_get_frame(exposures, "0")); 00977 00978 KMO_TRY_EXIT_IF_NULL( 00979 lcal_frame = kmo_dfs_get_frame(frameset, LCAL)); 00980 00981 KMO_TRY_EXIT_IF_NULL( 00982 lcalImg = kmo_dfs_load_cal_image_frame(lcal_frame, 00983 1, 0, exposure_rotangle, 00984 FALSE, NULL, 00985 &rotangle_found, -1, 0, 0)); 00986 00987 KMO_TRY_EXIT_IF_NULL( 00988 tmp_header = kmo_dfs_load_primary_header(frameset, LCAL)); 00989 00990 KMO_TRY_EXIT_IF_NULL( 00991 keyword = cpl_sprintf("%s%d%s", IFU_FILTID_PREFIX, device_nr, 00992 IFU_FILTID_POSTFIX)); 00993 KMO_TRY_EXIT_IF_NULL( 00994 filter_id = cpl_propertylist_get_string(tmp_header, keyword)); 00995 00996 int band_method = 0; 00997 KMO_TRY_EXIT_IF_NULL( 00998 band_table = kmo_dfs_load_table(frameset, WAVE_BAND, 1, 0)); 00999 01000 KMO_TRY_EXIT_IF_ERROR( 01001 kmclipm_setup_grid_band_lcal(&gd, lcalImg, filter_id, 01002 band_method, band_table)); 01003 cpl_image_delete(lcalImg); lcalImg = NULL; 01004 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01005 cpl_free(keyword); keyword = NULL; 01006 cpl_table_delete(band_table); band_table = NULL; 01007 01008 //extract sub-headers for each exposures, calculate WCS 01009 KMO_TRY_EXIT_IF_NULL( 01010 header_data = cpl_malloc(nr_science_frames*sizeof(cpl_propertylist*))); 01011 for (i = 0; i < nr_science_frames; i++) { 01012 device_nr = ((exposure_ifus[0] -1) / KMOS_IFUS_PER_DETECTOR) + 1; 01013 KMO_TRY_EXIT_IF_NULL( 01014 header_data[i] = kmclipm_propertylist_load(exposure_filename[i], 01015 device_nr)); 01016 KMO_TRY_EXIT_IF_ERROR( 01017 kmclipm_update_property_int(header_data[i],"NAXIS", 3,"")); 01018 KMO_TRY_EXIT_IF_ERROR( 01019 kmclipm_update_property_int(header_data[i],"NAXIS1",gd.x.dim,"")); 01020 KMO_TRY_EXIT_IF_ERROR( 01021 kmclipm_update_property_int(header_data[i],"NAXIS2",gd.y.dim,"")); 01022 KMO_TRY_EXIT_IF_ERROR( 01023 kmclipm_update_property_int(header_data[i],"NAXIS3",gd.l.dim,"")); 01024 cpl_propertylist *tmpHeader; 01025 KMO_TRY_EXIT_IF_NULL( 01026 tmpHeader = kmclipm_propertylist_load(exposure_filename[i],0)); 01027 KMO_TRY_EXIT_IF_ERROR( 01028 kmo_calc_wcs_gd(tmpHeader, header_data[i], exposure_ifus[i], gd)); 01029 cpl_propertylist_delete(tmpHeader); 01030 } 01031 01032 // check rotation angle 01033 if (dev_cal == FALSE) { 01034 cd1_1 = kmo_dfs_get_property_double(header_data[0], CD1_1); 01035 cd1_2 = kmo_dfs_get_property_double(header_data[0], CD1_2); 01036 KMO_TRY_CHECK_ERROR_STATE(); 01037 ang1 = atan(cd1_2/cd1_1)*180/CPL_MATH_PI; 01038 for (i = 1; i < nr_science_frames; i++) { 01039 cd1_1 = kmo_dfs_get_property_double(header_data[i], CD1_1); 01040 cd1_2 = kmo_dfs_get_property_double(header_data[i], CD1_2); 01041 KMO_TRY_CHECK_ERROR_STATE(); 01042 ang2 = atan(cd1_2/cd1_1)*180/CPL_MATH_PI; 01043 01044 if (strcmp(smethod, "none") != 0) { 01045 // center, header, user 01046 KMO_TRY_ASSURE(fabs(ang1-ang2) <= 0.5, 01047 CPL_ERROR_ILLEGAL_INPUT, 01048 "Orientation of cube 1 (%gdeg) and cube %d " 01049 "(%gdeg) differ! " 01050 "Align the orientation of this cube with " 01051 "kmo_rotate before applying this recipe.", 01052 ang1, i+1, ang2); 01053 } else { 01054 // none 01055 if (fabs(ang1-ang2) > 0.5) { 01056 cpl_msg_warning("", 01057 "Orientation of cube 1 (%gdeg) and cube %d " 01058 "(%gdeg) differ! Processing anyway.", 01059 ang1, i+1, ang2); 01060 } 01061 } 01062 } 01063 } 01064 01065 // set x/y shifts 01066 KMO_TRY_EXIT_IF_NULL( 01067 xshifts = cpl_malloc(nr_science_frames * sizeof(double))); 01068 KMO_TRY_EXIT_IF_NULL( 01069 yshifts = cpl_malloc(nr_science_frames * sizeof(double))); 01070 KMO_TRY_EXIT_IF_ERROR( 01071 kmo_mr_get_offsets(nr_science_frames, smethod, imethod, neighborhoodRange, 01072 filename, frameset, exposures, exposure_ifus, 01073 (const cpl_propertylist**)header_data, 01074 fmethod, 01075 cmethod, 01076 cpos_rej, 01077 cneg_rej, 01078 citer, 01079 cmin, 01080 cmax, 01081 pix_scale, 01082 xshifts, yshifts)); 01083 01084 for (i = 0; i < nr_science_frames; i++) { 01085 printf("exposure %d: filename %s, selected IFU %d, object name " 01086 "\"%s\", xshift %f, yshift %f\n", i, exposure_filename[i], 01087 exposure_ifus[i], exposure_objectname[i], xshifts[i], yshifts[i]); 01088 } 01089 01090 // 01091 // set spatial part of the grid 01092 // 01093 // size = "max"; 01094 if (strcmp(size, "max") == 0) { 01095 double xmin=0, xmax=0, ymin=0, ymax=0; 01096 double gxshift, gyshift, gxdim, gydim; 01097 double pixel_resolution = pix_scale; 01098 int xdim, ydim; 01099 01100 for (i = 0; i < nr_science_frames; i++) { 01101 if (xmin > xshifts[i]) { xmin = xshifts[i]; } 01102 if (xmax < xshifts[i]) { xmax = xshifts[i]; } 01103 if (ymin > yshifts[i]) { ymin = yshifts[i]; } 01104 if (ymax < yshifts[i]) { ymax = yshifts[i]; } 01105 } 01106 if (xmax > 0.0001) { 01107 gxshift = - ceil(xmax); 01108 } else { 01109 gxshift = 0.; 01110 } 01111 if (ymin < -0.0001) { 01112 gyshift = floor(ymin); 01113 } else { 01114 gyshift = 0.; 01115 } 01116 if (xmin < -0.0001) { 01117 gxdim = - floor(xmin); 01118 } else { 01119 gxdim = 0.; 01120 } 01121 if (ymax > 0.0001) { 01122 gydim = ceil(ymax); 01123 } else { 01124 gydim = 0.; 01125 } 01126 01127 xdim = (int) (gxdim - gxshift + .5); 01128 ydim = (int) (gydim - gyshift + .5); 01129 gd.x.start += gxshift * pixel_resolution; 01130 gd.y.start += gyshift * pixel_resolution; 01131 gd.x.dim += xdim; 01132 gd.y.dim += ydim; 01133 // printf("X: %f < %f Y: %f < %f \n",xmin,xmax,ymin,ymax); 01134 // printf("gxshift: %f gxdim: %f xdim: %d gyshift: %f gydim: %f ydim: %d \n", 01135 // gxshift, gxdim, xdim, gyshift, gydim, ydim); 01136 // printf("GD: %f %d %f %d\n", gd.x.start, gd.x.dim, gd.y.start, gd.y.dim); 01137 } 01138 01139 // 01140 // reconstruct multiple detector images 01141 // 01142 01143 // printf("GD: %f %f %d %f %f %d %f %f %d\n", 01144 // gd.x.start, gd.x.delta, gd.x.dim, 01145 // gd.y.start, gd.y.delta, gd.y.dim, 01146 // gd.l.start, gd.l.delta, gd.l.dim); 01147 01148 KMO_TRY_EXIT_IF_ERROR( 01149 kmo_priv_multi_reconstruct(frameset, 01150 exposures, 01151 exposure_ifus, 01152 xshifts, 01153 yshifts, 01154 gd, 01155 &cube_combined_data, 01156 &cube_combined_noise, 01157 pix_scale)); 01158 01159 if (!suppress_extension) { 01160 // setup output category COMBINE + ESO PRO CATG 01161 if (strcmp(ifus_txt, "") != 0) { //IFU selected by user given list 01162 KMO_TRY_EXIT_IF_NULL( 01163 tmp_str = cpl_sprintf("IFU")); 01164 } else { 01165 KMO_TRY_EXIT_IF_NULL( 01166 tmp_str = cpl_sprintf("%s", name)); 01167 } 01168 01169 KMO_TRY_EXIT_IF_NULL( 01170 filename_output_cube = cpl_sprintf("%s_%s", CUBE_MULTI, tmp_str)); 01171 cpl_free(tmp_str); tmp_str = NULL; 01172 } else { 01173 KMO_TRY_EXIT_IF_NULL( 01174 filename_output_cube = cpl_sprintf("%s", CUBE_MULTI)); 01175 } 01176 01177 KMO_TRY_EXIT_IF_ERROR( 01178 kmo_dfs_save_main_header(frameset, filename_output_cube, "", 01179 ref_frame, NULL, parlist, cpl_func)); 01180 // save output 01181 KMO_TRY_EXIT_IF_NULL( 01182 extname = kmo_extname_creator(ifu_frame, exposure_ifus[0], 01183 EXT_DATA)); 01184 01185 // calculate WCS 01186 KMO_TRY_EXIT_IF_ERROR( 01187 kmo_calc_wcs_gd(ref_main_header, ref_sub_header, exposure_ifus[0], gd)); 01188 01189 KMO_TRY_EXIT_IF_ERROR( 01190 kmclipm_update_property_string(ref_sub_header, 01191 EXTNAME, 01192 extname, 01193 "FITS extension name")); 01194 cpl_free(extname); extname = NULL; 01195 01196 KMO_TRY_EXIT_IF_ERROR( 01197 kmo_dfs_save_cube(cube_combined_data, filename_output_cube, 01198 "", ref_sub_header, 0./0.)); 01199 01200 if (cube_combined_noise != NULL) { 01201 KMO_TRY_EXIT_IF_NULL( 01202 extname = kmo_extname_creator(ifu_frame, exposure_ifus[0], 01203 EXT_NOISE)); 01204 01205 KMO_TRY_EXIT_IF_ERROR( 01206 kmclipm_update_property_string(ref_sub_header, 01207 EXTNAME, 01208 extname, 01209 "FITS extension name")); 01210 cpl_free(extname); extname = NULL; 01211 01212 KMO_TRY_EXIT_IF_ERROR( 01213 kmo_dfs_save_cube(cube_combined_noise, filename_output_cube, 01214 "", ref_sub_header, 0./0.)); 01215 } 01216 } 01217 KMO_CATCH 01218 { 01219 KMO_CATCH_MSG(); 01220 ret_val = -1; 01221 } 01222 01223 cpl_free(suffix); suffix = NULL; 01224 cpl_free(filename_output_cube); filename_output_cube = NULL; 01225 cpl_propertylist_delete(main_header); main_header = NULL; 01226 cpl_vector_delete(ifus); ifus = NULL; 01227 cpl_imagelist_delete(cube_combined_data); cube_combined_data = NULL; 01228 cpl_imagelist_delete(cube_combined_noise); cube_combined_noise = NULL; 01229 if (exposures != NULL) {cpl_frameset_delete(exposures);} 01230 if (exposure_filename != NULL) {cpl_free(exposure_filename);} 01231 if ((ifus_txt != NULL) && (strcmp(ifus_txt, "") != 0)) { //IFU selected by user given list 01232 for (i = 0; i < nr_alloc; i++) { 01233 cpl_free(exposure_objectname[i]); 01234 } 01235 } 01236 if (exposure_objectname != NULL) {cpl_free(exposure_objectname);} 01237 if (exposure_ifus != NULL) {cpl_free(exposure_ifus);} 01238 if (ref_main_header != NULL) {cpl_propertylist_delete(ref_main_header);} 01239 if (ref_sub_header != NULL) {cpl_propertylist_delete(ref_sub_header);} 01240 if (xshifts != NULL) {cpl_free(xshifts);} 01241 if (yshifts != NULL) {cpl_free(yshifts);} 01242 01243 if (data_cube_list != NULL) { 01244 for (i = 0; i < nr_science_frames; i++) { 01245 cpl_imagelist_delete(data_cube_list[i]); data_cube_list[i] = NULL; 01246 } 01247 cpl_free(data_cube_list); data_cube_list = NULL; 01248 } 01249 01250 if (noise_cube_list != NULL) { 01251 for (i = 0; i < nr_science_frames; i++) { 01252 cpl_imagelist_delete(noise_cube_list[i]); noise_cube_list[i] = NULL; 01253 } 01254 cpl_free(noise_cube_list); noise_cube_list = NULL; 01255 } 01256 01257 if (data_header_list != NULL) { 01258 for (i = 0; i < nr_science_frames; i++) { 01259 cpl_propertylist_delete(data_header_list[i]); 01260 data_header_list[i] = NULL; 01261 } 01262 cpl_free(data_header_list); data_header_list = NULL; 01263 } 01264 01265 if (noise_header_list != NULL) { 01266 for (i = 0; i < nr_science_frames; i++) { 01267 cpl_propertylist_delete(noise_header_list[i]); 01268 noise_header_list[i] = NULL; 01269 } 01270 cpl_free(noise_header_list); noise_header_list = NULL; 01271 } 01272 01273 if (header_data != NULL) { 01274 for (i = 0; i < nr_science_frames; i++) { 01275 cpl_propertylist_delete(header_data[i]); 01276 header_data[i] = NULL; 01277 } 01278 cpl_free(header_data); header_data = NULL; 01279 } 01280 01281 return ret_val; 01282 } 01283
1.7.6.1