|
KMOS Pipeline Reference Manual
1.2.4
|
00001 /* $Id: kmo_combine.c,v 1.32 2013/06/27 13:10:21 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:10:21 $ 00024 * $Revision: 1.32 $ 00025 * $Name: kmosp_v1_2_4__20130807 $ 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 00419 static int kmo_combine(cpl_parameterlist *parlist, cpl_frameset *frameset) 00420 { 00421 const char *method = NULL, 00422 *cmethod = NULL, 00423 *fmethod = NULL, 00424 *filename = NULL, 00425 *frame_filename = NULL, 00426 *ifus_txt = NULL, 00427 *tmp_strc = NULL; 00428 00429 char *tmp_str = NULL, 00430 *mapping_mode = NULL, 00431 *name = NULL, 00432 **name_vec = NULL; 00433 00434 cpl_imagelist **data_cube_list = NULL, 00435 **noise_cube_list = NULL, 00436 *cube_combined_data = NULL, 00437 *cube_combined_noise= NULL; 00438 00439 cpl_vector *ifus = NULL; 00440 00441 int ret_val = 0, 00442 nr_frames = 0, 00443 index = 0, 00444 data_cube_counter = 0, 00445 noise_cube_counter = 0, 00446 citer = 0, 00447 cmin = 0, 00448 cmax = 0, 00449 flux = FALSE, 00450 edge_nan = FALSE, 00451 name_vec_size = 0, 00452 found = 0, 00453 suppress_extension = FALSE, 00454 suppress_index = 0, 00455 i = 0, 00456 j = 0, 00457 ifu_nr = 0, 00458 nv = 0; 00459 00460 double cpos_rej = 0.0, 00461 cneg_rej = 0.0; 00462 00463 cpl_propertylist *main_header = NULL, 00464 **data_header_list = NULL, 00465 **noise_header_list = NULL, 00466 *tmp_header = NULL; 00467 00468 cpl_frame *frame = NULL; 00469 cpl_size ci = 0; 00470 main_fits_desc desc; 00471 00472 enum extrapolationType extrapol_enum = NONE_CLIPPING; 00473 00474 KMO_TRY 00475 { 00476 /* --- check input --- */ 00477 KMO_TRY_ASSURE((parlist != NULL) && 00478 (frameset != NULL), 00479 CPL_ERROR_NULL_INPUT, 00480 "Not all input data is provided!"); 00481 00482 nr_frames = cpl_frameset_get_size(frameset); 00483 00484 KMO_TRY_ASSURE(nr_frames >= 2, 00485 CPL_ERROR_NULL_INPUT, 00486 "At least two frames must be provided to combine!"); 00487 00488 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_combine") == 1, 00489 CPL_ERROR_ILLEGAL_INPUT, 00490 "Cannot identify RAW and CALIB frames!"); 00491 00492 cpl_msg_info("", "--- Parameter setup for kmo_combine -------"); 00493 00494 KMO_TRY_EXIT_IF_NULL( 00495 method = kmo_dfs_get_parameter_string(parlist, 00496 "kmos.kmo_combine.method")); 00497 00498 KMO_TRY_EXIT_IF_NULL( 00499 fmethod = kmo_dfs_get_parameter_string(parlist, 00500 "kmos.kmo_combine.fmethod")); 00501 00502 KMO_TRY_ASSURE((strcmp(method, "none") == 0) || 00503 (strcmp(method, "header") == 0) || 00504 (strcmp(method, "center") == 0) || 00505 (strcmp(method, "user") == 0), 00506 CPL_ERROR_ILLEGAL_INPUT, 00507 "Following shift methods are available : 'none', " 00508 "'header', 'center' or 'user'"); 00509 00510 if (strcmp(method, "user") == 0) { 00511 filename = kmo_dfs_get_parameter_string(parlist, 00512 "kmos.kmo_combine.filename"); 00513 KMO_TRY_CHECK_ERROR_STATE(); 00514 00515 KMO_TRY_ASSURE(strcmp(filename, "") != 0, 00516 CPL_ERROR_ILLEGAL_INPUT, 00517 "path of file with shift information must be " 00518 "provided!"); 00519 00520 KMO_TRY_EXIT_IF_ERROR( 00521 kmo_dfs_print_parameter_help(parlist, 00522 "kmos.kmo_combine.filename")); 00523 } 00524 00525 KMO_TRY_EXIT_IF_ERROR( 00526 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_combine.method")); 00527 00528 ifus_txt = kmo_dfs_get_parameter_string(parlist, 00529 "kmos.kmo_combine.ifus"); 00530 KMO_TRY_CHECK_ERROR_STATE(); 00531 00532 name = (char*)kmo_dfs_get_parameter_string(parlist, "kmos.kmo_combine.name"); 00533 KMO_TRY_CHECK_ERROR_STATE(); 00534 00535 if (strcmp(ifus_txt, "") != 0) { 00536 KMO_TRY_ASSURE(strcmp(name, "") == 0, 00537 CPL_ERROR_ILLEGAL_INPUT, 00538 "name parameter must be NULL if IFU indices are " 00539 "provided!"); 00540 00541 KMO_TRY_EXIT_IF_NULL( 00542 ifus = kmo_identify_values(ifus_txt)); 00543 00544 KMO_TRY_ASSURE(cpl_vector_get_size(ifus) == nr_frames, 00545 CPL_ERROR_ILLEGAL_INPUT, 00546 "ifus parameter must have the same number of values " 00547 "than frames provided ) (%lld!=%d)", 00548 cpl_vector_get_size(ifus), nr_frames); 00549 } 00550 00551 if (strcmp(name, "") != 0) { 00552 KMO_TRY_ASSURE(strcmp(ifus_txt, "") == 0, 00553 CPL_ERROR_ILLEGAL_INPUT, 00554 "ifus parameter must be NULL if name is provided!"); 00555 } 00556 00557 flux = kmo_dfs_get_parameter_bool(parlist, 00558 "kmos.kmo_combine.flux"); 00559 KMO_TRY_CHECK_ERROR_STATE(); 00560 KMO_TRY_EXIT_IF_ERROR( 00561 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_combine.flux")); 00562 00563 KMO_TRY_ASSURE((flux == TRUE) || (flux == FALSE), 00564 CPL_ERROR_ILLEGAL_INPUT, 00565 "flux must be TRUE or FALSE!"); 00566 00567 edge_nan = kmo_dfs_get_parameter_bool(parlist, 00568 "kmos.kmo_combine.edge_nan"); 00569 KMO_TRY_CHECK_ERROR_STATE(); 00570 KMO_TRY_EXIT_IF_ERROR( 00571 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_combine.edge_nan")); 00572 00573 KMO_TRY_ASSURE((edge_nan == TRUE) || (edge_nan == FALSE), 00574 CPL_ERROR_ILLEGAL_INPUT, 00575 "edge_nan must be TRUE or FALSE!"); 00576 00577 suppress_extension = kmo_dfs_get_parameter_bool(parlist, 00578 "kmos.kmo_combine.suppress_extension"); 00579 KMO_TRY_CHECK_ERROR_STATE(); 00580 KMO_TRY_EXIT_IF_ERROR( 00581 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_combine.suppress_extension")); 00582 00583 KMO_TRY_ASSURE((suppress_extension == TRUE) || (suppress_extension == FALSE), 00584 CPL_ERROR_ILLEGAL_INPUT, 00585 "suppress_extension must be TRUE or FALSE!"); 00586 00587 KMO_TRY_EXIT_IF_ERROR( 00588 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_combine.ifus")); 00589 00590 KMO_TRY_EXIT_IF_ERROR( 00591 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_combine.name")); 00592 00593 KMO_TRY_EXIT_IF_ERROR( 00594 kmo_combine_pars_load(parlist, 00595 "kmos.kmo_combine", 00596 &cmethod, 00597 &cpos_rej, 00598 &cneg_rej, 00599 &citer, 00600 &cmin, 00601 &cmax, 00602 FALSE)); 00603 00604 cpl_msg_info("", "-------------------------------------------"); 00605 00606 // load data and noise 00607 KMO_TRY_EXIT_IF_NULL( 00608 data_cube_list = cpl_calloc(nr_frames*KMOS_NR_IFUS, 00609 sizeof(cpl_imagelist*))); 00610 00611 KMO_TRY_EXIT_IF_NULL( 00612 data_header_list = cpl_calloc(nr_frames*KMOS_NR_IFUS, 00613 sizeof(cpl_propertylist*))); 00614 00615 KMO_TRY_EXIT_IF_NULL( 00616 noise_cube_list = cpl_calloc(nr_frames*KMOS_NR_IFUS, 00617 sizeof(cpl_imagelist*))); 00618 00619 KMO_TRY_EXIT_IF_NULL( 00620 noise_header_list = cpl_calloc(nr_frames*KMOS_NR_IFUS, 00621 sizeof(cpl_propertylist*))); 00622 00623 // 00624 // check for mapping mode 00625 // 00626 cpl_size fs_size = cpl_frameset_get_size(frameset); 00627 KMO_TRY_CHECK_ERROR_STATE(); 00628 00629 for (ci = 0; ci < fs_size; ci++) { 00630 KMO_TRY_EXIT_IF_NULL( 00631 frame = cpl_frameset_get_position(frameset, ci)); 00632 00633 KMO_TRY_EXIT_IF_NULL( 00634 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(frame), 0)); 00635 if (cpl_propertylist_has(tmp_header, TPL_ID)) { 00636 KMO_TRY_EXIT_IF_NULL( 00637 tmp_strc = cpl_propertylist_get_string(tmp_header, TPL_ID)); 00638 if (mapping_mode == NULL) { 00639 if (strcmp(tmp_strc, MAPPING8) == 0) 00640 { 00641 mapping_mode = cpl_sprintf("%s", tmp_strc); 00642 } 00643 if (strcmp(tmp_strc, MAPPING24) == 0) 00644 { 00645 mapping_mode = cpl_sprintf("%s", tmp_strc); 00646 } 00647 } else { 00648 if (strcmp(tmp_strc, mapping_mode) != 0) 00649 { 00650 cpl_msg_warning("","There are different TPL IDs present in " 00651 "the set of frames: %s and %s", 00652 tmp_strc, mapping_mode); 00653 } 00654 } 00655 } 00656 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00657 } 00658 00659 if (mapping_mode != NULL) { 00660 if ((strcmp(ifus_txt, "") == 0) && (strcmp(name, "") == 0)) { 00661 cpl_msg_info("","**************************************************"); 00662 cpl_msg_info("","* A map containing all IFUs will be generated! *"); 00663 cpl_msg_info("","**************************************************"); 00664 extrapol_enum = BCS_NATURAL; 00665 } else { 00666 cpl_msg_info("","The frames aren't combined into a map although they originate " 00667 "from a mapping template. But since the name- or ifu-parameter " 00668 "has been specified, the default behaviour is overridden."); 00669 cpl_free(mapping_mode); mapping_mode = NULL; 00670 } 00671 } 00672 00673 // 00674 // create name/ifu map... 00675 // 00676 KMO_TRY_EXIT_IF_NULL( 00677 name_vec = cpl_calloc(nr_frames*KMOS_NR_IFUS, sizeof(char*))); 00678 00679 if ((strcmp(ifus_txt, "") == 0) && 00680 (strcmp(name, "") == 0) && 00681 (mapping_mode == NULL)) 00682 { 00683 // all available names should be combined in one go 00684 name_vec_size = 0; 00685 for (i = 0; i < nr_frames; i++) { 00686 KMO_TRY_EXIT_IF_NULL( 00687 tmp_str = cpl_sprintf("%d", i)); 00688 KMO_TRY_EXIT_IF_NULL( 00689 frame = kmo_dfs_get_frame(frameset, tmp_str)); 00690 cpl_free(tmp_str); tmp_str = NULL; 00691 00692 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 00693 tmp_str = kmo_get_name_from_ocs_ifu(frame, ifu_nr); 00694 KMO_TRY_CHECK_ERROR_STATE(); 00695 found = 0; 00696 for (j = 0; j < name_vec_size; j++) { 00697 if (strcmp(name_vec[j], tmp_str) == 0) { 00698 found = TRUE; 00699 break; 00700 } 00701 } 00702 if (!found) { 00703 name_vec[name_vec_size++] = tmp_str; 00704 } else { 00705 cpl_free(tmp_str); tmp_str = NULL; 00706 } 00707 } 00708 } 00709 } else { 00710 // standard behavior: either ifu_nr- or name- or mapping-case 00711 name_vec_size = 1; 00712 if (mapping_mode != NULL) { 00713 KMO_TRY_EXIT_IF_NULL( 00714 name_vec[0] = cpl_sprintf("mapping")); 00715 } else { 00716 if (ifus != NULL) { 00717 KMO_TRY_EXIT_IF_NULL( 00718 name_vec[0] = cpl_sprintf("IFU%s", ifus_txt)); 00719 } else { 00720 KMO_TRY_EXIT_IF_NULL( 00721 name_vec[0] = cpl_sprintf("%s", name)); 00722 } 00723 } 00724 } 00725 00726 // 00727 // load all data (and noise if existent) cubes and store them 00728 // 00729 for (nv = 0; nv < name_vec_size; nv++){ 00730 name = name_vec[nv]; 00731 00732 data_cube_counter = 0; 00733 noise_cube_counter = 0; 00734 for (i = 0; i < nr_frames; i++) { 00735 KMO_TRY_EXIT_IF_NULL( 00736 tmp_str = cpl_sprintf("%d", i)); 00737 00738 KMO_TRY_EXIT_IF_NULL( 00739 frame = kmo_dfs_get_frame(frameset, tmp_str)); 00740 00741 KMO_TRY_EXIT_IF_NULL( 00742 frame_filename = cpl_frame_get_filename(frame)); 00743 00744 kmo_init_fits_desc(&desc); 00745 00746 desc = kmo_identify_fits_header(frame_filename); 00747 KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to " 00748 "be in KMOS-format!"); 00749 00750 KMO_TRY_ASSURE(desc.fits_type == f3i_fits, 00751 CPL_ERROR_ILLEGAL_INPUT, 00752 "Frame No. %d hasn't correct data type " 00753 "(must be of type F3I)!", i+1); 00754 00755 if (mapping_mode != NULL) { 00756 // we are in mapping mode 00757 for (j = 1; j <= KMOS_NR_IFUS; j++) { 00758 //loop over all IFUs 00759 if (desc.sub_desc[j-1].valid_data == TRUE) { 00760 // load data frames 00761 override_err_msg = TRUE; 00762 data_cube_list[data_cube_counter] = 00763 kmo_dfs_load_cube(frameset, tmp_str, j, FALSE); 00764 override_err_msg = FALSE; 00765 if (data_cube_list[data_cube_counter] == NULL) { 00766 // no data found for this IFU 00767 cpl_error_reset(); 00768 } else { 00769 if (edge_nan) { 00770 KMO_TRY_EXIT_IF_ERROR( 00771 kmo_edge_nan(data_cube_list[data_cube_counter], j)); 00772 } 00773 KMO_TRY_EXIT_IF_NULL( 00774 data_header_list[data_cube_counter] = 00775 kmo_dfs_load_sub_header(frameset, tmp_str, j, FALSE)); 00776 cpl_propertylist_update_string(data_header_list[data_cube_counter], 00777 "ESO PRO FRNAME", 00778 frame_filename); 00779 cpl_propertylist_update_int(data_header_list[data_cube_counter], 00780 "ESO PRO IFUNR", 00781 j); 00782 data_cube_counter++; 00783 } 00784 00785 // load noise frames 00786 override_err_msg = TRUE; 00787 noise_cube_list[noise_cube_counter] = 00788 kmo_dfs_load_cube(frameset, tmp_str, j, TRUE); 00789 00790 override_err_msg = FALSE; 00791 if (noise_cube_list[noise_cube_counter] == NULL) { 00792 // no noise found for this IFU 00793 cpl_error_reset(); 00794 } else { 00795 if (edge_nan) { 00796 KMO_TRY_EXIT_IF_ERROR( 00797 kmo_edge_nan(noise_cube_list[noise_cube_counter], j)); 00798 } 00799 KMO_TRY_EXIT_IF_NULL( 00800 noise_header_list[noise_cube_counter] = 00801 kmo_dfs_load_sub_header(frameset, tmp_str, j, TRUE)); 00802 noise_cube_counter++; 00803 } 00804 00805 // check for every iteration if number of data and noise 00806 // frames is the same 00807 if (noise_cube_counter > 0) { 00808 KMO_TRY_ASSURE(data_cube_counter == noise_cube_counter, 00809 CPL_ERROR_ILLEGAL_INPUT, 00810 "Frame No. %d (%s) has no noise frame " 00811 "while the preceeding ones had!", 00812 i+1, frame_filename); 00813 } 00814 } // end if valid_data 00815 } 00816 } else { 00817 // we are in name/ifu mode (single) 00818 if (ifus != NULL) { 00819 ifu_nr = cpl_vector_get(ifus, i); 00820 KMO_TRY_CHECK_ERROR_STATE(); 00821 } else { 00822 ifu_nr = kmo_get_index_from_ocs_name(frame, name); 00823 KMO_TRY_CHECK_ERROR_STATE(); 00824 } 00825 00826 if (ifu_nr > 0) { 00827 index = kmo_identify_index(frame_filename, ifu_nr , FALSE); 00828 KMO_TRY_CHECK_ERROR_STATE(); 00829 00830 if (desc.sub_desc[index-1].valid_data == TRUE) { 00831 // load data frames 00832 override_err_msg = TRUE; 00833 data_cube_list[data_cube_counter] = 00834 kmo_dfs_load_cube(frameset, tmp_str, ifu_nr, FALSE); 00835 override_err_msg = FALSE; 00836 if (data_cube_list[data_cube_counter] == NULL) { 00837 // no data found for this IFU 00838 cpl_error_reset(); 00839 if (ifus != NULL) { 00840 cpl_msg_warning(cpl_func, "Frame No. %d (%s) " 00841 "doesn't contain IFU No. %d!", i+1, 00842 frame_filename, ifu_nr); 00843 } else { 00844 cpl_msg_warning(cpl_func, "Frame No. %d (%s) " 00845 "doesn't contain IFU with object " 00846 "name '%s'!", i+1, 00847 frame_filename, name); 00848 } 00849 } else { 00850 if (edge_nan) { 00851 KMO_TRY_EXIT_IF_ERROR( 00852 kmo_edge_nan(data_cube_list[data_cube_counter], ifu_nr)); 00853 } 00854 00855 KMO_TRY_EXIT_IF_NULL( 00856 data_header_list[data_cube_counter] = 00857 kmo_dfs_load_sub_header(frameset, tmp_str, 00858 ifu_nr, FALSE)); 00859 cpl_propertylist_update_string(data_header_list[data_cube_counter], 00860 "ESO PRO FRNAME", 00861 frame_filename); 00862 cpl_propertylist_update_int(data_header_list[data_cube_counter], 00863 "ESO PRO IFUNR", 00864 ifu_nr); 00865 data_cube_counter++; 00866 } 00867 00868 // load noise frames 00869 override_err_msg = TRUE; 00870 noise_cube_list[noise_cube_counter] = 00871 kmo_dfs_load_cube(frameset, tmp_str, ifu_nr, TRUE); 00872 override_err_msg = FALSE; 00873 if (noise_cube_list[noise_cube_counter] == NULL) { 00874 // no noise found for this IFU 00875 cpl_error_reset(); 00876 } else { 00877 if (edge_nan) { 00878 KMO_TRY_EXIT_IF_ERROR( 00879 kmo_edge_nan(noise_cube_list[noise_cube_counter], ifu_nr)); 00880 } 00881 00882 KMO_TRY_EXIT_IF_NULL( 00883 noise_header_list[noise_cube_counter] = 00884 kmo_dfs_load_sub_header(frameset, tmp_str, 00885 ifu_nr, TRUE)); 00886 noise_cube_counter++; 00887 } 00888 00889 // check for every iteration if number of data and noise 00890 // frames is the same 00891 if (noise_cube_counter > 0) { 00892 KMO_TRY_ASSURE(data_cube_counter == noise_cube_counter, 00893 CPL_ERROR_ILLEGAL_INPUT, 00894 "Frame No. %d (%s) has no noise frame " 00895 "while the preceeding ones had!", 00896 i+1, frame_filename); 00897 } 00898 } // end if valid_data 00899 } // end if (ifu_nr > 0) 00900 } 00901 00902 kmo_free_fits_desc(&desc); 00903 cpl_free(tmp_str); tmp_str = NULL; 00904 } // for i = nr_frames 00905 KMO_TRY_CHECK_ERROR_STATE(); 00906 00907 // 00908 // combine data 00909 // 00910 KMO_TRY_EXIT_IF_ERROR( 00911 kmo_priv_combine(data_cube_list, 00912 noise_cube_list, 00913 data_header_list, 00914 noise_header_list, 00915 data_cube_counter, 00916 noise_cube_counter, 00917 name, 00918 ifus_txt, 00919 method, 00920 "BCS", 00921 fmethod, 00922 filename, 00923 cmethod, 00924 cpos_rej, 00925 cneg_rej, 00926 citer, 00927 cmin, 00928 cmax, 00929 extrapol_enum, 00930 flux, 00931 &cube_combined_data, 00932 &cube_combined_noise)); 00933 00934 // 00935 // save data 00936 // 00937 /* save data and noise (if existing) */ 00938 // --- load, update & save primary header --- 00939 00940 00941 if (!suppress_extension) { 00942 // setup output category COMBINE + ESO PRO CATG 00943 KMO_TRY_EXIT_IF_NULL( 00944 main_header = kmo_dfs_load_primary_header(frameset, "0")); 00945 KMO_TRY_EXIT_IF_NULL( 00946 tmp_str = cpl_sprintf("%s_%s_%s", 00947 COMBINE, 00948 cpl_propertylist_get_string(main_header, CPL_DFS_PRO_CATG), 00949 name_vec[nv])); 00950 cpl_propertylist_delete(main_header); main_header = NULL; 00951 } else { 00952 KMO_TRY_EXIT_IF_NULL( 00953 tmp_str = cpl_sprintf("%s_%d", COMBINE, suppress_index++)); 00954 } 00955 00956 frame = cpl_frameset_get_first(frameset); 00957 KMO_TRY_EXIT_IF_ERROR( 00958 kmo_dfs_save_main_header(frameset, tmp_str, "", frame, NULL, 00959 parlist, cpl_func)); 00960 00961 if (data_header_list[0] != NULL) { 00962 if (cpl_propertylist_has(data_header_list[0], "ESO PRO FRNAME")) { 00963 cpl_propertylist_erase(data_header_list[0], "ESO PRO FRNAME"); 00964 } 00965 if (cpl_propertylist_has(data_header_list[0], "ESO PRO IFUNR")) { 00966 cpl_propertylist_erase(data_header_list[0], "ESO PRO IFUNR"); 00967 } 00968 } 00969 KMO_TRY_CHECK_ERROR_STATE(); 00970 00971 KMO_TRY_EXIT_IF_ERROR( 00972 kmo_dfs_save_cube(cube_combined_data, tmp_str, "", 00973 data_header_list[0], 0./0.)); 00974 00975 KMO_TRY_EXIT_IF_ERROR( 00976 kmo_dfs_save_cube(cube_combined_noise, tmp_str, "", 00977 noise_header_list[0], 0./0.)); 00978 00979 cpl_imagelist_delete(cube_combined_data); cube_combined_data = NULL; 00980 cpl_imagelist_delete(cube_combined_noise); cube_combined_noise = NULL; 00981 if (data_cube_list != NULL) { 00982 for (i = 0; i < nr_frames*KMOS_NR_IFUS; i++) { 00983 cpl_imagelist_delete(data_cube_list[i]); data_cube_list[i] = NULL; 00984 } 00985 } 00986 if (noise_cube_list != NULL) { 00987 for (i = 0; i < nr_frames*KMOS_NR_IFUS; i++) { 00988 cpl_imagelist_delete(noise_cube_list[i]); noise_cube_list[i] = NULL; 00989 } 00990 } 00991 if (data_header_list != NULL) { 00992 for (i = 0; i < nr_frames*KMOS_NR_IFUS; i++) { 00993 cpl_propertylist_delete(data_header_list[i]); 00994 data_header_list[i] = NULL; 00995 } 00996 } 00997 if (noise_header_list != NULL) { 00998 for (i = 0; i < nr_frames*KMOS_NR_IFUS; i++) { 00999 cpl_propertylist_delete(noise_header_list[i]); 01000 noise_header_list[i] = NULL; 01001 } 01002 } 01003 cpl_free(tmp_str); tmp_str = NULL; 01004 } 01005 } 01006 KMO_CATCH 01007 { 01008 KMO_CATCH_MSG(); 01009 ret_val = -1; 01010 } 01011 01012 cpl_propertylist_delete(main_header); main_header = NULL; 01013 cpl_vector_delete(ifus); ifus = NULL; 01014 cpl_imagelist_delete(cube_combined_data); cube_combined_data = NULL; 01015 cpl_imagelist_delete(cube_combined_noise); cube_combined_noise = NULL; 01016 01017 if (data_cube_list != NULL) { 01018 for (i = 0; i < nr_frames*KMOS_NR_IFUS; i++) { 01019 cpl_imagelist_delete(data_cube_list[i]); data_cube_list[i] = NULL; 01020 } 01021 cpl_free(data_cube_list); data_cube_list = NULL; 01022 } 01023 01024 if (noise_cube_list != NULL) { 01025 for (i = 0; i < nr_frames*KMOS_NR_IFUS; i++) { 01026 cpl_imagelist_delete(noise_cube_list[i]); noise_cube_list[i] = NULL; 01027 } 01028 cpl_free(noise_cube_list); noise_cube_list = NULL; 01029 } 01030 01031 if (data_header_list != NULL) { 01032 for (i = 0; i < nr_frames*KMOS_NR_IFUS; i++) { 01033 cpl_propertylist_delete(data_header_list[i]); 01034 data_header_list[i] = NULL; 01035 } 01036 cpl_free(data_header_list); data_header_list = NULL; 01037 } 01038 01039 if (noise_header_list != NULL) { 01040 for (i = 0; i < nr_frames*KMOS_NR_IFUS; i++) { 01041 cpl_propertylist_delete(noise_header_list[i]); 01042 noise_header_list[i] = NULL; 01043 } 01044 cpl_free(noise_header_list); noise_header_list = NULL; 01045 } 01046 01047 if (name_vec != NULL) { 01048 for (i = 0; i < nr_frames*KMOS_NR_IFUS; i++) { 01049 cpl_free(name_vec[i]); name_vec[i] = NULL; 01050 } 01051 cpl_free(name_vec); name_vec = NULL; 01052 } 01053 cpl_free(mapping_mode);mapping_mode = NULL; 01054 01055 return ret_val; 01056 } 01057
1.7.6.1