crires_spec_dark.c

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: crire-2_1_1 $
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_frame(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_frame(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 

Generated on 22 Mar 2011 for CRIRES Pipeline Reference Manual by  doxygen 1.6.1