isaac_img_detlin.c

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

Generated on Wed Mar 9 15:43:10 2011 for ISAAC Pipeline Reference Manual by  doxygen 1.5.8