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