naco_img_dark.c

00001 /* $Id: naco_img_dark.c,v 1.75 2011-12-22 11:12:38 llundin Exp $
00002  *
00003  * This file is part of the NACO 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: 2011-12-22 11:12:38 $
00024  * $Revision: 1.75 $
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 "naco_recipe.h"
00037 
00038 /*-----------------------------------------------------------------------------
00039                             Defines
00040  -----------------------------------------------------------------------------*/
00041 
00042 #define RECIPE_STRING "naco_img_dark"
00043 
00044 /*-----------------------------------------------------------------------------
00045                             Private Functions prototypes
00046  -----------------------------------------------------------------------------*/
00047 
00048 static cpl_error_code naco_img_dark_reduce(cpl_propertylist *,
00049                                            const irplib_framelist *,
00050                                            cpl_image **, cpl_mask **,
00051                                            cpl_mask **, cpl_mask **);
00052 
00053 static cpl_error_code naco_img_dark_qc(cpl_propertylist *,
00054                                        cpl_propertylist *,
00055                                        const irplib_framelist *);
00056 
00057 static cpl_error_code naco_img_dark_save(cpl_frameset *,
00058                                          const cpl_parameterlist *,
00059                                          const cpl_propertylist *,
00060                                          const cpl_propertylist *,
00061                                          const cpl_image *, const cpl_mask *,
00062                                          const cpl_mask *, const cpl_mask *,
00063                                          int, const irplib_framelist *);
00064 
00065 static char * naco_img_dark_make_tag(const cpl_frame*,
00066                                      const cpl_propertylist *, int);
00067 
00068 NACO_RECIPE_DEFINE(naco_img_dark, 
00069                    NACO_PARAM_REJBORD |                        
00070                    NACO_PARAM_HOT_LIM |                        
00071                    NACO_PARAM_COLD_LIM |                       
00072                    NACO_PARAM_DEV_LIM |                        
00073                    NACO_PARAM_NSAMPLES |                       
00074                    NACO_PARAM_HALFSIZE,
00075                    "Dark recipe",
00076                    "naco_img_dark -- NACO imaging dark recipe.\n"                       
00077                    "The files listed in the Set Of Frames (sof-file) "
00078                    "must be tagged:\n" 
00079                    "NACO-raw-file.fits " NACO_IMG_DARK_RAW "\n");
00080 
00081 /*-----------------------------------------------------------------------------
00082                             Static variables
00083  -----------------------------------------------------------------------------*/
00084 
00085 static struct {
00086     /* Inputs */
00087     int         rej_left;
00088     int         rej_right;
00089     int         rej_bottom;
00090     int         rej_top;
00091     double      hot_thresh;
00092     double      cold_thresh;
00093     double      dev_thresh;
00094     int         hsize;
00095     int         nsamples;
00096 } naco_img_dark_config;
00097 
00098 /*----------------------------------------------------------------------------*/
00102 /*----------------------------------------------------------------------------*/
00103 
00104 /*-----------------------------------------------------------------------------
00105                                 Functions code
00106  -----------------------------------------------------------------------------*/
00107 
00108 
00109 /*----------------------------------------------------------------------------*/
00116 /*----------------------------------------------------------------------------*/
00117 static int naco_img_dark(cpl_frameset            * framelist,
00118                          const cpl_parameterlist * parlist)
00119 {
00120     irplib_framelist* allframes = NULL;
00121     irplib_framelist* rawframes = NULL;
00122     const char     ** taglist   = NULL;
00123     const char      * rej_bord;
00124     irplib_framelist* f_one = NULL;
00125     cpl_imagelist   * i_one = NULL;
00126     cpl_image       * avg = NULL;
00127     cpl_mask        * hot = NULL;
00128     cpl_mask        * cold = NULL;
00129     cpl_mask        * dev = NULL;
00130     cpl_propertylist * qclist  = cpl_propertylist_new();
00131     cpl_propertylist * paflist = cpl_propertylist_new();
00132     int               nsets;
00133     int               i;
00134     int               nb_good = 0;
00135 
00136 
00137     /* Retrieve input parameters */
00138     rej_bord = naco_parameterlist_get_string(parlist, RECIPE_STRING, NACO_PARAM_REJBORD);
00139     skip_if (0);
00140     skip_if (sscanf(rej_bord, "%d %d %d %d",
00141                     &naco_img_dark_config.rej_left,
00142                     &naco_img_dark_config.rej_right,
00143                     &naco_img_dark_config.rej_bottom,
00144                     &naco_img_dark_config.rej_top) != 4);
00145 
00146     naco_img_dark_config.hot_thresh =
00147         naco_parameterlist_get_double(parlist, RECIPE_STRING, NACO_PARAM_HOT_LIM);
00148     naco_img_dark_config.dev_thresh =
00149         naco_parameterlist_get_double(parlist, RECIPE_STRING, NACO_PARAM_DEV_LIM);
00150     naco_img_dark_config.cold_thresh =
00151         naco_parameterlist_get_double(parlist, RECIPE_STRING, NACO_PARAM_COLD_LIM);
00152     naco_img_dark_config.hsize =
00153         naco_parameterlist_get_int(parlist, RECIPE_STRING, NACO_PARAM_HALFSIZE);
00154     naco_img_dark_config.nsamples =
00155         naco_parameterlist_get_int(parlist, RECIPE_STRING, NACO_PARAM_NSAMPLES);
00156 
00157     skip_if (0);
00158 
00159     /* Identify the RAW and CALIB frames in the input frameset */
00160     skip_if (naco_dfs_set_groups(framelist));
00161 
00162     allframes = irplib_framelist_cast(framelist);
00163     skip_if(allframes == NULL);
00164 
00165     rawframes = irplib_framelist_extract(allframes, NACO_IMG_DARK_RAW);
00166     skip_if(rawframes == NULL);
00167     irplib_framelist_empty(allframes);
00168 
00169     skip_if(irplib_framelist_load_propertylist_all(rawframes, 0, "^(" 
00170                                                    IRPLIB_PFITS_REGEXP_RECAL "|"
00171                                                    NACO_PFITS_REGEXP_DARK "|"
00172                                                    NACO_PFITS_REGEXP_DARK_PAF
00173                                                    ")$", CPL_FALSE));
00174 
00175     taglist = naco_framelist_set_tag(rawframes, naco_img_dark_make_tag, &nsets);
00176     skip_if(taglist == NULL);
00177 
00178     cpl_msg_info(cpl_func, "Identified %d setting(s) in %d frames",
00179                  nsets, irplib_framelist_get_size(rawframes));
00180 
00181     /* Extract settings and reduce each of them */
00182     for (i=0 ; i < nsets ; i++) {
00183 
00184         /* Reduce data set nb i */
00185         f_one = irplib_framelist_extract(rawframes, taglist[i]);
00186 
00187         /* Reset the tag */
00188         skip_if(irplib_framelist_set_tag_all(f_one, NACO_IMG_DARK_RAW));
00189 
00190         cpl_msg_info(cpl_func, "Reducing frame set %d of %d (size=%d) with "
00191                      "setting: %s", i+1, nsets,
00192                      irplib_framelist_get_size(f_one), taglist[i]);
00193 
00194         skip_if (f_one == NULL);
00195         
00196         /* At least 2 frames required */
00197         if (irplib_framelist_get_size(f_one) < 2) {
00198             cpl_msg_warning(cpl_func, "Setting %d skipped (Need at least 2 "
00199                             "frames)", i+1);
00200             irplib_framelist_delete(f_one);
00201             f_one = NULL;
00202             continue;
00203         }
00204 
00205         skip_if(naco_img_dark_reduce(qclist, f_one, &avg, &hot, &cold, &dev));
00206 
00207         skip_if(naco_img_dark_qc(qclist, paflist, f_one));
00208 
00209         /* Save the products */
00210         skip_if (naco_img_dark_save(framelist, parlist, qclist, paflist,
00211                                     avg, hot, cold, dev, i+1, f_one));
00212 
00213         nb_good++;
00214 
00215         cpl_image_delete(avg);
00216         cpl_mask_delete(hot);
00217         cpl_mask_delete(cold);
00218         cpl_mask_delete(dev);
00219         irplib_framelist_delete(f_one);
00220         cpl_propertylist_empty(qclist);
00221         cpl_propertylist_empty(paflist);
00222         avg   = NULL;
00223         cold  = NULL;
00224         hot   = NULL;
00225         dev   = NULL;
00226         f_one = NULL;
00227     }
00228 
00229     skip_if (nb_good == 0);
00230 
00231     end_skip;
00232 
00233     cpl_imagelist_delete(i_one);
00234     cpl_free(taglist);
00235     cpl_image_delete(avg);
00236     cpl_mask_delete(hot);
00237     cpl_mask_delete(cold);
00238     cpl_mask_delete(dev);
00239     irplib_framelist_delete(f_one);
00240     irplib_framelist_delete(allframes);
00241     irplib_framelist_delete(rawframes);
00242     cpl_propertylist_delete(qclist);
00243     cpl_propertylist_delete(paflist);
00244 
00245     return cpl_error_get_code();
00246 }
00247 
00248 /*----------------------------------------------------------------------------*/
00261 /*----------------------------------------------------------------------------*/
00262 static cpl_error_code naco_img_dark_reduce(cpl_propertylist * qclist,
00263                                            const irplib_framelist * f_one,
00264                                            cpl_image ** pavg, cpl_mask ** phot,
00265                                            cpl_mask ** pcold, cpl_mask ** pdev)
00266 {
00267 
00268     cpl_image * dark = NULL;
00269     cpl_image * diff  = NULL;
00270     char      * ron_key = NULL;
00271     double      rms;
00272     double      lower, upper;
00273     double      dark_med;
00274     double      mean;
00275     int         ndevpix;
00276     cpl_size    zone[4];
00277     int         coldpix_nb;
00278     int         hotpix_nb;
00279     int nfiles;
00280     int i;
00281 
00282     skip_if (f_one == NULL);
00283 
00284     nfiles = irplib_framelist_get_size(f_one);
00285 
00286     skip_if (nfiles < 2);
00287 
00288     skip_if (irplib_framelist_contains(f_one, "NAXIS1",
00289                                        CPL_TYPE_INT, CPL_TRUE, 0.0));
00290    
00291     skip_if (irplib_framelist_contains(f_one, "NAXIS2",
00292                                        CPL_TYPE_INT, CPL_TRUE, 0.0));
00293  
00294     for (i=0 ; i < nfiles ; i++) {
00295         const cpl_frame        * frame = irplib_framelist_get_const(f_one, i);
00296         const char             * name  = cpl_frame_get_filename(frame);
00297 
00298         cpl_image_delete(diff);
00299         diff = dark;
00300         irplib_check(dark = cpl_image_load(name, CPL_TYPE_FLOAT, 0, 0),
00301                      "Could not load FITS-image from %s", name);
00302 
00303         if (i == 0) {
00304             const int nx = cpl_image_get_size_x(dark);
00305             const int ny = cpl_image_get_size_y(dark);
00306 
00307             zone[0] = naco_img_dark_config.rej_left+1;
00308             zone[1] = nx - naco_img_dark_config.rej_right;
00309             zone[2] = naco_img_dark_config.rej_bottom+1;
00310             zone[3] = ny - naco_img_dark_config.rej_top;
00311 
00312             *pavg = cpl_image_duplicate(dark);
00313             skip_if(*pavg == NULL);
00314         } else {
00315             const cpl_propertylist * plist
00316                 = irplib_framelist_get_propertylist_const(f_one, i-1);
00317             const int    ndit = naco_pfits_get_ndit(plist);
00318             const char   ron_format[] = "ESO QC RON%d";
00319             double       ron;
00320 
00321             skip_if(0);
00322 
00323             irplib_ensure(ndit > 0, CPL_ERROR_ILLEGAL_INPUT,
00324                           NACO_PFITS_INT_NDIT " must be positive, not %d",
00325                            ndit);
00326 
00327             skip_if(cpl_image_subtract(diff, dark));
00328 
00329             /* Compute the read-out noise */
00330             irplib_check(cpl_flux_get_noise_window(diff, zone,
00331                                                    naco_img_dark_config.hsize,
00332                                                    naco_img_dark_config.nsamples,
00333                                                    &rms, NULL),
00334                          "Cannot compute the RON for difference between images "
00335                           "%d and %d", i, i+1);
00336 
00337             /* Normalise the RON with NDIT */
00338             ron = rms * sqrt(ndit/2.0);
00339 
00340             /* Add QC parameters */
00341             cpl_free(ron_key);
00342             ron_key = cpl_sprintf(ron_format, i);
00343 
00344             bug_if(ron_key == NULL);
00345 
00346             skip_if(cpl_propertylist_append_double(qclist, ron_key, ron));
00347 
00348             /* Sum up the darks */
00349             skip_if(cpl_image_add(*pavg, dark));
00350 
00351         }
00352 
00353     }
00354     cpl_image_delete(dark);
00355     dark = NULL;
00356 
00357     mean = cpl_image_get_mean(diff);
00358 
00359     /* Use the rms of the difference of the last two images to
00360        create the deviant pixel map */
00361     lower = mean - rms * naco_img_dark_config.dev_thresh;
00362     upper = mean + rms * naco_img_dark_config.dev_thresh;
00363     cpl_mask_delete(*pdev);
00364     irplib_check(*pdev = cpl_mask_threshold_image_create(diff, lower, upper),
00365                  "Cannot compute the deviant pixel map");
00366     cpl_image_delete(diff);
00367     diff = NULL;
00368     
00369     skip_if (cpl_mask_not(*pdev));
00370     ndevpix = cpl_mask_count(*pdev);
00371     skip_if (0);
00372     
00373     /* Average it to the master dark */
00374     skip_if(cpl_image_divide_scalar(*pavg, (double)nfiles));
00375 
00376     /* Compute median-rms of the central part of the dark  */
00377     dark_med = cpl_image_get_median_window(*pavg, zone[0], zone[2], zone[1],
00378                                            zone[3]);
00379 
00380     irplib_check (cpl_flux_get_noise_window(*pavg, zone,
00381                                             naco_img_dark_config.hsize,
00382                                             naco_img_dark_config.nsamples,
00383                                             &rms, NULL),
00384                   "Cannot compute the RON of the master dark");
00385 
00386     lower = dark_med - rms * naco_img_dark_config.cold_thresh;
00387     upper = dark_med + rms * naco_img_dark_config.hot_thresh;
00388 
00389     /* Create the cold pixel map */
00390     cpl_mask_delete(*pcold);
00391     irplib_check(*pcold = cpl_mask_threshold_image_create(*pavg, -FLT_MAX,
00392                                                           lower),
00393                  "Cannot compute the cold pixel map");
00394     coldpix_nb = cpl_mask_count(*pcold);
00395     skip_if (0);
00396 
00397     /* Create the hot pixel map */
00398     cpl_mask_delete(*phot);
00399     irplib_check(*phot = cpl_mask_threshold_image_create(*pavg, upper, DBL_MAX),
00400                  "Cannot compute the hot pixel map");
00401     hotpix_nb = cpl_mask_count(*phot);
00402     skip_if (0);
00403 
00404     /* Add QC parameters */
00405 
00406     skip_if(cpl_propertylist_append_double(qclist, "ESO QC DARKMED", dark_med));
00407     skip_if(cpl_propertylist_append_int(qclist, "ESO QC NBCOLPIX", coldpix_nb));
00408     skip_if(cpl_propertylist_append_int(qclist, "ESO QC NBHOTPIX", hotpix_nb));
00409     skip_if(cpl_propertylist_append_int(qclist, "ESO QC NBDEVPIX", ndevpix));
00410 
00411     end_skip;
00412 
00413     cpl_image_delete(dark);
00414     cpl_image_delete(diff);
00415     cpl_free(ron_key);
00416 
00417     return cpl_error_get_code();
00418 }
00419 
00420 
00421 /*----------------------------------------------------------------------------*/
00429 /*----------------------------------------------------------------------------*/
00430 static cpl_error_code naco_img_dark_qc(cpl_propertylist       * qclist,
00431                                        cpl_propertylist       * paflist,
00432                                        const irplib_framelist * rawframes)
00433 {
00434 
00435     const cpl_propertylist * reflist
00436         = irplib_framelist_get_propertylist_const(rawframes, 0);
00437     const char               pafcopy[] = "^(" NACO_PFITS_REGEXP_DARK_PAF ")$";
00438 
00439 
00440     bug_if (0);
00441 
00442     bug_if (cpl_propertylist_copy_property_regexp(paflist, reflist, pafcopy,
00443                                                   0));
00444     bug_if (cpl_propertylist_append(paflist, qclist));
00445 
00446     bug_if (cpl_propertylist_copy_property_regexp(qclist, reflist, "^("
00447                                                   IRPLIB_PFITS_REGEXP_RECAL 
00448                                                   ")$", 0));
00449 
00450     bug_if (irplib_pfits_set_airmass(qclist, rawframes));
00451 
00452     end_skip;
00453 
00454     return cpl_error_get_code();
00455 }
00456 
00457 /*----------------------------------------------------------------------------*/
00472 /*----------------------------------------------------------------------------*/
00473 static cpl_error_code naco_img_dark_save(cpl_frameset            * set_tot,
00474                                          const cpl_parameterlist * parlist,
00475                                          const cpl_propertylist  * qclist,
00476                                          const cpl_propertylist  * paflist,
00477                                          const cpl_image         * avg,
00478                                          const cpl_mask          * hot,
00479                                          const cpl_mask          * cold,
00480                                          const cpl_mask          * dev,
00481                                          int                       set_nb,
00482                                          const irplib_framelist  * f_one)
00483 {
00484     cpl_frameset * set_one = irplib_frameset_cast(f_one);
00485     cpl_image    * image   = NULL;
00486     char         * filename = NULL;
00487 
00488 
00489     bug_if (0);
00490 
00491     /* Write the average image */
00492     filename = cpl_sprintf(RECIPE_STRING "_set%02d_avg" CPL_DFS_FITS,
00493                               set_nb);
00494     skip_if (irplib_dfs_save_image(set_tot, parlist, set_one, avg,
00495                                CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
00496                                NACO_IMG_DARK_AVG, qclist, NULL, naco_pipe_id,
00497                                filename));
00498 
00499     /* Write the hotpixel map */
00500     image = cpl_image_new_from_mask(hot);
00501     bug_if(0);
00502 
00503     cpl_free(filename);
00504     filename = cpl_sprintf(RECIPE_STRING "_set%02d_hotpix" CPL_DFS_FITS,
00505                               set_nb);
00506     skip_if (irplib_dfs_save_image(set_tot, parlist, set_one, image,
00507                                CPL_BPP_8_UNSIGNED, RECIPE_STRING, NACO_IMG_DARK_HOT,
00508                                qclist, NULL, naco_pipe_id, filename));
00509 
00510     /* Write the coldpixel map */
00511     cpl_image_delete(image);
00512     image = cpl_image_new_from_mask(cold);
00513     bug_if(0);
00514 
00515     cpl_free(filename);
00516     filename = cpl_sprintf(RECIPE_STRING "_set%02d_coldpix" CPL_DFS_FITS,
00517                               set_nb);
00518     skip_if (irplib_dfs_save_image(set_tot, parlist, set_one, image,
00519                                CPL_BPP_8_UNSIGNED, RECIPE_STRING,
00520                                NACO_IMG_DARK_COLD, qclist, NULL, naco_pipe_id,
00521                                filename));
00522 
00523     /* Write the deviant pixel map */
00524     cpl_image_delete(image);
00525     image = cpl_image_new_from_mask(dev);
00526     bug_if(0);
00527 
00528     cpl_free(filename);
00529     filename = cpl_sprintf(RECIPE_STRING "_set%02d_devpix" CPL_DFS_FITS,
00530                               set_nb);
00531     skip_if (irplib_dfs_save_image(set_tot, parlist, set_one, image,
00532                                CPL_BPP_8_UNSIGNED, RECIPE_STRING, NACO_IMG_DARK_DEV,
00533                                qclist, NULL, naco_pipe_id, filename));
00534     cpl_image_delete(image);
00535     image = NULL;
00536 
00537 #ifdef NACO_SAVE_PAF
00538     /* THE PAF FILE FOR QC PARAMETERS */
00539 
00540     /* PRO.CATG */
00541     bug_if(cpl_propertylist_append_string(paflist, CPL_DFS_PRO_CATG,
00542                                           NACO_IMG_DARK_AVG));
00543 
00544     cpl_free(filename);
00545     filename = cpl_sprintf(RECIPE_STRING "_set%02d" CPL_DFS_PAF, set_nb);
00546     skip_if (cpl_dfs_save_paf("NACO", RECIPE_STRING, paflist, filename));
00547 #else
00548     bug_if(paflist == NULL);
00549 #endif
00550 
00551     end_skip;
00552 
00553     cpl_image_delete(image);
00554     cpl_frameset_delete(set_one);
00555     cpl_free(filename);
00556 
00557     return cpl_error_get_code();
00558 }
00559 
00560 
00561 /*----------------------------------------------------------------------------*/
00571 /*----------------------------------------------------------------------------*/
00572 static char * naco_img_dark_make_tag(const cpl_frame* self,
00573                                      const cpl_propertylist * plist, int dummy)
00574 {
00575 
00576     char       * tag = NULL;
00577     const char * mode;
00578     const char * name;
00579     double       etime;
00580     int          irom;
00581 
00582 
00583     skip_if (cpl_error_get_code());
00584 
00585     skip_if(self  == NULL);
00586     skip_if(plist == NULL);
00587     skip_if(dummy < 0); /* Avoid warning of unused variable */
00588 
00589     /* exposure time */
00590     etime = naco_pfits_get_exptime(plist);
00591     skip_if(cpl_error_get_code());
00592 
00593     /* readout mode */
00594     irom = naco_pfits_get_rom(plist);
00595     skip_if(cpl_error_get_code());
00596 
00597 
00598     /* detector mode */
00599     mode = naco_pfits_get_mode(plist);
00600     skip_if(cpl_error_get_code());
00601 
00602     /* Compare the camera */
00603     name = naco_pfits_get_opti7_name(plist);
00604     skip_if(cpl_error_get_code());
00605 
00606     tag = cpl_sprintf("%s:%s:%d:%.5f", name, mode, irom,
00607                                         etime);
00608     bug_if(tag == NULL);
00609 
00610     end_skip;
00611 
00612     if (cpl_error_get_code()) {
00613         cpl_free(tag);
00614         tag = NULL;
00615     }
00616 
00617     return tag;
00618 
00619 }
Generated on Mon Feb 17 15:01:44 2014 for NACO Pipeline Reference Manual by  doxygen 1.6.3