visir_img_dark.c

00001 /* $Id: visir_img_dark.c,v 1.27 2010/03/09 12:52:18 llundin Exp $
00002  *
00003  * This file is part of the VISIR 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., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: llundin $
00023  * $Date: 2010/03/09 12:52:18 $
00024  * $Revision: 1.27 $
00025  * $Name: HEAD $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                 Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include "visir_recipe.h"
00037 
00038 /*-----------------------------------------------------------------------------
00039                             Defines
00040  -----------------------------------------------------------------------------*/
00041 
00042 #define RECIPE_STRING "visir_img_dark"
00043 
00044 
00045 /*-----------------------------------------------------------------------------
00046                             Private Functions prototypes
00047  -----------------------------------------------------------------------------*/
00048 
00049 static cpl_error_code visir_img_dark_reduce(cpl_propertylist *,
00050                                            const irplib_framelist *,
00051                                            cpl_image **, cpl_mask **,
00052                                            cpl_mask **, cpl_mask **);
00053 
00054 static cpl_error_code visir_img_dark_save(cpl_frameset *,
00055                                           const cpl_parameterlist *, 
00056                                           const cpl_propertylist *,
00057                                           const cpl_image *, const cpl_mask *,
00058                                           const cpl_mask *, const cpl_mask *,
00059                                           int, const irplib_framelist *);
00060 
00061 static char * visir_img_dark_make_tag(const cpl_frame*,
00062                                      const cpl_propertylist *, int);
00063 
00064 VISIR_RECIPE_DEFINE(visir_img_dark,
00065                     VISIR_PARAM_REJBORD |                        
00066                     VISIR_PARAM_HOT_LIM |                        
00067                     VISIR_PARAM_COLD_LIM |                       
00068                     VISIR_PARAM_DEV_LIM |                        
00069                     VISIR_PARAM_NSAMPLES |                       
00070                     VISIR_PARAM_HALFSIZE,
00071                     "Dark recipe",
00072                     "This recipe computes the dark.\n"
00073                     "The files listed in the Set Of Frames (sof-file) must be "
00074                     "tagged either\n"
00075                     "VISIR-dark-image-raw-file.fits " VISIR_IMG_DARK_RAW " or\n"
00076                     "VISIR-dark-spectro-raw-file.fits " VISIR_SPC_DARK_RAW "\n"
00077                     "\n"
00078                     "The corresponding four products will each have a FITS "
00079                     "card\n'HIERARCH ESO PRO CATG' with values (for imaging)\n"
00080                     VISIR_IMG_DARK_AVG_PROCATG   "\n"
00081                     VISIR_IMG_DARK_HOT_PROCATG   "\n"
00082                     VISIR_IMG_DARK_COLD_PROCATG  "\n"
00083                     VISIR_IMG_DARK_DEV_PROCATG   "\n"
00084                     "  or (for spectroscopy)\n"
00085                     VISIR_SPC_DARK_AVG_PROCATG   "\n"
00086                     VISIR_SPC_DARK_HOT_PROCATG   "\n"
00087                     VISIR_SPC_DARK_COLD_PROCATG  "\n"
00088                     VISIR_SPC_DARK_DEV_PROCATG   "\n");
00089 
00090 /*-----------------------------------------------------------------------------
00091                             Static variables
00092  -----------------------------------------------------------------------------*/
00093 
00094 enum _visir_dark_mode_ {
00095     visir_dark_none = 0,
00096     visir_dark_img,
00097     visir_dark_spc
00098 };
00099 
00100 typedef enum _visir_dark_mode_ visir_dark_mode;
00101 
00102 static struct {
00103     /* Inputs */
00104     visir_dark_mode mode;
00105     int         rej_left;
00106     int         rej_right;
00107     int         rej_bottom;
00108     int         rej_top;
00109     double      hot_thresh;
00110     double      cold_thresh;
00111     double      dev_thresh;
00112     int         hsize;
00113     int         nsamples;
00114 } visir_img_dark_config;
00115 
00116 /*----------------------------------------------------------------------------*/
00120 /*----------------------------------------------------------------------------*/
00121 
00122 /*-----------------------------------------------------------------------------
00123                                 Functions code
00124  -----------------------------------------------------------------------------*/
00125 
00126 
00127 /*----------------------------------------------------------------------------*/
00134 /*----------------------------------------------------------------------------*/
00135 static int visir_img_dark(cpl_frameset            * framelist,
00136                           const cpl_parameterlist * parlist)
00137 {
00138     irplib_framelist* allframes = NULL;
00139     irplib_framelist* rawframes = NULL;
00140     const char     ** taglist   = NULL;
00141     const char      * rej_bord;
00142     const char      * orgtag = NULL; /* Avoid (false) uninit warning */
00143     irplib_framelist* f_one = NULL;
00144     cpl_imagelist   * i_one = NULL;
00145     cpl_image       * avg = NULL;
00146     cpl_mask        * hot = NULL;
00147     cpl_mask        * cold = NULL;
00148     cpl_mask        * dev = NULL;
00149     cpl_propertylist * qclist = cpl_propertylist_new();
00150     int               nsets;
00151     int               i;
00152     int               nb_good = 0;
00153 
00154 
00155     /* Retrieve input parameters */
00156     rej_bord = visir_parameterlist_get_string(parlist, RECIPE_STRING,
00157                                               VISIR_PARAM_REJBORD);
00158     skip_if (0);
00159     skip_if (sscanf(rej_bord, "%d %d %d %d",
00160                     &visir_img_dark_config.rej_left,
00161                     &visir_img_dark_config.rej_right,
00162                     &visir_img_dark_config.rej_bottom,
00163                     &visir_img_dark_config.rej_top) != 4);
00164 
00165     visir_img_dark_config.hot_thresh =
00166         visir_parameterlist_get_double(parlist, RECIPE_STRING,
00167                                        VISIR_PARAM_HOT_LIM);
00168     visir_img_dark_config.dev_thresh =
00169         visir_parameterlist_get_double(parlist, RECIPE_STRING,
00170                                        VISIR_PARAM_DEV_LIM);
00171     visir_img_dark_config.cold_thresh =
00172         visir_parameterlist_get_double(parlist, RECIPE_STRING,
00173                                        VISIR_PARAM_COLD_LIM);
00174     visir_img_dark_config.hsize =
00175         visir_parameterlist_get_int(parlist, RECIPE_STRING, VISIR_PARAM_HALFSIZE);
00176     visir_img_dark_config.nsamples =
00177         visir_parameterlist_get_int(parlist, RECIPE_STRING, VISIR_PARAM_NSAMPLES);
00178 
00179     skip_if (0);
00180 
00181     /* Identify the RAW and CALIB frames in the input frameset */
00182     skip_if (visir_dfs_set_groups(framelist));
00183 
00184     allframes = irplib_framelist_cast(framelist);
00185     skip_if(allframes == NULL);
00186 
00187     rawframes = irplib_framelist_extract_regexp(allframes,
00188                                                 "^(" VISIR_IMG_DARK_RAW
00189                                                 "|" VISIR_SPC_DARK_RAW  ")$",
00190                                                 CPL_FALSE);
00191     skip_if(rawframes == NULL);
00192 
00193     /* Verify uniqueness of frame type */
00194     visir_img_dark_config.mode = visir_dark_none;
00195     if (cpl_frameset_find(framelist, VISIR_IMG_DARK_RAW)) {
00196         visir_img_dark_config.mode = visir_dark_img;
00197         orgtag = VISIR_IMG_DARK_RAW;
00198     }
00199     if (cpl_frameset_find(framelist, VISIR_SPC_DARK_RAW)) {
00200         skip_if (visir_img_dark_config.mode);
00201         visir_img_dark_config.mode = visir_dark_spc;
00202         orgtag = VISIR_SPC_DARK_RAW;
00203     }
00204 
00205     bug_if(visir_img_dark_config.mode == visir_dark_none);
00206 
00207     skip_if(irplib_framelist_load_propertylist_all(rawframes, 0, "^(" 
00208                                                    VISIR_PFITS_REGEXP_DARK "|"
00209                                                    VISIR_PFITS_REGEXP_DARK_PAF
00210                                                    ")$", CPL_FALSE));
00211 
00212     skip_if(visir_dfs_check_framelist_tag(rawframes));
00213 
00214     taglist = visir_framelist_set_tag(rawframes, visir_img_dark_make_tag, &nsets);
00215     skip_if(taglist == NULL);
00216 
00217     cpl_msg_info(cpl_func, "Identified %d setting(s) in %d frames",
00218                  nsets, irplib_framelist_get_size(rawframes));
00219 
00220     /* Extract settings and reduce each of them */
00221     for (i=0 ; i < nsets ; i++) {
00222 
00223         /* Reduce data set nb i */
00224         f_one = irplib_framelist_extract(rawframes, taglist[i]);
00225 
00226         /* Reset the tag */
00227         skip_if(irplib_framelist_set_tag_all(f_one, orgtag));
00228 
00229         cpl_msg_info(cpl_func, "Reducing frame set %d of %d (size=%d) with "
00230                      "setting: %s", i+1, nsets,
00231                      irplib_framelist_get_size(f_one), taglist[i]);
00232 
00233         skip_if (f_one == NULL);
00234         
00235         /* At least 2 frames required */
00236         if (irplib_framelist_get_size(f_one) < 2) {
00237             cpl_msg_warning(cpl_func, "Setting %d skipped (Need at least 2 "
00238                             "frames)", i+1);
00239             irplib_framelist_delete(f_one);
00240             f_one = NULL;
00241             continue;
00242         }
00243 
00244         skip_if(visir_img_dark_reduce(qclist, f_one, &avg, &hot, &cold, &dev));
00245 
00246         /* Save the products */
00247         skip_if (visir_img_dark_save(framelist, parlist, qclist, avg, hot,
00248                                      cold, dev, i+1, f_one));
00249 
00250         nb_good++;
00251 
00252         cpl_image_delete(avg);
00253         cpl_mask_delete(hot);
00254         cpl_mask_delete(cold);
00255         cpl_mask_delete(dev);
00256         irplib_framelist_delete(f_one);
00257         cpl_propertylist_empty(qclist);
00258         avg   = NULL;
00259         cold  = NULL;
00260         hot   = NULL;
00261         dev   = NULL;
00262         f_one = NULL;
00263     }
00264 
00265     skip_if (nb_good == 0);
00266 
00267     end_skip;
00268 
00269     cpl_imagelist_delete(i_one);
00270     cpl_free(taglist);
00271     cpl_image_delete(avg);
00272     cpl_mask_delete(hot);
00273     cpl_mask_delete(cold);
00274     cpl_mask_delete(dev);
00275     irplib_framelist_delete(f_one);
00276     irplib_framelist_delete(allframes);
00277     irplib_framelist_delete(rawframes);
00278     cpl_propertylist_delete(qclist);
00279 
00280     return cpl_error_get_code();
00281 }
00282 
00283 /*----------------------------------------------------------------------------*/
00296 /*----------------------------------------------------------------------------*/
00297 static cpl_error_code visir_img_dark_reduce(cpl_propertylist * qclist,
00298                                            const irplib_framelist * f_one,
00299                                            cpl_image ** pavg, cpl_mask ** phot,
00300                                            cpl_mask ** pcold, cpl_mask ** pdev)
00301 {
00302 
00303     cpl_image * dark = NULL;
00304     cpl_image * diff  = NULL;
00305     char      * ron_key = NULL;
00306     double      rms;
00307     double      lower, upper;
00308     double      dark_med;
00309     double      mean;
00310     int         ndevpix;
00311     int         zone[4];
00312     int         coldpix_nb;
00313     int         hotpix_nb;
00314     int nfiles;
00315     int i;
00316 
00317     skip_if (f_one == NULL);
00318 
00319     nfiles = irplib_framelist_get_size(f_one);
00320 
00321     skip_if (nfiles < 2);
00322 
00323     skip_if (irplib_framelist_contains(f_one, "NAXIS1",
00324                                        CPL_TYPE_INT, CPL_TRUE, 0.0));
00325    
00326     skip_if (irplib_framelist_contains(f_one, "NAXIS2",
00327                                        CPL_TYPE_INT, CPL_TRUE, 0.0));
00328  
00329     for (i=0 ; i < nfiles ; i++) {
00330         const cpl_frame        * frame = irplib_framelist_get_const(f_one, i);
00331         const char             * name  = cpl_frame_get_filename(frame);
00332 
00333         cpl_image_delete(diff);
00334         diff = dark;
00335         irplib_check(dark = cpl_image_load(name, CPL_TYPE_FLOAT, 0, 0),
00336                      "Could not load FITS-image from %s", name);
00337 
00338         if (i == 0) {
00339             const int nx = cpl_image_get_size_x(dark);
00340             const int ny = cpl_image_get_size_y(dark);
00341 
00342             zone[0] = visir_img_dark_config.rej_left+1;
00343             zone[1] = nx - visir_img_dark_config.rej_right;
00344             zone[2] = visir_img_dark_config.rej_bottom+1;
00345             zone[3] = ny - visir_img_dark_config.rej_top;
00346 
00347             *pavg = cpl_image_duplicate(dark);
00348             skip_if(*pavg == NULL);
00349         } else {
00350             const cpl_propertylist * plist
00351                 = irplib_framelist_get_propertylist_const(f_one, i-1);
00352             const int    ndit = visir_pfits_get_ndit(plist);
00353             const char   ron_format[] = "ESO QC RON%d";
00354             double       ron;
00355 
00356             skip_if(0);
00357 
00358             irplib_ensure(ndit > 0, CPL_ERROR_ILLEGAL_INPUT,
00359                           VISIR_PFITS_INT_NDIT " must be positive, not %d",
00360                            ndit);
00361 
00362             skip_if(cpl_image_subtract(diff, dark));
00363 
00364             /* Compute the read-out noise */
00365             irplib_check(cpl_flux_get_noise_window(diff, zone,
00366                                                    visir_img_dark_config.hsize,
00367                                                    visir_img_dark_config.nsamples,
00368                                                    &rms, NULL),
00369                          "Cannot compute the RON for difference between images "
00370                           "%d and %d", i, i+1);
00371 
00372             /* Normalise the RON with NDIT */
00373             ron = rms * sqrt(ndit/2.0);
00374 
00375             /* Add QC parameters */
00376             cpl_free(ron_key);
00377             ron_key = cpl_sprintf(ron_format, i);
00378 
00379             bug_if(ron_key == NULL);
00380 
00381             skip_if(cpl_propertylist_append_double(qclist, ron_key, ron));
00382 
00383             /* Sum up the darks */
00384             skip_if(cpl_image_add(*pavg, dark));
00385 
00386         }
00387 
00388     }
00389     cpl_image_delete(dark);
00390     dark = NULL;
00391 
00392     mean = cpl_image_get_mean(diff);
00393 
00394     /* Use the rms of the difference of the last two images to
00395        create the deviant pixel map */
00396     lower = mean - rms * visir_img_dark_config.dev_thresh;
00397     upper = mean + rms * visir_img_dark_config.dev_thresh;
00398     cpl_mask_delete(*pdev);
00399     irplib_check(*pdev = cpl_mask_threshold_image_create(diff, lower, upper),
00400                  "Cannot compute the deviant pixel map");
00401     cpl_image_delete(diff);
00402     diff = NULL;
00403     
00404     skip_if (cpl_mask_not(*pdev));
00405     ndevpix = cpl_mask_count(*pdev);
00406     skip_if (0);
00407     
00408     /* Average it to the master dark */
00409     skip_if(cpl_image_divide_scalar(*pavg, (double)nfiles));
00410 
00411     /* Compute median-rms of the central part of the dark  */
00412     dark_med = cpl_image_get_median_window(*pavg, zone[0], zone[2], zone[1],
00413                                            zone[3]);
00414 
00415     irplib_check (cpl_flux_get_noise_window(*pavg, zone,
00416                                             visir_img_dark_config.hsize,
00417                                             visir_img_dark_config.nsamples,
00418                                             &rms, NULL),
00419                   "Cannot compute the RON of the master dark");
00420 
00421     lower = dark_med - rms * visir_img_dark_config.cold_thresh;
00422     upper = dark_med + rms * visir_img_dark_config.hot_thresh;
00423 
00424     /* Create the cold pixel map */
00425     cpl_mask_delete(*pcold);
00426     irplib_check(*pcold = cpl_mask_threshold_image_create(*pavg, -FLT_MAX,
00427                                                           lower),
00428                  "Cannot compute the cold pixel map");
00429     coldpix_nb = cpl_mask_count(*pcold);
00430     skip_if (0);
00431 
00432     /* Create the hot pixel map */
00433     cpl_mask_delete(*phot);
00434     irplib_check(*phot = cpl_mask_threshold_image_create(*pavg, upper, DBL_MAX),
00435                  "Cannot compute the hot pixel map");
00436     hotpix_nb = cpl_mask_count(*phot);
00437     skip_if (0);
00438 
00439     /* Add QC parameters */
00440 
00441     skip_if(cpl_propertylist_append_double(qclist, "ESO QC DARKMED", dark_med));
00442     skip_if(cpl_propertylist_append_int(qclist, "ESO QC NBCOLPIX", coldpix_nb));
00443     skip_if(cpl_propertylist_append_int(qclist, "ESO QC NBHOTPIX", hotpix_nb));
00444     skip_if(cpl_propertylist_append_int(qclist, "ESO QC NBDEVPIX", ndevpix));
00445 
00446     end_skip;
00447 
00448     cpl_image_delete(dark);
00449     cpl_image_delete(diff);
00450     cpl_free(ron_key);
00451 
00452     return cpl_error_get_code();
00453 }
00454 
00455 /*----------------------------------------------------------------------------*/
00469 /*----------------------------------------------------------------------------*/
00470 static cpl_error_code visir_img_dark_save(cpl_frameset            * set_tot,
00471                                           const cpl_parameterlist * parlist,
00472                                           const cpl_propertylist  * qclist,
00473                                           const cpl_image         * avg,
00474                                           const cpl_mask          * hot,
00475                                           const cpl_mask          * cold,
00476                                           const cpl_mask          * dev,
00477                                           int                       set_nb,
00478                                           const irplib_framelist  * f_one)
00479 {
00480     cpl_frameset           * set   = irplib_frameset_cast(f_one);
00481     const cpl_propertylist * plist
00482         = irplib_framelist_get_propertylist_const(f_one, 0);
00483     cpl_propertylist       * paflist = cpl_propertylist_new();
00484     cpl_image              * image = NULL;
00485     const char               pafcopy[]  = "^(" VISIR_PFITS_REGEXP_DARK_PAF ")$";
00486     char                   * filename = NULL;
00487     const char             * procatg_avg;
00488     const char             * procatg_dev;
00489     const char             * procatg_hot;
00490     const char             * procatg_cold;
00491 
00492 
00493     /* This will catch f_one == NULL or plist == NULL */
00494     skip_if (0);
00495 
00496 
00497     switch (visir_img_dark_config.mode) {
00498     case visir_dark_img:
00499         procatg_avg  = VISIR_IMG_DARK_AVG_PROCATG;
00500         procatg_dev  = VISIR_IMG_DARK_DEV_PROCATG;
00501         procatg_hot  = VISIR_IMG_DARK_HOT_PROCATG;
00502         procatg_cold = VISIR_IMG_DARK_COLD_PROCATG;
00503         break;
00504     case visir_dark_spc:
00505         procatg_avg  = VISIR_SPC_DARK_AVG_PROCATG;
00506         procatg_dev  = VISIR_SPC_DARK_DEV_PROCATG;
00507         procatg_hot  = VISIR_SPC_DARK_HOT_PROCATG;
00508         procatg_cold = VISIR_SPC_DARK_COLD_PROCATG;
00509         break;
00510     default:
00511         bug_if(1);
00512     }
00513 
00514 
00515     /* Write the average image */
00516     filename = cpl_sprintf(RECIPE_STRING "_set%02d_avg" CPL_DFS_FITS,
00517                               set_nb);
00518     skip_if (irplib_dfs_save_image(set_tot, parlist, set, avg, CPL_BPP_IEEE_FLOAT,
00519                                RECIPE_STRING, procatg_avg, qclist, NULL,
00520                                visir_pipe_id, filename));
00521 
00522     /* Write the hotpixel map */
00523     image = cpl_image_new_from_mask(hot);
00524     skip_if(0);
00525 
00526     cpl_free(filename);
00527     filename = cpl_sprintf(RECIPE_STRING "_set%02d_hotpix" CPL_DFS_FITS,
00528                               set_nb);
00529     skip_if (irplib_dfs_save_image(set_tot, parlist, set, image, CPL_BPP_32_SIGNED,
00530                                RECIPE_STRING, procatg_hot, qclist, NULL,
00531                                visir_pipe_id, filename));
00532     cpl_image_delete(image);
00533     image = NULL;
00534 
00535     /* Write the coldpixel map */
00536     image = cpl_image_new_from_mask(cold);
00537     skip_if(0);
00538 
00539     cpl_free(filename);
00540     filename = cpl_sprintf(RECIPE_STRING "_set%02d_coldpix" CPL_DFS_FITS,
00541                               set_nb);
00542     skip_if (irplib_dfs_save_image(set_tot, parlist, set, image, CPL_BPP_32_SIGNED,
00543                                RECIPE_STRING, procatg_cold, qclist, NULL,
00544                                visir_pipe_id, filename));
00545     cpl_image_delete(image);
00546     image = NULL;
00547 
00548     /* Write the deviant pixel map */
00549     image = cpl_image_new_from_mask(dev);
00550     skip_if(0);
00551 
00552     cpl_free(filename);
00553     filename = cpl_sprintf(RECIPE_STRING "_set%02d_devpix" CPL_DFS_FITS,
00554                               set_nb);
00555     skip_if (irplib_dfs_save_image(set_tot, parlist, set, image,
00556                                CPL_BPP_32_SIGNED, RECIPE_STRING,
00557                                procatg_dev, qclist, NULL, visir_pipe_id,
00558                                filename));
00559     cpl_image_delete(image);
00560     image = NULL;
00561 
00562 #ifdef VISIR_SAVE_PAF
00563     /* THE PAF FILE FOR QC PARAMETERS */
00564 
00565     skip_if (cpl_propertylist_copy_property_regexp(paflist, plist, pafcopy, 0));
00566     skip_if (cpl_propertylist_append(paflist, qclist));
00567 
00568     /* PRO.CATG */
00569     bug_if (cpl_propertylist_append_string(paflist, CPL_DFS_PRO_CATG,
00570                                            procatg_avg));
00571 
00572     cpl_free(filename);
00573     filename = cpl_sprintf(RECIPE_STRING "_set%02d" CPL_DFS_PAF, set_nb);
00574     skip_if (cpl_dfs_save_paf("VISIR", RECIPE_STRING, paflist, filename));
00575 #else
00576     bug_if(paflist == NULL);
00577     bug_if(plist == NULL);
00578     bug_if(pafcopy == NULL);
00579 #endif
00580 
00581     end_skip;
00582 
00583     cpl_image_delete(image);
00584     cpl_frameset_delete(set);
00585     cpl_propertylist_delete(paflist);
00586     cpl_free(filename);
00587 
00588     return cpl_error_get_code();
00589 }
00590 
00591 
00592 /*----------------------------------------------------------------------------*/
00602 /*----------------------------------------------------------------------------*/
00603 static char * visir_img_dark_make_tag(const cpl_frame* self,
00604                                       const cpl_propertylist * plist, int dummy)
00605 {
00606 
00607     char       * tag = NULL;
00608     double       etime;
00609 
00610 
00611     skip_if (0);
00612 
00613     skip_if(self  == NULL);
00614     skip_if(plist == NULL);
00615     skip_if(dummy < 0); /* Avoid warning of unused variable */
00616 
00617     /* exposure time */
00618     etime = visir_pfits_get_exptime(plist);
00619     skip_if(0);
00620 
00621     tag = cpl_sprintf("%.5f", etime);
00622     bug_if(tag == NULL);
00623 
00624     end_skip;
00625 
00626     if (cpl_error_get_code()) {
00627         cpl_free(tag);
00628         tag = NULL;
00629     }
00630 
00631     return tag;
00632 
00633 }
00634 

Generated on Thu Mar 24 11:59:39 2011 for VISIR Pipeline Reference Manual by  doxygen 1.5.8