|
KMOS Pipeline Reference Manual
1.2.2
|
00001 /* $Id: kmo_multi_reconstruct.c,v 1.40 2013/06/27 13:09:49 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/27 13:09:49 $ 00024 * $Revision: 1.40 $ 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 "header"); 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 00471 static int kmo_multi_reconstruct(cpl_parameterlist *parlist, cpl_frameset *frameset) 00472 { 00473 const char *smethod = NULL, 00474 *cmethod = NULL, 00475 *fmethod = NULL, 00476 *imethod = NULL, 00477 *filename = NULL, 00478 *ifus_txt = NULL, 00479 *name = NULL, 00480 *size = NULL, 00481 *filter_id = NULL; 00482 char *tmp_str = NULL, 00483 *filename_output_cube = NULL, 00484 *extname = NULL, 00485 *keyword = NULL, 00486 *suffix = NULL, 00487 *tmp_ocs = NULL, 00488 **exposure_filename = NULL, 00489 **exposure_objectname = NULL; 00490 int ret_val = 0, 00491 device_nr = 0, 00492 citer = 0, 00493 cmin = 0, 00494 cmax = 0, 00495 nr_alloc = 0, 00496 suppress_extension = FALSE, 00497 i = 0, 00498 *exposure_ifus = NULL, 00499 nr_science_frames = 0, 00500 dev_cal = 0; 00501 double neighborhoodRange = 1.001, 00502 cpos_rej = 0.0, 00503 cneg_rej = 0.0, 00504 pix_scale = 0.0, 00505 *xshifts = NULL, 00506 *yshifts = NULL, 00507 cd1_1 = 0.0, 00508 cd1_2 = 0.0, 00509 ang1 = 0.0, 00510 ang2 = 0.0, 00511 exposure_rotangle = 0.0, 00512 rotangle_found = 0.0; 00513 cpl_imagelist **data_cube_list = NULL, 00514 **noise_cube_list = NULL, 00515 *cube_combined_data = NULL, 00516 *cube_combined_noise = NULL; 00517 cpl_vector *ifus = NULL; 00518 cpl_propertylist *pl = NULL, 00519 *main_header = NULL, 00520 *ref_main_header = NULL, 00521 *ref_sub_header = NULL, 00522 *tmp_header = NULL, 00523 **header_data = NULL, 00524 **data_header_list = NULL, 00525 **noise_header_list = NULL; 00526 cpl_frame *frame = NULL, 00527 *lcal_frame = NULL, 00528 **empty_frames = NULL, 00529 *tmp_frame = NULL, 00530 *ref_frame = NULL; 00531 cpl_table *band_table = NULL; 00532 cpl_image *lcalImg = NULL; 00533 cpl_frameset *exposures = NULL; 00534 main_fits_desc desc; 00535 gridDefinition gd; 00536 00537 KMO_TRY 00538 { 00539 // 00540 // check frameset 00541 // 00542 KMO_TRY_ASSURE((parlist != NULL) && 00543 (frameset != NULL), 00544 CPL_ERROR_NULL_INPUT, 00545 "Not all input data is provided!"); 00546 00547 KMO_TRY_ASSURE(! ((cpl_frameset_count_tags(frameset, XCAL) == 0) && 00548 (cpl_frameset_count_tags(frameset, YCAL) == 0) && 00549 (cpl_frameset_count_tags(frameset, LCAL) == 0) && 00550 (cpl_frameset_count_tags(frameset, WAVE_BAND) == 0)), 00551 CPL_ERROR_FILE_NOT_FOUND, 00552 "XCAL, YCAL, LCAL or WAVE_BAND frames missing in " 00553 "frameset!!"); 00554 00555 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, XCAL) == 1, 00556 CPL_ERROR_FILE_NOT_FOUND, 00557 "Exactly one XCAL frame is expected in frameset!"); 00558 00559 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, YCAL) == 1, 00560 CPL_ERROR_FILE_NOT_FOUND, 00561 "Exactly one YCAL frame is expected in frameset!"); 00562 00563 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, LCAL) == 1, 00564 CPL_ERROR_FILE_NOT_FOUND, 00565 "Exactly one LCAL frame is expected in frameset!"); 00566 00567 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, WAVE_BAND) == 1, 00568 CPL_ERROR_FILE_NOT_FOUND, 00569 "Exactly one WAVE_BAND frame is expected in frameset!"); 00570 00571 // assert that at least two SCIENCE frames are available and create 00572 // intermediate frameset just with these science frames 00573 nr_science_frames = cpl_frameset_count_tags(frameset, SCIENCE); 00574 KMO_TRY_CHECK_ERROR_STATE(); 00575 00576 KMO_TRY_ASSURE(nr_science_frames > 1, 00577 CPL_ERROR_ILLEGAL_INPUT, 00578 "At least two SCIENCE frames must be provided to combine!"); 00579 00580 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_multi_reconstruct") == 1, 00581 CPL_ERROR_ILLEGAL_INPUT, 00582 "Cannot identify RAW and CALIB frames!"); 00583 00584 KMO_TRY_EXIT_IF_NULL( 00585 exposures = cpl_frameset_new()); 00586 KMO_TRY_EXIT_IF_NULL( 00587 tmp_frame = kmo_dfs_get_frame(frameset, SCIENCE)); 00588 00589 for (i = 0; i < nr_science_frames; i++) { 00590 KMO_TRY_EXIT_IF_ERROR( 00591 cpl_frameset_insert(exposures, cpl_frame_duplicate(tmp_frame))); 00592 KMO_TRY_CHECK_ERROR_STATE(); 00593 00594 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 00595 } 00596 00597 cpl_msg_info("", "--- Parameter setup for kmo_multi_reconstruct -------"); 00598 00599 KMO_TRY_EXIT_IF_NULL( 00600 imethod = kmo_dfs_get_parameter_string(parlist, 00601 "kmos.kmo_multi_reconstruct.imethod")); 00602 00603 KMO_TRY_ASSURE((strcmp(imethod, "NN") == 0) || 00604 (strcmp(imethod, "lwNN") == 0) || 00605 (strcmp(imethod, "swNN") == 0) || 00606 (strcmp(imethod, "MS") == 0) || 00607 (strcmp(imethod, "CS") == 0), 00608 CPL_ERROR_ILLEGAL_INPUT, 00609 "imethod must be either \"NN\", \"lwNN\", " 00610 "\"swNN\", \"MS\" or \"CS\"!"); 00611 00612 KMO_TRY_EXIT_IF_ERROR( 00613 kmo_dfs_print_parameter_help(parlist, 00614 "kmos.kmo_multi_reconstruct.imethod")); 00615 00616 pix_scale = kmo_dfs_get_parameter_double(parlist, 00617 "kmos.kmo_multi_reconstruct.pix_scale"); 00618 KMO_TRY_CHECK_ERROR_STATE(); 00619 KMO_TRY_EXIT_IF_ERROR( 00620 kmo_dfs_print_parameter_help(parlist, 00621 "kmos.kmo_multi_reconstruct.pix_scale")); 00622 KMO_TRY_ASSURE((pix_scale >= 0.01) && 00623 (pix_scale <= 0.4), 00624 CPL_ERROR_ILLEGAL_INPUT, 00625 "pix_scale must be between 0.01 and 0.4 (results in cubes " 00626 "with 7x7 to 280x280 pixels)!"); 00627 00628 neighborhoodRange = kmo_dfs_get_parameter_double(parlist, 00629 "kmos.kmo_multi_reconstruct.neighborhoodRange"); 00630 KMO_TRY_CHECK_ERROR_STATE(); 00631 00632 KMO_TRY_ASSURE(neighborhoodRange > 0.0, 00633 CPL_ERROR_ILLEGAL_INPUT, 00634 "neighborhoodRange must be greater than 0.0"); 00635 00636 KMO_TRY_EXIT_IF_ERROR( 00637 kmo_dfs_print_parameter_help(parlist, 00638 "kmos.kmo_multi_reconstruct.neighborhoodRange")); 00639 00640 KMO_TRY_EXIT_IF_NULL( 00641 size = kmo_dfs_get_parameter_string(parlist, 00642 "kmos.kmo_multi_reconstruct.size")); 00643 00644 KMO_TRY_EXIT_IF_NULL( 00645 smethod = kmo_dfs_get_parameter_string(parlist, 00646 "kmos.kmo_multi_reconstruct.smethod")); 00647 00648 KMO_TRY_EXIT_IF_NULL( 00649 fmethod = kmo_dfs_get_parameter_string(parlist, 00650 "kmos.kmo_multi_reconstruct.fmethod")); 00651 00652 KMO_TRY_ASSURE((strcmp(size, "max") == 0) || 00653 (strcmp(size, "std") == 0), 00654 CPL_ERROR_ILLEGAL_INPUT, 00655 "Following output cube size specifications are available: " 00656 "'std' or 'max'"); 00657 00658 00659 KMO_TRY_ASSURE((strcmp(smethod, "none") == 0) || 00660 (strcmp(smethod, "header") == 0) || 00661 (strcmp(smethod, "center") == 0) || 00662 (strcmp(smethod, "user") == 0), 00663 CPL_ERROR_ILLEGAL_INPUT, 00664 "Following shift methods are available : 'none', " 00665 "'header', 'center' or 'user'"); 00666 00667 if (strcmp(smethod, "user") == 0) { 00668 filename = kmo_dfs_get_parameter_string(parlist, 00669 "kmos.kmo_multi_reconstruct.filename"); 00670 KMO_TRY_CHECK_ERROR_STATE(); 00671 00672 KMO_TRY_ASSURE(strcmp(filename, "") != 0, 00673 CPL_ERROR_ILLEGAL_INPUT, 00674 "path of file with shift information must be " 00675 "provided!"); 00676 00677 KMO_TRY_EXIT_IF_ERROR( 00678 kmo_dfs_print_parameter_help(parlist, 00679 "kmos.kmo_multi_reconstruct.filename")); 00680 } 00681 00682 KMO_TRY_EXIT_IF_ERROR( 00683 kmo_dfs_print_parameter_help(parlist, 00684 "kmos.kmo_multi_reconstruct.smethod")); 00685 00686 ifus_txt = kmo_dfs_get_parameter_string(parlist, 00687 "kmos.kmo_multi_reconstruct.ifus"); 00688 KMO_TRY_CHECK_ERROR_STATE(); 00689 00690 name = kmo_dfs_get_parameter_string(parlist, 00691 "kmos.kmo_multi_reconstruct.name"); 00692 KMO_TRY_CHECK_ERROR_STATE(); 00693 00694 if (strcmp(ifus_txt, "") != 0) { 00695 KMO_TRY_ASSURE(strcmp(name, "") == 0, 00696 CPL_ERROR_ILLEGAL_INPUT, 00697 "name parameter must be NULL if IFU indices are " 00698 "provided!"); 00699 00700 KMO_TRY_EXIT_IF_NULL( 00701 ifus = kmo_identify_values(ifus_txt)); 00702 00703 KMO_TRY_ASSURE(cpl_vector_get_size(ifus) == nr_science_frames, 00704 CPL_ERROR_ILLEGAL_INPUT, 00705 "ifus parameter must have the same number of values " 00706 "than frames provided ) (%lld!=%d)", 00707 cpl_vector_get_size(ifus), nr_science_frames); 00708 00709 for (i = 0; i < nr_science_frames; i++) { 00710 KMO_TRY_ASSURE((cpl_vector_get(ifus, i) > 0.5 && 00711 cpl_vector_get(ifus, i) < 24.5 ), 00712 CPL_ERROR_ILLEGAL_INPUT, 00713 "IFU numbers must be in the range 1..24"); 00714 } 00715 } 00716 00717 if (strcmp(name, "") != 0) { 00718 KMO_TRY_ASSURE(strcmp(ifus_txt, "") == 0, 00719 CPL_ERROR_ILLEGAL_INPUT, 00720 "ifus parameter must be NULL if name is provided!"); 00721 } 00722 00723 KMO_TRY_ASSURE((strcmp(name, "") != 0) || (strcmp(ifus_txt, "") != 0), 00724 CPL_ERROR_ILLEGAL_INPUT, 00725 "Either the name of the object or the numbers of the " 00726 "IFUs to combine must be provided (--name or --ifus " 00727 "parameters)"); 00728 00729 KMO_TRY_EXIT_IF_ERROR( 00730 kmo_dfs_print_parameter_help(parlist, 00731 "kmos.kmo_multi_reconstruct.ifus")); 00732 00733 KMO_TRY_EXIT_IF_ERROR( 00734 kmo_dfs_print_parameter_help(parlist, 00735 "kmos.kmo_multi_reconstruct.name")); 00736 00737 00738 suppress_extension = kmo_dfs_get_parameter_bool(parlist, 00739 "kmos.kmo_multi_reconstruct.suppress_extension"); 00740 KMO_TRY_CHECK_ERROR_STATE(); 00741 KMO_TRY_EXIT_IF_ERROR( 00742 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_multi_reconstruct.suppress_extension")); 00743 00744 KMO_TRY_ASSURE((suppress_extension == TRUE) || (suppress_extension == FALSE), 00745 CPL_ERROR_ILLEGAL_INPUT, 00746 "suppress_extension must be TRUE or FALSE!"); 00747 00748 dev_cal = kmo_dfs_get_parameter_bool(parlist, 00749 "kmos.kmo_multi_reconstruct.dev_cal"); 00750 KMO_TRY_CHECK_ERROR_STATE(); 00751 KMO_TRY_EXIT_IF_ERROR( 00752 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_multi_reconstruct.dev_cal")); 00753 00754 KMO_TRY_ASSURE((dev_cal == TRUE) || (dev_cal == FALSE), 00755 CPL_ERROR_ILLEGAL_INPUT, 00756 "dev_cal must be TRUE or FALSE!"); 00757 00758 KMO_TRY_EXIT_IF_ERROR( 00759 kmo_combine_pars_load(parlist, 00760 "kmos.kmo_multi_reconstruct", 00761 &cmethod, 00762 &cpos_rej, 00763 &cneg_rej, 00764 &citer, 00765 &cmin, 00766 &cmax, 00767 FALSE)); 00768 00769 kmo_band_pars_load(parlist, "kmos.kmo_multi_reconstruct"); 00770 00771 cpl_msg_info("", "-------------------------------------------"); 00772 00773 KMO_TRY_EXIT_IF_NULL( 00774 tmp_frame = kmo_dfs_get_frame(frameset, SCIENCE)); 00775 00776 KMO_TRY_EXIT_IF_NULL( 00777 suffix = kmo_dfs_get_suffix(tmp_frame, TRUE, FALSE)); 00778 00779 KMO_TRY_EXIT_IF_ERROR( 00780 kmo_check_frame_setup_md5_xycal(frameset)); 00781 KMO_TRY_EXIT_IF_ERROR( 00782 kmo_check_frame_setup_md5(frameset)); 00783 00784 cpl_msg_info("", "Detected instrument setup: %s", suffix+1); 00785 cpl_msg_info("", "(grating 1, 2 & 3)"); 00786 cpl_msg_info("", "-------------------------------------------"); 00787 00788 // assure that filters and grating match for 00789 // XCAL, YCAL, LCAL and for data frames to reconstruct 00790 KMO_TRY_EXIT_IF_ERROR( 00791 kmo_check_frameset_setup(frameset, XCAL, TRUE, FALSE, FALSE)); 00792 KMO_TRY_EXIT_IF_ERROR( 00793 kmo_check_frameset_setup(frameset, YCAL, TRUE, FALSE, FALSE)); 00794 KMO_TRY_EXIT_IF_ERROR( 00795 kmo_check_frameset_setup(frameset, LCAL, TRUE, FALSE, FALSE)); 00796 KMO_TRY_EXIT_IF_ERROR( 00797 kmo_check_frame_setup(frameset, XCAL, YCAL, TRUE, FALSE, TRUE)); 00798 KMO_TRY_EXIT_IF_ERROR( 00799 kmo_check_frame_setup(frameset, XCAL, LCAL, TRUE, FALSE, TRUE)); 00800 KMO_TRY_EXIT_IF_ERROR( 00801 kmo_check_frameset_setup(frameset, SCIENCE, TRUE, FALSE, FALSE)); 00802 KMO_TRY_EXIT_IF_ERROR( 00803 kmo_check_frame_setup(frameset, XCAL, SCIENCE, TRUE, FALSE, TRUE)); 00804 KMO_TRY_EXIT_IF_ERROR( 00805 kmo_check_frame_setup_md5_xycal(frameset)); 00806 KMO_TRY_EXIT_IF_ERROR( 00807 kmo_check_frame_setup_md5(frameset)); 00808 00809 // KMO_TRY_EXIT_IF_ERROR( 00810 // kmo_check_cal_frames_rotangle(frameset, XCAL, YCAL)); 00811 // KMO_TRY_EXIT_IF_ERROR( 00812 // kmo_check_cal_frames_rotangle(frameset, XCAL, LCAL)); 00813 00814 nr_alloc = nr_science_frames; 00815 KMO_TRY_EXIT_IF_NULL( 00816 exposure_filename = cpl_malloc(nr_alloc * sizeof(char *))); 00817 KMO_TRY_EXIT_IF_NULL( 00818 exposure_objectname = cpl_malloc(nr_alloc * sizeof(char *))); 00819 KMO_TRY_EXIT_IF_NULL( 00820 exposure_ifus = cpl_malloc(nr_alloc * sizeof(int))); 00821 00822 // check exposure frames 00823 for (i = 0; i < nr_science_frames; i++) { 00824 KMO_TRY_EXIT_IF_NULL( 00825 tmp_str = cpl_sprintf("%d", i)); 00826 00827 KMO_TRY_EXIT_IF_NULL( 00828 frame = kmo_dfs_get_frame(exposures, tmp_str)); 00829 cpl_free(tmp_str); 00830 00831 KMO_TRY_EXIT_IF_NULL( 00832 exposure_filename[i] = (char*)cpl_frame_get_filename(frame)); 00833 00834 kmo_init_fits_desc(&desc); 00835 00836 desc = kmo_identify_fits_header(exposure_filename[i]); 00837 KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to " 00838 "be in KMOS-format!"); 00839 00840 KMO_TRY_ASSURE(((desc.nr_ext == KMOS_NR_DETECTORS) || 00841 ((desc.nr_ext == 2*KMOS_NR_DETECTORS))) && 00842 (desc.ex_badpix == FALSE) && 00843 ((desc.fits_type == raw_fits) || 00844 (desc.fits_type == f2d_fits)) && 00845 (desc.frame_type == detector_frame), 00846 CPL_ERROR_ILLEGAL_INPUT, 00847 "The frame to reconstruct isn't in the correct " 00848 "format!!!"); 00849 kmo_free_fits_desc(&desc); 00850 } 00851 00852 // select IFU for each exposure 00853 KMO_TRY_EXIT_IF_NULL( 00854 empty_frames = cpl_malloc(nr_alloc * sizeof(cpl_frame *))); 00855 int found=0; 00856 for (i = 0; i < nr_science_frames; i++) { 00857 empty_frames[i] = NULL; 00858 if (strcmp(ifus_txt, "") != 0) { //IFU selected by user given list 00859 found = 1; 00860 // const char *tmpString; 00861 exposure_ifus[i] = (int) (cpl_vector_get(ifus, i) + 0.1); 00862 KMO_TRY_EXIT_IF_NULL( 00863 pl = kmclipm_propertylist_load(exposure_filename[i], 0)); 00864 KMO_TRY_EXIT_IF_NULL( 00865 tmp_ocs = cpl_sprintf("%s%d%s", IFU_NAME_PREFIX, 00866 exposure_ifus[i], IFU_NAME_POSTFIX)); 00867 if (cpl_propertylist_has(pl, tmp_ocs)) { 00868 tmp_str = (char*)cpl_propertylist_get_string(pl, tmp_ocs); 00869 } else { 00870 tmp_str = ""; 00871 } 00872 KMO_TRY_EXIT_IF_NULL( 00873 exposure_objectname[i] = cpl_sprintf("%s", tmp_str)); 00874 cpl_free(tmp_ocs); 00875 cpl_propertylist_delete(pl); pl = NULL; 00876 } else { //IFU selected by user given object name 00877 exposure_objectname[i] = (char*)name; 00878 KMO_TRY_EXIT_IF_NULL( 00879 tmp_str = cpl_sprintf("%d", i)); 00880 00881 KMO_TRY_EXIT_IF_NULL( 00882 frame = kmo_dfs_get_frame(exposures, tmp_str)); 00883 cpl_free(tmp_str); 00884 00885 KMO_TRY_CHECK_ERROR_STATE(); 00886 int this_ifu = kmo_get_index_from_ocs_name(frame, name); 00887 KMO_TRY_CHECK_ERROR_STATE(); 00888 if (this_ifu > 0) { 00889 found = 1; 00890 exposure_ifus[i] = this_ifu; 00891 } else { 00892 empty_frames[i] = frame; 00893 exposure_ifus[i] = -1; 00894 cpl_msg_warning("", 00895 "Could not find any IFU with an object " 00896 "named '%s' in file %s", 00897 name, exposure_filename[i]); 00898 } 00899 } 00900 KMO_TRY_CHECK_ERROR_STATE(); 00901 } 00902 if (! found) { 00903 cpl_msg_error("", 00904 "Could not find any IFU with an object named '%s' in " 00905 "any input file", name); 00906 KMO_TRY_EXIT_WITH_ERROR(CPL_ERROR_ILLEGAL_INPUT); 00907 } 00908 int j = 0; 00909 for (i = 0; i < nr_alloc; i++) { 00910 if (empty_frames[i] != NULL) { 00911 KMO_TRY_EXIT_IF_ERROR( 00912 cpl_frameset_erase_frame(exposures, empty_frames[i])); 00913 nr_science_frames--; 00914 exposure_ifus[j] = exposure_ifus[i]; 00915 } else { 00916 exposure_ifus[j] = exposure_ifus[i]; 00917 j++; 00918 } 00919 } 00920 for (i = 0; i < nr_science_frames; i++) { 00921 KMO_TRY_EXIT_IF_NULL( 00922 tmp_str = cpl_sprintf("%d", i)); 00923 00924 KMO_TRY_EXIT_IF_NULL( 00925 frame = kmo_dfs_get_frame(exposures, tmp_str)); 00926 cpl_free(tmp_str); 00927 00928 KMO_TRY_EXIT_IF_NULL( 00929 exposure_filename[i] = (char*)cpl_frame_get_filename(frame)); 00930 } 00931 00932 cpl_free(empty_frames); empty_frames = NULL; 00933 00934 // get reference header, subheader and set grid definition 00935 device_nr = ((exposure_ifus[0] -1) / KMOS_IFUS_PER_DETECTOR) + 1; 00936 00937 KMO_TRY_EXIT_IF_NULL( 00938 ref_main_header = kmclipm_propertylist_load(exposure_filename[0],0)); 00939 KMO_TRY_EXIT_IF_NULL( 00940 ref_frame = cpl_frameset_get_first(exposures)); 00941 KMO_TRY_EXIT_IF_NULL( 00942 ref_sub_header = kmclipm_propertylist_load(exposure_filename[0], 00943 device_nr)); 00944 KMO_TRY_EXIT_IF_ERROR( 00945 kmclipm_setup_grid(&gd, imethod, neighborhoodRange, pix_scale)); 00946 00947 exposure_rotangle = kmo_mr_get_rot_angle(kmo_dfs_get_frame(exposures, "0")); 00948 00949 KMO_TRY_EXIT_IF_NULL( 00950 lcal_frame = kmo_dfs_get_frame(frameset, LCAL)); 00951 00952 KMO_TRY_EXIT_IF_NULL( 00953 lcalImg = kmo_dfs_load_cal_image_frame(lcal_frame, 00954 1, 0, exposure_rotangle, 00955 FALSE, NULL, 00956 &rotangle_found, -1, 0, 0)); 00957 00958 KMO_TRY_EXIT_IF_NULL( 00959 tmp_header = kmo_dfs_load_primary_header(frameset, LCAL)); 00960 00961 KMO_TRY_EXIT_IF_NULL( 00962 keyword = cpl_sprintf("%s%d%s", IFU_FILTID_PREFIX, device_nr, 00963 IFU_FILTID_POSTFIX)); 00964 KMO_TRY_EXIT_IF_NULL( 00965 filter_id = cpl_propertylist_get_string(tmp_header, keyword)); 00966 00967 int band_method = 0; 00968 KMO_TRY_EXIT_IF_NULL( 00969 band_table = kmo_dfs_load_table(frameset, WAVE_BAND, 1, 0)); 00970 00971 KMO_TRY_EXIT_IF_ERROR( 00972 kmclipm_setup_grid_band_lcal(&gd, lcalImg, filter_id, 00973 band_method, band_table)); 00974 cpl_image_delete(lcalImg); lcalImg = NULL; 00975 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00976 cpl_free(keyword); keyword = NULL; 00977 cpl_table_delete(band_table); band_table = NULL; 00978 00979 //extract sub-headers for each exposures, calculate WCS 00980 KMO_TRY_EXIT_IF_NULL( 00981 header_data = cpl_malloc(nr_science_frames*sizeof(cpl_propertylist*))); 00982 for (i = 0; i < nr_science_frames; i++) { 00983 device_nr = ((exposure_ifus[0] -1) / KMOS_IFUS_PER_DETECTOR) + 1; 00984 KMO_TRY_EXIT_IF_NULL( 00985 header_data[i] = kmclipm_propertylist_load(exposure_filename[i], 00986 device_nr)); 00987 KMO_TRY_EXIT_IF_ERROR( 00988 kmclipm_update_property_int(header_data[i],"NAXIS", 3,"")); 00989 KMO_TRY_EXIT_IF_ERROR( 00990 kmclipm_update_property_int(header_data[i],"NAXIS1",gd.x.dim,"")); 00991 KMO_TRY_EXIT_IF_ERROR( 00992 kmclipm_update_property_int(header_data[i],"NAXIS2",gd.y.dim,"")); 00993 KMO_TRY_EXIT_IF_ERROR( 00994 kmclipm_update_property_int(header_data[i],"NAXIS3",gd.l.dim,"")); 00995 cpl_propertylist *tmpHeader; 00996 KMO_TRY_EXIT_IF_NULL( 00997 tmpHeader = kmclipm_propertylist_load(exposure_filename[i],0)); 00998 KMO_TRY_EXIT_IF_ERROR( 00999 kmo_calc_wcs_gd(tmpHeader, header_data[i], exposure_ifus[i], gd)); 01000 cpl_propertylist_delete(tmpHeader); 01001 } 01002 01003 // check rotation angle 01004 if (dev_cal == FALSE) { 01005 cd1_1 = kmo_dfs_get_property_double(header_data[0], CD1_1); 01006 cd1_2 = kmo_dfs_get_property_double(header_data[0], CD1_2); 01007 KMO_TRY_CHECK_ERROR_STATE(); 01008 ang1 = atan(cd1_2/cd1_1)*180/CPL_MATH_PI; 01009 for (i = 1; i < nr_science_frames; i++) { 01010 cd1_1 = kmo_dfs_get_property_double(header_data[i], CD1_1); 01011 cd1_2 = kmo_dfs_get_property_double(header_data[i], CD1_2); 01012 KMO_TRY_CHECK_ERROR_STATE(); 01013 ang2 = atan(cd1_2/cd1_1)*180/CPL_MATH_PI; 01014 01015 if (strcmp(smethod, "none") != 0) { 01016 // center, header, user 01017 KMO_TRY_ASSURE(fabs(ang1-ang2) <= 0.5, 01018 CPL_ERROR_ILLEGAL_INPUT, 01019 "Orientation of cube 1 (%gdeg) and cube %d " 01020 "(%gdeg) differ! " 01021 "Align the orientation of this cube with " 01022 "kmo_rotate before applying this recipe.", 01023 ang1, i+1, ang2); 01024 } else { 01025 // none 01026 if (fabs(ang1-ang2) > 0.5) { 01027 cpl_msg_warning("", 01028 "Orientation of cube 1 (%gdeg) and cube %d " 01029 "(%gdeg) differ! Processing anyway.", 01030 ang1, i+1, ang2); 01031 } 01032 } 01033 } 01034 } 01035 01036 // set x/y shifts 01037 KMO_TRY_EXIT_IF_NULL( 01038 xshifts = cpl_malloc(nr_science_frames * sizeof(double))); 01039 KMO_TRY_EXIT_IF_NULL( 01040 yshifts = cpl_malloc(nr_science_frames * sizeof(double))); 01041 KMO_TRY_EXIT_IF_ERROR( 01042 kmo_mr_get_offsets(nr_science_frames, smethod, imethod, neighborhoodRange, 01043 filename, frameset, exposures, exposure_ifus, 01044 (const cpl_propertylist**)header_data, 01045 fmethod, 01046 cmethod, 01047 cpos_rej, 01048 cneg_rej, 01049 citer, 01050 cmin, 01051 cmax, 01052 pix_scale, 01053 xshifts, yshifts)); 01054 01055 for (i = 0; i < nr_science_frames; i++) { 01056 printf("exposure %d: filename %s, selected IFU %d, object name " 01057 "\"%s\", xshift %f, yshift %f\n", i, exposure_filename[i], 01058 exposure_ifus[i], exposure_objectname[i], xshifts[i], yshifts[i]); 01059 } 01060 01061 // 01062 // set spatial part of the grid 01063 // 01064 // size = "max"; 01065 if (strcmp(size, "max") == 0) { 01066 double xmin=0, xmax=0, ymin=0, ymax=0; 01067 double gxshift, gyshift, gxdim, gydim; 01068 double pixel_resolution = pix_scale; 01069 int xdim, ydim; 01070 01071 for (i = 0; i < nr_science_frames; i++) { 01072 if (xmin > xshifts[i]) { xmin = xshifts[i]; } 01073 if (xmax < xshifts[i]) { xmax = xshifts[i]; } 01074 if (ymin > yshifts[i]) { ymin = yshifts[i]; } 01075 if (ymax < yshifts[i]) { ymax = yshifts[i]; } 01076 } 01077 if (xmax > 0.0001) { 01078 gxshift = - ceil(xmax); 01079 } else { 01080 gxshift = 0.; 01081 } 01082 if (ymin < -0.0001) { 01083 gyshift = floor(ymin); 01084 } else { 01085 gyshift = 0.; 01086 } 01087 if (xmin < -0.0001) { 01088 gxdim = - floor(xmin); 01089 } else { 01090 gxdim = 0.; 01091 } 01092 if (ymax > 0.0001) { 01093 gydim = ceil(ymax); 01094 } else { 01095 gydim = 0.; 01096 } 01097 01098 xdim = (int) (gxdim - gxshift + .5); 01099 ydim = (int) (gydim - gyshift + .5); 01100 gd.x.start += gxshift * pixel_resolution; 01101 gd.y.start += gyshift * pixel_resolution; 01102 gd.x.dim += xdim; 01103 gd.y.dim += ydim; 01104 // printf("X: %f < %f Y: %f < %f \n",xmin,xmax,ymin,ymax); 01105 // printf("gxshift: %f gxdim: %f xdim: %d gyshift: %f gydim: %f ydim: %d \n", 01106 // gxshift, gxdim, xdim, gyshift, gydim, ydim); 01107 // printf("GD: %f %d %f %d\n", gd.x.start, gd.x.dim, gd.y.start, gd.y.dim); 01108 } 01109 01110 // 01111 // reconstruct multiple detector images 01112 // 01113 01114 // printf("GD: %f %f %d %f %f %d %f %f %d\n", 01115 // gd.x.start, gd.x.delta, gd.x.dim, 01116 // gd.y.start, gd.y.delta, gd.y.dim, 01117 // gd.l.start, gd.l.delta, gd.l.dim); 01118 01119 KMO_TRY_EXIT_IF_ERROR( 01120 kmo_priv_multi_reconstruct(frameset, 01121 exposures, 01122 exposure_ifus, 01123 xshifts, 01124 yshifts, 01125 gd, 01126 &cube_combined_data, 01127 &cube_combined_noise, 01128 pix_scale)); 01129 01130 if (!suppress_extension) { 01131 // setup output category COMBINE + ESO PRO CATG 01132 if (strcmp(ifus_txt, "") != 0) { //IFU selected by user given list 01133 KMO_TRY_EXIT_IF_NULL( 01134 tmp_str = cpl_sprintf("IFU")); 01135 } else { 01136 KMO_TRY_EXIT_IF_NULL( 01137 tmp_str = cpl_sprintf("%s", name)); 01138 } 01139 01140 KMO_TRY_EXIT_IF_NULL( 01141 filename_output_cube = cpl_sprintf("%s_%s", CUBE_MULTI, tmp_str)); 01142 cpl_free(tmp_str); tmp_str = NULL; 01143 } else { 01144 KMO_TRY_EXIT_IF_NULL( 01145 filename_output_cube = cpl_sprintf("%s", CUBE_MULTI)); 01146 } 01147 01148 KMO_TRY_EXIT_IF_ERROR( 01149 kmo_dfs_save_main_header(frameset, filename_output_cube, "", 01150 ref_frame, NULL, parlist, cpl_func)); 01151 // save output 01152 KMO_TRY_EXIT_IF_NULL( 01153 extname = kmo_extname_creator(ifu_frame, exposure_ifus[0], 01154 EXT_DATA)); 01155 01156 // calculate WCS 01157 KMO_TRY_EXIT_IF_ERROR( 01158 kmo_calc_wcs_gd(ref_main_header, ref_sub_header, exposure_ifus[0], gd)); 01159 01160 KMO_TRY_EXIT_IF_ERROR( 01161 kmclipm_update_property_string(ref_sub_header, 01162 EXTNAME, 01163 extname, 01164 "FITS extension name")); 01165 cpl_free(extname); extname = NULL; 01166 01167 KMO_TRY_EXIT_IF_ERROR( 01168 kmo_dfs_save_cube(cube_combined_data, filename_output_cube, 01169 "", ref_sub_header, 0./0.)); 01170 01171 if (cube_combined_noise != NULL) { 01172 KMO_TRY_EXIT_IF_NULL( 01173 extname = kmo_extname_creator(ifu_frame, exposure_ifus[0], 01174 EXT_NOISE)); 01175 01176 KMO_TRY_EXIT_IF_ERROR( 01177 kmclipm_update_property_string(ref_sub_header, 01178 EXTNAME, 01179 extname, 01180 "FITS extension name")); 01181 cpl_free(extname); extname = NULL; 01182 01183 KMO_TRY_EXIT_IF_ERROR( 01184 kmo_dfs_save_cube(cube_combined_noise, filename_output_cube, 01185 "", ref_sub_header, 0./0.)); 01186 } 01187 } 01188 KMO_CATCH 01189 { 01190 KMO_CATCH_MSG(); 01191 ret_val = -1; 01192 } 01193 01194 cpl_free(suffix); suffix = NULL; 01195 cpl_free(filename_output_cube); filename_output_cube = NULL; 01196 cpl_propertylist_delete(main_header); main_header = NULL; 01197 cpl_vector_delete(ifus); ifus = NULL; 01198 cpl_imagelist_delete(cube_combined_data); cube_combined_data = NULL; 01199 cpl_imagelist_delete(cube_combined_noise); cube_combined_noise = NULL; 01200 if (exposures != NULL) {cpl_frameset_delete(exposures);} 01201 if (exposure_filename != NULL) {cpl_free(exposure_filename);} 01202 if ((ifus_txt != NULL) && (strcmp(ifus_txt, "") != 0)) { //IFU selected by user given list 01203 for (i = 0; i < nr_alloc; i++) { 01204 cpl_free(exposure_objectname[i]); 01205 } 01206 } 01207 if (exposure_objectname != NULL) {cpl_free(exposure_objectname);} 01208 if (exposure_ifus != NULL) {cpl_free(exposure_ifus);} 01209 if (ref_main_header != NULL) {cpl_propertylist_delete(ref_main_header);} 01210 if (ref_sub_header != NULL) {cpl_propertylist_delete(ref_sub_header);} 01211 if (xshifts != NULL) {cpl_free(xshifts);} 01212 if (yshifts != NULL) {cpl_free(yshifts);} 01213 01214 if (data_cube_list != NULL) { 01215 for (i = 0; i < nr_science_frames; i++) { 01216 cpl_imagelist_delete(data_cube_list[i]); data_cube_list[i] = NULL; 01217 } 01218 cpl_free(data_cube_list); data_cube_list = NULL; 01219 } 01220 01221 if (noise_cube_list != NULL) { 01222 for (i = 0; i < nr_science_frames; i++) { 01223 cpl_imagelist_delete(noise_cube_list[i]); noise_cube_list[i] = NULL; 01224 } 01225 cpl_free(noise_cube_list); noise_cube_list = NULL; 01226 } 01227 01228 if (data_header_list != NULL) { 01229 for (i = 0; i < nr_science_frames; i++) { 01230 cpl_propertylist_delete(data_header_list[i]); 01231 data_header_list[i] = NULL; 01232 } 01233 cpl_free(data_header_list); data_header_list = NULL; 01234 } 01235 01236 if (noise_header_list != NULL) { 01237 for (i = 0; i < nr_science_frames; i++) { 01238 cpl_propertylist_delete(noise_header_list[i]); 01239 noise_header_list[i] = NULL; 01240 } 01241 cpl_free(noise_header_list); noise_header_list = NULL; 01242 } 01243 01244 if (header_data != NULL) { 01245 for (i = 0; i < nr_science_frames; i++) { 01246 cpl_propertylist_delete(header_data[i]); 01247 header_data[i] = NULL; 01248 } 01249 cpl_free(header_data); header_data = NULL; 01250 } 01251 01252 return ret_val; 01253 } 01254
1.7.6.1