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