|
KMOS Pipeline Reference Manual
1.3.16
|
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 char * tmp_str, * fn_combine, * fn_mask, * mapping_mode, 00337 * name, ** name_vec ; 00338 const char * frame_filename, * tmp_strc ; 00339 cpl_image * exp_mask ; 00340 cpl_imagelist ** data_cube_list, ** noise_cube_list, * cube_combined_data, 00341 * cube_combined_noise ; 00342 cpl_propertylist * main_header, **data_header_list, **noise_header_list, 00343 * tmp_header, * pro_plist ; 00344 cpl_bivector * skipped_bivector ; 00345 cpl_frame * frame ; 00346 cpl_size ci ; 00347 main_fits_desc desc; 00348 int * used_frame_idx ; 00349 int * used_ifus ; 00350 char * used_ifus_str ; 00351 enum extrapolationType extrapol_enum = NONE_CLIPPING; 00352 int i, j ; 00353 00354 /* Check entries */ 00355 if (parlist == NULL || frameset == NULL) { 00356 cpl_msg_error(__func__, "Null Inputs") ; 00357 cpl_error_set(__func__, CPL_ERROR_NULL_INPUT) ; 00358 return -1 ; 00359 } 00360 00361 /* Get parameters */ 00362 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_combine.method"); 00363 method = cpl_parameter_get_string(par) ; 00364 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_combine.fmethod"); 00365 fmethod = cpl_parameter_get_string(par) ; 00366 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_combine.filename"); 00367 filename = cpl_parameter_get_string(par) ; 00368 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_combine.ifus"); 00369 ifus_txt = cpl_parameter_get_string(par) ; 00370 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_combine.name"); 00371 name = (char*)cpl_parameter_get_string(par) ; 00372 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_combine.flux"); 00373 flux = cpl_parameter_get_bool(par) ; 00374 par = cpl_parameterlist_find_const(parlist, 00375 "kmos.kmos_combine.skipped_frames"); 00376 skipped_frames = cpl_parameter_get_string(par) ; 00377 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_combine.edge_nan"); 00378 edge_nan = cpl_parameter_get_bool(par) ; 00379 par = cpl_parameterlist_find_const(parlist, 00380 "kmos.kmos_combine.suppress_extension"); 00381 suppress_extension = cpl_parameter_get_bool(par) ; 00382 kmos_combine_pars_load(parlist, "kmos.kmos_combine", &cmethod, &cpos_rej, 00383 &cneg_rej, &citer, &cmin, &cmax, FALSE); 00384 par = cpl_parameterlist_find_const(parlist, 00385 "kmos.kmos_combine.collapse_combined"); 00386 collapse_combined = cpl_parameter_get_bool(par); 00387 00388 /* Check Parameters */ 00389 if (strcmp(method, "none") && strcmp(method, "header") && 00390 strcmp(method, "center") && strcmp(method, "user")) { 00391 cpl_msg_error(__func__, 00392 "shift methods must be 'none', 'header', 'center' or 'user'") ; 00393 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00394 return -1 ; 00395 } 00396 if (strcmp(ifus_txt, "") && strcmp(name, "")) { 00397 cpl_msg_error(__func__, 00398 "name and IFU indices cannot be both provided") ; 00399 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00400 return -1 ; 00401 } 00402 if (!strcmp(method, "user") && !strcmp(filename, "")) { 00403 cpl_msg_error(__func__, 00404 "path of file with shift information must be provided") ; 00405 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00406 return -1 ; 00407 } 00408 00409 /* Identify the RAW and CALIB frames in the input frameset */ 00410 if (kmo_dfs_set_groups(frameset, "kmos_combine") != 1) { 00411 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ; 00412 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00413 return -1 ; 00414 } 00415 00416 /* Parse the skipped frames option */ 00417 skipped_bivector = NULL ; 00418 if (strcmp(skipped_frames, "")) { 00419 skipped_bivector = kmos_combine_parse_skipped(skipped_frames) ; 00420 if (skipped_bivector != NULL) 00421 cpl_msg_info(__func__, "Skip the following frames: %s", 00422 skipped_frames); 00423 } 00424 00425 /* Get the frames to combine - Filter out OH_SPEC */ 00426 rawframes = cpl_frameset_duplicate(frameset) ; 00427 cpl_frameset_erase(rawframes, "OH_SPEC") ; 00428 00429 /* Check Nb of frames */ 00430 nr_frames = cpl_frameset_get_size(rawframes); 00431 if (nr_frames < 2) { 00432 if (skipped_bivector!=NULL) cpl_bivector_delete(skipped_bivector) ; 00433 cpl_frameset_delete(rawframes) ; 00434 cpl_msg_error(__func__, "At least two frames must be provided") ; 00435 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00436 return -1 ; 00437 } 00438 00439 /* Load IFUS if specified */ 00440 if (strcmp(ifus_txt, "")) { 00441 ifus = kmo_identify_values(ifus_txt); 00442 if (ifus == NULL || cpl_vector_get_size(ifus) != nr_frames) { 00443 if (ifus != NULL) cpl_vector_delete(ifus); 00444 if (skipped_bivector!=NULL) cpl_bivector_delete(skipped_bivector) ; 00445 cpl_frameset_delete(rawframes) ; 00446 cpl_msg_error(__func__, "ifus size must match the science frames") ; 00447 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00448 return -1 ; 00449 } 00450 } else { 00451 ifus = NULL ; 00452 } 00453 00454 /* Check for mapping mode */ 00455 mapping_mode = NULL ; 00456 cpl_size fs_size = cpl_frameset_get_size(rawframes); 00457 for (ci = 0; ci < fs_size; ci++) { 00458 frame = cpl_frameset_get_position(rawframes, ci); 00459 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(frame),0); 00460 if (cpl_propertylist_has(tmp_header, TPL_ID)) { 00461 tmp_strc = cpl_propertylist_get_string(tmp_header, TPL_ID); 00462 if (mapping_mode == NULL) { 00463 if (!strcmp(tmp_strc, MAPPING8)) 00464 mapping_mode = cpl_sprintf("%s", tmp_strc); 00465 if (!strcmp(tmp_strc, MAPPING24)) 00466 mapping_mode = cpl_sprintf("%s", tmp_strc); 00467 } else { 00468 if (strcmp(tmp_strc, mapping_mode)) { 00469 cpl_msg_warning(__func__, 00470 "There are different TPL IDs in input: %s and %s", 00471 tmp_strc, mapping_mode); 00472 } 00473 } 00474 } 00475 cpl_propertylist_delete(tmp_header); 00476 } 00477 00478 if (mapping_mode != NULL) { 00479 if (!strcmp(ifus_txt, "") && !strcmp(name, "")) { 00480 cpl_msg_info(__func__,"*****************************************"); 00481 cpl_msg_info(__func__,"* A map with all IFUs will be generated *"); 00482 cpl_msg_info(__func__,"*****************************************"); 00483 extrapol_enum = BCS_NATURAL; 00484 } else { 00485 cpl_msg_info(__func__, "No Map as name / ifu is specified"); 00486 cpl_free(mapping_mode); 00487 mapping_mode = NULL ; 00488 } 00489 } 00490 00491 /* Create name/ifu map... */ 00492 name_vec = cpl_calloc(nr_frames*KMOS_NR_IFUS, sizeof(char*)); 00493 00494 /* No name / IFU specified - Non mapping mode */ 00495 if (!strcmp(ifus_txt, "") && !strcmp(name, "") && mapping_mode==NULL) { 00496 /* All available names should be combined in one go */ 00497 name_vec_size = 0; 00498 for (i = 0; i < nr_frames; i++) { 00499 tmp_str = cpl_sprintf("%d", i); 00500 frame = kmo_dfs_get_frame(rawframes, tmp_str); 00501 cpl_free(tmp_str); 00502 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 00503 found = 0; 00504 tmp_str = kmo_get_name_from_ocs_ifu(frame, ifu_nr); 00505 if (tmp_str != NULL) { 00506 for (j = 0; j < name_vec_size; j++) { 00507 if (!strcmp(name_vec[j], tmp_str)) { 00508 found = TRUE; 00509 break; 00510 } 00511 } 00512 if (!found) name_vec[name_vec_size++] = tmp_str; 00513 else cpl_free(tmp_str); 00514 } 00515 } 00516 } 00517 } else { 00518 /* Standard behavior: either ifu_nr- or name- or mapping-case */ 00519 name_vec_size = 1; 00520 if (mapping_mode != NULL) { 00521 name_vec[0] = cpl_sprintf("mapping"); 00522 } else { 00523 if (ifus != NULL) { 00524 char *tmptmp = NULL; 00525 00526 // replace all ; with _ 00527 char *found_char = NULL; 00528 found_char = strstr(ifus_txt, ";"); 00529 while (found_char != NULL) { 00530 strncpy(found_char, "_", 1); 00531 found_char = strstr(ifus_txt, ";"); 00532 } 00533 00534 if (strlen(ifus_txt) > 10) { 00535 tmptmp = kmo_shorten_ifu_string(ifus_txt); 00536 cpl_msg_info(__func__, "Truncate to ..ifu%s..", tmptmp); 00537 } else { 00538 tmptmp = cpl_sprintf("%s", ifus_txt); 00539 } 00540 name_vec[0] = cpl_sprintf("IFU%s", tmptmp); 00541 ifus_txt = ""; 00542 cpl_free(tmptmp); 00543 } else { 00544 name_vec[0] = cpl_sprintf("%s", name); 00545 } 00546 } 00547 } 00548 00549 /* Load data and noise */ 00550 data_cube_list = cpl_calloc(nr_frames*KMOS_NR_IFUS, 00551 sizeof(cpl_imagelist*)); 00552 data_header_list = cpl_calloc(nr_frames*KMOS_NR_IFUS, 00553 sizeof(cpl_propertylist*)); 00554 noise_cube_list = cpl_calloc(nr_frames*KMOS_NR_IFUS, 00555 sizeof(cpl_imagelist*)); 00556 noise_header_list = cpl_calloc(nr_frames*KMOS_NR_IFUS, 00557 sizeof(cpl_propertylist*)); 00558 00559 /* 00560 if (ifus != NULL) cpl_vector_delete(ifus); 00561 cpl_frameset_delete(rawframes) ; 00562 cpl_free(data_cube_list); 00563 cpl_free(noise_cube_list); 00564 cpl_free(data_header_list); 00565 cpl_free(noise_header_list); 00566 for (i = 0; i < name_vec_size ; i++) cpl_free(name_vec[i]); 00567 cpl_free(name_vec); 00568 if (mapping_mode != NULL) cpl_free(mapping_mode) ; 00569 return 0 ; 00570 */ 00571 00572 /* Load all data (and noise if existent) cubes and store them */ 00573 for (nv = 0; nv < name_vec_size; nv++) { 00574 name = name_vec[nv]; 00575 00576 used_frame_idx = cpl_calloc(nr_frames*KMOS_NR_IFUS, sizeof(int)) ; 00577 used_ifus = cpl_calloc(nr_frames*KMOS_NR_IFUS, sizeof(int)) ; 00578 00579 data_cube_counter = 0; 00580 noise_cube_counter = 0; 00581 for (i = 0; i < nr_frames; i++) { 00582 tmp_str = cpl_sprintf("%d", i); 00583 frame = kmo_dfs_get_frame(rawframes, tmp_str); 00584 frame_filename = cpl_frame_get_filename(frame); 00585 kmo_init_fits_desc(&desc); 00586 desc = kmo_identify_fits_header(frame_filename); 00587 00588 if (mapping_mode != NULL) { 00589 /* Mapping mode */ 00590 for (j = 1; j <= KMOS_NR_IFUS; j++) { 00591 /* Loop over all IFUs */ 00592 if (desc.sub_desc[j-1].valid_data == TRUE && 00593 !kmos_combine_is_skipped(skipped_bivector,i+1,j)) { 00594 /* Load data frames */ 00595 override_err_msg = TRUE; 00596 data_cube_list[data_cube_counter] = 00597 kmo_dfs_load_cube(rawframes, tmp_str, j,FALSE); 00598 override_err_msg = FALSE; 00599 if (data_cube_list[data_cube_counter] == NULL) { 00600 cpl_error_reset(); 00601 } else { 00602 if (edge_nan) kmo_edge_nan( 00603 data_cube_list[data_cube_counter], j); 00604 data_header_list[data_cube_counter] = 00605 kmo_dfs_load_sub_header(rawframes, 00606 tmp_str, j, FALSE); 00607 cpl_propertylist_update_string( 00608 data_header_list[data_cube_counter], 00609 "ESO PRO FRNAME", frame_filename); 00610 cpl_propertylist_update_int( 00611 data_header_list[data_cube_counter], 00612 "ESO PRO IFUNR", j); 00613 used_frame_idx[data_cube_counter] = i+1 ; 00614 used_ifus[data_cube_counter] = j ; 00615 data_cube_counter++; 00616 } 00617 00618 /* Load noise frames */ 00619 override_err_msg = TRUE; 00620 noise_cube_list[noise_cube_counter] = 00621 kmo_dfs_load_cube(rawframes, tmp_str, j, TRUE); 00622 00623 override_err_msg = FALSE; 00624 if (noise_cube_list[noise_cube_counter] == NULL) { 00625 // no noise found for this IFU 00626 cpl_error_reset(); 00627 } else { 00628 if (edge_nan) kmo_edge_nan( 00629 noise_cube_list[noise_cube_counter], j); 00630 noise_header_list[noise_cube_counter] = 00631 kmo_dfs_load_sub_header(rawframes, tmp_str, 00632 j, TRUE); 00633 noise_cube_counter++; 00634 } 00635 00636 /* Check if number of data and noise frames match */ 00637 if (noise_cube_counter > 0) { 00638 if (data_cube_counter != noise_cube_counter) { 00639 cpl_msg_error(__func__, "Noise missing") ; 00640 cpl_error_set(__func__,CPL_ERROR_ILLEGAL_INPUT); 00641 /* TODO - deallocate */ 00642 return -1 ; 00643 } 00644 } 00645 } 00646 } 00647 } else { 00648 /* name/ifu mode (single) */ 00649 if (ifus != NULL) ifu_nr = cpl_vector_get(ifus, i); 00650 else ifu_nr = kmo_get_index_from_ocs_name(frame, name); 00651 if (ifu_nr > 0) { 00652 index = kmo_identify_index(frame_filename, ifu_nr , FALSE); 00653 if (desc.sub_desc[index-1].valid_data == TRUE && 00654 !kmos_combine_is_skipped(skipped_bivector,i+1, 00655 ifu_nr)) { 00656 /* Load data frames */ 00657 override_err_msg = TRUE; 00658 data_cube_list[data_cube_counter] = 00659 kmo_dfs_load_cube(rawframes, tmp_str, ifu_nr, 00660 FALSE); 00661 override_err_msg = FALSE; 00662 if (data_cube_list[data_cube_counter] == NULL) { 00663 /* No data found for this IFU */ 00664 cpl_error_reset(); 00665 if (ifus != NULL) cpl_msg_warning(cpl_func, 00666 "IFU %d miѕsing in frame %s", 00667 ifu_nr, frame_filename); 00668 else cpl_msg_warning(cpl_func, 00669 "Object %s missing in Frame %d (%s)", 00670 name, i+1, frame_filename) ; 00671 } else { 00672 if (edge_nan) kmo_edge_nan( 00673 data_cube_list[data_cube_counter], ifu_nr); 00674 data_header_list[data_cube_counter] = 00675 kmo_dfs_load_sub_header(rawframes, tmp_str, 00676 ifu_nr, FALSE); 00677 cpl_propertylist_update_string( 00678 data_header_list[data_cube_counter], 00679 "ESO PRO FRNAME", frame_filename); 00680 cpl_propertylist_update_int( 00681 data_header_list[data_cube_counter], 00682 "ESO PRO IFUNR", ifu_nr); 00683 used_frame_idx[data_cube_counter] = i+1 ; 00684 used_ifus[data_cube_counter] = ifu_nr ; 00685 data_cube_counter++; 00686 } 00687 00688 /* Load noise frames */ 00689 override_err_msg = TRUE; 00690 noise_cube_list[noise_cube_counter] = 00691 kmo_dfs_load_cube(rawframes, tmp_str, ifu_nr, 00692 TRUE); 00693 override_err_msg = FALSE; 00694 if (noise_cube_list[noise_cube_counter] == NULL) { 00695 /* No noise found for this IFU */ 00696 cpl_error_reset(); 00697 } else { 00698 if (edge_nan) kmo_edge_nan( 00699 noise_cube_list[noise_cube_counter],ifu_nr); 00700 noise_header_list[noise_cube_counter] = 00701 kmo_dfs_load_sub_header(rawframes, 00702 tmp_str, ifu_nr, TRUE); 00703 noise_cube_counter++; 00704 } 00705 00706 /* Check if number of data and noise frames match */ 00707 if (noise_cube_counter > 0) { 00708 if (data_cube_counter != noise_cube_counter) { 00709 /* TODO - deallocate */ 00710 cpl_msg_error(__func__, "Noise missing") ; 00711 cpl_error_set(__func__,CPL_ERROR_ILLEGAL_INPUT); 00712 return -1 ; 00713 } 00714 } 00715 } 00716 } 00717 } 00718 kmo_free_fits_desc(&desc); 00719 cpl_free(tmp_str); 00720 } 00721 00722 /* Create String for the output header - IFUs usage */ 00723 used_ifus_str = kmos_combine_create_used_ifus_string(used_frame_idx, 00724 used_ifus, data_cube_counter); 00725 cpl_free(used_frame_idx) ; 00726 cpl_free(used_ifus) ; 00727 00728 /* Combine data */ 00729 exp_mask = NULL ; 00730 cube_combined_noise = NULL ; 00731 cube_combined_data = NULL ; 00732 if (kmo_priv_combine(data_cube_list, noise_cube_list, data_header_list, 00733 noise_header_list, data_cube_counter, noise_cube_counter, 00734 name, ifus_txt, method, "BCS", fmethod, filename, cmethod, 00735 cpos_rej, cneg_rej, citer, cmin, cmax, extrapol_enum, flux, 00736 &cube_combined_data, &cube_combined_noise, 00737 &exp_mask) != CPL_ERROR_NONE) { 00738 for (i = 0; i < data_cube_counter ; i++) 00739 cpl_imagelist_delete(data_cube_list[i]); 00740 for (i = 0; i < noise_cube_counter ; i++) 00741 cpl_imagelist_delete(noise_cube_list[i]); 00742 for (i = 0; i < data_cube_counter ; i++) 00743 cpl_propertylist_delete(data_header_list[i]); 00744 for (i = 0; i < noise_cube_counter ; i++) 00745 cpl_propertylist_delete(noise_header_list[i]); 00746 if (ifus != NULL) cpl_vector_delete(ifus); 00747 cpl_free(data_cube_list); 00748 cpl_free(noise_cube_list); 00749 cpl_free(data_header_list); 00750 cpl_free(noise_header_list); 00751 for (i = 0; i < name_vec_size ; i++) cpl_free(name_vec[i]); 00752 cpl_free(name_vec); 00753 cpl_free(used_ifus_str) ; 00754 cpl_frameset_delete(rawframes) ; 00755 if (mapping_mode != NULL) cpl_free(mapping_mode) ; 00756 cpl_msg_error(__func__, "Failed Combination") ; 00757 cpl_error_set(__func__,CPL_ERROR_ILLEGAL_INPUT); 00758 return -1 ; 00759 } 00760 for (i = 0; i < data_cube_counter ; i++) 00761 cpl_imagelist_delete(data_cube_list[i]); 00762 for (i = 0; i < noise_cube_counter ; i++) 00763 cpl_imagelist_delete(noise_cube_list[i]); 00764 00765 /* 00766 for (i = 0; i < data_cube_counter ; i++) 00767 cpl_propertylist_delete(data_header_list[i]); 00768 for (i = 0; i < noise_cube_counter ; i++) 00769 cpl_propertylist_delete(noise_header_list[i]); 00770 if (ifus != NULL) cpl_vector_delete(ifus); 00771 cpl_free(data_cube_list); 00772 cpl_free(noise_cube_list); 00773 cpl_free(data_header_list); 00774 cpl_free(noise_header_list); 00775 for (i = 0; i < name_vec_size ; i++) cpl_free(name_vec[i]); 00776 cpl_free(name_vec); 00777 if (mapping_mode != NULL) cpl_free(mapping_mode) ; 00778 cpl_image_delete(exp_mask); 00779 cpl_imagelist_delete(cube_combined_noise); 00780 cpl_imagelist_delete(cube_combined_data); 00781 if (noise_header_list!=NULL && noise_cube_counter==0) 00782 cpl_propertylist_delete(noise_header_list[0]) ; 00783 cpl_frameset_delete(rawframes) ; 00784 */ 00785 /* Save data */ 00786 if (!suppress_extension) { 00787 /* Setup output category COMBINE + ESO PRO CATG */ 00788 main_header = kmo_dfs_load_primary_header(rawframes, "0"); 00789 fn_combine = cpl_sprintf("%s_%s_%s", COMBINE, 00790 cpl_propertylist_get_string(main_header, CPL_DFS_PRO_CATG), 00791 name_vec[nv]); 00792 fn_mask = cpl_sprintf("%s_%s_%s", EXP_MASK, 00793 cpl_propertylist_get_string(main_header, CPL_DFS_PRO_CATG), 00794 name_vec[nv]); 00795 cpl_propertylist_delete(main_header); 00796 } else { 00797 fn_combine = cpl_sprintf("%s_%d", COMBINE, suppress_index); 00798 fn_mask = cpl_sprintf("%s_%d", EXP_MASK, suppress_index++); 00799 } 00800 00801 /* Create PRO keys plist */ 00802 pro_plist = cpl_propertylist_new() ; 00803 cpl_propertylist_update_string(pro_plist, "ESO PRO USEDIFUS", 00804 used_ifus_str) ; 00805 cpl_propertylist_update_string(pro_plist, "ESO PRO SKIPPEDIFUS", 00806 skipped_frames) ; 00807 00808 /* Save Headers first */ 00809 frame = cpl_frameset_find(rawframes, NULL); 00810 kmo_dfs_save_main_header(frameset, fn_combine, "", frame, pro_plist, 00811 parlist, cpl_func); 00812 kmo_dfs_save_main_header(frameset, fn_mask, "", frame, pro_plist, 00813 parlist, cpl_func); 00814 cpl_propertylist_delete(pro_plist) ; 00815 cpl_free(used_ifus_str) ; 00816 00817 /* Clean */ 00818 if (data_header_list[0] != NULL) { 00819 if (cpl_propertylist_has(data_header_list[0], "ESO PRO FRNAME")) { 00820 cpl_propertylist_erase(data_header_list[0], "ESO PRO FRNAME"); 00821 } 00822 if (cpl_propertylist_has(data_header_list[0], "ESO PRO IFUNR")) { 00823 cpl_propertylist_erase(data_header_list[0], "ESO PRO IFUNR"); 00824 } 00825 } 00826 if (noise_header_list[0] != NULL) { 00827 if (cpl_propertylist_has(noise_header_list[0], "ESO PRO FRNAME")) { 00828 cpl_propertylist_erase(noise_header_list[0], "ESO PRO FRNAME"); 00829 } 00830 if (cpl_propertylist_has(noise_header_list[0], "ESO PRO IFUNR")) { 00831 cpl_propertylist_erase(noise_header_list[0], "ESO PRO IFUNR"); 00832 } 00833 } 00834 kmo_dfs_save_cube(cube_combined_data, fn_combine, "", 00835 data_header_list[0], 0./0.); 00836 cpl_imagelist_delete(cube_combined_data); 00837 kmo_dfs_save_cube(cube_combined_noise, fn_combine, "", 00838 noise_header_list[0], 0./0.); 00839 cpl_imagelist_delete(cube_combined_noise); 00840 cpl_free(fn_combine); 00841 00842 cpl_propertylist_erase(data_header_list[0], CRPIX3); 00843 cpl_propertylist_erase(data_header_list[0], CRPIX3); 00844 cpl_propertylist_erase(data_header_list[0], CRVAL3); 00845 cpl_propertylist_erase(data_header_list[0], CDELT3); 00846 cpl_propertylist_erase(data_header_list[0], CD1_3); 00847 cpl_propertylist_erase(data_header_list[0], CD2_3); 00848 cpl_propertylist_erase(data_header_list[0], CD3_1); 00849 cpl_propertylist_erase(data_header_list[0], CD3_2); 00850 cpl_propertylist_erase(data_header_list[0], CD3_3); 00851 cpl_propertylist_erase(data_header_list[0], CTYPE3); 00852 kmo_dfs_save_image(exp_mask, fn_mask, "", data_header_list[0], 0./0.); 00853 cpl_free(fn_mask); 00854 cpl_image_delete(exp_mask); 00855 00856 for (i = 0; i < data_cube_counter ; i++) 00857 cpl_propertylist_delete(data_header_list[i]); 00858 for (i = 0; i < noise_cube_counter ; i++) 00859 cpl_propertylist_delete(noise_header_list[i]); 00860 if (noise_header_list!=NULL && noise_cube_counter==0) 00861 cpl_propertylist_delete(noise_header_list[0]) ; 00862 } 00863 cpl_frameset_delete(rawframes) ; 00864 if (skipped_bivector!=NULL) cpl_bivector_delete(skipped_bivector) ; 00865 if (ifus != NULL) cpl_vector_delete(ifus); 00866 cpl_free(data_cube_list); 00867 cpl_free(noise_cube_list); 00868 cpl_free(data_header_list); 00869 cpl_free(noise_header_list); 00870 for (i = 0; i < name_vec_size ; i++) cpl_free(name_vec[i]); 00871 cpl_free(name_vec); 00872 cpl_free(mapping_mode) ; 00873 00874 /* Collapse the combined cubes if requested */ 00875 if (collapse_combined) { 00876 kmos_collapse_cubes(COMBINED_RECONS, frameset, parlist, 0.1, "", 00877 DEF_REJ_METHOD, DEF_POS_REJ_THRES, DEF_NEG_REJ_THRES, 00878 DEF_ITERATIONS, DEF_NR_MIN_REJ, DEF_NR_MAX_REJ) ; 00879 } 00880 return 0; 00881 } 00882 00885 /*----------------------------------------------------------------------------*/ 00891 /*----------------------------------------------------------------------------*/ 00892 static char * kmos_combine_create_used_ifus_string( 00893 const int * used_frame_idx, 00894 const int * used_ifus, 00895 int nb) 00896 { 00897 char out[8192] ; 00898 char tmp[7] ; 00899 int i ; 00900 00901 if (nb > 1000) return NULL ; 00902 for (i=0 ; i<nb ; i++) { 00903 /* Build the current string */ 00904 if (used_frame_idx[i] < 10 && used_ifus[i] < 10) 00905 if (i==0) sprintf(tmp, "%1d:%1d", used_frame_idx[i], used_ifus[i]); 00906 else sprintf(tmp, ",%1d:%1d", used_frame_idx[i], used_ifus[i]); 00907 else if (used_frame_idx[i] < 10 && used_ifus[i] >= 10) 00908 if (i==0) sprintf(tmp, "%1d:%2d", used_frame_idx[i], used_ifus[i]); 00909 else sprintf(tmp, ",%1d:%2d", used_frame_idx[i], used_ifus[i]); 00910 else if (used_frame_idx[i] >= 10 && used_ifus[i] < 10) 00911 if (i==0) sprintf(tmp, "%2d:%1d", used_frame_idx[i], used_ifus[i]); 00912 else sprintf(tmp, ",%2d:%1d", used_frame_idx[i], used_ifus[i]); 00913 else if (used_frame_idx[i] >= 10 && used_ifus[i] >= 10) 00914 if (i==0) sprintf(tmp, "%2d:%2d", used_frame_idx[i], used_ifus[i]); 00915 else sprintf(tmp, ",%2d:%2d", used_frame_idx[i], used_ifus[i]); 00916 else return NULL ; 00917 00918 if (i==0) strcpy(out, tmp) ; 00919 else strcat(out, tmp); 00920 } 00921 00922 /* Warning : If larger than 51 char, it does not fit in the header card */ 00923 if (strlen(out) > 51) return NULL ; 00924 00925 return cpl_strdup(out) ; 00926 } 00927 00928 /*----------------------------------------------------------------------------*/ 00934 /*----------------------------------------------------------------------------*/ 00935 static cpl_bivector * kmos_combine_parse_skipped(const char * str) 00936 { 00937 cpl_bivector * out ; 00938 cpl_vector * out_x ; 00939 cpl_vector * out_y ; 00940 char * my_str ; 00941 int nb_values ; 00942 char * s1 ; 00943 char * s2 ; 00944 int val1, val2, ret ; 00945 00946 /* Check Entries */ 00947 if (str == NULL) return NULL ; 00948 00949 /* Initialise */ 00950 nb_values = 0 ; 00951 my_str = cpl_strdup(str) ; 00952 00953 /* Count the values */ 00954 for (s2 = my_str; s2; ) { 00955 while (*s2 == ' ' || *s2 == '\t') s2++; 00956 s1 = strsep(&s2, ",") ; 00957 if (*s1) { 00958 if (sscanf(s1," %i:%i", &val1, &val2) == 2) { 00959 nb_values ++ ; 00960 } 00961 } 00962 } 00963 cpl_free(my_str) ; 00964 if (nb_values == 0) return NULL ; 00965 00966 /* Create the vector */ 00967 out = cpl_bivector_new(nb_values) ; 00968 out_x = cpl_bivector_get_x(out) ; 00969 out_y = cpl_bivector_get_y(out) ; 00970 00971 /* Fill the vector */ 00972 nb_values = 0 ; 00973 my_str = cpl_strdup(str) ; 00974 for (s2 = my_str; s2; ) { 00975 while (*s2 == ' ' || *s2 == '\t') s2++; 00976 s1 = strsep(&s2, ",") ; 00977 if (*s1) { 00978 if (sscanf(s1," %i:%i", &val1, &val2) == 2) { 00979 cpl_vector_set(out_x, nb_values, val1) ; 00980 cpl_vector_set(out_y, nb_values, val2) ; 00981 nb_values ++ ; 00982 } 00983 } 00984 } 00985 cpl_free(my_str) ; 00986 return out; 00987 } 00988 00989 /*----------------------------------------------------------------------------*/ 00997 /*----------------------------------------------------------------------------*/ 00998 static int kmos_combine_is_skipped( 00999 const cpl_bivector * skipped, 01000 int frame_idx, 01001 int ifu_nr) 01002 { 01003 const cpl_vector * vec_x ; 01004 const cpl_vector * vec_y ; 01005 double val1, val2 ; 01006 int i ; 01007 01008 /* Check entries */ 01009 if (skipped == NULL) return 0; 01010 01011 /* Initialise */ 01012 vec_x = cpl_bivector_get_x_const(skipped) ; 01013 vec_y = cpl_bivector_get_y_const(skipped) ; 01014 01015 /* Loop */ 01016 for (i=0 ; i<cpl_bivector_get_size(skipped) ; i++) { 01017 val1 = cpl_vector_get(vec_x, i) ; 01018 val2 = cpl_vector_get(vec_y, i) ; 01019 if (fabs(val1-frame_idx)<1e-3 && fabs(val2-ifu_nr)<1e-3) return 1 ; 01020 } 01021 return 0 ; 01022 } 01023
1.7.6.1