sofi_img_detlin.c

00001 /* $Id: sofi_img_detlin.c,v 1.15 2009/10/05 12:38:02 llundin Exp $
00002  *
00003  * This file is part of the SOFI 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: llundin $
00023  * $Date: 2009/10/05 12:38:02 $
00024  * $Revision: 1.15 $
00025  * $Name: sofi-1_5_5 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                 Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include <math.h>
00037 #include <cpl.h>
00038 
00039 #include "irplib_utils.h"
00040 
00041 #include "sofi_utils.h"
00042 #include "sofi_pfits.h"
00043 #include "sofi_dfs.h"
00044 
00045 /*-----------------------------------------------------------------------------
00046                             Functions prototypes
00047  -----------------------------------------------------------------------------*/
00048 
00049 static int sofi_img_detlin_create(cpl_plugin *) ;
00050 static int sofi_img_detlin_exec(cpl_plugin *) ;
00051 static int sofi_img_detlin_destroy(cpl_plugin *) ;
00052 static int sofi_img_detlin(cpl_parameterlist *, cpl_frameset *) ;
00053 
00054 static cpl_imagelist * sofi_img_detlin_load(cpl_frameset *, cpl_frameset *, 
00055         cpl_vector **) ;
00056 static int sofi_img_detlin_save(cpl_imagelist *, cpl_parameterlist *, 
00057         cpl_frameset *) ;
00058 
00059 /*-----------------------------------------------------------------------------
00060                             Static variables
00061  -----------------------------------------------------------------------------*/
00062 
00063 static struct {
00064     /* Inputs */
00065     int     force_flag ;
00066 
00067     /* Outputs */
00068     double  lamp_stability ;
00069 } sofi_img_detlin_config ;
00070 
00071 static char sofi_img_detlin_description[] =
00072 "sofi_img_detlin -- SOFI imaging detector linearity recipe.\n"
00073 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00074 "raw-file.fits "SOFI_IMG_DETLIN_LAMP_RAW" or\n"
00075 "raw-file.fits "SOFI_IMG_DETLIN_DARK_RAW"\n";
00076 
00077 /*-----------------------------------------------------------------------------
00078                                 Functions code
00079  -----------------------------------------------------------------------------*/
00080 
00081 /*----------------------------------------------------------------------------*/
00089 /*----------------------------------------------------------------------------*/
00090 int cpl_plugin_get_info(cpl_pluginlist * list)
00091 {
00092     cpl_recipe  *   recipe = cpl_calloc(1, sizeof(*recipe)) ;
00093     cpl_plugin  *   plugin = &recipe->interface ;
00094 
00095     cpl_plugin_init(plugin,
00096                     CPL_PLUGIN_API,
00097                     SOFI_BINARY_VERSION,
00098                     CPL_PLUGIN_TYPE_RECIPE,
00099                     "sofi_img_detlin",
00100                     "Detector linearity recipe",
00101                     sofi_img_detlin_description,
00102                     "Yves Jung",
00103                     "yjung@eso.org",
00104                     sofi_get_license(),
00105                     sofi_img_detlin_create,
00106                     sofi_img_detlin_exec,
00107                     sofi_img_detlin_destroy) ;
00108 
00109     cpl_pluginlist_append(list, plugin) ;
00110     
00111     return 0;
00112 }
00113 
00114 /*----------------------------------------------------------------------------*/
00123 /*----------------------------------------------------------------------------*/
00124 static int sofi_img_detlin_create(cpl_plugin * plugin)
00125 {
00126     cpl_recipe      * recipe ;
00127     cpl_parameter   * p ;
00128 
00129     /* Get the recipe out of the plugin */
00130     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00131         recipe = (cpl_recipe *)plugin ;
00132     else return -1 ;
00133 
00134     /* Create the parameters list in the cpl_recipe object */
00135     recipe->parameters = cpl_parameterlist_new() ; 
00136 
00137     /* Fill the parameters list */
00138     /* --force */
00139     p = cpl_parameter_new_value("sofi.sofi_img_detlin.force", CPL_TYPE_BOOL,
00140             "flag to force th computation", "sofi.sofi_img_detlin",
00141             FALSE) ;
00142     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "force") ;
00143     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00144     cpl_parameterlist_append(recipe->parameters, p) ;
00145 
00146     /* Return */
00147     return 0;
00148 }
00149 
00150 /*----------------------------------------------------------------------------*/
00156 /*----------------------------------------------------------------------------*/
00157 static int sofi_img_detlin_exec(cpl_plugin * plugin)
00158 {
00159     cpl_recipe  *   recipe ;
00160 
00161     /* Get the recipe out of the plugin */
00162     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00163         recipe = (cpl_recipe *)plugin ;
00164     else return -1 ;
00165 
00166     return sofi_img_detlin(recipe->parameters, recipe->frames) ;
00167 }
00168 
00169 /*----------------------------------------------------------------------------*/
00175 /*----------------------------------------------------------------------------*/
00176 static int sofi_img_detlin_destroy(cpl_plugin * plugin)
00177 {
00178     cpl_recipe  *   recipe ;
00179 
00180     /* Get the recipe out of the plugin */
00181     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00182         recipe = (cpl_recipe *)plugin ;
00183     else return -1 ;
00184 
00185     cpl_parameterlist_delete(recipe->parameters) ;
00186     return 0 ;
00187 }
00188 
00189 /*----------------------------------------------------------------------------*/
00196 /*----------------------------------------------------------------------------*/
00197 static int sofi_img_detlin(
00198         cpl_parameterlist   *   parlist, 
00199         cpl_frameset        *   framelist)
00200 {
00201     cpl_parameter   *   par ;
00202     cpl_frameset    *   darkframes ;
00203     cpl_frameset    *   lampframes ;
00204     cpl_imagelist   *   iset ;
00205     cpl_vector      *   ditval ;
00206     cpl_imagelist   *   fitres ;
00207     cpl_image       *   error_im ;
00208     int                 degree ;
00209 
00210     /* Initialise */
00211     par = NULL ;
00212     degree = 2 ;
00213 
00214     /* Retrieve input parameters */
00215     /* Force flag */
00216     par = cpl_parameterlist_find(parlist, "sofi.sofi_img_detlin.force") ;
00217     sofi_img_detlin_config.force_flag = cpl_parameter_get_bool(par) ;
00218 
00219     /* Identify the RAW and CALIB frames in the input frameset */
00220     if (sofi_dfs_set_groups(framelist)) {
00221         cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames") ;
00222         return -1 ;
00223     }
00224 
00225     /* Retrieve raw frames */
00226     if ((lampframes = sofi_extract_frameset(framelist,
00227                     SOFI_IMG_DETLIN_LAMP_RAW)) == NULL) {
00228         cpl_msg_error(cpl_func, "Cannot find any lamp frame in input");
00229         return -1 ;
00230     }
00231     if ((darkframes = sofi_extract_frameset(framelist,
00232                     SOFI_IMG_DETLIN_DARK_RAW)) == NULL) {
00233         cpl_msg_error(cpl_func, "Cannot find any dark frame in input");
00234         cpl_frameset_delete(lampframes) ;
00235         return -1 ;
00236     }
00237 
00238     /* Load the data and check the DIT consistency */
00239     cpl_msg_info(cpl_func, "Load the data") ;
00240     cpl_msg_indent_more() ;
00241     if ((iset = sofi_img_detlin_load(lampframes, darkframes, &ditval))==NULL) {
00242         cpl_msg_error(cpl_func, "Cannot load the data") ;
00243         cpl_frameset_delete(lampframes) ;
00244         cpl_frameset_delete(darkframes) ;
00245         cpl_msg_indent_less() ;
00246         return -1 ;
00247     }
00248     cpl_frameset_delete(lampframes) ;
00249     cpl_frameset_delete(darkframes) ;
00250     cpl_msg_indent_less() ;
00251 
00252     /* Create the error image */
00253     error_im = cpl_image_duplicate(cpl_imagelist_get(iset, 0)) ;
00254  
00255     /* Compute the linearity coefficients */
00256     cpl_msg_info(cpl_func, "Compute the linearity coefficients") ;
00257     cpl_msg_indent_more() ;
00258     if ((fitres = cpl_fit_imagelist_polynomial(ditval, iset, 0, degree,
00259                     CPL_FALSE, CPL_TYPE_FLOAT, error_im)) == NULL) {
00260         cpl_msg_error(cpl_func, "Cannot compute the linearity coefficients") ;
00261         cpl_imagelist_delete(iset) ;
00262         cpl_vector_delete(ditval) ;
00263         cpl_image_delete(error_im) ;
00264         cpl_msg_indent_less() ;
00265         return -1 ;
00266     }
00267     cpl_msg_indent_less() ;
00268     cpl_vector_delete(ditval) ;
00269     cpl_imagelist_delete(iset) ;
00270 
00271     /* Add the error image to the coefficients */
00272     cpl_imagelist_set(fitres, error_im, degree+1) ;
00273     
00274     /* Save the products */
00275     cpl_msg_info(cpl_func, "Save the products") ;
00276     cpl_msg_indent_more() ;
00277     if (sofi_img_detlin_save(fitres, parlist, framelist)==-1) {
00278         cpl_msg_error(cpl_func, "Cannot save the products") ;
00279         cpl_imagelist_delete(fitres) ;
00280         cpl_msg_indent_less() ;
00281         return -1 ;
00282     }
00283     cpl_msg_indent_less() ;
00284 
00285     /* Free and return */
00286     cpl_imagelist_delete(fitres) ;
00287     return 0 ;
00288 }
00289 
00290 /*----------------------------------------------------------------------------*/
00298 /*----------------------------------------------------------------------------*/
00299 static cpl_imagelist * sofi_img_detlin_load(
00300         cpl_frameset    *   lamps,
00301         cpl_frameset    *   darks,
00302         cpl_vector      **  ditvals)
00303 {
00304     int                     nb_lamps ;
00305     cpl_vector          *   selection ;
00306     cpl_frame           *   frame ;
00307     cpl_propertylist    *   propertylist ;
00308     double                  dit_lamp, dit_dark ;
00309     int                     dit_stab ;
00310     cpl_imagelist       *   lamps_data ;
00311     cpl_imagelist       *   darks_data ;
00312     double              *   stab_levels ;
00313     cpl_vector          *   dit_purged ;
00314     double              *   pditvals ;
00315     double              *   pdit_purged ;
00316     int                     i, j ;
00317 
00318     /* Check that there are as many lamp as darks */
00319     if ((nb_lamps = cpl_frameset_get_size(lamps)) < 3) return NULL ;
00320     if (cpl_frameset_get_size(darks) != nb_lamps) return NULL ;
00321 
00322     /* Check out that they have consistent integration times */
00323     cpl_msg_info(cpl_func, "Checking DIT consistency") ;
00324     selection = cpl_vector_new(nb_lamps) ;
00325     *ditvals = cpl_vector_new(nb_lamps) ;
00326     pditvals = cpl_vector_get_data(*ditvals) ;
00327     dit_stab = 0 ;
00328     for (i=0 ; i<nb_lamps ; i++) {
00329         /* Check if ok */
00330         if (cpl_error_get_code()) {
00331             cpl_vector_delete(selection) ;
00332             cpl_vector_delete(*ditvals) ;
00333             return NULL ;
00334         }
00335         /* DIT from LAMP */
00336         frame = cpl_frameset_get_frame(lamps, i) ;
00337         propertylist=cpl_propertylist_load(cpl_frame_get_filename(frame), 0) ;
00338         dit_lamp = (double)sofi_pfits_get_dit(propertylist) ;
00339         cpl_propertylist_delete(propertylist) ;
00340         if (cpl_error_get_code()) {
00341             cpl_msg_error(cpl_func, "Cannot get DIT") ;
00342             cpl_vector_delete(selection) ;
00343             cpl_vector_delete(*ditvals) ;
00344             return NULL ;
00345         }
00346         /* DIT from DARK */
00347         frame = cpl_frameset_get_frame(darks, i) ;
00348         propertylist=cpl_propertylist_load(cpl_frame_get_filename(frame), 0) ;
00349         dit_dark = (double)sofi_pfits_get_dit(propertylist) ;
00350         cpl_propertylist_delete(propertylist) ;
00351         if (cpl_error_get_code()) {
00352             cpl_msg_error(cpl_func, "Cannot get DIT") ;
00353             cpl_vector_delete(selection) ;
00354             cpl_vector_delete(*ditvals) ;
00355             return NULL ;
00356         }
00357         /* Check consistency */
00358         if (fabs(dit_dark-dit_lamp) > 1e-3) {
00359             cpl_msg_error(cpl_func, "DIT not consistent between LAMP and DARK");
00360             cpl_vector_delete(selection) ;
00361             cpl_vector_delete(*ditvals) ;
00362             return NULL ;
00363         }
00364         pditvals[i] = dit_lamp ;
00365         /* Set selection */
00366         if (i==0) {
00367             cpl_vector_set(selection, i, -1.0) ;
00368             dit_stab ++ ;
00369         } else {
00370             if (fabs(dit_lamp - pditvals[0]) < 1e-5) {
00371                 cpl_vector_set(selection, i, -1.0) ;
00372                 dit_stab ++ ;
00373             } else {
00374                 cpl_vector_set(selection, i, 1.0) ;
00375             }
00376         }
00377     }
00378     
00379     /* Check if there are enough DITs for stability check */
00380     if (dit_stab < 2) {
00381         cpl_msg_error(cpl_func, "Not enough frames for stability check") ;
00382         cpl_vector_delete(selection) ;
00383         cpl_vector_delete(*ditvals) ;
00384         return NULL ;
00385     }
00386 
00387     /* Load the data and compute lamp-dark */
00388     cpl_msg_info(cpl_func, "Compute the differences lamp - dark") ;
00389     lamps_data = cpl_imagelist_load_frameset(lamps, CPL_TYPE_FLOAT, 1, 0) ;
00390     darks_data = cpl_imagelist_load_frameset(darks, CPL_TYPE_FLOAT, 1, 0) ;
00391     if (cpl_imagelist_subtract(lamps_data,darks_data) != CPL_ERROR_NONE) {
00392         cpl_msg_error(cpl_func, "Cannot subtract the 2 image lists") ;
00393         cpl_vector_delete(selection) ;
00394         cpl_vector_delete(*ditvals) ;
00395         if (lamps_data) cpl_imagelist_delete(lamps_data) ;
00396         if (darks_data) cpl_imagelist_delete(darks_data) ;
00397         return NULL ;
00398     }
00399     cpl_imagelist_delete(darks_data) ;
00400     
00401     /* Check the lamp stability */
00402     cpl_msg_info(cpl_func, "Check the lamp stability") ;
00403     stab_levels = cpl_malloc(dit_stab * sizeof(double)) ;
00404     j = 0 ;
00405     for (i=0 ; i<nb_lamps ; i++) {
00406         if (cpl_vector_get(selection, i) < 0) {
00407             stab_levels[j] = 
00408                 cpl_image_get_mean(cpl_imagelist_get(lamps_data, i)) ;
00409             j++ ;
00410         }
00411     }
00412 
00413     /* Compute the lamp stability */
00414     sofi_img_detlin_config.lamp_stability = 0.0 ;
00415     for (i=1 ; i<dit_stab ; i++) {
00416         if ((fabs(stab_levels[i]-stab_levels[0]) / stab_levels[0]) >
00417                 sofi_img_detlin_config.lamp_stability) 
00418             sofi_img_detlin_config.lamp_stability = 
00419                 fabs(stab_levels[i]-stab_levels[0]) / stab_levels[0] ;
00420     }
00421     cpl_free(stab_levels) ;
00422     
00423     /* Check the lamp stability */
00424     if (sofi_img_detlin_config.lamp_stability > 0.01) {
00425         if (sofi_img_detlin_config.force_flag == 1) {
00426             cpl_msg_warning(cpl_func, 
00427                     "level difference #%d too high - proceed anyway",i+1);
00428         } else {
00429             cpl_msg_error(cpl_func, "level difference #%d too high", i+1);
00430             cpl_vector_delete(selection) ;
00431             cpl_vector_delete(*ditvals) ;
00432             cpl_imagelist_delete(lamps_data) ;
00433             return NULL ;
00434         }
00435     }
00436 
00437     /* Purge the stability check data and DITs */
00438     if (cpl_imagelist_erase(lamps_data, selection) != CPL_ERROR_NONE) {
00439         cpl_msg_error(cpl_func, "cannot discard stability frames") ;
00440         cpl_vector_delete(selection) ;
00441         cpl_vector_delete(*ditvals) ;
00442         cpl_imagelist_delete(lamps_data) ;
00443         return NULL ;
00444     }
00445     dit_purged = cpl_vector_new(cpl_imagelist_get_size(lamps_data)) ;
00446     pdit_purged = cpl_vector_get_data(dit_purged) ;
00447     j = 0 ;
00448     for (i=0 ; i<nb_lamps ; i++) {
00449         if (cpl_vector_get(selection, i) > 0) {
00450             pdit_purged[j] = pditvals[i] ;
00451             j++ ;
00452         }
00453     }
00454     cpl_vector_delete(*ditvals) ;
00455     *ditvals = dit_purged ;
00456     
00457     /* Free and eturn  */
00458     cpl_vector_delete(selection) ;
00459     return lamps_data ;
00460 }
00461 
00462 /*----------------------------------------------------------------------------*/
00470 /*----------------------------------------------------------------------------*/
00471 static int sofi_img_detlin_save(
00472         cpl_imagelist       *   fitres,
00473         cpl_parameterlist   *   parlist,
00474         cpl_frameset        *   set)
00475 {
00476     const cpl_frame     *   ref_frame;
00477     cpl_propertylist    *   plist ;
00478     cpl_propertylist    *   qclist ;
00479     cpl_propertylist    *   paflist ;
00480     double                  qc_meda, qc_medb, qc_medc, qc_medq ;
00481 
00482     /* Compute the QC params */
00483     qc_meda = cpl_image_get_median(cpl_imagelist_get(fitres, 0)) ;
00484     qc_medb = cpl_image_get_median(cpl_imagelist_get(fitres, 1)) ;
00485     qc_medc = cpl_image_get_median(cpl_imagelist_get(fitres, 2)) ;
00486     qc_medq = cpl_image_get_median(cpl_imagelist_get(fitres, 3)) ;
00487    
00488     /* Get the QC params in qclist */
00489     qclist = cpl_propertylist_new() ;
00490     cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDA", qc_meda) ;
00491     cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDB", qc_medb) ;
00492     cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDC", qc_medc) ;
00493     cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDQ", qc_medq) ;
00494     cpl_propertylist_append_double(qclist, "ESO QC DETLIN LAMP", 
00495             sofi_img_detlin_config.lamp_stability ) ;
00496 
00497     /* Write the _A FITS FILE */
00498     irplib_dfs_save_image(set,
00499             parlist,
00500             set,
00501             cpl_imagelist_get(fitres, 0),
00502             CPL_BPP_IEEE_FLOAT,
00503             "sofi_img_detlin",
00504             SOFI_IMG_DETLIN_A,
00505             qclist,
00506             NULL,
00507             PACKAGE "/" PACKAGE_VERSION,
00508             "sofi_img_detlin_A.fits") ;
00509 
00510     /* Write the _B FITS FILE */
00511     irplib_dfs_save_image(set,
00512             parlist,
00513             set,
00514             cpl_imagelist_get(fitres, 1),
00515             CPL_BPP_IEEE_FLOAT,
00516             "sofi_img_detlin",
00517             SOFI_IMG_DETLIN_B,
00518             qclist,
00519             NULL,
00520             PACKAGE "/" PACKAGE_VERSION,
00521             "sofi_img_detlin_B.fits") ;
00522 
00523     /* Write the _C FITS FILE */
00524     irplib_dfs_save_image(set,
00525             parlist,
00526             set,
00527             cpl_imagelist_get(fitres, 2),
00528             CPL_BPP_IEEE_FLOAT,
00529             "sofi_img_detlin",
00530             SOFI_IMG_DETLIN_C,
00531             qclist,
00532             NULL,
00533             PACKAGE "/" PACKAGE_VERSION,
00534             "sofi_img_detlin_C.fits") ;
00535 
00536     /* Write the _Q FITS FILE */
00537     irplib_dfs_save_image(set,
00538             parlist,
00539             set,
00540             cpl_imagelist_get(fitres, 3),
00541             CPL_BPP_IEEE_FLOAT,
00542             "sofi_img_detlin",
00543             SOFI_IMG_DETLIN_Q,
00544             qclist,
00545             NULL,
00546             PACKAGE "/" PACKAGE_VERSION,
00547             "sofi_img_detlin_Q.fits") ;
00548 
00549     /* Get the reference frame */
00550     ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW) ;
00551 
00552     /* Get FITS header from reference file */
00553     if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
00554                     0)) == NULL) {
00555         cpl_msg_error(cpl_func, "getting header from reference frame");
00556         cpl_propertylist_delete(qclist) ;
00557         return -1 ;
00558     }
00559 
00560     /* Get the keywords for the paf file */
00561     paflist = cpl_propertylist_new() ;
00562     cpl_propertylist_copy_property_regexp(paflist, plist,
00563         "^(ARCFILE|MJD-OBS|ESO TPL ID|DATE-OBS|ESO DET DIT|"
00564         "ESO DET NDIT|ESO DET NCORRS|ESO DET MODE NAME)$", 0) ;
00565     cpl_propertylist_delete(plist) ;
00566 
00567     /* Copy the QC in paflist */
00568     cpl_propertylist_copy_property_regexp(paflist, qclist, "", 0) ;
00569     cpl_propertylist_delete(qclist) ;
00570 
00571     /* Save the PAF file */
00572     cpl_dfs_save_paf("SOFI",
00573             "sofi_img_detlin",
00574             paflist,
00575             "sofi_img_detlin_QC.paf") ;
00576     cpl_propertylist_delete(paflist) ;
00577     return  0;
00578 }
00579 

Generated on Thu Mar 7 16:21:06 2013 for SOFI Pipeline Reference Manual by  doxygen 1.5.8