|
KMOS Pipeline Reference Manual
1.2.0
|
00001 /* $Id: kmo_sky_mask.c,v 1.8 2013/05/21 12:13:58 aagudo Exp $ 00002 * 00003 * This file is part of the KMOS Pipeline 00004 * Copyright (C) 2002,2003 European Southern Observatory 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 */ 00020 00021 /* 00022 * $Author: aagudo $ 00023 * $Date: 2013/05/21 12:13:58 $ 00024 * $Revision: 1.8 $ 00025 * $Name: HEAD $ 00026 */ 00027 00028 #ifdef HAVE_CONFIG_H 00029 #include <config.h> 00030 #endif 00031 00032 /*----------------------------------------------------------------------------- 00033 * Includes 00034 *----------------------------------------------------------------------------*/ 00035 00036 #include <string.h> 00037 00038 #include <cpl.h> 00039 00040 #include "kmo_utils.h" 00041 #include "kmo_dfs.h" 00042 #include "kmo_priv_sky_mask.h" 00043 #include "kmo_priv_functions.h" 00044 #include "kmo_error.h" 00045 #include "kmo_constants.h" 00046 #include "kmo_debug.h" 00047 00048 /*----------------------------------------------------------------------------- 00049 * Functions prototypes 00050 *----------------------------------------------------------------------------*/ 00051 00052 static int kmo_sky_mask_create(cpl_plugin *); 00053 static int kmo_sky_mask_exec(cpl_plugin *); 00054 static int kmo_sky_mask_destroy(cpl_plugin *); 00055 static int kmo_sky_mask(cpl_parameterlist *, cpl_frameset *); 00056 00057 /*----------------------------------------------------------------------------- 00058 * Static variables 00059 *----------------------------------------------------------------------------*/ 00060 00061 static char kmo_sky_mask_description[] = 00062 "This recipes calculates masks of the skies surrounding the objects in the diff-\n" 00063 "erent IFUs of a reconstructed F3I frame. In the resulting mask pixels belonging\n" 00064 "to objects have value 1 and sky pixels have value 0.\n" 00065 "The noise and the background level of the input data cube are estimated using\n" 00066 "the mode calculated in kmo_stats. If the results aren't satisfactory, try chan-\n" 00067 "ging --cpos_rej and --cneg_rej. Then pixels are flagged in the data cube which\n" 00068 "have a value less than the mode plus twice the noise (val < mode + 2*sigma).\n" 00069 "For each spatial pixel the fraction of flagged pixels in its spectral channel\n" 00070 "is determined.\n" 00071 "Spatial pixels are selected where the fraction of flagged spectral pixels is\n" 00072 "greater than 0.95 (corresponding to the 2*sigma above).\n" 00073 "The input cube can contain noise extensions, but they will be ignored. The out-\n" 00074 "put doesn’t contain noise extensions.\n" 00075 "\n" 00076 "BASIC PARAMETERS:\n" 00077 "-----------------\n" 00078 "--fraction\n" 00079 "The fraction of pixels that have to be greater than the threshold can be defi-\n" 00080 "ned with this parameter (value must be between 0 and 1).\n" 00081 "\n" 00082 "--range\n" 00083 "If required, a limited wavelength range can be defined (e.g. \"1.8,2.1\").\n" 00084 "\n" 00085 "ADVANCED PARAMETERS\n" 00086 "-------------------\n" 00087 "--cpos_rej\n" 00088 "--cneg_rej\n" 00089 "--citer\n" 00090 "An iterative sigma clipping is applied in order to calculate the mode (using\n" 00091 "kmo_stats). For each position all pixels in the spectrum are examined. If they\n" 00092 "deviate significantly, they will be rejected according to the conditions:\n" 00093 " val > mean + stdev * cpos_rej\n" 00094 " and\n" 00095 " val < mean - stdev * cneg_rej\n" 00096 "In the first iteration median and percentile level are used.\n" 00097 "\n" 00098 "-------------------------------------------------------------------------------\n" 00099 " Input files:\n" 00100 "\n" 00101 " DO KMOS \n" 00102 " category Type Explanation Required #Frames\n" 00103 " -------- ----- ----------- -------- -------\n" 00104 " <none or any> F3I The datacube frame Y 1 \n" 00105 "\n" 00106 " Output files:\n" 00107 "\n" 00108 " DO KMOS\n" 00109 " category Type Explanation\n" 00110 " -------- ----- -----------\n" 00111 " SKY_MASK F2I The mask frame\n" 00112 "-------------------------------------------------------------------------------\n" 00113 "\n"; 00114 00115 /*----------------------------------------------------------------------------- 00116 * Functions code 00117 *----------------------------------------------------------------------------*/ 00118 00135 int cpl_plugin_get_info(cpl_pluginlist *list) 00136 { 00137 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00138 cpl_plugin *plugin = &recipe->interface; 00139 00140 cpl_plugin_init(plugin, 00141 CPL_PLUGIN_API, 00142 KMOS_BINARY_VERSION, 00143 CPL_PLUGIN_TYPE_RECIPE, 00144 "kmo_sky_mask", 00145 "Create a mask of spatial pixels that indicates which " 00146 "pixels can be considered as sky.", 00147 kmo_sky_mask_description, 00148 "Alex Agudo Berbel", 00149 "kmos-spark@mpe.mpg.de", 00150 kmos_get_license(), 00151 kmo_sky_mask_create, 00152 kmo_sky_mask_exec, 00153 kmo_sky_mask_destroy); 00154 00155 cpl_pluginlist_append(list, plugin); 00156 00157 return 0; 00158 } 00159 00167 static int kmo_sky_mask_create(cpl_plugin *plugin) 00168 { 00169 cpl_recipe *recipe; 00170 cpl_parameter *p; 00171 00172 /* Check that the plugin is part of a valid recipe */ 00173 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00174 recipe = (cpl_recipe *)plugin; 00175 else 00176 return -1; 00177 00178 /* Create the parameters list in the cpl_recipe object */ 00179 recipe->parameters = cpl_parameterlist_new(); 00180 00181 /* Fill the parameters list */ 00182 /* --range */ 00183 p = cpl_parameter_new_value("kmos.kmo_sky_mask.range", 00184 CPL_TYPE_STRING, 00185 "Min & max wavelengths to use in sky pixel " 00186 "determination, e.g. [x1_start,x1_end]" 00187 " (microns).", 00188 "kmos.kmo_sky_mask", 00189 ""); 00190 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "range"); 00191 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00192 cpl_parameterlist_append(recipe->parameters, p); 00193 00194 /* --fraction */ 00195 p = cpl_parameter_new_value("kmos.kmo_sky_mask.fraction", 00196 CPL_TYPE_DOUBLE, 00197 "Minimum fraction of spatial pixels to select " 00198 "as sky (value between 0 and 1).", 00199 "kmos.kmo_sky_mask", 00200 0.95); 00201 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fraction"); 00202 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00203 cpl_parameterlist_append(recipe->parameters, p); 00204 00205 return kmo_combine_pars_create(recipe->parameters, 00206 "kmos.kmo_sky_mask", 00207 DEF_REJ_METHOD, 00208 TRUE); 00209 } 00210 00216 static int kmo_sky_mask_exec(cpl_plugin *plugin) 00217 { 00218 cpl_recipe *recipe; 00219 00220 /* Get the recipe out of the plugin */ 00221 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00222 recipe = (cpl_recipe *)plugin; 00223 else return -1; 00224 00225 return kmo_sky_mask(recipe->parameters, recipe->frames); 00226 } 00227 00233 static int kmo_sky_mask_destroy(cpl_plugin *plugin) 00234 { 00235 cpl_recipe *recipe; 00236 00237 /* Get the recipe out of the plugin */ 00238 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00239 recipe = (cpl_recipe *)plugin; 00240 else return -1 ; 00241 00242 cpl_parameterlist_delete(recipe->parameters); 00243 return 0 ; 00244 } 00245 00260 static int kmo_sky_mask(cpl_parameterlist *parlist, cpl_frameset *frameset) 00261 { 00262 cpl_imagelist *data_in = NULL; 00263 00264 cpl_image *data_out = NULL; 00265 00266 cpl_vector *ranges = NULL; 00267 00268 int ret_val = 0, 00269 nr_devices = 0, 00270 i = 0, 00271 valid_ifu = FALSE, 00272 citer = 0, 00273 devnr = 0, 00274 index_data = 0; 00275 00276 double cpos_rej = 0.0, 00277 cneg_rej = 0.0, 00278 fraction = 0.0, 00279 ifu_crpix = 0.0, 00280 ifu_crval = 0.0, 00281 ifu_cdelt = 0.0; 00282 00283 const char *ranges_txt = NULL, 00284 *cmethod = NULL; 00285 00286 cpl_propertylist *sub_header_data = NULL; 00287 00288 main_fits_desc desc; 00289 00290 cpl_frame *frame = NULL; 00291 00292 KMO_TRY 00293 { 00294 kmo_init_fits_desc(&desc); 00295 00296 // --- check input --- 00297 KMO_TRY_ASSURE((parlist != NULL) && 00298 (frameset != NULL), 00299 CPL_ERROR_NULL_INPUT, 00300 "Not all input data is provided!"); 00301 00302 KMO_TRY_ASSURE(cpl_frameset_get_size(frameset) == 1, 00303 CPL_ERROR_NULL_INPUT, 00304 "Exactly one data cube must be provided!"); 00305 00306 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_sky_mask") == 1, 00307 CPL_ERROR_ILLEGAL_INPUT, 00308 "Cannot identify RAW and CALIB frames!"); 00309 00310 KMO_TRY_EXIT_IF_NULL( 00311 frame = kmo_dfs_get_frame(frameset, "0")); 00312 00313 cpl_msg_info("", "--- Parameter setup for kmo_sky_mask ------"); 00314 00315 ranges_txt = kmo_dfs_get_parameter_string(parlist, 00316 "kmos.kmo_sky_mask.range"); 00317 KMO_TRY_CHECK_ERROR_STATE(); 00318 KMO_TRY_EXIT_IF_ERROR( 00319 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_shift.range")); 00320 00321 ranges = kmo_identify_ranges(ranges_txt); 00322 KMO_TRY_CHECK_ERROR_STATE(); 00323 00324 fraction = kmo_dfs_get_parameter_double(parlist, 00325 "kmos.kmo_sky_mask.fraction"); 00326 KMO_TRY_CHECK_ERROR_STATE(); 00327 KMO_TRY_EXIT_IF_ERROR( 00328 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_shift.fraction")); 00329 00330 KMO_TRY_ASSURE((fraction >= 0.0) && 00331 (fraction <= 1.0), 00332 CPL_ERROR_ILLEGAL_INPUT, 00333 "fraction must be between 0.0 and 1.0!!"); 00334 00335 KMO_TRY_EXIT_IF_ERROR( 00336 kmo_combine_pars_load(parlist, 00337 "kmos.kmo_sky_mask", 00338 &cmethod, 00339 &cpos_rej, 00340 &cneg_rej, 00341 &citer, 00342 NULL, 00343 NULL, 00344 FALSE)); 00345 00346 cpl_msg_info("", "-------------------------------------------"); 00347 00348 // load descriptor, header and data of first operand 00349 desc = kmo_identify_fits_header( 00350 cpl_frame_get_filename(frame)); 00351 KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to be " 00352 "in KMOS-format!"); 00353 00354 KMO_TRY_ASSURE(desc.fits_type == f3i_fits, 00355 CPL_ERROR_ILLEGAL_INPUT, 00356 "The input file hasn't correct data type " 00357 "(KMOSTYPE must be F3I)!"); 00358 00359 // --- load, update & save primary header --- 00360 KMO_TRY_EXIT_IF_ERROR( 00361 kmo_dfs_save_main_header(frameset, SKY_MASK, "", frame, 00362 NULL, parlist, cpl_func)); 00363 00364 // --- load data --- 00365 if (desc.ex_noise == TRUE) { 00366 nr_devices = desc.nr_ext / 2; 00367 } else { 00368 nr_devices = desc.nr_ext; 00369 } 00370 00371 for (i = 1; i <= nr_devices; i++) { 00372 if (desc.ex_noise == FALSE) { 00373 devnr = desc.sub_desc[i - 1].device_nr; 00374 } else { 00375 devnr = desc.sub_desc[2 * i - 1].device_nr; 00376 } 00377 00378 if (desc.ex_badpix == FALSE) { 00379 index_data = kmo_identify_index_desc(desc, devnr, FALSE); 00380 } else { 00381 index_data = kmo_identify_index_desc(desc, devnr, 2); 00382 } 00383 KMO_TRY_CHECK_ERROR_STATE(); 00384 00385 KMO_TRY_EXIT_IF_NULL( 00386 sub_header_data = kmo_dfs_load_sub_header(frameset, "0", devnr, 00387 FALSE)); 00388 00389 // check if IFU is valid 00390 valid_ifu = FALSE; 00391 if (desc.sub_desc[index_data-1].valid_data == TRUE) { 00392 valid_ifu = TRUE; 00393 } 00394 00395 if (valid_ifu) { 00396 // load data 00397 KMO_TRY_EXIT_IF_NULL( 00398 data_in = kmo_dfs_load_cube(frameset, "0", devnr, FALSE)); 00399 00400 if (ranges != NULL) { 00401 ifu_crpix = cpl_propertylist_get_double(sub_header_data, 00402 CRPIX3); 00403 KMO_TRY_CHECK_ERROR_STATE_MSG( 00404 "CRPIX3 keyword in FITS-header is missing!"); 00405 00406 ifu_crval = cpl_propertylist_get_double(sub_header_data, 00407 CRVAL3); 00408 KMO_TRY_CHECK_ERROR_STATE_MSG( 00409 "CRVAL3 keyword in FITS-header is missing!"); 00410 00411 ifu_cdelt = cpl_propertylist_get_double(sub_header_data, 00412 CDELT3); 00413 KMO_TRY_CHECK_ERROR_STATE_MSG( 00414 "CDELT3 keyword in FITS-header is missing!"); 00415 } 00416 00417 // calc mode and noise 00418 KMO_TRY_EXIT_IF_NULL( 00419 data_out = kmo_calc_sky_mask(data_in, 00420 ranges, 00421 fraction, 00422 ifu_crpix, 00423 ifu_crval, 00424 ifu_cdelt, 00425 cpos_rej, 00426 cneg_rej, 00427 citer)); 00428 00429 // save data 00430 KMO_TRY_EXIT_IF_ERROR( 00431 kmo_dfs_save_image(data_out, SKY_MASK, "", sub_header_data, 0.)); 00432 00433 // free memory 00434 cpl_imagelist_delete(data_in); data_in = NULL; 00435 cpl_image_delete(data_out); data_out = NULL; 00436 } else { 00437 // invalid IFU, just save sub_headers 00438 KMO_TRY_EXIT_IF_ERROR( 00439 kmo_dfs_save_sub_header(SKY_MASK, "", sub_header_data)); 00440 } 00441 00442 // free memory 00443 cpl_propertylist_delete(sub_header_data); sub_header_data = NULL; 00444 } 00445 } 00446 KMO_CATCH 00447 { 00448 KMO_CATCH_MSG(); 00449 00450 ret_val = -1; 00451 } 00452 00453 kmo_free_fits_desc(&desc); 00454 cpl_propertylist_delete(sub_header_data); sub_header_data = NULL; 00455 cpl_imagelist_delete(data_in); data_in = NULL; 00456 cpl_image_delete(data_out); data_out = NULL; 00457 cpl_vector_delete(ranges); ranges = NULL; 00458 return ret_val; 00459 } 00460
1.7.6.1