|
KMOS Pipeline Reference Manual
1.1.5
|
00001 /* $Id: kmo_combine.c,v 1.29 2013/05/24 14:32:23 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/05/24 14:32:23 $ 00024 * $Revision: 1.29 $ 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_combine.h" 00046 00047 static int kmo_combine_create(cpl_plugin *); 00048 static int kmo_combine_exec(cpl_plugin *); 00049 static int kmo_combine_destroy(cpl_plugin *); 00050 static int kmo_combine(cpl_parameterlist *, cpl_frameset *); 00051 00052 static char kmo_combine_description[] = 00053 "This recipe shifts several exposures of an object and combines them. The diffe-\n" 00054 "rent methods to match the exposures are described below (--method parameter).\n" 00055 "The output cube is larger than the input cubes, according to the shifts to be\n" 00056 "applied. Additionally a border of NaN values is added. The WCS is the same as\n" 00057 "for the first exposure.\n" 00058 "For each spatial/spectral pixel a new value will be calculated (according the\n" 00059 "--cmethod parameter) and written into the output cube.\n" 00060 "Only exposures with equal orientation regarding the WCS can be combined (except\n" 00061 "-–method=”none”), north must point to the same direction. It is recommended to\n" 00062 "apply any rotation possibly after combining.\n" 00063 "The default mapping mode is done via the --name parameter, where the name of\n" 00064 "the object has to be provided. The recipe searches in all input data cubes IFUs\n" 00065 "pointing to that object.\n" 00066 "\n" 00067 "BASIC PARAMETERS:\n" 00068 "-----------------\n" 00069 "--name\n" 00070 "--ifus\n" 00071 "Since an object can be present only once per exposure and since it can be\n" 00072 "located in different IFUs for the existing exposures, there are two modes to\n" 00073 "identify the objects:\n" 00074 " * Combine by object names (default)\n" 00075 " In this case the object name must be provided via the --name parameter. The\n" 00076 " object name will be searched for in all primary headers of all provided frames\n" 00077 " in the keyword ESO OCS ARMx NAME.\n" 00078 "\n" 00079 " * Combine by index (advanced)\n" 00080 " In this case the --ifus parameter must be provided. The parameter must have\n" 00081 " the same number of entries as frames are provided, e.g. \"3;1;24\" for 3 expo-\n" 00082 " sures. The index doesn't reference the extension in the frame but the real\n" 00083 " index of the IFU as defined in the EXTNAME keyword (e.g. 'IFU.3.DATA').\n" 00084 "\n" 00085 "--method\n" 00086 "There are following sources to get the shift parameters from:\n" 00087 " * 'none' (default)\n" 00088 " The cubes are directly recombined, not shifting at all. The ouput frame will\n" 00089 " have the same dimensions as the input cubes.\n" 00090 " If the size differs a warning will be emitted and the cubes will be aligned\n" 00091 " to the lower left corner. If the orientation differs a warning will be emit-\n" 00092 " ted, but the cubes are combined anyway.\n" 00093 "\n" 00094 " * 'header'\n" 00095 " The shifts are calculated according to the WCS information stored in the\n" 00096 " header of every IFU. The output frame will get larger, except the object is\n" 00097 " at the exact same position for all exposures. The size of the exposures can\n" 00098 " differ, but the orientation must be the same for all exposures.\n" 00099 "\n" 00100 " * 'center'\n" 00101 " The shifts are calculated using a centering algorithm. The cube will be col-\n" 00102 " lapsed and a 2D profile will be fitted to it to identify the centre. With \n" 00103 " the parameter --fmethod the function to fit can be provided. The size of the\n" 00104 " exposures can differ, but the orientation must be the same for all exposures.\n" 00105 "\n" 00106 " * 'user'\n" 00107 " Read the shifts from a user specified file. The path of the file must be pro-\n" 00108 " vided using the --filename parameter. For every exposure (except the first one)\n" 00109 " two shift values are expected per line, they have to be separated with simple\n" 00110 " spaces. The values indicate pixel shifts and are referenced to the first\n" 00111 " frame. The 1st value is the shift in x-direction to the left, the 2nd the\n" 00112 " shift in y-direction upwards. The size of the exposures can differ, but the\n" 00113 " orientation must be the same for all exposures.\n" 00114 "\n" 00115 "ADVANCED PARAMETERS\n" 00116 "-------------------\n" 00117 "--edge_nan\n" 00118 "Set borders of two sides of the cubes to NaN before combining them. This minimises\n" 00119 "unwanted border effects when dithering.\n" 00120 "\n" 00121 "--fmethod\n" 00122 "see --method='center'\n" 00123 "The type of function that should be fitted spatially to the collapsed image.\n" 00124 "This fit is used to create a mask to extract the spectrum of the object. Valid\n" 00125 "values are “gauss” and “moffat”.\n" 00126 "\n" 00127 "--filename\n" 00128 "see --method='user'\n" 00129 "\n" 00130 "--cpos_rej\n" 00131 "--cneg_rej\n" 00132 "--citer\n" 00133 "see --cmethod='ksigma'\n" 00134 "\n" 00135 "--cmax\n" 00136 "--cmin\n" 00137 "see --cmethod='min_max'\n" 00138 "\n" 00139 "--flux\n" 00140 "Specify if flux conservation should be applied.\n" 00141 "--suppress_extension\n" 00142 "If set to TRUE, the arbitrary filename extensions are supressed. If multiple\n" 00143 "products with the same category are produced, they will be numered consecutively\n" 00144 "starting from 0.\n" 00145 "\n" 00146 "-------------------------------------------------------------------------------\n" 00147 " Input files:\n" 00148 "\n" 00149 " DO KMOS \n" 00150 " category Type Explanation Required #Frames\n" 00151 " -------- ----- ----------- -------- -------\n" 00152 " <none or any> F3I data frame Y 2-n \n" 00153 "\n" 00154 " Output files:\n" 00155 "\n" 00156 " DO KMOS\n" 00157 " category Type Explanation\n" 00158 " -------- ----- -----------\n" 00159 " COMBINE_<ESO PRO CATG> F3I Combined data cube\n" 00160 "-------------------------------------------------------------------------------\n" 00161 "\n"; 00162 00179 int cpl_plugin_get_info(cpl_pluginlist *list) 00180 { 00181 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00182 cpl_plugin *plugin = &recipe->interface; 00183 00184 cpl_plugin_init(plugin, 00185 CPL_PLUGIN_API, 00186 KMOS_BINARY_VERSION, 00187 CPL_PLUGIN_TYPE_RECIPE, 00188 "kmo_combine", 00189 "Combine reconstructed cubes", 00190 kmo_combine_description, 00191 "Alex Agudo Berbel", 00192 "kmos-spark@mpe.mpg.de", 00193 kmos_get_license(), 00194 kmo_combine_create, 00195 kmo_combine_exec, 00196 kmo_combine_destroy); 00197 00198 cpl_pluginlist_append(list, plugin); 00199 00200 return 0; 00201 } 00202 00210 static int kmo_combine_create(cpl_plugin *plugin) 00211 { 00212 cpl_recipe *recipe; 00213 cpl_parameter *p; 00214 00215 /* Check that the plugin is part of a valid recipe */ 00216 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00217 recipe = (cpl_recipe *)plugin; 00218 else 00219 return -1; 00220 00221 /* Create the parameters list in the cpl_recipe object */ 00222 recipe->parameters = cpl_parameterlist_new(); 00223 00224 /* Fill the parameters list */ 00225 /* --name */ 00226 p = cpl_parameter_new_value("kmos.kmo_combine.name", 00227 CPL_TYPE_STRING, 00228 "Name of the object to combine.", 00229 "kmos.kmo_combine", 00230 ""); 00231 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "name"); 00232 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00233 cpl_parameterlist_append(recipe->parameters, p); 00234 00235 /* --ifus */ 00236 p = cpl_parameter_new_value("kmos.kmo_combine.ifus", 00237 CPL_TYPE_STRING, 00238 "The indices of the IFUs to combine. " 00239 "\"ifu1;ifu2;...\"", 00240 "kmos.kmo_combine", 00241 ""); 00242 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ifus"); 00243 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00244 cpl_parameterlist_append(recipe->parameters, p); 00245 00246 /* --method */ 00247 p = cpl_parameter_new_value("kmos.kmo_combine.method", 00248 CPL_TYPE_STRING, 00249 "The shifting method: " 00250 "'none': no shifting, combined directly " 00251 "(default), " 00252 "'header': shift according to WCS, " 00253 "'center': centering algorithm, " 00254 "'user': read shifts from file", 00255 "kmos.kmo_combine", 00256 "none"); 00257 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "method"); 00258 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00259 cpl_parameterlist_append(recipe->parameters, p); 00260 00261 /* --fmethod */ 00262 p = cpl_parameter_new_value("kmos.kmo_combine.fmethod", 00263 CPL_TYPE_STRING, 00264 "The fitting method (applies only when " 00265 "method='center'): " 00266 "'gauss': fit a gauss function to collapsed " 00267 "image (default), " 00268 "'moffat': fit a moffat function to collapsed" 00269 " image", 00270 "kmos.kmo_combine", 00271 "gauss"); 00272 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fmethod"); 00273 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00274 cpl_parameterlist_append(recipe->parameters, p); 00275 00276 /* --filename */ 00277 p = cpl_parameter_new_value("kmos.kmo_combine.filename", 00278 CPL_TYPE_STRING, 00279 "The path to the file with the shift vectors." 00280 "(Applies only to method='user')", 00281 "kmos.kmo_combine", 00282 ""); 00283 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "filename"); 00284 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00285 cpl_parameterlist_append(recipe->parameters, p); 00286 00287 /* --flux */ 00288 p = cpl_parameter_new_value("kmos.kmo_combine.flux", 00289 CPL_TYPE_BOOL, 00290 "Apply flux conservation: " 00291 "(TRUE (apply) or " 00292 "FALSE (don't apply)", 00293 "kmos.kmo_combine", 00294 FALSE); 00295 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "flux"); 00296 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00297 cpl_parameterlist_append(recipe->parameters, p); 00298 00299 /* --edge_nan */ 00300 p = cpl_parameter_new_value("kmos.kmo_combine.edge_nan", 00301 CPL_TYPE_BOOL, 00302 "Set borders of cubes to NaN before combining them." 00303 "(TRUE (apply) or " 00304 "FALSE (don't apply)", 00305 "kmos.kmo_combine", 00306 FALSE); 00307 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "edge_nan"); 00308 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00309 cpl_parameterlist_append(recipe->parameters, p); 00310 00311 /* --suppress_extension */ 00312 p = cpl_parameter_new_value("kmos.kmo_combine.suppress_extension", 00313 CPL_TYPE_BOOL, 00314 "Suppress arbitrary filename extension." 00315 "(TRUE (apply) or FALSE (don't apply)", 00316 "kmos.kmo_combine", 00317 FALSE); 00318 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "suppress_extension"); 00319 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00320 cpl_parameterlist_append(recipe->parameters, p); 00321 00322 return kmo_combine_pars_create(recipe->parameters, 00323 "kmos.kmo_combine", 00324 DEF_REJ_METHOD, 00325 FALSE); 00326 } 00327 00333 static int kmo_combine_exec(cpl_plugin *plugin) 00334 { 00335 cpl_recipe *recipe; 00336 00337 /* Get the recipe out of the plugin */ 00338 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00339 recipe = (cpl_recipe *)plugin; 00340 else return -1 ; 00341 00342 return kmo_combine(recipe->parameters, recipe->frames); 00343 } 00344 00350 static int kmo_combine_destroy(cpl_plugin *plugin) 00351 { 00352 cpl_recipe *recipe; 00353 00354 /* Get the recipe out of the plugin */ 00355 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00356 recipe = (cpl_recipe *)plugin; 00357 else return -1 ; 00358 00359 cpl_parameterlist_delete(recipe->parameters); 00360 return 0 ; 00361 } 00362 00363 //int kmo_tolerance_round(double x, double tol) 00364 //{ 00365 // int ret = 0; 00366 00367 // KMO_TRY 00368 // { 00369 // if (fabs(x - floor(x)) < tol) { 00370 // // value is slightly greater than the real int value 00371 // ret = floor(x); 00372 // } else { 00373 // if (fabs(x - floor(x+tol)) < tol) { 00374 // // value is slightly greater than the real int value 00375 // ret = floor(x+tol); 00376 // } else { 00377 // // error: sub pixel shift 00378 // KMO_TRY_ASSURE(1 == 0, 00379 // CPL_ERROR_ILLEGAL_INPUT, 00380 // "Please apply only whole pixel shifts here " 00381 // "and no subpixel shifts!"); 00382 // } 00383 // } 00384 // } 00385 // KMO_CATCH 00386 // { 00387 // KMO_CATCH_MSG(); 00388 00389 // ret = 0; 00390 // } 00391 00392 // return ret; 00393 //} 00394 00409 static int kmo_combine(cpl_parameterlist *parlist, cpl_frameset *frameset) 00410 { 00411 const char *method = NULL, 00412 *cmethod = NULL, 00413 *fmethod = NULL, 00414 *filename = NULL, 00415 *frame_filename = NULL, 00416 *ifus_txt = NULL, 00417 *tmp_strc = NULL; 00418 00419 char *tmp_str = NULL, 00420 *mapping_mode = NULL, 00421 *name = NULL, 00422 **name_vec = NULL; 00423 00424 cpl_imagelist **data_cube_list = NULL, 00425 **noise_cube_list = NULL, 00426 *cube_combined_data = NULL, 00427 *cube_combined_noise= NULL; 00428 00429 cpl_vector *ifus = NULL; 00430 00431 int ret_val = 0, 00432 nr_frames = 0, 00433 index = 0, 00434 data_cube_counter = 0, 00435 noise_cube_counter = 0, 00436 ifu_nr = 0, 00437 citer = 0, 00438 cmin = 0, 00439 cmax = 0, 00440 flux = FALSE, 00441 edge_nan = FALSE, 00442 name_vec_size = 0, 00443 found = 0, 00444 suppress_extension = FALSE, 00445 suppress_index = 0; 00446 00447 double cpos_rej = 0.0, 00448 cneg_rej = 0.0; 00449 00450 cpl_propertylist *main_header = NULL, 00451 **data_header_list = NULL, 00452 **noise_header_list = NULL, 00453 *tmp_header = NULL; 00454 00455 cpl_frame *frame = NULL; 00456 00457 main_fits_desc desc; 00458 00459 enum extrapolationType extrapol_enum = NONE_CLIPPING; 00460 00461 KMO_TRY 00462 { 00463 /* --- check input --- */ 00464 KMO_TRY_ASSURE((parlist != NULL) && 00465 (frameset != NULL), 00466 CPL_ERROR_NULL_INPUT, 00467 "Not all input data is provided!"); 00468 00469 nr_frames = cpl_frameset_get_size(frameset); 00470 00471 KMO_TRY_ASSURE(nr_frames >= 2, 00472 CPL_ERROR_NULL_INPUT, 00473 "At least two frames must be provided to combine!"); 00474 00475 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_combine") == 1, 00476 CPL_ERROR_ILLEGAL_INPUT, 00477 "Cannot identify RAW and CALIB frames!"); 00478 00479 cpl_msg_info("", "--- Parameter setup for kmo_combine -------"); 00480 00481 KMO_TRY_EXIT_IF_NULL( 00482 method = kmo_dfs_get_parameter_string(parlist, 00483 "kmos.kmo_combine.method")); 00484 00485 KMO_TRY_EXIT_IF_NULL( 00486 fmethod = kmo_dfs_get_parameter_string(parlist, 00487 "kmos.kmo_combine.fmethod")); 00488 00489 KMO_TRY_ASSURE((strcmp(method, "none") == 0) || 00490 (strcmp(method, "header") == 0) || 00491 (strcmp(method, "center") == 0) || 00492 (strcmp(method, "user") == 0), 00493 CPL_ERROR_ILLEGAL_INPUT, 00494 "Following shift methods are available : 'none', " 00495 "'header', 'center' or 'user'"); 00496 00497 if (strcmp(method, "user") == 0) { 00498 filename = kmo_dfs_get_parameter_string(parlist, 00499 "kmos.kmo_combine.filename"); 00500 KMO_TRY_CHECK_ERROR_STATE(); 00501 00502 KMO_TRY_ASSURE(strcmp(filename, "") != 0, 00503 CPL_ERROR_ILLEGAL_INPUT, 00504 "path of file with shift information must be " 00505 "provided!"); 00506 00507 KMO_TRY_EXIT_IF_ERROR( 00508 kmo_dfs_print_parameter_help(parlist, 00509 "kmos.kmo_combine.filename")); 00510 } 00511 00512 KMO_TRY_EXIT_IF_ERROR( 00513 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_combine.method")); 00514 00515 ifus_txt = kmo_dfs_get_parameter_string(parlist, 00516 "kmos.kmo_combine.ifus"); 00517 KMO_TRY_CHECK_ERROR_STATE(); 00518 00519 name = (char*)kmo_dfs_get_parameter_string(parlist, "kmos.kmo_combine.name"); 00520 KMO_TRY_CHECK_ERROR_STATE(); 00521 00522 if (strcmp(ifus_txt, "") != 0) { 00523 KMO_TRY_ASSURE(strcmp(name, "") == 0, 00524 CPL_ERROR_ILLEGAL_INPUT, 00525 "name parameter must be NULL if IFU indices are " 00526 "provided!"); 00527 00528 KMO_TRY_EXIT_IF_NULL( 00529 ifus = kmo_identify_values(ifus_txt)); 00530 00531 KMO_TRY_ASSURE(cpl_vector_get_size(ifus) == nr_frames, 00532 CPL_ERROR_ILLEGAL_INPUT, 00533 "ifus parameter must have the same number of values " 00534 "than frames provided ) (%lld!=%d)", 00535 cpl_vector_get_size(ifus), nr_frames); 00536 } 00537 00538 if (strcmp(name, "") != 0) { 00539 KMO_TRY_ASSURE(strcmp(ifus_txt, "") == 0, 00540 CPL_ERROR_ILLEGAL_INPUT, 00541 "ifus parameter must be NULL if name is provided!"); 00542 } 00543 00544 flux = kmo_dfs_get_parameter_bool(parlist, 00545 "kmos.kmo_combine.flux"); 00546 KMO_TRY_CHECK_ERROR_STATE(); 00547 KMO_TRY_EXIT_IF_ERROR( 00548 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_combine.flux")); 00549 00550 KMO_TRY_ASSURE((flux == TRUE) || (flux == FALSE), 00551 CPL_ERROR_ILLEGAL_INPUT, 00552 "flux must be TRUE or FALSE!"); 00553 00554 edge_nan = kmo_dfs_get_parameter_bool(parlist, 00555 "kmos.kmo_combine.edge_nan"); 00556 KMO_TRY_CHECK_ERROR_STATE(); 00557 KMO_TRY_EXIT_IF_ERROR( 00558 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_combine.edge_nan")); 00559 00560 KMO_TRY_ASSURE((edge_nan == TRUE) || (edge_nan == FALSE), 00561 CPL_ERROR_ILLEGAL_INPUT, 00562 "edge_nan must be TRUE or FALSE!"); 00563 00564 suppress_extension = kmo_dfs_get_parameter_bool(parlist, 00565 "kmos.kmo_combine.suppress_extension"); 00566 KMO_TRY_CHECK_ERROR_STATE(); 00567 KMO_TRY_EXIT_IF_ERROR( 00568 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_combine.suppress_extension")); 00569 00570 KMO_TRY_ASSURE((suppress_extension == TRUE) || (suppress_extension == FALSE), 00571 CPL_ERROR_ILLEGAL_INPUT, 00572 "suppress_extension must be TRUE or FALSE!"); 00573 00574 KMO_TRY_EXIT_IF_ERROR( 00575 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_combine.ifus")); 00576 00577 KMO_TRY_EXIT_IF_ERROR( 00578 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_combine.name")); 00579 00580 KMO_TRY_EXIT_IF_ERROR( 00581 kmo_combine_pars_load(parlist, 00582 "kmos.kmo_combine", 00583 &cmethod, 00584 &cpos_rej, 00585 &cneg_rej, 00586 &citer, 00587 &cmin, 00588 &cmax, 00589 FALSE)); 00590 00591 cpl_msg_info("", "-------------------------------------------"); 00592 00593 // load data and noise 00594 KMO_TRY_EXIT_IF_NULL( 00595 data_cube_list = cpl_calloc(nr_frames*KMOS_NR_IFUS, 00596 sizeof(cpl_imagelist*))); 00597 00598 KMO_TRY_EXIT_IF_NULL( 00599 data_header_list = cpl_calloc(nr_frames*KMOS_NR_IFUS, 00600 sizeof(cpl_propertylist*))); 00601 00602 KMO_TRY_EXIT_IF_NULL( 00603 noise_cube_list = cpl_calloc(nr_frames*KMOS_NR_IFUS, 00604 sizeof(cpl_imagelist*))); 00605 00606 KMO_TRY_EXIT_IF_NULL( 00607 noise_header_list = cpl_calloc(nr_frames*KMOS_NR_IFUS, 00608 sizeof(cpl_propertylist*))); 00609 00610 // 00611 // check for mapping mode 00612 // 00613 cpl_size fs_size = cpl_frameset_get_size(frameset); 00614 KMO_TRY_CHECK_ERROR_STATE(); 00615 00616 for (cpl_size i = 0; i < fs_size; i++) { 00617 KMO_TRY_EXIT_IF_NULL( 00618 frame = cpl_frameset_get_position(frameset, i)); 00619 00620 KMO_TRY_EXIT_IF_NULL( 00621 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(frame), 0)); 00622 if (cpl_propertylist_has(tmp_header, TPL_ID)) { 00623 KMO_TRY_EXIT_IF_NULL( 00624 tmp_strc = cpl_propertylist_get_string(tmp_header, TPL_ID)); 00625 if (mapping_mode == NULL) { 00626 if (strcmp(tmp_strc, MAPPING8) == 0) 00627 { 00628 mapping_mode = cpl_sprintf("%s", tmp_strc); 00629 } 00630 if (strcmp(tmp_strc, MAPPING24) == 0) 00631 { 00632 mapping_mode = cpl_sprintf("%s", tmp_strc); 00633 } 00634 } else { 00635 if (strcmp(tmp_strc, mapping_mode) != 0) 00636 { 00637 cpl_msg_warning("","There are different TPL IDs present in " 00638 "the set of frames: %s and %s", 00639 tmp_strc, mapping_mode); 00640 } 00641 } 00642 } 00643 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00644 } 00645 00646 if (mapping_mode != NULL) { 00647 if ((strcmp(ifus_txt, "") == 0) && (strcmp(name, "") == 0)) { 00648 cpl_msg_info("","**************************************************"); 00649 cpl_msg_info("","* A map containing all IFUs will be generated! *"); 00650 cpl_msg_info("","**************************************************"); 00651 extrapol_enum = BCS_NATURAL; 00652 } else { 00653 cpl_msg_info("","The frames aren't combined into a map although they originate " 00654 "from a mapping template. But since the name- or ifu-parameter " 00655 "has been specified, the default behaviour is overridden."); 00656 cpl_free(mapping_mode); mapping_mode = NULL; 00657 } 00658 } 00659 00660 // 00661 // create name/ifu map... 00662 // 00663 KMO_TRY_EXIT_IF_NULL( 00664 name_vec = cpl_calloc(nr_frames*KMOS_NR_IFUS, sizeof(char*))); 00665 00666 if ((strcmp(ifus_txt, "") == 0) && 00667 (strcmp(name, "") == 0) && 00668 (mapping_mode == NULL)) 00669 { 00670 // all available names should be combined in one go 00671 name_vec_size = 0; 00672 for (int i = 0; i < nr_frames; i++) { 00673 KMO_TRY_EXIT_IF_NULL( 00674 tmp_str = cpl_sprintf("%d", i)); 00675 KMO_TRY_EXIT_IF_NULL( 00676 frame = kmo_dfs_get_frame(frameset, tmp_str)); 00677 cpl_free(tmp_str); tmp_str = NULL; 00678 00679 for (int ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 00680 tmp_str = kmo_get_name_from_ocs_ifu(frame, ifu_nr); 00681 KMO_TRY_CHECK_ERROR_STATE(); 00682 found = 0; 00683 for (int j = 0; j < name_vec_size; j++) { 00684 if (strcmp(name_vec[j], tmp_str) == 0) { 00685 found = TRUE; 00686 break; 00687 } 00688 } 00689 if (!found) { 00690 name_vec[name_vec_size++] = tmp_str; 00691 } else { 00692 cpl_free(tmp_str); tmp_str = NULL; 00693 } 00694 } 00695 } 00696 } else { 00697 // standard behavior: either ifu_nr- or name- or mapping-case 00698 name_vec_size = 1; 00699 if (mapping_mode != NULL) { 00700 KMO_TRY_EXIT_IF_NULL( 00701 name_vec[0] = cpl_sprintf("mapping")); 00702 } else { 00703 if (ifus != NULL) { 00704 KMO_TRY_EXIT_IF_NULL( 00705 name_vec[0] = cpl_sprintf("IFU%s", ifus_txt)); 00706 } else { 00707 KMO_TRY_EXIT_IF_NULL( 00708 name_vec[0] = cpl_sprintf("%s", name)); 00709 } 00710 } 00711 } 00712 00713 // 00714 // load all data (and noise if existent) cubes and store them 00715 // 00716 for (int nv = 0; nv < name_vec_size; nv++){ 00717 name = name_vec[nv]; 00718 00719 data_cube_counter = 0; 00720 noise_cube_counter = 0; 00721 for (int i = 0; i < nr_frames; i++) { 00722 KMO_TRY_EXIT_IF_NULL( 00723 tmp_str = cpl_sprintf("%d", i)); 00724 00725 KMO_TRY_EXIT_IF_NULL( 00726 frame = kmo_dfs_get_frame(frameset, tmp_str)); 00727 00728 KMO_TRY_EXIT_IF_NULL( 00729 frame_filename = cpl_frame_get_filename(frame)); 00730 00731 kmo_init_fits_desc(&desc); 00732 00733 desc = kmo_identify_fits_header(frame_filename); 00734 KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to " 00735 "be in KMOS-format!"); 00736 00737 KMO_TRY_ASSURE(desc.fits_type == f3i_fits, 00738 CPL_ERROR_ILLEGAL_INPUT, 00739 "Frame No. %d hasn't correct data type " 00740 "(must be of type F3I)!", i+1); 00741 00742 if (mapping_mode != NULL) { 00743 // we are in mapping mode 00744 for (int j = 1; j <= KMOS_NR_IFUS; j++) { 00745 //loop over all IFUs 00746 if (desc.sub_desc[j-1].valid_data == TRUE) { 00747 // load data frames 00748 override_err_msg = TRUE; 00749 data_cube_list[data_cube_counter] = 00750 kmo_dfs_load_cube(frameset, tmp_str, j, FALSE); 00751 override_err_msg = FALSE; 00752 if (data_cube_list[data_cube_counter] == NULL) { 00753 // no data found for this IFU 00754 cpl_error_reset(); 00755 } else { 00756 if (edge_nan) { 00757 KMO_TRY_EXIT_IF_ERROR( 00758 kmo_edge_nan(data_cube_list[data_cube_counter], j)); 00759 } 00760 KMO_TRY_EXIT_IF_NULL( 00761 data_header_list[data_cube_counter] = 00762 kmo_dfs_load_sub_header(frameset, tmp_str, j, FALSE)); 00763 cpl_propertylist_update_string(data_header_list[data_cube_counter], 00764 "ESO PRO FRNAME", 00765 frame_filename); 00766 cpl_propertylist_update_int(data_header_list[data_cube_counter], 00767 "ESO PRO IFUNR", 00768 j); 00769 data_cube_counter++; 00770 } 00771 00772 // load noise frames 00773 override_err_msg = TRUE; 00774 noise_cube_list[noise_cube_counter] = 00775 kmo_dfs_load_cube(frameset, tmp_str, j, TRUE); 00776 00777 override_err_msg = FALSE; 00778 if (noise_cube_list[noise_cube_counter] == NULL) { 00779 // no noise found for this IFU 00780 cpl_error_reset(); 00781 } else { 00782 if (edge_nan) { 00783 KMO_TRY_EXIT_IF_ERROR( 00784 kmo_edge_nan(noise_cube_list[noise_cube_counter], j)); 00785 } 00786 KMO_TRY_EXIT_IF_NULL( 00787 noise_header_list[noise_cube_counter] = 00788 kmo_dfs_load_sub_header(frameset, tmp_str, j, TRUE)); 00789 noise_cube_counter++; 00790 } 00791 00792 // check for every iteration if number of data and noise 00793 // frames is the same 00794 if (noise_cube_counter > 0) { 00795 KMO_TRY_ASSURE(data_cube_counter == noise_cube_counter, 00796 CPL_ERROR_ILLEGAL_INPUT, 00797 "Frame No. %d (%s) has no noise frame " 00798 "while the preceeding ones had!", 00799 i+1, frame_filename); 00800 } 00801 } // end if valid_data 00802 } 00803 } else { 00804 // we are in name/ifu mode (single) 00805 if (ifus != NULL) { 00806 ifu_nr = cpl_vector_get(ifus, i); 00807 KMO_TRY_CHECK_ERROR_STATE(); 00808 } else { 00809 ifu_nr = kmo_get_index_from_ocs_name(frame, name); 00810 KMO_TRY_CHECK_ERROR_STATE(); 00811 } 00812 00813 if (ifu_nr > 0) { 00814 index = kmo_identify_index(frame_filename, ifu_nr , FALSE); 00815 KMO_TRY_CHECK_ERROR_STATE(); 00816 00817 if (desc.sub_desc[index-1].valid_data == TRUE) { 00818 // load data frames 00819 override_err_msg = TRUE; 00820 data_cube_list[data_cube_counter] = 00821 kmo_dfs_load_cube(frameset, tmp_str, ifu_nr, FALSE); 00822 override_err_msg = FALSE; 00823 if (data_cube_list[data_cube_counter] == NULL) { 00824 // no data found for this IFU 00825 cpl_error_reset(); 00826 if (ifus != NULL) { 00827 cpl_msg_warning(cpl_func, "Frame No. %d (%s) " 00828 "doesn't contain IFU No. %d!", i+1, 00829 frame_filename, ifu_nr); 00830 } else { 00831 cpl_msg_warning(cpl_func, "Frame No. %d (%s) " 00832 "doesn't contain IFU with object " 00833 "name '%s'!", i+1, 00834 frame_filename, name); 00835 } 00836 } else { 00837 if (edge_nan) { 00838 KMO_TRY_EXIT_IF_ERROR( 00839 kmo_edge_nan(data_cube_list[data_cube_counter], ifu_nr)); 00840 } 00841 00842 KMO_TRY_EXIT_IF_NULL( 00843 data_header_list[data_cube_counter] = 00844 kmo_dfs_load_sub_header(frameset, tmp_str, 00845 ifu_nr, FALSE)); 00846 cpl_propertylist_update_string(data_header_list[data_cube_counter], 00847 "ESO PRO FRNAME", 00848 frame_filename); 00849 cpl_propertylist_update_int(data_header_list[data_cube_counter], 00850 "ESO PRO IFUNR", 00851 ifu_nr); 00852 data_cube_counter++; 00853 } 00854 00855 // load noise frames 00856 override_err_msg = TRUE; 00857 noise_cube_list[noise_cube_counter] = 00858 kmo_dfs_load_cube(frameset, tmp_str, ifu_nr, TRUE); 00859 override_err_msg = FALSE; 00860 if (noise_cube_list[noise_cube_counter] == NULL) { 00861 // no noise found for this IFU 00862 cpl_error_reset(); 00863 } else { 00864 if (edge_nan) { 00865 KMO_TRY_EXIT_IF_ERROR( 00866 kmo_edge_nan(noise_cube_list[noise_cube_counter], ifu_nr)); 00867 } 00868 00869 KMO_TRY_EXIT_IF_NULL( 00870 noise_header_list[noise_cube_counter] = 00871 kmo_dfs_load_sub_header(frameset, tmp_str, 00872 ifu_nr, TRUE)); 00873 noise_cube_counter++; 00874 } 00875 00876 // check for every iteration if number of data and noise 00877 // frames is the same 00878 if (noise_cube_counter > 0) { 00879 KMO_TRY_ASSURE(data_cube_counter == noise_cube_counter, 00880 CPL_ERROR_ILLEGAL_INPUT, 00881 "Frame No. %d (%s) has no noise frame " 00882 "while the preceeding ones had!", 00883 i+1, frame_filename); 00884 } 00885 } // end if valid_data 00886 } // end if (ifu_nr > 0) 00887 } 00888 00889 kmo_free_fits_desc(&desc); 00890 cpl_free(tmp_str); tmp_str = NULL; 00891 } // for i = nr_frames 00892 KMO_TRY_CHECK_ERROR_STATE(); 00893 00894 // 00895 // combine data 00896 // 00897 KMO_TRY_EXIT_IF_ERROR( 00898 kmo_priv_combine(data_cube_list, 00899 noise_cube_list, 00900 data_header_list, 00901 noise_header_list, 00902 data_cube_counter, 00903 noise_cube_counter, 00904 name, 00905 ifus_txt, 00906 method, 00907 "BCS", 00908 fmethod, 00909 filename, 00910 cmethod, 00911 cpos_rej, 00912 cneg_rej, 00913 citer, 00914 cmin, 00915 cmax, 00916 extrapol_enum, 00917 flux, 00918 &cube_combined_data, 00919 &cube_combined_noise)); 00920 00921 // 00922 // save data 00923 // 00924 /* save data and noise (if existing) */ 00925 // --- load, update & save primary header --- 00926 00927 00928 if (!suppress_extension) { 00929 // setup output category COMBINE + ESO PRO CATG 00930 KMO_TRY_EXIT_IF_NULL( 00931 main_header = kmo_dfs_load_primary_header(frameset, "0")); 00932 KMO_TRY_EXIT_IF_NULL( 00933 tmp_str = cpl_sprintf("%s_%s_%s", 00934 COMBINE, 00935 cpl_propertylist_get_string(main_header, CPL_DFS_PRO_CATG), 00936 name_vec[nv])); 00937 cpl_propertylist_delete(main_header); main_header = NULL; 00938 } else { 00939 KMO_TRY_EXIT_IF_NULL( 00940 tmp_str = cpl_sprintf("%s_%d", COMBINE, suppress_index++)); 00941 } 00942 00943 frame = cpl_frameset_get_first(frameset); 00944 KMO_TRY_EXIT_IF_ERROR( 00945 kmo_dfs_save_main_header(frameset, tmp_str, "", frame, NULL, 00946 parlist, cpl_func)); 00947 00948 if (data_header_list[0] != NULL) { 00949 if (cpl_propertylist_has(data_header_list[0], "ESO PRO FRNAME")) { 00950 cpl_propertylist_erase(data_header_list[0], "ESO PRO FRNAME"); 00951 } 00952 if (cpl_propertylist_has(data_header_list[0], "ESO PRO IFUNR")) { 00953 cpl_propertylist_erase(data_header_list[0], "ESO PRO IFUNR"); 00954 } 00955 } 00956 KMO_TRY_CHECK_ERROR_STATE(); 00957 00958 KMO_TRY_EXIT_IF_ERROR( 00959 kmo_dfs_save_cube(cube_combined_data, tmp_str, "", 00960 data_header_list[0], 0./0.)); 00961 00962 KMO_TRY_EXIT_IF_ERROR( 00963 kmo_dfs_save_cube(cube_combined_noise, tmp_str, "", 00964 noise_header_list[0], 0./0.)); 00965 00966 cpl_imagelist_delete(cube_combined_data); cube_combined_data = NULL; 00967 cpl_imagelist_delete(cube_combined_noise); cube_combined_noise = NULL; 00968 if (data_cube_list != NULL) { 00969 for (int i = 0; i < nr_frames*KMOS_NR_IFUS; i++) { 00970 cpl_imagelist_delete(data_cube_list[i]); data_cube_list[i] = NULL; 00971 } 00972 } 00973 if (noise_cube_list != NULL) { 00974 for (int i = 0; i < nr_frames*KMOS_NR_IFUS; i++) { 00975 cpl_imagelist_delete(noise_cube_list[i]); noise_cube_list[i] = NULL; 00976 } 00977 } 00978 if (data_header_list != NULL) { 00979 for (int i = 0; i < nr_frames*KMOS_NR_IFUS; i++) { 00980 cpl_propertylist_delete(data_header_list[i]); 00981 data_header_list[i] = NULL; 00982 } 00983 } 00984 if (noise_header_list != NULL) { 00985 for (int i = 0; i < nr_frames*KMOS_NR_IFUS; i++) { 00986 cpl_propertylist_delete(noise_header_list[i]); 00987 noise_header_list[i] = NULL; 00988 } 00989 } 00990 cpl_free(tmp_str); tmp_str = NULL; 00991 } 00992 } 00993 KMO_CATCH 00994 { 00995 KMO_CATCH_MSG(); 00996 ret_val = -1; 00997 } 00998 00999 cpl_propertylist_delete(main_header); main_header = NULL; 01000 cpl_vector_delete(ifus); ifus = NULL; 01001 cpl_imagelist_delete(cube_combined_data); cube_combined_data = NULL; 01002 cpl_imagelist_delete(cube_combined_noise); cube_combined_noise = NULL; 01003 01004 if (data_cube_list != NULL) { 01005 for (int i = 0; i < nr_frames*KMOS_NR_IFUS; i++) { 01006 cpl_imagelist_delete(data_cube_list[i]); data_cube_list[i] = NULL; 01007 } 01008 cpl_free(data_cube_list); data_cube_list = NULL; 01009 } 01010 01011 if (noise_cube_list != NULL) { 01012 for (int i = 0; i < nr_frames*KMOS_NR_IFUS; i++) { 01013 cpl_imagelist_delete(noise_cube_list[i]); noise_cube_list[i] = NULL; 01014 } 01015 cpl_free(noise_cube_list); noise_cube_list = NULL; 01016 } 01017 01018 if (data_header_list != NULL) { 01019 for (int i = 0; i < nr_frames*KMOS_NR_IFUS; i++) { 01020 cpl_propertylist_delete(data_header_list[i]); 01021 data_header_list[i] = NULL; 01022 } 01023 cpl_free(data_header_list); data_header_list = NULL; 01024 } 01025 01026 if (noise_header_list != NULL) { 01027 for (int i = 0; i < nr_frames*KMOS_NR_IFUS; i++) { 01028 cpl_propertylist_delete(noise_header_list[i]); 01029 noise_header_list[i] = NULL; 01030 } 01031 cpl_free(noise_header_list); noise_header_list = NULL; 01032 } 01033 01034 if (name_vec != NULL) { 01035 for (int i = 0; i < nr_frames*KMOS_NR_IFUS; i++) { 01036 cpl_free(name_vec[i]); name_vec[i] = NULL; 01037 } 01038 cpl_free(name_vec); name_vec = NULL; 01039 } 01040 cpl_free(mapping_mode);mapping_mode = NULL; 01041 01042 return ret_val; 01043 } 01044
1.7.6.1