|
KMOS Pipeline Reference Manual
1.3.17
|
00001 /* 00002 * This file is part of the KMOS Pipeline 00003 * Copyright (C) 2002,2003 European Southern Observatory 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 */ 00019 00020 #ifdef HAVE_CONFIG_H 00021 #include <config.h> 00022 #endif 00023 00024 /*----------------------------------------------------------------------------- 00025 * Includes 00026 *----------------------------------------------------------------------------*/ 00027 00028 #include <string.h> 00029 #include <math.h> 00030 00031 #include <cpl.h> 00032 #include <cpl_wcs.h> 00033 00034 #include "kmo_debug.h" 00035 #include "kmo_utils.h" 00036 #include "kmo_dfs.h" 00037 #include "kmo_error.h" 00038 #include "kmo_priv_functions.h" 00039 #include "kmo_cpl_extensions.h" 00040 #include "kmo_constants.h" 00041 #include "kmo_priv_combine.h" 00042 00043 /*----------------------------------------------------------------------------- 00044 * Functions prototypes 00045 *----------------------------------------------------------------------------*/ 00046 00047 static char * kmos_combine_create_used_ifus_string(const int *,const int *,int); 00048 static cpl_bivector * kmos_combine_parse_skipped(const char *) ; 00049 static int kmos_combine_is_skipped(const cpl_bivector *, int, int) ; 00050 00051 static int kmos_combine_create(cpl_plugin *); 00052 static int kmos_combine_exec(cpl_plugin *); 00053 static int kmos_combine_destroy(cpl_plugin *); 00054 static int kmos_combine(cpl_parameterlist *, cpl_frameset *); 00055 00056 /*----------------------------------------------------------------------------- 00057 * Static variables 00058 *----------------------------------------------------------------------------*/ 00059 00060 static char kmos_combine_description[] = 00061 "This recipe shifts several exposures of an object and combines them. Diffe-\n" 00062 "rent methods to match the exposures are described here (--method parameter).\n" 00063 "The output cube is larger than the input cubes, according to the shifts to\n" 00064 "be applied. Additionally a border of NaN values is added. The WCS is the\n" 00065 "same as for the first exposure.\n" 00066 "For each spatial/spectral pixel a new value is calculated (according the\n" 00067 "--cmethod parameter) and written into the output cube.\n" 00068 "Only exposures with the same WCS orientation can be combined (except\n" 00069 "-–method=”none”), north must point to the same direction. It is recommended\n" 00070 "to apply any rotation possibly after combining.\n" 00071 "\n" 00072 "The behavior of the selection of IFUs to combine differs for some templates\n" 00073 "and can be controlled with the parameters --name and --ifus.\n" 00074 "If the input data cubes stem from templates KMOS_spec_obs_mapping8 or\n" 00075 "KMOS_spec_obs_mapping24 all extensions from all input frames are combined\n" 00076 "into a single map by default (like in recipe kmo_sci_red). If just the area\n" 00077 "of a specific IFU should be combined, the parameter --ifus can be specified,\n" 00078 "or more easily --name.\n" 00079 "If the input data cubes stem from other templates like e.g.\n" 00080 "KMOS_spec_obs_freedither all extensions of all input frames are combined\n" 00081 "into several output frames by default. The input IFUs are grouped according\n" 00082 "to their targeted object name stored in the keywords ESO OCS ARMx NAME. If \n" 00083 "just a specific object should be combined, its name can be specified with \n" 00084 "--name. If arbitrary IFUs shoukd be comined, one can specify these with the\n" 00085 "parameter --ifus.\n" 00086 "\n" 00087 "The default mapping mode is done via the --name parameter, where the name of\n" 00088 "the object has to be provided. The recipe searches in input data cubes IFUs\n" 00089 "pointing to that object.\n" 00090 "\n" 00091 "---------------------------------------------------------------------------\n" 00092 " Input files:\n" 00093 "\n" 00094 " DO KMOS \n" 00095 " category Type Explanation Required #Frames\n" 00096 " -------- ----- ----------- -------- -------\n" 00097 " <none or any> F3I data frame Y 2-n \n" 00098 "\n" 00099 " Output files:\n" 00100 "\n" 00101 " DO KMOS\n" 00102 " category Type Explanation\n" 00103 " -------- ----- -----------\n" 00104 " COMBINE_<ESO PRO CATG> F3I Combined data cube\n" 00105 " EXP_MASK_<ESO PRO CATG> F3I Exposure time mask\n" 00106 " SCI_COMBINED_COLL (optional) Collapsed combined cube\n" 00107 " (set --collapse_combined)\n" 00108 "---------------------------------------------------------------------------\n" 00109 "\n"; 00110 00111 /*----------------------------------------------------------------------------- 00112 * Functions code 00113 *----------------------------------------------------------------------------*/ 00114 00115 /*----------------------------------------------------------------------------*/ 00119 /*----------------------------------------------------------------------------*/ 00120 00123 /*----------------------------------------------------------------------------*/ 00132 /*----------------------------------------------------------------------------*/ 00133 int cpl_plugin_get_info(cpl_pluginlist *list) 00134 { 00135 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00136 cpl_plugin *plugin = &recipe->interface; 00137 00138 cpl_plugin_init(plugin, 00139 CPL_PLUGIN_API, 00140 KMOS_BINARY_VERSION, 00141 CPL_PLUGIN_TYPE_RECIPE, 00142 "kmos_combine", 00143 "Combine reconstructed cubes", 00144 kmos_combine_description, 00145 "Alex Agudo Berbel, Y. Jung", 00146 "usd-help@eso.org", 00147 kmos_get_license(), 00148 kmos_combine_create, 00149 kmos_combine_exec, 00150 kmos_combine_destroy); 00151 cpl_pluginlist_append(list, plugin); 00152 00153 return 0; 00154 } 00155 00156 /*----------------------------------------------------------------------------*/ 00164 /*----------------------------------------------------------------------------*/ 00165 static int kmos_combine_create(cpl_plugin *plugin) 00166 { 00167 cpl_recipe *recipe; 00168 cpl_parameter *p; 00169 00170 /* Check that the plugin is part of a valid recipe */ 00171 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00172 recipe = (cpl_recipe *)plugin; 00173 else 00174 return -1; 00175 00176 /* Create the parameters list in the cpl_recipe object */ 00177 recipe->parameters = cpl_parameterlist_new(); 00178 00179 /* Fill the parameters list */ 00180 /* --name */ 00181 p = cpl_parameter_new_value("kmos.kmos_combine.name", CPL_TYPE_STRING, 00182 "Name of the object to combine.", "kmos.kmos_combine", ""); 00183 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "name"); 00184 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00185 cpl_parameterlist_append(recipe->parameters, p); 00186 00187 /* --ifus */ 00188 p = cpl_parameter_new_value("kmos.kmos_combine.ifus", CPL_TYPE_STRING, 00189 "The indices of the IFUs to combine. " "\"ifu1;ifu2;...\"", 00190 "kmos.kmos_combine", ""); 00191 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ifus"); 00192 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00193 cpl_parameterlist_append(recipe->parameters, p); 00194 00195 /* --method */ 00196 p = cpl_parameter_new_value("kmos.kmos_combine.method", CPL_TYPE_STRING, 00197 "The shifting method: " 00198 "'none': no shifting, combined directly, " 00199 "'header': shift according to WCS (default), " 00200 "'center': centering algorithm, " 00201 "'user': read shifts from file", 00202 "kmos.kmos_combine", "none"); 00203 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "method"); 00204 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00205 cpl_parameterlist_append(recipe->parameters, p); 00206 00207 /* --fmethod */ 00208 p = cpl_parameter_new_value("kmos.kmos_combine.fmethod", CPL_TYPE_STRING, 00209 "The fitting method (applies only when method='center'): " 00210 "'gauss': fit a gauss function to collapsed image (default), " 00211 "'moffat': fit a moffat function to collapsed image", 00212 "kmos.kmos_combine", "gauss"); 00213 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fmethod"); 00214 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00215 cpl_parameterlist_append(recipe->parameters, p); 00216 00217 /* --filename */ 00218 p = cpl_parameter_new_value("kmos.kmos_combine.filename", CPL_TYPE_STRING, 00219 "The path to the file with the shift vectors (method='user')", 00220 "kmos.kmos_combine", ""); 00221 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "filename"); 00222 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00223 cpl_parameterlist_append(recipe->parameters, p); 00224 00225 /* --flux */ 00226 p = cpl_parameter_new_value("kmos.kmos_combine.flux", CPL_TYPE_BOOL, 00227 "Apply flux conservation: (TRUE (apply) or FALSE (don't apply)", 00228 "kmos.kmos_combine", FALSE); 00229 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "flux"); 00230 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00231 cpl_parameterlist_append(recipe->parameters, p); 00232 00233 /* --edge_nan */ 00234 p = cpl_parameter_new_value("kmos.kmos_combine.edge_nan", CPL_TYPE_BOOL, 00235 "Set borders of cubes to NaN before combining them." 00236 "(TRUE (apply) or FALSE (don't apply)", "kmos.kmos_combine", FALSE); 00237 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "edge_nan"); 00238 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00239 cpl_parameterlist_append(recipe->parameters, p); 00240 00241 /* --skipped_frames */ 00242 p = cpl_parameter_new_value("kmos.kmos_combine.skipped_frames", 00243 CPL_TYPE_STRING, 00244 "Comma separated List of IFUs to skip for the combination. An IFU is specified with R:I." 00245 "R is the index (starting at 1) of the reconstructed frame, I the IFU number", 00246 "kmos.kmos_combine", ""); 00247 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "skipped_frames"); 00248 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00249 cpl_parameterlist_append(recipe->parameters, p); 00250 00251 /* --suppress_extension */ 00252 p = cpl_parameter_new_value("kmos.kmos_combine.suppress_extension", 00253 CPL_TYPE_BOOL, "Suppress arbitrary filename extension.", 00254 "kmos.kmos_combine", FALSE); 00255 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "suppress_extension"); 00256 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00257 cpl_parameterlist_append(recipe->parameters, p); 00258 00259 /* --collapse_combined */ 00260 p = cpl_parameter_new_value("kmos.kmos_combine.collapse_combined", 00261 CPL_TYPE_BOOL, "Flag to collapse the combined images", 00262 "kmos.kmos_combine", FALSE); 00263 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "collapse_combined"); 00264 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00265 cpl_parameterlist_append(recipe->parameters, p); 00266 00267 return kmos_combine_pars_create(recipe->parameters, "kmos.kmos_combine", 00268 DEF_REJ_METHOD, FALSE); 00269 } 00270 00271 /*----------------------------------------------------------------------------*/ 00277 /*----------------------------------------------------------------------------*/ 00278 static int kmos_combine_exec(cpl_plugin *plugin) 00279 { 00280 cpl_recipe *recipe; 00281 00282 /* Get the recipe out of the plugin */ 00283 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00284 recipe = (cpl_recipe *)plugin; 00285 else return -1 ; 00286 00287 return kmos_combine(recipe->parameters, recipe->frames); 00288 } 00289 00290 /*----------------------------------------------------------------------------*/ 00296 /*----------------------------------------------------------------------------*/ 00297 static int kmos_combine_destroy(cpl_plugin *plugin) 00298 { 00299 cpl_recipe *recipe; 00300 00301 /* Get the recipe out of the plugin */ 00302 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00303 recipe = (cpl_recipe *)plugin; 00304 else return -1 ; 00305 00306 cpl_parameterlist_delete(recipe->parameters); 00307 return 0 ; 00308 } 00309 00310 /*----------------------------------------------------------------------------*/ 00323 /*----------------------------------------------------------------------------*/ 00324 static int kmos_combine(cpl_parameterlist *parlist, cpl_frameset *frameset) 00325 { 00326 const cpl_parameter * par ; 00327 cpl_frameset * rawframes ; 00328 const char * filename,* fmethod,* method,* ifus_txt,* cmethod, 00329 * skipped_frames; 00330 double cpos_rej, cneg_rej ; 00331 cpl_vector * ifus ; 00332 int citer, cmin, cmax, nr_frames, index, 00333 data_cube_counter, noise_cube_counter, flux, 00334 edge_nan, name_vec_size, found, suppress_extension, 00335 suppress_index, ifu_nr, nv, collapse_combined, 00336 mapping_id ; 00337 char * tmp_str, * fn_combine, * fn_mask, * mapping_mode, 00338 * name, ** name_vec, * name_loc ; 00339 const char * frame_filename, * tmp_strc ; 00340 cpl_image * exp_mask ; 00341 cpl_imagelist ** data_cube_list, ** noise_cube_list, * cube_combined_data, 00342 * cube_combined_noise ; 00343 cpl_propertylist * main_header, **data_header_list, **noise_header_list, 00344 * tmp_header, * pro_plist ; 00345 char * reflex_suffix ; 00346 cpl_bivector * skipped_bivector ; 00347 cpl_frame * frame ; 00348 cpl_size ci ; 00349 main_fits_desc desc; 00350 int * used_frame_idx ; 00351 int * used_ifus ; 00352 char * used_ifus_str ; 00353 enum extrapolationType extrapol_enum = NONE_CLIPPING; 00354 int i, j ; 00355 00356 /* Check entries */ 00357 if (parlist == NULL || frameset == NULL) { 00358 cpl_msg_error(__func__, "Null Inputs") ; 00359 cpl_error_set(__func__, CPL_ERROR_NULL_INPUT) ; 00360 return -1 ; 00361 } 00362 00363 /* Get parameters */ 00364 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_combine.method"); 00365 method = cpl_parameter_get_string(par) ; 00366 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_combine.fmethod"); 00367 fmethod = cpl_parameter_get_string(par) ; 00368 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_combine.filename"); 00369 filename = cpl_parameter_get_string(par) ; 00370 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_combine.ifus"); 00371 ifus_txt = cpl_parameter_get_string(par) ; 00372 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_combine.name"); 00373 name = (char*)cpl_parameter_get_string(par) ; 00374 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_combine.flux"); 00375 flux = cpl_parameter_get_bool(par) ; 00376 par = cpl_parameterlist_find_const(parlist, 00377 "kmos.kmos_combine.skipped_frames"); 00378 skipped_frames = cpl_parameter_get_string(par) ; 00379 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_combine.edge_nan"); 00380 edge_nan = cpl_parameter_get_bool(par) ; 00381 par = cpl_parameterlist_find_const(parlist, 00382 "kmos.kmos_combine.suppress_extension"); 00383 suppress_extension = cpl_parameter_get_bool(par) ; 00384 kmos_combine_pars_load(parlist, "kmos.kmos_combine", &cmethod, &cpos_rej, 00385 &cneg_rej, &citer, &cmin, &cmax, FALSE); 00386 par = cpl_parameterlist_find_const(parlist, 00387 "kmos.kmos_combine.collapse_combined"); 00388 collapse_combined = cpl_parameter_get_bool(par); 00389 00390 /* Check Parameters */ 00391 if (strcmp(method, "none") && strcmp(method, "header") && 00392 strcmp(method, "center") && strcmp(method, "user")) { 00393 cpl_msg_error(__func__, 00394 "shift methods must be 'none', 'header', 'center' or 'user'") ; 00395 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00396 return -1 ; 00397 } 00398 if (strcmp(ifus_txt, "") && strcmp(name, "")) { 00399 cpl_msg_error(__func__, 00400 "name and IFU indices cannot be both provided") ; 00401 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00402 return -1 ; 00403 } 00404 if (!strcmp(method, "user") && !strcmp(filename, "")) { 00405 cpl_msg_error(__func__, 00406 "path of file with shift information must be provided") ; 00407 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00408 return -1 ; 00409 } 00410 00411 /* Identify the RAW and CALIB frames in the input frameset */ 00412 if (kmo_dfs_set_groups(frameset, "kmos_combine") != 1) { 00413 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ; 00414 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00415 return -1 ; 00416 } 00417 00418 /* Parse the skipped frames option */ 00419 skipped_bivector = NULL ; 00420 if (strcmp(skipped_frames, "")) { 00421 skipped_bivector = kmos_combine_parse_skipped(skipped_frames) ; 00422 if (skipped_bivector != NULL) 00423 cpl_msg_info(__func__, "Skip the following frames: %s", 00424 skipped_frames); 00425 } 00426 00427 /* Get the frames to combine - Filter out OH_SPEC */ 00428 rawframes = cpl_frameset_duplicate(frameset) ; 00429 cpl_frameset_erase(rawframes, "OH_SPEC") ; 00430 00431 /* Check Nb of frames */ 00432 nr_frames = cpl_frameset_get_size(rawframes); 00433 if (nr_frames < 2) { 00434 if (skipped_bivector!=NULL) cpl_bivector_delete(skipped_bivector) ; 00435 cpl_frameset_delete(rawframes) ; 00436 cpl_msg_error(__func__, "At least two frames must be provided") ; 00437 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00438 return -1 ; 00439 } 00440 00441 /* Load IFUS if specified */ 00442 if (strcmp(ifus_txt, "")) { 00443 ifus = kmo_identify_values(ifus_txt); 00444 if (ifus == NULL || cpl_vector_get_size(ifus) != nr_frames) { 00445 if (ifus != NULL) cpl_vector_delete(ifus); 00446 if (skipped_bivector!=NULL) cpl_bivector_delete(skipped_bivector) ; 00447 cpl_frameset_delete(rawframes) ; 00448 cpl_msg_error(__func__, "ifus size must match the science frames") ; 00449 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00450 return -1 ; 00451 } 00452 } else { 00453 ifus = NULL ; 00454 } 00455 00456 /* Check for mapping mode */ 00457 mapping_mode = NULL ; 00458 cpl_size fs_size = cpl_frameset_get_size(rawframes); 00459 for (ci = 0; ci < fs_size; ci++) { 00460 frame = cpl_frameset_get_position(rawframes, ci); 00461 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(frame),0); 00462 if (cpl_propertylist_has(tmp_header, TPL_ID)) { 00463 tmp_strc = cpl_propertylist_get_string(tmp_header, TPL_ID); 00464 if (mapping_mode == NULL) { 00465 if (!strcmp(tmp_strc, MAPPING8)) 00466 mapping_mode = cpl_sprintf("%s", tmp_strc); 00467 if (!strcmp(tmp_strc, MAPPING24)) 00468 mapping_mode = cpl_sprintf("%s", tmp_strc); 00469 } else { 00470 if (strcmp(tmp_strc, mapping_mode)) { 00471 cpl_msg_warning(__func__, 00472 "There are different TPL IDs in input: %s and %s", 00473 tmp_strc, mapping_mode); 00474 } 00475 } 00476 } 00477 cpl_propertylist_delete(tmp_header); 00478 } 00479 00480 if (mapping_mode != NULL) { 00481 if (!strcmp(ifus_txt, "") && !strcmp(name, "")) { 00482 cpl_msg_info(__func__,"*****************************************"); 00483 cpl_msg_info(__func__,"* A map with all IFUs will be generated *"); 00484 cpl_msg_info(__func__,"*****************************************"); 00485 extrapol_enum = BCS_NATURAL; 00486 } else { 00487 cpl_msg_info(__func__, "No Map as name / ifu is specified"); 00488 cpl_free(mapping_mode); 00489 mapping_mode = NULL ; 00490 } 00491 } 00492 00493 /* Mapping Id */ 00494 mapping_id = -1 ; 00495 if (mapping_mode == NULL) { 00496 mapping_id = 0 ; 00497 } else { 00498 if (!strcmp(mapping_mode, MAPPING8)) mapping_id = 1 ; 00499 if (!strcmp(mapping_mode, MAPPING24)) mapping_id = 2 ; 00500 } 00501 00502 /* Create name/ifu map... */ 00503 name_vec = cpl_calloc(nr_frames*KMOS_NR_IFUS, sizeof(char*)); 00504 00505 /* No name / IFU specified - Non mapping mode */ 00506 if (!strcmp(ifus_txt, "") && !strcmp(name, "") && mapping_mode==NULL) { 00507 /* All available names should be combined in one go */ 00508 name_vec_size = 0; 00509 for (i = 0; i < nr_frames; i++) { 00510 tmp_str = cpl_sprintf("%d", i); 00511 frame = kmo_dfs_get_frame(rawframes, tmp_str); 00512 cpl_free(tmp_str); 00513 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 00514 found = 0; 00515 tmp_str = kmo_get_name_from_ocs_ifu(frame, ifu_nr); 00516 if (tmp_str != NULL) { 00517 for (j = 0; j < name_vec_size; j++) { 00518 if (!strcmp(name_vec[j], tmp_str)) { 00519 found = TRUE; 00520 break; 00521 } 00522 } 00523 if (!found) name_vec[name_vec_size++] = tmp_str; 00524 else cpl_free(tmp_str); 00525 } 00526 } 00527 } 00528 } else { 00529 /* Standard behavior: either ifu_nr- or name- or mapping-case */ 00530 name_vec_size = 1; 00531 if (mapping_mode != NULL) { 00532 name_vec[0] = cpl_sprintf("mapping"); 00533 } else { 00534 if (ifus != NULL) { 00535 char *tmptmp = NULL; 00536 00537 // replace all ; with _ 00538 char *found_char = NULL; 00539 found_char = strstr(ifus_txt, ";"); 00540 while (found_char != NULL) { 00541 strncpy(found_char, "_", 1); 00542 found_char = strstr(ifus_txt, ";"); 00543 } 00544 00545 if (strlen(ifus_txt) > 10) { 00546 tmptmp = kmo_shorten_ifu_string(ifus_txt); 00547 cpl_msg_info(__func__, "Truncate to ..ifu%s..", tmptmp); 00548 } else { 00549 tmptmp = cpl_sprintf("%s", ifus_txt); 00550 } 00551 name_vec[0] = cpl_sprintf("IFU%s", tmptmp); 00552 ifus_txt = ""; 00553 cpl_free(tmptmp); 00554 } else { 00555 name_vec[0] = cpl_sprintf("%s", name); 00556 } 00557 } 00558 } 00559 00560 /* Load data and noise */ 00561 data_cube_list = cpl_calloc(nr_frames*KMOS_NR_IFUS, 00562 sizeof(cpl_imagelist*)); 00563 data_header_list = cpl_calloc(nr_frames*KMOS_NR_IFUS, 00564 sizeof(cpl_propertylist*)); 00565 noise_cube_list = cpl_calloc(nr_frames*KMOS_NR_IFUS, 00566 sizeof(cpl_imagelist*)); 00567 noise_header_list = cpl_calloc(nr_frames*KMOS_NR_IFUS, 00568 sizeof(cpl_propertylist*)); 00569 00570 /* 00571 if (ifus != NULL) cpl_vector_delete(ifus); 00572 cpl_frameset_delete(rawframes) ; 00573 cpl_free(data_cube_list); 00574 cpl_free(noise_cube_list); 00575 cpl_free(data_header_list); 00576 cpl_free(noise_header_list); 00577 for (i = 0; i < name_vec_size ; i++) cpl_free(name_vec[i]); 00578 cpl_free(name_vec); 00579 if (mapping_mode != NULL) cpl_free(mapping_mode) ; 00580 return 0 ; 00581 */ 00582 00583 /* Load all data (and noise if existent) cubes and store them */ 00584 for (nv = 0; nv < name_vec_size; nv++) { 00585 name_loc = name_vec[nv]; 00586 00587 used_frame_idx = cpl_calloc(nr_frames*KMOS_NR_IFUS, sizeof(int)) ; 00588 used_ifus = cpl_calloc(nr_frames*KMOS_NR_IFUS, sizeof(int)) ; 00589 00590 data_cube_counter = 0; 00591 noise_cube_counter = 0; 00592 for (i = 0; i < nr_frames; i++) { 00593 tmp_str = cpl_sprintf("%d", i); 00594 frame = kmo_dfs_get_frame(rawframes, tmp_str); 00595 frame_filename = cpl_frame_get_filename(frame); 00596 kmo_init_fits_desc(&desc); 00597 desc = kmo_identify_fits_header(frame_filename); 00598 00599 if (mapping_mode != NULL) { 00600 /* Mapping mode */ 00601 for (j = 1; j <= KMOS_NR_IFUS; j++) { 00602 /* Loop over all IFUs */ 00603 if (desc.sub_desc[j-1].valid_data == TRUE && 00604 !kmos_combine_is_skipped(skipped_bivector,i+1,j)) { 00605 /* Load data frames */ 00606 override_err_msg = TRUE; 00607 data_cube_list[data_cube_counter] = 00608 kmo_dfs_load_cube(rawframes, tmp_str, j,FALSE); 00609 override_err_msg = FALSE; 00610 if (data_cube_list[data_cube_counter] == NULL) { 00611 cpl_error_reset(); 00612 } else { 00613 if (edge_nan) kmo_edge_nan( 00614 data_cube_list[data_cube_counter], j); 00615 data_header_list[data_cube_counter] = 00616 kmo_dfs_load_sub_header(rawframes, 00617 tmp_str, j, FALSE); 00618 cpl_propertylist_update_string( 00619 data_header_list[data_cube_counter], 00620 "ESO PRO FRNAME", frame_filename); 00621 cpl_propertylist_update_int( 00622 data_header_list[data_cube_counter], 00623 "ESO PRO IFUNR", j); 00624 used_frame_idx[data_cube_counter] = i+1 ; 00625 used_ifus[data_cube_counter] = j ; 00626 data_cube_counter++; 00627 } 00628 00629 /* Load noise frames */ 00630 override_err_msg = TRUE; 00631 noise_cube_list[noise_cube_counter] = 00632 kmo_dfs_load_cube(rawframes, tmp_str, j, TRUE); 00633 00634 override_err_msg = FALSE; 00635 if (noise_cube_list[noise_cube_counter] == NULL) { 00636 // no noise found for this IFU 00637 cpl_error_reset(); 00638 } else { 00639 if (edge_nan) kmo_edge_nan( 00640 noise_cube_list[noise_cube_counter], j); 00641 noise_header_list[noise_cube_counter] = 00642 kmo_dfs_load_sub_header(rawframes, tmp_str, 00643 j, TRUE); 00644 noise_cube_counter++; 00645 } 00646 00647 /* Check if number of data and noise frames match */ 00648 if (noise_cube_counter > 0) { 00649 if (data_cube_counter != noise_cube_counter) { 00650 cpl_msg_error(__func__, "Noise missing") ; 00651 cpl_error_set(__func__,CPL_ERROR_ILLEGAL_INPUT); 00652 /* TODO - deallocate */ 00653 return -1 ; 00654 } 00655 } 00656 } 00657 } 00658 } else { 00659 /* name/ifu mode (single) */ 00660 if (ifus != NULL) ifu_nr = cpl_vector_get(ifus, i); 00661 else ifu_nr = kmo_get_index_from_ocs_name(frame, name_loc); 00662 if (ifu_nr > 0) { 00663 index = kmo_identify_index(frame_filename, ifu_nr , FALSE); 00664 if (desc.sub_desc[index-1].valid_data == TRUE && 00665 !kmos_combine_is_skipped(skipped_bivector,i+1, 00666 ifu_nr)) { 00667 /* Load data frames */ 00668 override_err_msg = TRUE; 00669 data_cube_list[data_cube_counter] = 00670 kmo_dfs_load_cube(rawframes, tmp_str, ifu_nr, 00671 FALSE); 00672 override_err_msg = FALSE; 00673 if (data_cube_list[data_cube_counter] == NULL) { 00674 /* No data found for this IFU */ 00675 cpl_error_reset(); 00676 if (ifus != NULL) cpl_msg_warning(cpl_func, 00677 "IFU %d miѕsing in frame %s", 00678 ifu_nr, frame_filename); 00679 else cpl_msg_warning(cpl_func, 00680 "Object %s missing in Frame %d (%s)", 00681 name_loc, i+1, frame_filename) ; 00682 } else { 00683 if (edge_nan) kmo_edge_nan( 00684 data_cube_list[data_cube_counter], ifu_nr); 00685 data_header_list[data_cube_counter] = 00686 kmo_dfs_load_sub_header(rawframes, tmp_str, 00687 ifu_nr, FALSE); 00688 cpl_propertylist_update_string( 00689 data_header_list[data_cube_counter], 00690 "ESO PRO FRNAME", frame_filename); 00691 cpl_propertylist_update_int( 00692 data_header_list[data_cube_counter], 00693 "ESO PRO IFUNR", ifu_nr); 00694 used_frame_idx[data_cube_counter] = i+1 ; 00695 used_ifus[data_cube_counter] = ifu_nr ; 00696 data_cube_counter++; 00697 } 00698 00699 /* Load noise frames */ 00700 override_err_msg = TRUE; 00701 noise_cube_list[noise_cube_counter] = 00702 kmo_dfs_load_cube(rawframes, tmp_str, ifu_nr, 00703 TRUE); 00704 override_err_msg = FALSE; 00705 if (noise_cube_list[noise_cube_counter] == NULL) { 00706 /* No noise found for this IFU */ 00707 cpl_error_reset(); 00708 } else { 00709 if (edge_nan) kmo_edge_nan( 00710 noise_cube_list[noise_cube_counter],ifu_nr); 00711 noise_header_list[noise_cube_counter] = 00712 kmo_dfs_load_sub_header(rawframes, 00713 tmp_str, ifu_nr, TRUE); 00714 noise_cube_counter++; 00715 } 00716 00717 /* Check if number of data and noise frames match */ 00718 if (noise_cube_counter > 0) { 00719 if (data_cube_counter != noise_cube_counter) { 00720 /* TODO - deallocate */ 00721 cpl_msg_error(__func__, "Noise missing") ; 00722 cpl_error_set(__func__,CPL_ERROR_ILLEGAL_INPUT); 00723 return -1 ; 00724 } 00725 } 00726 } 00727 } 00728 } 00729 kmo_free_fits_desc(&desc); 00730 cpl_free(tmp_str); 00731 } 00732 00733 /* Create String for the output header - IFUs usage */ 00734 used_ifus_str = kmos_combine_create_used_ifus_string(used_frame_idx, 00735 used_ifus, data_cube_counter); 00736 cpl_free(used_frame_idx) ; 00737 cpl_free(used_ifus) ; 00738 00739 /* Combine data */ 00740 exp_mask = NULL ; 00741 cube_combined_noise = NULL ; 00742 cube_combined_data = NULL ; 00743 if (kmo_priv_combine(data_cube_list, noise_cube_list, data_header_list, 00744 noise_header_list, data_cube_counter, noise_cube_counter, 00745 name_loc, ifus_txt, method, "BCS", fmethod, filename, 00746 cmethod, cpos_rej, cneg_rej, citer, cmin, cmax, 00747 extrapol_enum, flux, &cube_combined_data, 00748 &cube_combined_noise, &exp_mask) != CPL_ERROR_NONE) { 00749 for (i = 0; i < data_cube_counter ; i++) 00750 cpl_imagelist_delete(data_cube_list[i]); 00751 for (i = 0; i < noise_cube_counter ; i++) 00752 cpl_imagelist_delete(noise_cube_list[i]); 00753 for (i = 0; i < data_cube_counter ; i++) 00754 cpl_propertylist_delete(data_header_list[i]); 00755 for (i = 0; i < noise_cube_counter ; i++) 00756 cpl_propertylist_delete(noise_header_list[i]); 00757 if (ifus != NULL) cpl_vector_delete(ifus); 00758 cpl_free(data_cube_list); 00759 cpl_free(noise_cube_list); 00760 cpl_free(data_header_list); 00761 cpl_free(noise_header_list); 00762 for (i = 0; i < name_vec_size ; i++) cpl_free(name_vec[i]); 00763 cpl_free(name_vec); 00764 cpl_free(used_ifus_str) ; 00765 cpl_frameset_delete(rawframes) ; 00766 if (mapping_mode != NULL) cpl_free(mapping_mode) ; 00767 cpl_msg_error(__func__, "Failed Combination") ; 00768 cpl_error_set(__func__,CPL_ERROR_ILLEGAL_INPUT); 00769 return -1 ; 00770 } 00771 for (i = 0; i < data_cube_counter ; i++) 00772 cpl_imagelist_delete(data_cube_list[i]); 00773 for (i = 0; i < noise_cube_counter ; i++) 00774 cpl_imagelist_delete(noise_cube_list[i]); 00775 00776 /* 00777 for (i = 0; i < data_cube_counter ; i++) 00778 cpl_propertylist_delete(data_header_list[i]); 00779 for (i = 0; i < noise_cube_counter ; i++) 00780 cpl_propertylist_delete(noise_header_list[i]); 00781 if (ifus != NULL) cpl_vector_delete(ifus); 00782 cpl_free(data_cube_list); 00783 cpl_free(noise_cube_list); 00784 cpl_free(data_header_list); 00785 cpl_free(noise_header_list); 00786 for (i = 0; i < name_vec_size ; i++) cpl_free(name_vec[i]); 00787 cpl_free(name_vec); 00788 if (mapping_mode != NULL) cpl_free(mapping_mode) ; 00789 cpl_image_delete(exp_mask); 00790 cpl_imagelist_delete(cube_combined_noise); 00791 cpl_imagelist_delete(cube_combined_data); 00792 if (noise_header_list!=NULL && noise_cube_counter==0) 00793 cpl_propertylist_delete(noise_header_list[0]) ; 00794 cpl_frameset_delete(rawframes) ; 00795 */ 00796 /* Save data */ 00797 if (!suppress_extension) { 00798 /* Setup output category COMBINE + ESO PRO CATG */ 00799 main_header = kmo_dfs_load_primary_header(rawframes, "0"); 00800 fn_combine = cpl_sprintf("%s_%s_%s", COMBINE, 00801 cpl_propertylist_get_string(main_header, CPL_DFS_PRO_CATG), 00802 name_vec[nv]); 00803 fn_mask = cpl_sprintf("%s_%s_%s", EXP_MASK, 00804 cpl_propertylist_get_string(main_header, CPL_DFS_PRO_CATG), 00805 name_vec[nv]); 00806 cpl_propertylist_delete(main_header); 00807 } else { 00808 fn_combine = cpl_sprintf("%s_%d", COMBINE, suppress_index); 00809 fn_mask = cpl_sprintf("%s_%d", EXP_MASK, suppress_index++); 00810 } 00811 00812 /* Create PRO keys plist */ 00813 pro_plist = cpl_propertylist_new() ; 00814 if (used_ifus_str != NULL) 00815 cpl_propertylist_update_string(pro_plist, "ESO PRO USEDIFUS", 00816 used_ifus_str) ; 00817 cpl_propertylist_update_string(pro_plist, "ESO PRO SKIPPEDIFUS", 00818 skipped_frames) ; 00819 00820 /* Add REFLEX SUFFIX keyword */ 00821 reflex_suffix = kmos_get_reflex_suffix(mapping_id, 00822 ifus_txt, name, name_loc) ; 00823 cpl_propertylist_update_string(pro_plist, "ESO PRO REFLEX SUFFIX", 00824 reflex_suffix) ; 00825 cpl_free(reflex_suffix) ; 00826 00827 /* Save Headers first */ 00828 frame = cpl_frameset_find(rawframes, NULL); 00829 kmo_dfs_save_main_header(frameset, fn_combine, "", frame, pro_plist, 00830 parlist, cpl_func); 00831 kmo_dfs_save_main_header(frameset, fn_mask, "", frame, pro_plist, 00832 parlist, cpl_func); 00833 cpl_propertylist_delete(pro_plist) ; 00834 cpl_free(used_ifus_str) ; 00835 00836 /* Clean */ 00837 if (data_header_list[0] != NULL) { 00838 if (cpl_propertylist_has(data_header_list[0], "ESO PRO FRNAME")) { 00839 cpl_propertylist_erase(data_header_list[0], "ESO PRO FRNAME"); 00840 } 00841 if (cpl_propertylist_has(data_header_list[0], "ESO PRO IFUNR")) { 00842 cpl_propertylist_erase(data_header_list[0], "ESO PRO IFUNR"); 00843 } 00844 } 00845 if (noise_header_list[0] != NULL) { 00846 if (cpl_propertylist_has(noise_header_list[0], "ESO PRO FRNAME")) { 00847 cpl_propertylist_erase(noise_header_list[0], "ESO PRO FRNAME"); 00848 } 00849 if (cpl_propertylist_has(noise_header_list[0], "ESO PRO IFUNR")) { 00850 cpl_propertylist_erase(noise_header_list[0], "ESO PRO IFUNR"); 00851 } 00852 } 00853 kmo_dfs_save_cube(cube_combined_data, fn_combine, "", 00854 data_header_list[0], 0./0.); 00855 cpl_imagelist_delete(cube_combined_data); 00856 kmo_dfs_save_cube(cube_combined_noise, fn_combine, "", 00857 noise_header_list[0], 0./0.); 00858 cpl_imagelist_delete(cube_combined_noise); 00859 cpl_free(fn_combine); 00860 00861 cpl_propertylist_erase(data_header_list[0], CRPIX3); 00862 cpl_propertylist_erase(data_header_list[0], CRPIX3); 00863 cpl_propertylist_erase(data_header_list[0], CRVAL3); 00864 cpl_propertylist_erase(data_header_list[0], CDELT3); 00865 cpl_propertylist_erase(data_header_list[0], CD1_3); 00866 cpl_propertylist_erase(data_header_list[0], CD2_3); 00867 cpl_propertylist_erase(data_header_list[0], CD3_1); 00868 cpl_propertylist_erase(data_header_list[0], CD3_2); 00869 cpl_propertylist_erase(data_header_list[0], CD3_3); 00870 cpl_propertylist_erase(data_header_list[0], CTYPE3); 00871 kmo_dfs_save_image(exp_mask, fn_mask, "", data_header_list[0], 0./0.); 00872 cpl_free(fn_mask); 00873 cpl_image_delete(exp_mask); 00874 00875 for (i = 0; i < data_cube_counter ; i++) 00876 cpl_propertylist_delete(data_header_list[i]); 00877 for (i = 0; i < noise_cube_counter ; i++) 00878 cpl_propertylist_delete(noise_header_list[i]); 00879 if (noise_header_list!=NULL && noise_cube_counter==0) 00880 cpl_propertylist_delete(noise_header_list[0]) ; 00881 } 00882 cpl_frameset_delete(rawframes) ; 00883 if (skipped_bivector!=NULL) cpl_bivector_delete(skipped_bivector) ; 00884 if (ifus != NULL) cpl_vector_delete(ifus); 00885 cpl_free(data_cube_list); 00886 cpl_free(noise_cube_list); 00887 cpl_free(data_header_list); 00888 cpl_free(noise_header_list); 00889 for (i = 0; i < name_vec_size ; i++) cpl_free(name_vec[i]); 00890 cpl_free(name_vec); 00891 cpl_free(mapping_mode) ; 00892 00893 /* Collapse the combined cubes if requested */ 00894 if (collapse_combined) { 00895 kmos_collapse_cubes(COMBINED_RECONS, frameset, parlist, 0.1, "", 00896 DEF_REJ_METHOD, DEF_POS_REJ_THRES, DEF_NEG_REJ_THRES, 00897 DEF_ITERATIONS, DEF_NR_MIN_REJ, DEF_NR_MAX_REJ) ; 00898 } 00899 return 0; 00900 } 00901 00904 /*----------------------------------------------------------------------------*/ 00910 /*----------------------------------------------------------------------------*/ 00911 static char * kmos_combine_create_used_ifus_string( 00912 const int * used_frame_idx, 00913 const int * used_ifus, 00914 int nb) 00915 { 00916 char out[8192] ; 00917 char tmp[7] ; 00918 int i ; 00919 00920 if (nb > 1000) return NULL ; 00921 for (i=0 ; i<nb ; i++) { 00922 /* Build the current string */ 00923 if (used_frame_idx[i] < 10 && used_ifus[i] < 10) 00924 if (i==0) sprintf(tmp, "%1d:%1d", used_frame_idx[i], used_ifus[i]); 00925 else sprintf(tmp, ",%1d:%1d", used_frame_idx[i], used_ifus[i]); 00926 else if (used_frame_idx[i] < 10 && used_ifus[i] >= 10) 00927 if (i==0) sprintf(tmp, "%1d:%2d", used_frame_idx[i], used_ifus[i]); 00928 else sprintf(tmp, ",%1d:%2d", used_frame_idx[i], used_ifus[i]); 00929 else if (used_frame_idx[i] >= 10 && used_ifus[i] < 10) 00930 if (i==0) sprintf(tmp, "%2d:%1d", used_frame_idx[i], used_ifus[i]); 00931 else sprintf(tmp, ",%2d:%1d", used_frame_idx[i], used_ifus[i]); 00932 else if (used_frame_idx[i] >= 10 && used_ifus[i] >= 10) 00933 if (i==0) sprintf(tmp, "%2d:%2d", used_frame_idx[i], used_ifus[i]); 00934 else sprintf(tmp, ",%2d:%2d", used_frame_idx[i], used_ifus[i]); 00935 else return NULL ; 00936 00937 if (i==0) strcpy(out, tmp) ; 00938 else strcat(out, tmp); 00939 } 00940 00941 /* Warning : If larger than 51 char, it does not fit in the header card */ 00942 if (strlen(out) > 51) return NULL ; 00943 00944 return cpl_strdup(out) ; 00945 } 00946 00947 /*----------------------------------------------------------------------------*/ 00953 /*----------------------------------------------------------------------------*/ 00954 static cpl_bivector * kmos_combine_parse_skipped(const char * str) 00955 { 00956 cpl_bivector * out ; 00957 cpl_vector * out_x ; 00958 cpl_vector * out_y ; 00959 char * my_str ; 00960 int nb_values ; 00961 char * s1 ; 00962 char * s2 ; 00963 int val1, val2, ret ; 00964 00965 /* Check Entries */ 00966 if (str == NULL) return NULL ; 00967 00968 /* Initialise */ 00969 nb_values = 0 ; 00970 my_str = cpl_strdup(str) ; 00971 00972 /* Count the values */ 00973 for (s2 = my_str; s2; ) { 00974 while (*s2 == ' ' || *s2 == '\t') s2++; 00975 s1 = strsep(&s2, ",") ; 00976 if (*s1) { 00977 if (sscanf(s1," %i:%i", &val1, &val2) == 2) { 00978 nb_values ++ ; 00979 } 00980 } 00981 } 00982 cpl_free(my_str) ; 00983 if (nb_values == 0) return NULL ; 00984 00985 /* Create the vector */ 00986 out = cpl_bivector_new(nb_values) ; 00987 out_x = cpl_bivector_get_x(out) ; 00988 out_y = cpl_bivector_get_y(out) ; 00989 00990 /* Fill the vector */ 00991 nb_values = 0 ; 00992 my_str = cpl_strdup(str) ; 00993 for (s2 = my_str; s2; ) { 00994 while (*s2 == ' ' || *s2 == '\t') s2++; 00995 s1 = strsep(&s2, ",") ; 00996 if (*s1) { 00997 if (sscanf(s1," %i:%i", &val1, &val2) == 2) { 00998 cpl_vector_set(out_x, nb_values, val1) ; 00999 cpl_vector_set(out_y, nb_values, val2) ; 01000 nb_values ++ ; 01001 } 01002 } 01003 } 01004 cpl_free(my_str) ; 01005 return out; 01006 } 01007 01008 /*----------------------------------------------------------------------------*/ 01016 /*----------------------------------------------------------------------------*/ 01017 static int kmos_combine_is_skipped( 01018 const cpl_bivector * skipped, 01019 int frame_idx, 01020 int ifu_nr) 01021 { 01022 const cpl_vector * vec_x ; 01023 const cpl_vector * vec_y ; 01024 double val1, val2 ; 01025 int i ; 01026 01027 /* Check entries */ 01028 if (skipped == NULL) return 0; 01029 01030 /* Initialise */ 01031 vec_x = cpl_bivector_get_x_const(skipped) ; 01032 vec_y = cpl_bivector_get_y_const(skipped) ; 01033 01034 /* Loop */ 01035 for (i=0 ; i<cpl_bivector_get_size(skipped) ; i++) { 01036 val1 = cpl_vector_get(vec_x, i) ; 01037 val2 = cpl_vector_get(vec_y, i) ; 01038 if (fabs(val1-frame_idx)<1e-3 && fabs(val2-ifu_nr)<1e-3) return 1 ; 01039 } 01040 return 0 ; 01041 } 01042
1.7.6.1