uves_mbias_impl.c

00001 /*                                                                              *
00002  *   This file is part of the ESO UVES Pipeline                                 *
00003  *   Copyright (C) 2004,2005 European Southern Observatory                      *
00004  *                                                                              *
00005  *   This library is free software; you can redistribute it and/or modify       *
00006  *   it under the terms of the GNU General Public License as published by       *
00007  *   the Free Software Foundation; either version 2 of the License, or          *
00008  *   (at your option) any later version.                                        *
00009  *                                                                              *
00010  *   This program is distributed in the hope that it will be useful,            *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of             *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
00013  *   GNU General Public License for more details.                               *
00014  *                                                                              *
00015  *   You should have received a copy of the GNU General Public License          *
00016  *   along with this program; if not, write to the Free Software                *
00017  *   Foundation, 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA          *
00018  */
00019  
00020 /*
00021  * $Author: amodigli $
00022  * $Date: 2010/09/24 09:49:18 $
00023  * $Revision: 1.60 $
00024  * $Name: uves-4_9_1 $
00025  * $Log: uves_mbias_impl.c,v $
00026  * Revision 1.60  2010/09/24 09:49:18  amodigli
00027  * added info on mean master bias level as asked by Daniel
00028  *
00029  * Revision 1.59  2010/09/24 09:32:03  amodigli
00030  * put back QFITS dependency to fix problem spot by NRI on FIBER mode (with MIDAS calibs) data
00031  *
00032  * Revision 1.57  2010/08/30 14:16:08  amodigli
00033  * fixed problem computing QC.RON.OUTi.RAW (DFS09268)
00034  *
00035  * Revision 1.56  2010/06/11 11:40:46  amodigli
00036  * rename method to stack_method
00037  *
00038  * Revision 1.55  2010/06/02 09:20:44  amodigli
00039  * added correction of bias level before computation of median stack-then put back mean of levels on master bias
00040  *
00041  * Revision 1.54  2010/03/31 10:09:59  amodigli
00042  * added description
00043  *
00044  * Revision 1.53  2010/03/22 15:58:02  amodigli
00045  * added params and possibility to compute master as mean stack
00046  *
00047  * Revision 1.52  2009/10/29 17:16:29  amodigli
00048  * added param to specify if red cdd is new/old in call to uves_get_badpix
00049  *
00050  * Revision 1.51  2008/09/29 06:56:48  amodigli
00051  * add #include <string.h>
00052  *
00053  * Revision 1.50  2008/05/01 09:51:03  amodigli
00054  * fixed compiler warnings
00055  *
00056  * Revision 1.49  2008/04/02 14:02:02  amodigli
00057  * fixed compilation warnings
00058  *
00059  * Revision 1.48  2008/03/28 08:53:43  amodigli
00060  * IRPLIB_CONCAT2X-->UVES_CONCAT2X
00061  *
00062  * Revision 1.47  2008/03/04 15:20:59  amodigli
00063  * fixed redchain problem with clean_traps parameter
00064  *
00065  * Revision 1.46  2008/03/03 16:34:03  amodigli
00066  * added parameter to control trap column correction
00067  *
00068  * Revision 1.45  2008/02/15 12:43:49  amodigli
00069  * allow lower/upper chip for parameter process_chip
00070  *
00071  * Revision 1.44  2007/10/05 16:01:44  amodigli
00072  * using proces_chip parameter to process or not a given RED chip
00073  *
00074  * Revision 1.43  2007/08/21 13:08:26  jmlarsen
00075  * Removed irplib_access module, largely deprecated by CPL-4
00076  *
00077  * Revision 1.42  2007/06/11 13:28:26  jmlarsen
00078  * Changed recipe contact address to cpl at eso.org
00079  *
00080  * Revision 1.41  2007/06/08 13:06:16  jmlarsen
00081  * Send bug reports to Andrea
00082  *
00083  * Revision 1.40  2007/06/06 08:17:33  amodigli
00084  * replace tab with 4 spaces
00085  *
00086  * Revision 1.39  2007/05/22 11:31:35  jmlarsen
00087  * Removed image plotting functionality
00088  *
00089  * Revision 1.38  2007/04/24 12:50:29  jmlarsen
00090  * Replaced cpl_propertylist -> uves_propertylist which is much faster
00091  *
00092  * Revision 1.37  2007/02/27 07:42:21  jmlarsen
00093  * Fixed bug when counting non-rejected pixels
00094  *
00095  * Revision 1.36  2007/02/26 10:15:56  jmlarsen
00096  * Be robust against the unlikely case that there are no good pixels to compute QC stats
00097  *
00098  * Revision 1.35  2007/02/23 13:32:43  jmlarsen
00099  * Change QC computation to exactly match MIDAS' STAT/IMAGE
00100  *
00101  * Revision 1.34  2007/02/09 13:37:43  jmlarsen
00102  * Enable calling from uves_cal_mkmaster
00103  *
00104  * Revision 1.33  2007/02/09 08:57:29  jmlarsen
00105  * Do not use CPL_PIXEL_MAXVAL which works only for integer images
00106  *
00107  * Revision 1.32  2007/02/09 08:14:16  jmlarsen
00108  * Do not use CPL_PIXEL_MAXVAL which works only for integer images
00109  *
00110  * Revision 1.31  2007/01/10 12:37:39  jmlarsen
00111  * Removed obsolete comments
00112  *
00113  * Revision 1.30  2006/12/07 08:23:23  jmlarsen
00114  * uves_load_raw_imagelist: support FLAMES
00115  *
00116  * Revision 1.29  2006/11/15 15:02:14  jmlarsen
00117  * Implemented const safe workarounds for CPL functions
00118  *
00119  * Revision 1.27  2006/11/15 14:04:08  jmlarsen
00120  * Removed non-const version of parameterlist_get_first/last/next which is 
00121  * already in CPL, added const-safe wrapper, unwrapper and deallocator functions
00122  *
00123  * Revision 1.26  2006/11/06 15:19:41  jmlarsen
00124  * Removed unused include directives
00125  *
00126  * Revision 1.25  2006/10/17 12:33:02  jmlarsen
00127  * Added semicolon at UVES_RECIPE_DEFINE invocation
00128  *
00129  * Revision 1.24  2006/10/09 13:01:13  jmlarsen
00130  * Use macro to define recipe interface functions
00131  *
00132  * Revision 1.23  2006/09/19 14:31:10  jmlarsen
00133  * uves_insert_frame(): use bitmap to specify which image statistics keywords must 
00134  * be computed
00135  *
00136  * Revision 1.22  2006/09/19 06:55:52  jmlarsen
00137  * Changed interface of uves_frameset to optionally write image statistics kewwords
00138  *
00139  * Revision 1.21  2006/08/24 11:36:37  jmlarsen
00140  * Write recipe start/stop time to header
00141  *
00142  * Revision 1.20  2006/08/18 13:35:42  jmlarsen
00143  * Fixed/changed QC parameter formats
00144  *
00145  * Revision 1.19  2006/08/17 13:56:53  jmlarsen
00146  * Reduced max line length
00147  *
00148  * Revision 1.18  2006/08/11 14:56:05  amodigli
00149  * removed Doxygen warnings
00150  *
00151  * Revision 1.17  2006/08/10 10:52:11  jmlarsen
00152  * Bugfix in comparison of chip id
00153  *
00154  * Revision 1.16  2006/07/14 12:19:28  jmlarsen
00155  * Support multiple QC tests per product
00156  *
00157  * Revision 1.15  2006/07/03 13:09:24  amodigli
00158  * adjusted description display layout
00159  *
00160  * Revision 1.14  2006/07/03 12:58:34  jmlarsen
00161  * Support flagging instead of interpolating bad pixels
00162  *
00163  * Revision 1.13  2006/06/22 08:58:33  jmlarsen
00164  * Use correct port number for QC
00165  *
00166  * Revision 1.12  2006/06/16 08:25:45  jmlarsen
00167  * Manually propagate ESO.DET. keywords from 1st/2nd input header
00168  *
00169  * Revision 1.11  2006/06/07 09:01:28  amodigli
00170  * added some doc
00171  *
00172  * Revision 1.10  2006/06/06 08:40:50  jmlarsen
00173  * Changed order of messages
00174  *
00175  * Revision 1.9  2006/05/12 15:40:08  jmlarsen
00176  * Fixed mixed code declarations
00177  *
00178  * Revision 1.8  2006/05/09 15:42:00  amodigli
00179  * added QC log
00180  *
00181  * Revision 1.7  2006/05/08 16:47:15  amodigli
00182  * added QC
00183  *
00184  * Revision 1.6  2006/05/08 15:38:46  amodigli
00185  * made changes to have port-id
00186  *
00187  * Revision 1.5  2006/05/05 14:33:22  jmlarsen
00188  * Removed debugging message
00189  *
00190  * Revision 1.4  2006/05/05 13:54:52  jmlarsen
00191  * Removed warnings about unused variables
00192  *
00193  * Revision 1.3  2006/04/20 10:47:39  amodigli
00194  * added qclog
00195  *
00196  * Revision 1.2  2006/04/06 09:48:15  amodigli
00197  * changed uves_frameset_insert interface to have QC log
00198  *
00199  * Revision 1.1  2006/02/03 07:46:30  jmlarsen
00200  * Moved recipe implementations to ./uves directory
00201  *
00202  * Revision 1.42  2006/01/19 08:47:24  jmlarsen
00203  * Inserted missing doxygen end tag
00204  *
00205  * Revision 1.41  2005/12/19 16:17:55  jmlarsen
00206  * Replaced bool -> int
00207  *
00208  */
00209 
00210 #ifdef HAVE_CONFIG_H
00211 #  include <config.h>
00212 #endif
00213 
00214 /*----------------------------------------------------------------------------*/
00221 /*----------------------------------------------------------------------------*/
00222 
00223 /*-----------------------------------------------------------------------------
00224                                 Includes
00225  -----------------------------------------------------------------------------*/
00226 #include <uves_mbias_impl.h>
00227 
00228 #include <uves_utils.h>
00229 #include <uves_corrbadpix.h>
00230 #include <uves_parameters.h>
00231 #include <uves.h>
00232 #include <uves_dfs.h>
00233 #include <uves_pfits.h>
00234 #include <uves_qclog.h>
00235 #include <uves_recipe.h>
00236 #include <uves_utils_wrappers.h>
00237 #include <uves_error.h>
00238 #include <uves_msg.h>
00239 
00240 /* Library */
00241 #include <cpl.h>
00242 #include <float.h>
00243 #include <ctype.h>
00244 #include <string.h>
00245 /*-----------------------------------------------------------------------------
00246                             Functions prototypes
00247  -----------------------------------------------------------------------------*/
00248 
00249 static void uves_mbias_qclog(const cpl_imagelist* raw_imgs,
00250                              uves_propertylist **raw_headers,
00251                  enum uves_chip chip,
00252                  const cpl_image* mbia,
00253                  /* int sx_pix, Size of X bin in pix 
00254                  int sy_pix, Size of Y bin in pix */
00255                             cpl_table* qclog
00256     );
00257 
00258 static void  
00259 uves_mbias_qc_ron_raw(const cpl_image* rbia,
00260                       enum uves_chip chip,
00261                       const int x_cent_s,
00262                       const int x_cent_e,
00263                       const int y_cent_s,
00264                       const int y_cent_e,
00265                       cpl_table* qclog);
00266 
00267 static int
00268 uves_mbias_define_parameters(cpl_parameterlist *parameters);
00269 
00270 /*-----------------------------------------------------------------------------
00271                             Recipe standard code
00272  -----------------------------------------------------------------------------*/
00273 #define cpl_plugin_get_info uves_mbias_get_info
00274 UVES_RECIPE_DEFINE(
00275     UVES_MBIAS_ID, UVES_MBIAS_DOM,
00276     /* Warning: if more parameters are added to this recipe, they 
00277        need to be propagated to uves_cal_mkmaster! */
00278     uves_mbias_define_parameters,
00279     "Jonas M. Larsen", "cpl@eso.org",
00280     "Creates the master bias frame", 
00281     "This recipe creates a master bias frame by computing the median of all input\n"
00282     "bias frames. All input frames must have same tag and size and must be either\n"
00283     "BIAS_BLUE or BIAS_RED.\n"
00284     "On blue input the recipe computes one master bias frame; on red input a \n"
00285     "master bias frame for each chip is produced. The average, standard deviation\n"
00286     "and median of the master bias image(s) are written to the FITS header(s)");
00287 
00288 
00289 /*-----------------------------------------------------------------------------
00290                             Functions code
00291  -----------------------------------------------------------------------------*/
00294 /*----------------------------------------------------------------------------*/
00301 /*----------------------------------------------------------------------------*/
00302 int uves_mbias_define_parameters_body(cpl_parameterlist *parameters,
00303                        const char *recipe_id)
00304 {
00305 
00306     /*****************
00307      *    General    *
00308      *****************/
00309     if (uves_define_global_parameters(parameters) != CPL_ERROR_NONE)
00310         {
00311             return -1;
00312         }
00313 
00314     /**************************************
00315      *  detector's trap correction        *
00316      **************************************/
00317  
00318     if (uves_corr_traps_define_parameters(parameters,recipe_id) 
00319         != CPL_ERROR_NONE)
00320         {
00321             return -1;
00322         }
00323 
00324     /**************************************
00325      *  Master stack generation           *
00326      **************************************/
00327 
00328     if (uves_master_stack_define_parameters(parameters,recipe_id) 
00329         != CPL_ERROR_NONE)
00330         {
00331             return -1;
00332         }
00333 
00334     return (cpl_error_get_code() != CPL_ERROR_NONE);
00335 }
00336 
00337 
00338 
00339 /*----------------------------------------------------------------------------*/
00345 /*----------------------------------------------------------------------------*/
00346 static int
00347 uves_mbias_define_parameters(cpl_parameterlist *parameters)
00348 {
00349     return uves_mbias_define_parameters_body(parameters, make_str(UVES_MBIAS_ID));
00350 }
00351 
00352 
00353 
00354 
00355 
00356 /*----------------------------------------------------------------------------*/
00373 /*----------------------------------------------------------------------------*/
00374 static cpl_image *
00375 uves_mbias_process_chip(const cpl_imagelist *raw_images, 
00376                         uves_propertylist **raw_headers, 
00377                         uves_propertylist *mbias_header,
00378                         int binx, int biny,
00379                         enum uves_chip chip,
00380                         bool CLEAN_TRAPS,
00381                         const char* STACK_METHOD,
00382                         const double STACK_KLOW,
00383                         const double STACK_KHIGH,
00384                         const int STACK_NITER)
00385 {
00386     cpl_image *master_bias        = NULL; /* Result */
00387     double exposure_time = 0;
00388     int badpixels_cleaned;
00389     int i;
00390     int nraw=0;
00391     bool red_ccd_is_new=false;
00392     cpl_vector* bias_levels=NULL;
00393     double bias_mean=0;
00394     cpl_imagelist* tmp_images=NULL;
00395 
00396     uves_msg("Calculating master bias...");
00397 
00398     check_nomsg(red_ccd_is_new=uves_ccd_is_new(raw_headers[0]));
00399     check_nomsg(tmp_images=cpl_imagelist_duplicate(raw_images));
00400     /* Get the median at each pixel */
00401     if(strcmp(STACK_METHOD,"MEDIAN")==0) {
00402        uves_msg("method median");
00403 
00404        check_nomsg(bias_levels=uves_imagelist_get_clean_mean_levels(tmp_images, 
00405                                                                     5.));
00406         bias_mean=cpl_vector_get_mean(bias_levels);
00407         uves_msg("Master bias mean level: %g",bias_mean);
00408        check_nomsg(uves_imagelist_subtract_values(&tmp_images,bias_levels));
00409        
00410        //cpl_imagelist_dump_structure(tmp_images,stdout);
00411        check( master_bias = cpl_imagelist_collapse_median_create(tmp_images), 
00412               "Error computing median");
00413        cpl_image_add_scalar(master_bias,bias_mean);
00414     } else {
00415        uves_msg("method mean");
00416 
00417        check_nomsg(bias_levels=uves_imagelist_get_clean_mean_levels(tmp_images, 
00418                                                                     5.));
00419         bias_mean=cpl_vector_get_mean(bias_levels);
00420         uves_msg("Master bias mean level: %g",bias_mean);
00421        check_nomsg(uves_imagelist_subtract_values(&tmp_images,bias_levels));
00422 
00423        check( master_bias = uves_ksigma_stack(tmp_images,STACK_KLOW,STACK_KHIGH,
00424                                               STACK_NITER), 
00425               "Error computing master bias");
00426        cpl_image_add_scalar(master_bias,bias_mean);
00427     }
00428     uves_free_vector(&bias_levels);
00429     uves_free_imagelist(&tmp_images);
00430 
00431     /* Set mbias exposure time to average of inputs */
00432     exposure_time = 0;
00433     nraw=cpl_imagelist_get_size(raw_images);
00434     for (i = 0; i < nraw; i++)
00435     {
00436         check( exposure_time += uves_pfits_get_exptime(raw_headers[i]), 
00437            "Error reading exposure time");
00438     }
00439     exposure_time /= nraw;
00440     
00441     check( uves_pfits_set_exptime(mbias_header, exposure_time),
00442        "Error setting master bias exposure time");
00443    if(CLEAN_TRAPS) {
00444       check( badpixels_cleaned = 
00445              uves_correct_badpix_all(master_bias, mbias_header, 
00446                                      chip, binx, biny, false,red_ccd_is_new),
00447              "Error replacing bad pixels");
00448 
00449       uves_msg("%d bad pixels replaced", badpixels_cleaned);
00450    }
00451 
00452   cleanup:
00453     if (cpl_error_get_code() != CPL_ERROR_NONE)
00454     {
00455         uves_free_image(&master_bias);
00456     }
00457     uves_free_imagelist(&tmp_images);
00458     
00459     return master_bias;
00460 }
00461 
00462 /*----------------------------------------------------------------------------*/
00469 /*----------------------------------------------------------------------------*/
00470 static void
00471 UVES_CONCAT2X(UVES_MBIAS_ID,exe)(cpl_frameset *frames, 
00472                    const cpl_parameterlist *parameters,
00473                    const char *starttime)
00474 {
00475     uves_mbias_exe_body(frames, parameters, starttime, make_str(UVES_MBIAS_ID));
00476     return;
00477 }
00478 
00479 /*----------------------------------------------------------------------------*/
00490 /*----------------------------------------------------------------------------*/
00491 void
00492 uves_mbias_exe_body(cpl_frameset *frames, 
00493             const cpl_parameterlist *parameters,
00494             const char *starttime,
00495             const char *recipe_id)
00496 {
00497     /* Input */
00498     cpl_imagelist *raw_images[2]        = {NULL, NULL};
00499     uves_propertylist **raw_headers[2]   = {NULL, NULL};    /* Two arrays of pointers */
00500 
00501     cpl_table* qclog[2] = {NULL, NULL};
00502 
00503     /* Output */
00504     uves_propertylist *product_header[2] = {NULL, NULL};
00505     cpl_image *master_bias              = NULL;
00506     cpl_stats *mbias_stats              = NULL;
00507     
00508     /* Local variables */
00509     char *product_filename = NULL;
00510     bool blue;
00511     enum uves_chip chip;
00512     int binx, biny;
00513     const char* PROCESS_CHIP=NULL;
00514     bool CLEAN_TRAPS;
00515     int raw_index = 0;
00516     int i=0;
00517 
00518     const char* STACK_METHOD=NULL;
00519     double STACK_KLOW=0;
00520     double STACK_KHIGH=0;
00521     int STACK_NITER=0;
00522 
00523     /* Load and check raw bias images and headers, identify arm (blue/red) */
00524     /* On success, 'raw_headers' will be arrays with the same length as 'raw_images' */
00525     check( uves_load_raw_imagelist(frames, 
00526                    false,     /* FLAMES format? (no) */
00527                    UVES_BIAS(true), UVES_BIAS(false),
00528                    CPL_TYPE_DOUBLE,
00529                    raw_images, raw_headers, product_header, 
00530                    &blue), "Error loading raw frames");
00531     
00532     /* Get binning from first header (i.e. BLUE or REDL chip, first raw frame) */
00533     check( binx = uves_pfits_get_binx(raw_headers[0][0]), 
00534        "Could not get raw frame x-binning");
00535     check( biny = uves_pfits_get_biny(raw_headers[0][0]), 
00536        "Could not get raw frame y-binning");
00537     check( uves_get_parameter(parameters, NULL, "uves", "process_chip", CPL_TYPE_STRING, &PROCESS_CHIP),
00538                "Could not read parameter");
00539     uves_string_toupper((char*)PROCESS_CHIP);
00540 
00541     check( uves_get_parameter(parameters, NULL, recipe_id, "clean_traps", CPL_TYPE_BOOL, &CLEAN_TRAPS),
00542                "Could not read parameter");
00543 
00544     check( uves_get_parameter(parameters, NULL, recipe_id, "stack_method", CPL_TYPE_STRING, &STACK_METHOD),
00545                "Could not read parameter");
00546     uves_string_toupper((char*)STACK_METHOD);
00547 
00548     check( uves_get_parameter(parameters, NULL, recipe_id, "klow", CPL_TYPE_DOUBLE, &STACK_KLOW),
00549                "Could not read parameter");
00550     check( uves_get_parameter(parameters, NULL, recipe_id, "khigh", CPL_TYPE_DOUBLE, &STACK_KHIGH),
00551                "Could not read parameter");
00552     check( uves_get_parameter(parameters, NULL, recipe_id, "niter", CPL_TYPE_INT, &STACK_NITER),
00553                "Could not read parameter");
00554 
00555     /* Loop over one or two chips */
00556     for (chip = uves_chip_get_first(blue); 
00557      chip != UVES_CHIP_INVALID;
00558      chip = uves_chip_get_next(chip))
00559     {
00560        if(strcmp(PROCESS_CHIP,"REDU") == 0) {
00561     chip = uves_chip_get_next(chip);
00562       }
00563         raw_index = uves_chip_get_index(chip);
00564 
00565         uves_msg("Processing %s chip",
00566              uves_chip_tostring_upper(chip));
00567 
00568         uves_msg_debug("Binning = %dx%d", binx, biny);
00569 
00570         /* Process chip */
00571         uves_free_image(&master_bias);
00572         check( master_bias = uves_mbias_process_chip(raw_images[raw_index], 
00573                                                      raw_headers[raw_index],
00574                                                      product_header[raw_index],
00575                                                      binx, biny,
00576                                                      chip,CLEAN_TRAPS,
00577                                                      STACK_METHOD,
00578                                                      STACK_KLOW,
00579                                                      STACK_KHIGH,
00580                                                      STACK_NITER),
00581            "Error processing chip");
00582         
00583         
00584         cpl_free(product_filename);
00585         check( product_filename = uves_masterbias_filename(chip), 
00586            "Error getting filename");
00587 
00588         /* Finished. Calculate QC parameters and save */
00589         uves_msg("Calculating QC parameters");
00590             uves_qclog_delete(&qclog[0]);
00591             qclog[0] = uves_qclog_init(raw_headers[raw_index][0], chip);
00592             check(uves_mbias_qclog(raw_images[raw_index],
00593                                    raw_headers[raw_index],
00594                                    chip,
00595                                    master_bias,
00596                    /* binx,biny, */
00597                    qclog[0]),"error computing qclog");
00598 
00599         /* Insert into frame set */
00600         uves_msg("Saving product...");
00601         
00602         check( uves_frameset_insert(frames,
00603                     master_bias,
00604                     CPL_FRAME_GROUP_PRODUCT,
00605                     CPL_FRAME_TYPE_IMAGE,
00606                     CPL_FRAME_LEVEL_INTERMEDIATE,
00607                     product_filename,
00608                     UVES_MASTER_BIAS(chip),
00609                     raw_headers[raw_index][0], /* First frame */
00610                     product_header[raw_index],
00611                     NULL,
00612                     parameters,
00613                     recipe_id,
00614                     PACKAGE "/" PACKAGE_VERSION,qclog,
00615                     starttime, true, 
00616                     UVES_ALL_STATS),
00617            "Could not add master bias %s to frameset", product_filename);
00618             uves_qclog_delete(&qclog[0]);
00619         uves_msg("Master bias '%s' added to frameset", product_filename);
00620 
00621         if(strcmp(PROCESS_CHIP,"REDL") == 0) {
00622     chip = uves_chip_get_next(chip);
00623       }
00624 
00625 
00626         } /* For each chip */
00627 
00628   cleanup:
00629     /* Input */
00630     if (raw_images[0] != NULL)
00631     {
00632 
00633         for (i = 0; i < cpl_imagelist_get_size(raw_images[0]); i++) 
00634         {
00635             if (raw_headers[0] != NULL) uves_free_propertylist(&raw_headers[0][i]);
00636             if (raw_headers[1] != NULL) uves_free_propertylist(&raw_headers[1][i]);
00637         }
00638         cpl_free(raw_headers[0]); raw_headers[0] = NULL;
00639         cpl_free(raw_headers[1]); raw_headers[1] = NULL;
00640     }
00641     uves_free_imagelist(&raw_images[0]);
00642     uves_free_imagelist(&raw_images[1]);
00643     /* Output */
00644 
00645     uves_qclog_delete(&qclog[0]);
00646     uves_free_image(&master_bias);
00647     uves_free_propertylist(&product_header[0]);
00648     uves_free_propertylist(&product_header[1]);
00649     cpl_free(product_filename);
00650     uves_free_stats(&mbias_stats);
00651     
00652     return;
00653 }
00654 
00655 
00656 
00657 static int
00658 count_good(const cpl_image *image)
00659 {
00660     return 
00661         cpl_image_get_size_x(image) * cpl_image_get_size_y(image) - 
00662         cpl_image_count_rejected(image);
00663 }
00664 /*----------------------------------------------------------------------------*/
00671 /*----------------------------------------------------------------------------*/
00672 static void
00673 reject_lo_hi(cpl_image *image, double min, double max)
00674 {
00675   cpl_mask *mask_lo = NULL;
00676   cpl_mask *mask_hi = NULL;
00677 
00678   mask_lo = cpl_mask_threshold_image_create(image, -DBL_MAX, min);
00679   mask_hi = cpl_mask_threshold_image_create(image, max, DBL_MAX);
00680   assure_mem( mask_lo );
00681   assure_mem( mask_hi );
00682 
00683   cpl_mask_or(mask_lo, mask_hi);
00684 
00685   cpl_image_reject_from_mask(image, mask_lo);
00686   
00687   cleanup:
00688   uves_free_mask(&mask_lo);
00689   uves_free_mask(&mask_hi);
00690   return;
00691 }
00692 
00703 static void uves_mbias_qclog(const cpl_imagelist* raw_imgs,
00704                              uves_propertylist **raw_headers,
00705                  enum uves_chip chip,
00706                  const cpl_image* mbia,
00707                  /* int sx_pix, Size of X bin in pix 
00708                  int sy_pix, Size of Y bin in pix */
00709                             cpl_table* qclog
00710                             ) 
00711 {
00712   int nx_pix= 0;  /* No of X pix */
00713   int ny_pix= 0;  /* No of Y pix */
00714 
00715   int sample_x= 100; /* X size of sampling window in pix */
00716   int sample_y= 100; /* Y size of sampling window in pix */
00717   int x_cent_s= 0;   /* X sampling window starting point */
00718   int x_cent_e= 0;   /* X sampling window ending point */
00719   int y_cent_s= 0;   /* Y sampling window starting point */
00720   int y_cent_e= 0;   /* Y sampling window ending point */
00721 
00722 
00723 
00724 
00725 
00726   double upp_threshold= 0.0;
00727   double low_threshold= 0.0;
00728   double extra=0.1;
00729   double qc_ron_master= 0.0;
00730 
00731   double master_median=0.0;
00732   int pn= 0;
00733 
00734 
00735   double min=0.0;
00736   double max=0.0;
00737   double struct_col=0.0;
00738   double struct_row=0.0;
00739 
00740   double time_s=+9999999.0;
00741   double time_e=-9999999.0;
00742   int nraw=0;
00743   double qc_duty_cycle=0.;
00744   double exposure_time=0;
00745   int i=0;
00746   char key_name[80];
00747 
00748   const cpl_image* rbia=NULL;
00749   cpl_image* tima=NULL;
00750   cpl_image* avg_col=NULL;
00751   cpl_image* avg_row=NULL;
00752   
00753   uves_qclog_add_string(qclog,
00754                         "QC TEST1 ID",
00755                         "Test-on-Master-Bias",
00756                         "Name of QC test",
00757                         "%s");
00758 
00759   uves_msg("Computing duty cycle...");
00760 
00761   /* Set mbias exposure time to average of inputs */
00762   exposure_time = 0;
00763   nraw = cpl_imagelist_get_size(raw_imgs);
00764   check_nomsg(uves_qclog_add_int(qclog,
00765                         "PRO DATANCOM",
00766                         nraw,
00767                         "Number of frames combined",
00768                         "%d"));
00769 
00770 
00771   for (i = 0; i < nraw; i++)
00772     {
00773       check( exposure_time = uves_pfits_get_mjdobs(raw_headers[i]),
00774          "Error reading exposure time");
00775       if(exposure_time >= time_e) time_e = exposure_time;
00776       if(exposure_time <= time_s) time_s = exposure_time;
00777     }
00778   if(nraw > 1) {
00779     qc_duty_cycle = (time_e-time_s)/ (nraw-1);
00780   }
00781   else
00782       {
00783       qc_duty_cycle = 0;
00784       }
00785  
00786   check_nomsg(uves_qclog_add_double(qclog,
00787                         "QC DUTYCYCL",
00788                         qc_duty_cycle,
00789                         "Time to store a frame",
00790                         "%.5e"));
00791 
00792   /* The following is not really used in MIDAS so we comment
00793   strcpy(date,uves_pfits_get_tpl_start(plist));
00794   */
00795 
00796 
00797   /* CONVERT FROM MIDAS
00798   nx_pix = m$value({mbia},NPIX(1));
00799   ny_pix = m$value({mbia},NPIX(2));
00800   */
00801 
00802   nx_pix = cpl_image_get_size_x(mbia);
00803   ny_pix = cpl_image_get_size_y(mbia);
00804 
00805 
00806   x_cent_s = (nx_pix - sample_x)/2;
00807   x_cent_e = (nx_pix + sample_x)/2;
00808   y_cent_s = (ny_pix - sample_y)/2;
00809   y_cent_e = (ny_pix + sample_y)/2;
00810  
00811   
00812   check_nomsg(upp_threshold = 
00813           cpl_image_get_median_window(mbia,
00814                       x_cent_s,
00815                       y_cent_s,
00816                       x_cent_e,
00817                       y_cent_e)*(1 + extra));
00818   check_nomsg(low_threshold = 
00819           cpl_image_get_median_window(mbia,
00820                       x_cent_s,
00821                       y_cent_s,
00822                       x_cent_e,
00823                       y_cent_e)*(1 - extra));
00824   
00825   /* convert from MIDAS
00826   pn = {uves_portid({PATHID})};
00827   */
00828   check_nomsg(pn = PORT_ID(chip));
00829   uves_msg_debug("Port number = %d", pn);
00830 
00831   rbia = cpl_imagelist_get_const(raw_imgs,0);
00832   check_nomsg(uves_mbias_qc_ron_raw(rbia, chip,
00833                     x_cent_s,x_cent_e,y_cent_s,y_cent_e,qclog));
00834 
00835 
00836   /* convert from  MIDAS
00837   stat/ima {mbia} + bins=1 exc={low_threshold},{upp_threshold};
00838   */
00839   check_nomsg(tima=cpl_image_duplicate(mbia));
00840 
00841   check_nomsg( reject_lo_hi(tima, low_threshold, upp_threshold) );
00842   if (count_good(tima) >= 2)
00843       {
00844           check_nomsg(master_median = cpl_image_get_median(tima));
00845           check_nomsg(qc_ron_master = cpl_image_get_stdev(tima));
00846       }
00847   else
00848       {
00849           master_median = -1;
00850           qc_ron_master = -1;
00851           uves_msg_warning("Only %d good pixels in image. Setting QC parameters to -1",
00852                            count_good(tima));
00853       }
00854   uves_free_image(&tima);
00855 
00856   check_nomsg(uves_qclog_add_double(qclog,
00857                         "PRO DATAMED",
00858                         master_median,
00859                         "Median of pixel values",
00860                         "%7.3f"));
00861 
00862   sprintf(key_name, "QC OUT%d RON MASTER", pn);
00863   check_nomsg(uves_qclog_add_double(qclog,
00864                         key_name,
00865                         qc_ron_master,
00866                         "Read noise frame in ADU",
00867                         "%8.4f"));
00868 
00869   /* ==========================
00870    * Calculates Bias struct
00871    * ==========================
00872    */
00873 
00874  
00875   /*
00876    * in case of RED frame cuts out values greater than 300.
00877    * as the frame can be affected by this local operation we 
00878    * do the calculation on a copy of the original frame
00879    */
00880 
00881   
00882   check_nomsg(tima=cpl_image_duplicate(mbia));
00883   if (chip != UVES_CHIP_BLUE) {
00884     /*
00885     replace/ima {mbia} {tmpfrm} 300,>=300.;
00886     */
00887     check_nomsg(cpl_image_threshold(tima,
00888                                     -DBL_MAX,300,
00889                                     -DBL_MAX,300));
00890   }
00891 
00892 
00893   check_nomsg(avg_col = cpl_image_collapse_create(tima,1));
00894   check_nomsg(cpl_image_divide_scalar(avg_col,cpl_image_get_size_x(tima)));
00895 
00896   /* restricts statistics to +/- 2 ADU around mean */
00897   min = cpl_image_get_mean(avg_col) - 2;
00898   max = cpl_image_get_mean(avg_col) + 2; 
00899 
00900   /* replace with MIDAS
00901   stat/ima avg_col + exc={min},{max};
00902   */
00903   check_nomsg( reject_lo_hi(avg_col, min, max) );
00904   if (count_good(avg_col) >= 2)
00905       {
00906           check_nomsg(struct_col = cpl_image_get_stdev(avg_col));
00907       }
00908   else
00909       {
00910           struct_col = -1;
00911           uves_msg_warning("Only %d good pixels in image. Setting QC parameter to -1",
00912                            count_good(avg_col));
00913       }
00914 
00915   sprintf(key_name,"%s%d%s","QC OUT",pn," STRUCTY");
00916   check_nomsg(uves_qclog_add_double(qclog,
00917                         key_name,
00918                         struct_col,
00919                         "structure in Y (bias slope)",
00920                         "%8.4f"));
00921 
00922 
00923 
00924   check_nomsg(avg_row = cpl_image_collapse_create(tima,0));
00925   check_nomsg(cpl_image_divide_scalar(avg_row,cpl_image_get_size_y(tima)));
00926 
00927   /* restricts statistics to +/- 2 ADU around mean */
00928   min = cpl_image_get_mean(avg_row) - 2;
00929   max = cpl_image_get_mean(avg_row) + 2;
00930  
00931   /* replace with MIDAS
00932   stat/ima avg_row + exc={min},{max};
00933   */
00934   check_nomsg( reject_lo_hi(avg_row, min, max) );
00935   if (count_good(avg_row) >= 2)
00936       {
00937           check_nomsg(struct_row = cpl_image_get_stdev(avg_row));
00938       }
00939   else
00940       {
00941           struct_row = -1;
00942           uves_msg_warning("Only %d good pixels in image. Setting QC parameter to -1",
00943                            count_good(avg_row));
00944       }
00945 
00946   
00947   sprintf(key_name,"%s%d%s","QC OUT",pn," STRUCTX");
00948   check_nomsg(uves_qclog_add_double(qclog,
00949                         key_name,
00950                         struct_row,
00951                         "structure in X (bias slope)",
00952                         "%8.4f"));
00953 
00954  
00955 
00956  
00957  cleanup:
00958   uves_free_image(&avg_col);
00959   uves_free_image(&avg_row);
00960   uves_free_image(&tima);
00961   
00962   return;
00963 
00964 }
00978 static void
00979 uves_mbias_qc_ron_raw(const cpl_image* rbia,
00980                       enum uves_chip chip,
00981                       const int x_cent_s,
00982                       const int x_cent_e,
00983                       const int y_cent_s,
00984                       const int y_cent_e,
00985                       cpl_table* qclog)
00986 {
00987 
00988   double qc_ron_raw=0.0;
00989   double upp_threshold=0.0;
00990   double low_threshold=0.0;
00991   double extra=0.1;
00992   char key_name[80];
00993   int pn=0;
00994   cpl_image* tima=NULL;
00995 
00996   /* replace with MIDAS
00997   date   = "{{mbia},ESO.TPL.START}";
00998   store/frame infrm {incat} 1;
00999   */
01000   check_nomsg(upp_threshold = 
01001           cpl_image_get_median_window(rbia,
01002                       x_cent_s,
01003                       y_cent_s,
01004                       x_cent_e,
01005                       y_cent_e)*(1 + extra));
01006   
01007   check_nomsg(low_threshold = 
01008           cpl_image_get_median_window(rbia,
01009                       x_cent_s,
01010                       y_cent_s,
01011                       x_cent_e,
01012                       y_cent_e)*(1 - extra));
01013   
01014 
01015 
01016   /* replace from MIDAS
01017   stat/ima {rbia} + bins=1 exc={low_treshold},{upp_treshold};
01018   */
01019   check_nomsg(tima=cpl_image_duplicate(rbia));
01020 
01021   check_nomsg( reject_lo_hi(tima, low_threshold, upp_threshold) );
01022   if (count_good(tima) >= 2)
01023       {
01024           check_nomsg(qc_ron_raw = cpl_image_get_stdev(tima));
01025       }
01026   else
01027       {
01028           qc_ron_raw = -1;
01029           uves_msg_warning("Only %d good pixels in image. Setting QC parameter to -1",
01030                            count_good(tima));
01031       }
01032 
01033 
01034   /* replace from MIDAS
01035   pn = {uves_portid({PATHID})};
01036   */
01037   check_nomsg(pn = PORT_ID(chip));
01038 
01039 
01040   sprintf(key_name,"%s%d%s","QC OUT",pn," RON RAW");
01041   check_nomsg(uves_qclog_add_double(qclog,
01042                         key_name,
01043                         qc_ron_raw,
01044                         "Read noise frame in ADU",
01045                         "%8.4f"));
01046 
01047  cleanup:
01048   uves_free_image(&tima);
01049   return;
01050 }
01051 

Generated on 8 Mar 2011 for UVES Pipeline Reference Manual by  doxygen 1.6.1