KMOS Pipeline Reference Manual
1.3.0
|
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 00033 #include "kmo_utils.h" 00034 #include "kmo_dfs.h" 00035 #include "kmo_error.h" 00036 #include "kmo_priv_extract_spec.h" 00037 #include "kmo_priv_functions.h" 00038 #include "kmo_cpl_extensions.h" 00039 #include "kmo_constants.h" 00040 #include "kmo_priv_fit_profile.h" 00041 #include "kmo_debug.h" 00042 00043 00044 /*----------------------------------------------------------------------------- 00045 * Functions prototypes 00046 *----------------------------------------------------------------------------*/ 00047 00048 static int kmo_extract_spec_create(cpl_plugin *); 00049 static int kmo_extract_spec_exec(cpl_plugin *); 00050 static int kmo_extract_spec_destroy(cpl_plugin *); 00051 static int kmo_extract_spec(cpl_parameterlist *, cpl_frameset *); 00052 00053 /*----------------------------------------------------------------------------- 00054 * Static variables 00055 *----------------------------------------------------------------------------*/ 00056 00057 static char kmo_extract_spec_description[] = 00058 "This recipe extracts a spectrum from a datacube. The datacube must be in\n" 00059 "F3I KMOS FITS format (either with or without noise). The output will be a\n" 00060 "similarly formatted F1I KMOS FITS file.\n" 00061 "\n" 00062 "BASIC PARAMETERS:\n" 00063 "-----------------\n" 00064 "--mask_method\n" 00065 "There are several ways to define the region to consider for spectrum calculation:\n" 00066 " * 'integrated'' (default)\n" 00067 " A circular mask with defined centre and radius is created (--centre and\n" 00068 " --radius have to be defined). This mask is applied to all extensions.\n" 00069 "\n" 00070 " * 'mask'\n" 00071 " An arbitrary mask can be provided (for example the mask created by kmo_sky_mask\n" 00072 " can be used). The mask must be in F2I KMOS FITS format, mustn't contain noise\n" 00073 " and must have as many extensions as the input cube. The mask can be binary as\n" 00074 " well as it can contain float values, so a weighted mask is also possible.\n" 00075 " (0: pixels is ignored, 1: pixel is included) The mask must be of the same size\n" 00076 " that the input datacube.\n" 00077 "\n" 00078 " * 'optimal'\n" 00079 " The mask is created automatically by fitting a normalised profile (using\n" 00080 " kmo_fit_profile) to the image of the datacube (using kmo_make_image the data-\n" 00081 " cube is summed up in spectral direction according to the specified --cmethod).\n" 00082 " This profile is then used as mask input. When --save_mask is set to true the\n" 00083 " mask is saved on disk. The remaining parameters not described here apply to\n" 00084 " the fitting of the profile.\n" 00085 "\n" 00086 "If the spectra of several objects in a IFU should be extracted, --mask_method=\n" 00087 "'mask' is recommended. With several calls to kmo_extract_spec using different\n" 00088 "masks all spectra can be extracted.\n" 00089 "\n" 00090 "ADVANCED PARAMETERS\n" 00091 "-------------------\n" 00092 "--centre\n" 00093 "--radius\n" 00094 "see --mask_method = 'integrated'\n" 00095 "\n" 00096 "--save_mask\n" 00097 "see --mask_method = 'optimal'\n" 00098 "\n" 00099 "--cmethod\n" 00100 "Applies only if –mask_method = 'integral'\n" 00101 "Following methods of frame combination are available:\n" 00102 " * 'ksigma' (Default)\n" 00103 " An iterative sigma clipping. For each position all pixels in the spectrum\n" 00104 " are examined. If they deviate significantly, they will be rejected according\n" 00105 " to the conditions:\n" 00106 " val > mean + stdev * cpos_rej\n" 00107 " and\n" 00108 " val < mean - stdev * cneg_rej\n" 00109 " where --cpos_rej, --cneg_rej and --citer are the corresponding configuration\n" 00110 " parameters. In the first iteration median and percentile level are used.\n" 00111 "\n" 00112 " * 'median'\n" 00113 " At each pixel position the median is calculated.\n" 00114 "\n" 00115 " * 'average'\n" 00116 " At each pixel position the average is calculated.\n" 00117 "\n" 00118 " * 'sum'\n" 00119 " At each pixel position the sum is calculated.\n" 00120 "\n" 00121 " * 'min_max'\n" 00122 " The specified number of minimum and maximum pixel values will be rejected.\n" 00123 " --cmax and --cmin apply to this method.\n" 00124 "\n" 00125 "--cpos_rej\n" 00126 "--cneg_rej\n" 00127 "--citer\n" 00128 "see --cmethod='ksigma'\n" 00129 "\n" 00130 "--cmax\n" 00131 "--cmin\n" 00132 "see --cmethod='min_max'\n" 00133 00134 "\n" 00135 "-------------------------------------------------------------------------------\n" 00136 " Input files:\n" 00137 "\n" 00138 " DO KMOS \n" 00139 " category Type Explanation Required #Frames\n" 00140 " -------- ----- ----------- -------- -------\n" 00141 " <none or any> F3I The datacubes Y 1 \n" 00142 " <none or any> F2I The mask N 0,1 \n" 00143 "\n" 00144 " Output files:\n" 00145 "\n" 00146 " DO KMOS\n" 00147 " category Type Explanation\n" 00148 " -------- ----- -----------\n" 00149 " EXTRACT_SPEC F1I Extracted spectrum \n" 00150 " EXTRACT_SPEC_MASK F2I (optional, if --save_mask=true and \n" 00151 " --mask_method='optimal': The calculated mask) \n" 00152 "-------------------------------------------------------------------------------\n" 00153 "\n"; 00154 00155 /*----------------------------------------------------------------------------- 00156 * Functions code 00157 *----------------------------------------------------------------------------*/ 00158 00175 int cpl_plugin_get_info(cpl_pluginlist *list) 00176 { 00177 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00178 cpl_plugin *plugin = &recipe->interface; 00179 00180 cpl_plugin_init(plugin, 00181 CPL_PLUGIN_API, 00182 KMOS_BINARY_VERSION, 00183 CPL_PLUGIN_TYPE_RECIPE, 00184 "kmo_extract_spec", 00185 "Extract a spectrum from a cube.", 00186 kmo_extract_spec_description, 00187 "Alex Agudo Berbel", 00188 "usd-help@eso.org", 00189 kmos_get_license(), 00190 kmo_extract_spec_create, 00191 kmo_extract_spec_exec, 00192 kmo_extract_spec_destroy); 00193 00194 cpl_pluginlist_append(list, plugin); 00195 00196 return 0; 00197 } 00198 00206 static int kmo_extract_spec_create(cpl_plugin *plugin) 00207 { 00208 cpl_recipe *recipe; 00209 cpl_parameter *p; 00210 00211 /* Check that the plugin is part of a valid recipe */ 00212 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00213 recipe = (cpl_recipe *)plugin; 00214 else 00215 return -1; 00216 00217 /* Create the parameters list in the cpl_recipe object */ 00218 recipe->parameters = cpl_parameterlist_new(); 00219 00220 /* Fill the parameters list */ 00221 /* --mask_method */ 00222 p = cpl_parameter_new_value("kmos.kmo_extract_spec.mask_method", 00223 CPL_TYPE_STRING, 00224 "Either apply 'mask', 'integrated' or " 00225 "'optimal' masking method.", 00226 "kmos.kmo_extract_spec", 00227 "integrated"); 00228 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "mask_method"); 00229 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00230 cpl_parameterlist_append(recipe->parameters, p); 00231 00232 /* --centre */ 00233 p = cpl_parameter_new_value("kmos.kmo_extract_spec.centre", 00234 CPL_TYPE_STRING, 00235 "The centre of the circular mask (pixel).", 00236 "kmos.kmo_extract_spec", 00237 "7.5,7.5"); 00238 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "centre"); 00239 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00240 cpl_parameterlist_append(recipe->parameters, p); 00241 00242 /* --radius */ 00243 p = cpl_parameter_new_value("kmos.kmo_extract_spec.radius", 00244 CPL_TYPE_DOUBLE, 00245 "The radius of the circular mask (pixel).", 00246 "kmos.kmo_extract_spec", 00247 3.0); 00248 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "radius"); 00249 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00250 cpl_parameterlist_append(recipe->parameters, p); 00251 00252 /* --save_mask */ 00253 p = cpl_parameter_new_value("kmos.kmo_extract_spec.save_mask", 00254 CPL_TYPE_BOOL, 00255 "True if the calculated mask should be saved.", 00256 "kmos.kmo_extract_spec", 00257 FALSE); 00258 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "save_mask"); 00259 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00260 cpl_parameterlist_append(recipe->parameters, p); 00261 00262 return kmo_combine_pars_create(recipe->parameters, 00263 "kmos.kmo_extract_spec", 00264 DEF_REJ_METHOD, 00265 FALSE); 00266 } 00267 00273 static int kmo_extract_spec_exec(cpl_plugin *plugin) 00274 { 00275 cpl_recipe *recipe; 00276 00277 /* Get the recipe out of the plugin */ 00278 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00279 recipe = (cpl_recipe *)plugin; 00280 else return -1; 00281 00282 return kmo_extract_spec(recipe->parameters, recipe->frames); 00283 } 00284 00290 static int kmo_extract_spec_destroy(cpl_plugin *plugin) 00291 { 00292 cpl_recipe *recipe; 00293 00294 /* Get the recipe out of the plugin */ 00295 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00296 recipe = (cpl_recipe *)plugin; 00297 else return -1 ; 00298 00299 cpl_parameterlist_delete(recipe->parameters); 00300 return 0 ; 00301 } 00302 00317 static int kmo_extract_spec(cpl_parameterlist *parlist, cpl_frameset *frameset) 00318 { 00319 cpl_imagelist *data_in = NULL, 00320 *noise_in = NULL; 00321 00322 cpl_image *mask = NULL, 00323 *made_data_img = NULL; 00324 00325 cpl_vector *spec_data_out = NULL, 00326 *spec_noise_out = NULL, 00327 *centre = NULL, 00328 *fit_par = NULL; 00329 00330 int ret_val = 0, 00331 nr_devices = 0, 00332 i = 0, 00333 valid_ifu = FALSE, 00334 citer = 0, 00335 cmin = 0, 00336 cmax = 0, 00337 x = 0, 00338 y = 0, 00339 save_mask = FALSE, 00340 devnr1 = 0, 00341 devnr2 = 0, 00342 index_data = 0, 00343 index_noise = 0; 00344 00345 cpl_propertylist *sub_header_data = NULL, 00346 *sub_header_noise = NULL, 00347 *sub_header_mask = NULL, 00348 *fit_pl = NULL; 00349 00350 const char *mask_method = NULL, 00351 *cmethod = NULL, 00352 *centre_txt = NULL; 00353 00354 double cpos_rej = 0.0, 00355 cneg_rej = 0.0, 00356 radius = 0.0, 00357 r = 0.0, 00358 x_lo = 0.0, 00359 y_lo = 0.0, 00360 x_hi = 0.0, 00361 y_hi = 0.0, 00362 cen_x = 0.0, 00363 cen_y = 0.0; 00364 00365 float *pmask = NULL; 00366 00367 main_fits_desc desc1, 00368 desc2; 00369 00370 cpl_frame *op1_frame = NULL, 00371 *op2_frame = NULL; 00372 00373 char do_mode1[256], 00374 do_mode2[256]; 00375 00376 KMO_TRY 00377 { 00378 kmo_init_fits_desc(&desc1); 00379 kmo_init_fits_desc(&desc2); 00380 00381 /* --- check input --- */ 00382 KMO_TRY_ASSURE((parlist != NULL) && 00383 (frameset != NULL), 00384 CPL_ERROR_NULL_INPUT, 00385 "Not all input data is provided!"); 00386 00387 KMO_TRY_ASSURE((cpl_frameset_get_size(frameset) == 1) || 00388 ((cpl_frameset_get_size(frameset) == 2)), 00389 CPL_ERROR_NULL_INPUT, 00390 "Either one data cube or a datacube and a mask" 00391 "must be provided!"); 00392 00393 if (cpl_frameset_get_size(frameset) == 1) { 00394 strcpy(do_mode1, "0"); 00395 strcpy(do_mode2, ""); 00396 } else { 00397 strcpy(do_mode1, "0"); 00398 strcpy(do_mode2, "1"); 00399 KMO_TRY_EXIT_IF_NULL( 00400 op2_frame = kmo_dfs_get_frame(frameset, do_mode2)); 00401 } 00402 KMO_TRY_EXIT_IF_NULL( 00403 op1_frame = kmo_dfs_get_frame(frameset, do_mode1)); 00404 00405 desc1 = kmo_identify_fits_header( 00406 cpl_frame_get_filename(op1_frame)); 00407 KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to be " 00408 "in KMOS-format!"); 00409 00410 KMO_TRY_ASSURE(desc1.fits_type == f3i_fits, 00411 CPL_ERROR_ILLEGAL_INPUT, 00412 "The input data hasn't the correct data type " 00413 "(KMOSTYPE must be F3I)!"); 00414 00415 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_extract_spec") == 1, 00416 CPL_ERROR_ILLEGAL_INPUT, 00417 "Cannot identify RAW and CALIB frames!"); 00418 00419 cpl_msg_info("", "--- Parameter setup for kmo_extract_spec ---"); 00420 00421 KMO_TRY_EXIT_IF_NULL( 00422 mask_method = kmo_dfs_get_parameter_string(parlist, 00423 "kmos.kmo_extract_spec.mask_method")); 00424 00425 KMO_TRY_EXIT_IF_ERROR( 00426 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_extract_spec.mask_method")); 00427 00428 if (strcmp(mask_method, "integrated") == 0) { 00429 KMO_TRY_EXIT_IF_NULL( 00430 centre_txt = kmo_dfs_get_parameter_string(parlist, 00431 "kmos.kmo_extract_spec.centre")); 00432 KMO_TRY_EXIT_IF_ERROR( 00433 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_extract_spec.centre")); 00434 00435 centre = kmo_identify_ranges(centre_txt); 00436 KMO_TRY_CHECK_ERROR_STATE(); 00437 00438 KMO_TRY_ASSURE(cpl_vector_get_size(centre) == 2, 00439 CPL_ERROR_ILLEGAL_INPUT, 00440 "centre must have exactly 2 values like \"2.0:3.1\"!"); 00441 00442 cen_x = cpl_vector_get(centre, 0); 00443 cen_y = cpl_vector_get(centre, 1); 00444 00445 KMO_TRY_ASSURE((cen_x >= 0.0) && 00446 (cen_y >= 0.0), 00447 CPL_ERROR_ILLEGAL_INPUT, 00448 "centre must be greater than 0.0!"); 00449 00450 radius = kmo_dfs_get_parameter_double(parlist, 00451 "kmos.kmo_extract_spec.radius"); 00452 KMO_TRY_CHECK_ERROR_STATE(); 00453 KMO_TRY_EXIT_IF_ERROR( 00454 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_extract_spec.radius")); 00455 00456 KMO_TRY_ASSURE(radius >= 0.0, 00457 CPL_ERROR_ILLEGAL_INPUT, 00458 "radius must be greater than 0.0!"); 00459 00460 } else if (strcmp(mask_method, "mask") == 0) { 00461 /* load descriptor of second operand */ 00462 desc2 = kmo_identify_fits_header( 00463 cpl_frame_get_filename(op2_frame)); 00464 KMO_TRY_CHECK_ERROR_STATE_MSG("Mask doesn't seem to be " 00465 "in KMOS-format!"); 00466 00467 KMO_TRY_ASSURE(desc2.fits_type == f2i_fits, 00468 CPL_ERROR_ILLEGAL_INPUT, 00469 "Mask hasn't correct data type " 00470 "(KMOSTYPE must be F2I)!"); 00471 00472 KMO_TRY_ASSURE(desc2.ex_noise == FALSE, 00473 CPL_ERROR_ILLEGAL_INPUT, 00474 "Mask must not contain noise extensions!"); 00475 00476 KMO_TRY_ASSURE( 00477 ((desc1.ex_noise == TRUE) && 00478 (desc1.nr_ext / 2 == desc2.nr_ext)) || 00479 ((desc1.ex_noise == FALSE) && 00480 (desc1.nr_ext == desc2.nr_ext)), 00481 CPL_ERROR_ILLEGAL_INPUT, 00482 "Cube and mask haven't same number of extensions!"); 00483 00484 KMO_TRY_ASSURE((desc1.naxis1 == desc2.naxis1) && 00485 (desc1.naxis2 == desc2.naxis2), 00486 CPL_ERROR_ILLEGAL_INPUT, 00487 "Cube and mask haven't same dimensions in x and y!"); 00488 00489 } else if (strcmp(mask_method, "optimal") == 0) { 00490 KMO_TRY_EXIT_IF_ERROR( 00491 kmo_combine_pars_load(parlist, 00492 "kmos.kmo_extract_spec", 00493 &cmethod, 00494 &cpos_rej, 00495 &cneg_rej, 00496 &citer, 00497 &cmin, 00498 &cmax, 00499 FALSE)); 00500 00501 save_mask = kmo_dfs_get_parameter_bool(parlist, 00502 "kmos.kmo_extract_spec.save_mask"); 00503 KMO_TRY_CHECK_ERROR_STATE(); 00504 KMO_TRY_EXIT_IF_ERROR( 00505 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_extract_spec.save_mask")); 00506 00507 } else { 00508 KMO_TRY_ERROR_SET_MSG(CPL_ERROR_ILLEGAL_INPUT, 00509 "Wrong mask method!"); 00510 } 00511 00512 cpl_msg_info(cpl_func, "-------------------------------------------"); 00513 00514 /* --- load, update & save primary header --- */ 00515 KMO_TRY_EXIT_IF_ERROR( 00516 kmo_dfs_save_main_header(frameset, EXTRACT_SPEC, "", op1_frame, 00517 NULL, parlist, cpl_func)); 00518 00519 if (save_mask) { 00520 KMO_TRY_EXIT_IF_ERROR( 00521 kmo_dfs_save_main_header(frameset, EXTRACT_SPEC_MASK, "", op1_frame, 00522 NULL, parlist, cpl_func)); 00523 } 00524 00525 /* --- load data --- */ 00526 if (desc1.ex_noise == TRUE) { 00527 nr_devices = desc1.nr_ext / 2; 00528 } else { 00529 nr_devices = desc1.nr_ext; 00530 } 00531 00532 // create mask for integrated-method just once here 00533 // and not in the for-loop 00534 if (strcmp(mask_method, "integrated") == 0) { 00535 KMO_TRY_EXIT_IF_NULL( 00536 mask = cpl_image_new(desc1.naxis1, desc1.naxis2, 00537 CPL_TYPE_FLOAT)); 00538 00539 KMO_TRY_EXIT_IF_ERROR( 00540 kmo_image_fill(mask,0.0)); 00541 00542 KMO_TRY_EXIT_IF_NULL( 00543 pmask = cpl_image_get_data_float(mask)); 00544 00545 /* draw circle */ 00546 x_lo = floor(cen_x - radius); 00547 if (x_lo < 0) { 00548 x_lo = 0; 00549 } 00550 00551 y_lo = floor(cen_y - radius); 00552 if (y_lo < 0) { 00553 y_lo = 0; 00554 } 00555 00556 x_hi = ceil(cen_x + radius); 00557 if (x_hi > desc1.naxis1) { 00558 x_hi = desc1.naxis1; 00559 } 00560 00561 y_hi = ceil(cen_y + radius); 00562 if (y_hi > desc1.naxis2) { 00563 y_hi = desc1.naxis2; 00564 } 00565 00566 for (x = x_lo; x < x_hi; x++) { 00567 for (y = y_lo; y < y_hi; y++) { 00568 r = sqrt(pow(x - cen_x,2) + pow(y - cen_y,2)); 00569 if (r <= radius) { 00570 pmask[x + y * desc1.naxis1] = 1.0; 00571 } 00572 } 00573 } 00574 } 00575 00576 for (i = 1; i <= nr_devices; i++) { 00577 if (desc1.ex_noise == FALSE) { 00578 devnr1 = desc1.sub_desc[i - 1].device_nr; 00579 } else { 00580 devnr1 = desc1.sub_desc[2 * i - 1].device_nr; 00581 } 00582 // mask doesn't contain any noise extensions 00583 if (strcmp(mask_method, "mask") == 0) { 00584 devnr2 = desc2.sub_desc[i - 1].device_nr; 00585 } 00586 00587 if (desc1.ex_badpix == FALSE) { 00588 index_data = kmo_identify_index_desc(desc1, devnr1, FALSE); 00589 } else { 00590 index_data = kmo_identify_index_desc(desc1, devnr1, 2); 00591 } 00592 KMO_TRY_CHECK_ERROR_STATE(); 00593 00594 if (desc1.ex_noise) { 00595 index_noise = kmo_identify_index_desc(desc1, devnr1, TRUE); 00596 } 00597 KMO_TRY_CHECK_ERROR_STATE(); 00598 00599 KMO_TRY_EXIT_IF_NULL( 00600 sub_header_data = kmo_dfs_load_sub_header(frameset, do_mode1, 00601 devnr1, FALSE)); 00602 00603 // check if IFU is valid 00604 valid_ifu = FALSE; 00605 if (desc1.sub_desc[index_data-1].valid_data == TRUE) { 00606 if ((strcmp(mask_method, "mask") != 0) || 00607 ((strcmp(mask_method, "mask") == 0) && 00608 (desc2.sub_desc[i - 1].valid_data == TRUE)) 00609 ) 00610 { 00611 valid_ifu = TRUE; 00612 } 00613 } 00614 00615 if (desc1.ex_noise) { 00616 KMO_TRY_EXIT_IF_NULL( 00617 sub_header_noise = kmo_dfs_load_sub_header(frameset, 00618 do_mode1, 00619 devnr1, TRUE)); 00620 } 00621 00622 if (valid_ifu) { 00623 // load data 00624 KMO_TRY_EXIT_IF_NULL( 00625 data_in = kmo_dfs_load_cube(frameset, do_mode1, devnr1, FALSE)); 00626 00627 // load noise, if existing 00628 if (desc1.ex_noise && desc1.sub_desc[index_noise-1].valid_data) { 00629 KMO_TRY_EXIT_IF_NULL( 00630 noise_in = kmo_dfs_load_cube(frameset, do_mode1, devnr1, TRUE)); 00631 } 00632 00633 // create or load mask (for integrated-method already 00634 // done outside the for-loop) 00635 if (strcmp(mask_method, "mask") == 0) { 00636 KMO_TRY_EXIT_IF_NULL( 00637 mask = kmo_dfs_load_image(frameset, do_mode2, 00638 devnr2, FALSE, FALSE, NULL)); 00639 } else if (strcmp(mask_method, "optimal") == 0) { 00640 KMO_TRY_EXIT_IF_ERROR( 00641 kmclipm_make_image(data_in, NULL, 00642 &made_data_img, NULL, 00643 NULL, 00644 cmethod, cpos_rej, cneg_rej, citer, 00645 cmax, cmin)); 00646 00647 KMO_TRY_EXIT_IF_NULL( 00648 fit_par = kmo_fit_profile_2D(made_data_img, 00649 NULL, 00650 "gauss", 00651 &mask, 00652 &fit_pl)); 00653 00654 // update subheader with fit parameters 00655 KMO_TRY_EXIT_IF_ERROR( 00656 cpl_propertylist_append(sub_header_data, fit_pl)); 00657 00658 cpl_propertylist_delete(fit_pl); fit_pl = NULL; 00659 00660 // normalise mask 00661 // (subtract first background and then normalise) 00662 cpl_image_subtract_scalar(mask, cpl_vector_get(fit_par, 0)); 00663 cpl_image_divide_scalar(mask, cpl_vector_get(fit_par, 1)); 00664 cpl_vector_delete(fit_par); fit_par = NULL; 00665 cpl_image_delete(made_data_img); made_data_img = NULL; 00666 } 00667 00668 // process & save data 00669 KMO_TRY_EXIT_IF_ERROR( 00670 kmo_priv_extract_spec(data_in, 00671 noise_in, 00672 mask, 00673 &spec_data_out, 00674 &spec_noise_out)); 00675 00676 KMO_TRY_EXIT_IF_NULL( 00677 sub_header_mask = cpl_propertylist_duplicate( 00678 sub_header_data)); 00679 00680 // change WCS here (CRPIX3 goes to CRPIX1 etc...) 00681 KMO_TRY_EXIT_IF_NULL( 00682 sub_header_data = kmo_priv_update_header(sub_header_data)); 00683 00684 kmclipm_vector *ddd = kmclipm_vector_create(spec_data_out); 00685 KMO_TRY_CHECK_ERROR_STATE(); 00686 00687 KMO_TRY_EXIT_IF_ERROR( 00688 kmo_dfs_save_vector(ddd, EXTRACT_SPEC, "", 00689 sub_header_data, 0./0.)); 00690 kmclipm_vector_delete(ddd); ddd = NULL; spec_data_out = NULL; 00691 00692 if (save_mask) { 00693 // delete WCS for 3rd dimension since mask is 2D 00694 KMO_TRY_EXIT_IF_ERROR( 00695 cpl_propertylist_erase(sub_header_mask, CRPIX3)); 00696 KMO_TRY_EXIT_IF_ERROR( 00697 cpl_propertylist_erase(sub_header_mask, CRVAL3)); 00698 KMO_TRY_EXIT_IF_ERROR( 00699 cpl_propertylist_erase(sub_header_mask, CDELT3)); 00700 KMO_TRY_EXIT_IF_ERROR( 00701 cpl_propertylist_erase(sub_header_mask, CTYPE3)); 00702 KMO_TRY_EXIT_IF_ERROR( 00703 cpl_propertylist_erase(sub_header_mask, CD1_3)); 00704 KMO_TRY_EXIT_IF_ERROR( 00705 cpl_propertylist_erase(sub_header_mask, CD2_3)); 00706 KMO_TRY_EXIT_IF_ERROR( 00707 cpl_propertylist_erase(sub_header_mask, CD3_3)); 00708 KMO_TRY_EXIT_IF_ERROR( 00709 cpl_propertylist_erase(sub_header_mask, CD3_1)); 00710 KMO_TRY_EXIT_IF_ERROR( 00711 cpl_propertylist_erase(sub_header_mask, CD3_2)); 00712 00713 KMO_TRY_EXIT_IF_ERROR( 00714 kmo_dfs_save_image(mask, EXTRACT_SPEC_MASK, "", 00715 sub_header_mask, 0.)); 00716 } 00717 cpl_propertylist_delete(sub_header_mask); 00718 sub_header_mask = NULL; 00719 00720 // process & save noise, if existing 00721 if (desc1.ex_noise) { 00722 kmclipm_vector *nnn = NULL; 00723 if (spec_noise_out != NULL) { 00724 nnn = kmclipm_vector_create(spec_noise_out); 00725 } 00726 KMO_TRY_EXIT_IF_NULL( 00727 sub_header_noise = kmo_priv_update_header( 00728 sub_header_noise)); 00729 00730 KMO_TRY_EXIT_IF_ERROR( 00731 kmo_dfs_save_vector(nnn, EXTRACT_SPEC, "", 00732 sub_header_noise, 0./0.)); 00733 kmclipm_vector_delete(nnn); nnn = NULL; spec_noise_out = NULL; 00734 } 00735 00736 // free memory 00737 cpl_imagelist_delete(data_in); data_in = NULL; 00738 cpl_imagelist_delete(noise_in); noise_in = NULL; 00739 KMO_TRY_CHECK_ERROR_STATE(); 00740 00741 if (strcmp(mask_method, "integrated") != 0) { 00742 // for integrated-method the mask will be deleted 00743 // at the very end! 00744 cpl_image_delete(mask); mask = NULL; 00745 } 00746 } else { 00747 // invalid IFU, just save sub_headers 00748 KMO_TRY_EXIT_IF_ERROR( 00749 kmo_dfs_save_sub_header(EXTRACT_SPEC, "", sub_header_data)); 00750 00751 if (desc1.ex_noise) { 00752 KMO_TRY_EXIT_IF_ERROR( 00753 kmo_dfs_save_sub_header(EXTRACT_SPEC, "", sub_header_noise)); 00754 } 00755 } 00756 00757 // free memory 00758 cpl_propertylist_delete(sub_header_data); sub_header_data = NULL; 00759 cpl_propertylist_delete(sub_header_noise); sub_header_noise = NULL; 00760 } 00761 00762 if (strcmp(mask_method, "integrated") == 0) { 00763 cpl_image_delete(mask); mask = NULL; 00764 cpl_vector_delete(centre); centre = NULL; 00765 } 00766 } 00767 KMO_CATCH 00768 { 00769 KMO_CATCH_MSG(); 00770 00771 ret_val = -1; 00772 } 00773 00774 kmo_free_fits_desc(&desc1); 00775 kmo_free_fits_desc(&desc2); 00776 00777 cpl_propertylist_delete(sub_header_data); sub_header_data = NULL; 00778 cpl_propertylist_delete(sub_header_noise); sub_header_noise = NULL; 00779 cpl_propertylist_delete(sub_header_mask); sub_header_mask = NULL; 00780 cpl_imagelist_delete(data_in); data_in = NULL; 00781 cpl_imagelist_delete(noise_in); noise_in = NULL; 00782 cpl_vector_delete(spec_data_out); spec_data_out = NULL; 00783 cpl_vector_delete(spec_noise_out); spec_noise_out = NULL; 00784 cpl_image_delete(mask); mask = NULL; 00785 cpl_vector_delete(centre); centre = NULL; 00786 00787 return ret_val; 00788 } 00789