CRIRES Pipeline Reference Manual
2.3.2
|
00001 /* $Id: crires_spec_dark.c,v 1.32 2011-02-09 10:45:01 yjung Exp $ 00002 * 00003 * This file is part of the CRIRES 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: yjung $ 00023 * $Date: 2011-02-09 10:45:01 $ 00024 * $Revision: 1.32 $ 00025 * $Name: not supported by cvs2svn $ 00026 */ 00027 00028 #ifdef HAVE_CONFIG_H 00029 #include <config.h> 00030 #endif 00031 00032 /*----------------------------------------------------------------------------- 00033 Includes 00034 -----------------------------------------------------------------------------*/ 00035 00036 #include "crires_recipe.h" 00037 00038 /*----------------------------------------------------------------------------- 00039 Define 00040 -----------------------------------------------------------------------------*/ 00041 00042 #define RECIPE_STRING "crires_spec_dark" 00043 00044 /*----------------------------------------------------------------------------- 00045 Functions prototypes 00046 -----------------------------------------------------------------------------*/ 00047 00048 static double crires_spec_dark_ron(const cpl_image *, const cpl_image *, int) ; 00049 static int crires_spec_dark_save(const cpl_imagelist *, 00050 const cpl_parameterlist *, cpl_frameset *) ; 00051 00052 static char crires_spec_dark_description[] = 00053 "crires_spec_dark -- Dark recipe\n" 00054 "The files listed in the Set Of Frames (sof-file) must be tagged:\n" 00055 "raw-file.fits "CRIRES_SPEC_DARK_RAW".\n" ; 00056 00057 CRIRES_RECIPE_DEFINE(crires_spec_dark, 00058 CRIRES_PARAM_RON_SAMPLES | 00059 CRIRES_PARAM_RON_SZ, 00060 "Dark recipe", 00061 crires_spec_dark_description) ; 00062 00063 /*----------------------------------------------------------------------------- 00064 Static variables 00065 -----------------------------------------------------------------------------*/ 00066 00067 static struct { 00068 /* Inputs */ 00069 int hsize ; 00070 int nsamples ; 00071 /* Outputs */ 00072 crires_illum_period period ; 00073 double dark_med[CRIRES_NB_DETECTORS] ; 00074 double dark_stdev[CRIRES_NB_DETECTORS] ; 00075 double ron1[CRIRES_NB_DETECTORS] ; 00076 double ron2[CRIRES_NB_DETECTORS] ; 00077 } crires_spec_dark_config ; 00078 00079 /*----------------------------------------------------------------------------- 00080 Functions code 00081 -----------------------------------------------------------------------------*/ 00082 00083 /*----------------------------------------------------------------------------*/ 00090 /*----------------------------------------------------------------------------*/ 00091 static int crires_spec_dark( 00092 cpl_frameset * frameset, 00093 const cpl_parameterlist * parlist) 00094 { 00095 cpl_frameset * rawframes ; 00096 cpl_frame * ref_frame ; 00097 cpl_propertylist * plist ; 00098 double dit ; 00099 int ndit, ly, uy, ysize ; 00100 cpl_imagelist * darks ; 00101 cpl_imagelist * darks_chip ; 00102 cpl_image * tmp_dark ; 00103 cpl_vector * medians ; 00104 double med ; 00105 int i, j ; 00106 00107 /* Initialise */ 00108 rawframes = NULL ; 00109 uy = ly = -1 ; 00110 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) { 00111 crires_spec_dark_config.ron1[i] = -1.0 ; 00112 crires_spec_dark_config.ron2[i] = -1.0 ; 00113 crires_spec_dark_config.dark_med[i] = -1.0 ; 00114 crires_spec_dark_config.dark_stdev[i] = -1.0 ; 00115 } 00116 00117 /* Retrieve input parameters */ 00118 crires_spec_dark_config.hsize = crires_parameterlist_get_int(parlist, 00119 RECIPE_STRING, CRIRES_PARAM_RON_SZ) ; 00120 crires_spec_dark_config.nsamples = crires_parameterlist_get_int(parlist, 00121 RECIPE_STRING, CRIRES_PARAM_RON_SAMPLES) ; 00122 00123 /* Identify the RAW and CALIB frames in the input frameset */ 00124 if (crires_dfs_set_groups(frameset, "crires_spec_dark")) { 00125 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ; 00126 return -1 ; 00127 } 00128 00129 /* Retrieve raw frames */ 00130 if ((rawframes = crires_extract_frameset(frameset, 00131 CRIRES_SPEC_DARK_RAW)) == NULL) { 00132 cpl_msg_error(__func__, "No raw frame in input") ; 00133 return -1 ; 00134 } 00135 00136 /* At least 3 frames */ 00137 if (cpl_frameset_get_size(rawframes) < 3) { 00138 cpl_msg_error(__func__, "Not enough input frames"); 00139 cpl_frameset_delete(rawframes) ; 00140 return -1 ; 00141 } 00142 00143 /* Get the detector illumination period */ 00144 crires_spec_dark_config.period = 00145 crires_get_detector_illum_period( 00146 cpl_frame_get_filename(cpl_frameset_get_position(rawframes, 0))) ; 00147 if (crires_spec_dark_config.period == CRIRES_ILLUM_UNKNOWN) { 00148 cpl_msg_error(__func__, 00149 "Cannot determine the detector illumination period") ; 00150 cpl_frameset_delete(rawframes) ; 00151 return -1 ; 00152 } else { 00153 crires_display_detector_illum(crires_spec_dark_config.period) ; 00154 } 00155 00156 /* Get DIT / NDIT from the header */ 00157 ref_frame = cpl_frameset_get_position(rawframes, 0) ; 00158 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame), 00159 0)) == NULL) { 00160 cpl_msg_error(__func__, "Cannot get header from frame"); 00161 cpl_msg_indent_less() ; 00162 cpl_frameset_delete(rawframes) ; 00163 return -1 ; 00164 } 00165 dit = crires_pfits_get_dit(plist) ; 00166 ndit = crires_pfits_get_ndit(plist) ; 00167 cpl_propertylist_delete(plist) ; 00168 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00169 cpl_msg_error(__func__, "Cannot get the DIT/NDIT from the header") ; 00170 cpl_msg_indent_less() ; 00171 cpl_frameset_delete(rawframes) ; 00172 return -1 ; 00173 } 00174 cpl_msg_info(__func__, "DIT value: %g sec.", dit) ; 00175 cpl_msg_info(__func__, "NDIT value: %d", ndit) ; 00176 00177 /* Loop on the chips */ 00178 darks = cpl_imagelist_new() ; 00179 cpl_msg_info(__func__, "Dark computation") ; 00180 cpl_msg_indent_more() ; 00181 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) { 00182 /* Get the illumination zone */ 00183 if (i==0) { 00184 ly=crires_get_detector_ly1(crires_spec_dark_config.period); 00185 uy=crires_get_detector_uy1(crires_spec_dark_config.period); 00186 } else if (i==1) { 00187 ly=crires_get_detector_ly2(crires_spec_dark_config.period); 00188 uy=crires_get_detector_uy2(crires_spec_dark_config.period); 00189 } else if (i==2) { 00190 ly=crires_get_detector_ly3(crires_spec_dark_config.period); 00191 uy=crires_get_detector_uy3(crires_spec_dark_config.period); 00192 } else if (i==3) { 00193 ly=crires_get_detector_ly4(crires_spec_dark_config.period); 00194 uy=crires_get_detector_uy4(crires_spec_dark_config.period); 00195 } 00196 ysize = uy - ly + 1; 00197 if (128-ly <= 0) ly = 1 ; 00198 else ly = 128-ly+1 ; 00199 if (ly+256 >= ysize) uy = ysize ; 00200 else uy = ly+256 ; 00201 00202 /* Load the chips */ 00203 cpl_msg_info(__func__, "Load chip number %d", i+1) ; 00204 if ((darks_chip = crires_load_frameset(rawframes, 00205 crires_spec_dark_config.period, i+1, 00206 CPL_TYPE_FLOAT)) == NULL) { 00207 cpl_msg_error(__func__, "Cannot load chip number %d", i+1) ; 00208 cpl_msg_indent_less() ; 00209 cpl_imagelist_delete(darks) ; 00210 cpl_frameset_delete(rawframes) ; 00211 return -1 ; 00212 } 00213 /* Compute the current dark */ 00214 cpl_msg_info(__func__, "Collapse images for chip number %d", i+1) ; 00215 if ((tmp_dark = cpl_imagelist_collapse_create(darks_chip)) == NULL) { 00216 cpl_msg_error(__func__, "Cannot average for chip number %d", i+1) ; 00217 cpl_msg_indent_less() ; 00218 cpl_imagelist_delete(darks) ; 00219 cpl_frameset_delete(rawframes) ; 00220 cpl_imagelist_delete(darks_chip) ; 00221 return -1 ; 00222 } 00223 /* Put the result in the image list */ 00224 cpl_imagelist_set(darks, tmp_dark, i) ; 00225 00226 /* Compute the dark_med and stdev */ 00227 medians = cpl_vector_new(cpl_imagelist_get_size(darks_chip)); 00228 for (j=0 ; j<cpl_imagelist_get_size(darks_chip) ; j++) { 00229 med = cpl_image_get_median_window(cpl_imagelist_get(darks_chip, j), 00230 256, ly, 768, uy) ; 00231 cpl_vector_set(medians, j, med) ; 00232 } 00233 crires_spec_dark_config.dark_med[i] = cpl_vector_get_mean(medians) ; 00234 crires_spec_dark_config.dark_stdev[i] = cpl_vector_get_stdev(medians) ; 00235 cpl_vector_delete(medians) ; 00236 00237 /* Compute the RONs */ 00238 crires_spec_dark_config.ron1[i] = crires_spec_dark_ron( 00239 cpl_imagelist_get(darks_chip, 0), 00240 cpl_imagelist_get(darks_chip, 1), 00241 ndit) ; 00242 crires_spec_dark_config.ron2[i] = crires_spec_dark_ron( 00243 cpl_imagelist_get(darks_chip, 1), 00244 cpl_imagelist_get(darks_chip, 2), 00245 ndit) ; 00246 cpl_imagelist_delete(darks_chip) ; 00247 } 00248 cpl_frameset_delete(rawframes) ; 00249 cpl_msg_indent_less() ; 00250 00251 /* Divide by DIT */ 00252 cpl_msg_info(__func__, "Division by DIT") ; 00253 cpl_imagelist_divide_scalar(darks, dit) ; 00254 00255 /* Save the product */ 00256 cpl_msg_info(__func__, "Save the product") ; 00257 cpl_msg_indent_more() ; 00258 if (crires_spec_dark_save(darks, parlist, frameset)) { 00259 cpl_msg_error(__func__, "Cannot save the product") ; 00260 cpl_imagelist_delete(darks) ; 00261 cpl_msg_indent_less() ; 00262 return -1 ; 00263 } 00264 cpl_imagelist_delete(darks) ; 00265 cpl_msg_indent_less() ; 00266 00267 /* Return */ 00268 if (cpl_error_get_code()) return -1 ; 00269 else return 0 ; 00270 } 00271 00272 /*----------------------------------------------------------------------------*/ 00280 /*----------------------------------------------------------------------------*/ 00281 static double crires_spec_dark_ron( 00282 const cpl_image * ima1, 00283 const cpl_image * ima2, 00284 int ndit) 00285 { 00286 cpl_image * ima ; 00287 double norm ; 00288 double ron ; 00289 00290 /* Test entries */ 00291 if (ima1 == NULL) return -1.0 ; 00292 if (ima2 == NULL) return -1.0 ; 00293 if (ndit < 1) return -1.0 ; 00294 00295 /* Compute norm */ 00296 norm = 0.5 * ndit ; 00297 norm = sqrt(norm) ; 00298 00299 /* Subtraction */ 00300 if ((ima = cpl_image_subtract_create(ima2, ima1)) == NULL) return -1.0 ; 00301 00302 /* RON measurement */ 00303 cpl_flux_get_noise_window(ima, NULL, crires_spec_dark_config.hsize, 00304 crires_spec_dark_config.nsamples, &ron, NULL) ; 00305 cpl_image_delete(ima) ; 00306 return norm*ron ; 00307 } 00308 00309 /*----------------------------------------------------------------------------*/ 00317 /*----------------------------------------------------------------------------*/ 00318 static int crires_spec_dark_save( 00319 const cpl_imagelist * dark, 00320 const cpl_parameterlist * parlist, 00321 cpl_frameset * set) 00322 { 00323 cpl_propertylist ** qclists ; 00324 const cpl_frame * ref_frame ; 00325 cpl_propertylist * inputlist ; 00326 const char * recipe_name = "crires_spec_dark" ; 00327 int i ; 00328 00329 /* Get the reference frame */ 00330 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW) ; 00331 00332 /* Create the QC lists */ 00333 qclists = cpl_malloc(CRIRES_NB_DETECTORS * sizeof(cpl_propertylist*)) ; 00334 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) { 00335 qclists[i] = cpl_propertylist_new() ; 00336 cpl_propertylist_append_double(qclists[i], "ESO QC RON1", 00337 crires_spec_dark_config.ron1[i]) ; 00338 cpl_propertylist_append_double(qclists[i], "ESO QC RON2", 00339 crires_spec_dark_config.ron2[i]) ; 00340 cpl_propertylist_append_double(qclists[i], "ESO QC DARKMED", 00341 crires_spec_dark_config.dark_med[i]) ; 00342 cpl_propertylist_append_double(qclists[i], "ESO QC DARKSTDEV", 00343 crires_spec_dark_config.dark_stdev[i]) ; 00344 00345 /* Propagate some keywords from input raw frame extensions */ 00346 inputlist = cpl_propertylist_load_regexp( 00347 cpl_frame_get_filename(ref_frame), i+1, 00348 CRIRES_HEADER_EXT_FORWARD, 0) ; 00349 cpl_propertylist_copy_property_regexp(qclists[i], inputlist, 00350 CRIRES_HEADER_EXT_FORWARD, 0) ; 00351 cpl_propertylist_delete(inputlist) ; 00352 } 00353 00354 /* Write the combined image */ 00355 crires_image_save(set, 00356 parlist, 00357 set, 00358 dark, 00359 recipe_name, 00360 CRIRES_CALPRO_DARK, 00361 CRIRES_PROTYPE_DARK, 00362 crires_spec_dark_config.period, 00363 NULL, 00364 (const cpl_propertylist**)qclists, 00365 PACKAGE "/" PACKAGE_VERSION, 00366 "crires_spec_dark.fits") ; 00367 00368 /* Remove the keywords for the FITS extensions */ 00369 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) { 00370 cpl_propertylist_erase_regexp(qclists[i], CRIRES_HEADER_EXT_FORWARD, 0); 00371 } 00372 00373 /* Free and return */ 00374 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) { 00375 cpl_propertylist_delete(qclists[i]) ; 00376 } 00377 cpl_free(qclists) ; 00378 return 0; 00379 } 00380