uves_reduce_mflat.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  02111-1307  USA       *
00018  *                                                                              */
00019 
00020 /*
00021  * $Author: amodigli $
00022  * $Date: 2007/06/06 08:17:33 $
00023  * $Revision: 1.22 $
00024  * $Name: uves-3_3_1 $
00025  * $Log: uves_reduce_mflat.c,v $
00026  * Revision 1.22  2007/06/06 08:17:33  amodigli
00027  * replace tab with 4 spaces
00028  *
00029  * Revision 1.21  2007/05/22 11:31:35  jmlarsen
00030  * Removed image plotting functionality
00031  *
00032  * Revision 1.20  2007/04/24 16:45:17  amodigli
00033  * changed interface of calls to uves_load_ordertable to match new interface
00034  *
00035  * Revision 1.19  2007/04/24 12:50:29  jmlarsen
00036  * Replaced cpl_propertylist -> uves_propertylist which is much faster
00037  *
00038  * Revision 1.18  2007/04/03 06:29:29  amodigli
00039  * changed interface to uves_load_ordertable
00040  *
00041  * Revision 1.17  2007/02/09 13:40:55  jmlarsen
00042  * Enable calling from uves_mkmaster_sflat
00043  *
00044  * Revision 1.16  2007/02/09 08:59:05  jmlarsen
00045  * Include <float.h>
00046  *
00047  * Revision 1.15  2007/02/09 08:14:16  jmlarsen
00048  * Do not use CPL_PIXEL_MAXVAL which works only for integer images
00049  *
00050  * Revision 1.14  2007/01/10 14:17:13  jmlarsen
00051  * Do not threshold master flat to zero
00052  *
00053  * Revision 1.13  2006/12/07 08:23:23  jmlarsen
00054  * uves_load_raw_imagelist: support FLAMES
00055  *
00056  * Revision 1.12  2006/12/01 12:30:15  jmlarsen
00057  * Load FLAMES order table oshift/yshift
00058  *
00059  * Revision 1.11  2006/11/16 14:12:21  jmlarsen
00060  * Changed undefined trace number from 0 to -1, to support zero as an actual 
00061  * trace number
00062  *
00063  * Revision 1.10  2006/11/15 15:02:15  jmlarsen
00064  * Implemented const safe workarounds for CPL functions
00065  *
00066  * Revision 1.8  2006/11/15 14:04:08  jmlarsen
00067  * Removed non-const version of parameterlist_get_first/last/next which is 
00068  * already in CPL, added const-safe wrapper, unwrapper and deallocator functions
00069  *
00070  * Revision 1.7  2006/11/13 12:47:39  jmlarsen
00071  * Don't subtract background for FLAMES reduction
00072  *
00073  * Revision 1.6  2006/11/06 15:19:41  jmlarsen
00074  * Removed unused include directives
00075  *
00076  * Revision 1.5  2006/10/24 14:08:16  jmlarsen
00077  * Added flames flag when loading frames
00078  *
00079  * Revision 1.4  2006/10/09 13:04:58  jmlarsen
00080  * Use macro to define recipe interface functions
00081  *
00082  * Revision 1.3  2006/10/02 08:38:16  jmlarsen
00083  * Added REF_TFLAT computation
00084  *
00085  * Revision 1.2  2006/09/27 15:08:45  jmlarsen
00086  * Fixed doc. bug
00087  *
00088  * Revision 1.1  2006/09/27 13:22:04  jmlarsen
00089  * Factored out flat reduction
00090  *
00091  * Revision 1.4  2006/08/17 13:56:52  jmlarsen
00092  * Reduced max line length
00093  *
00094  * Revision 1.3  2005/12/19 16:17:56  jmlarsen
00095  * Replaced bool -> int
00096  *
00097  */
00098 
00099 #ifdef HAVE_CONFIG_H
00100 #  include <config.h>
00101 #endif
00102 
00103 /*----------------------------------------------------------------------------*/
00108 /*----------------------------------------------------------------------------*/
00113 /*-----------------------------------------------------------------------------
00114                                 Includes
00115  -----------------------------------------------------------------------------*/
00116 #include <uves_reduce_mflat.h>
00117 
00118 #include <uves.h>
00119 #include <uves_backsub.h>
00120 #include <uves_chip.h>
00121 #include <uves_dfs.h>
00122 #include <uves_pfits.h>
00123 #include <uves_parameters.h>
00124 #include <uves_utils.h>
00125 #include <uves_utils_wrappers.h>
00126 #include <uves_qclog.h>
00127 #include <uves_error.h>
00128 #include <uves_msg.h>
00129 
00130 #include <irplib_access.h>
00131 #include <cpl.h>
00132 #include <float.h>
00133 
00134 /*-----------------------------------------------------------------------------
00135                             Functions prototypes
00136  -----------------------------------------------------------------------------*/
00137 
00138 static void uves_mflat_qclog(const cpl_imagelist* raw_images,
00139                      cpl_table* qclog);
00140 
00141 static cpl_error_code uves_msflats(cpl_frameset * set, const cpl_parameterlist *parameters,
00142                    const char *recipe_id,
00143                    const char *starttime);
00144 static void uves_mflat_one(cpl_frameset *frames,
00145                const cpl_parameterlist *parameters, 
00146                bool flames,
00147                const char *recipe_id,
00148                const char *starttime,
00149                const char* prefix);
00150 
00151 static cpl_error_code
00152 uves_mflat_at_ypos(cpl_frameset* set,
00153            const cpl_parameterlist* parameters,
00154            const char *recipe_id,
00155            const char *starttime,
00156                    const cpl_frameset* raw,
00157                    const cpl_frameset* cdb,
00158                    const int ref_x1enc,
00159                    const int ref_x2enc,
00160            const int set_no);
00161 
00162 static void uves_reduce_mflat(cpl_frameset *frames, const cpl_parameterlist *parameters,
00163                   bool flames,
00164                   const char *recipe_id, 
00165                   const char *starttime,
00166                   const char *prefix);
00167 
00168 /*-----------------------------------------------------------------------------
00169                             Implementation
00170  -----------------------------------------------------------------------------*/
00171 const char * const uves_mflat_desc =
00172 "This recipe creates a master flat frame by 1) subtracting the master bias\n"
00173 "frame from each flat field frame, 2) dividing each flat field frame by the\n"
00174 " exposure time for that frame, 3) taking the median of all bias subtracted,\n"
00175 " normalized raw\n flat frames, 4) optionally subtracting the master dark \n"
00176 "frame, and 5) subtracting\n the background to get the bias subtracted, \n"
00177 "optionally dark subtracted, normalized, background subtracted master \n"
00178 "flat-field frame. Symbolically,\n"
00179 " masterflat = median( (flat_i - masterbias)/exptime_i ) - masterdark/exptime\n"
00180 "            - background.\n"
00181 "\n"
00182 "The input flat field frames must have same tag which must match\n"
00183 "(I|D|S|T|SCREEN|)FLAT_(BLUE|RED), for example TFLAT_BLUE or FLAT_RED. Also, a\n"
00184 "master bias (MASTER_BIAS_xxxx) and ordertable (ORDER_TABLE_xxxx) must be\n"
00185 "provided for each chip (xxxx = BLUE, REDL, REDU). A master dark frame\n"
00186 "(MASTER_(P)DARK_xxxx) may optionally be provided. On blue input the recipe\n"
00187 "computes one master flat field frame; on red input the recipe produces a\n"
00188 "master flat field frame for each chip (MASTER_FLAT_xxxx, MASTER_IFLAT_xxxx,\n"
00189 "MASTER_DFLAT_xxxx, MASTER_TFLAT_xxxx or MASTER_SCREEN_FLAT_xxxx).";
00190 
00191 /*----------------------------------------------------------------------------*/
00198 /*----------------------------------------------------------------------------*/
00199 int
00200 uves_mflat_define_parameters_body(cpl_parameterlist *parameters, 
00201                   const char *recipe_id)
00202 {
00203     /*****************
00204      *    General    *
00205      *****************/
00206     if (uves_define_global_parameters(parameters) != CPL_ERROR_NONE)
00207     {
00208         return -1;
00209     }
00210 
00211     
00212     /****************************
00213      *  Spline back.sub.        *
00214      ****************************/
00215     
00216     if (uves_propagate_parameters_step(UVES_BACKSUB_ID, parameters, 
00217                        recipe_id, NULL) != 0)
00218     {
00219         return -1;
00220     }
00221 
00222     return (cpl_error_get_code() != CPL_ERROR_NONE);
00223 }
00224 
00225 /*----------------------------------------------------------------------------*/
00263 /*----------------------------------------------------------------------------*/
00264 static cpl_image *
00265 uves_mflat_process_chip(const cpl_imagelist *raw_images, uves_propertylist **raw_headers, 
00266             uves_propertylist *master_flat_header,
00267             const cpl_image *master_bias,
00268             const cpl_image *master_dark, const uves_propertylist *mdark_header, 
00269             const cpl_table *ordertable, const polynomial *order_locations,
00270             bool flames,
00271             const cpl_parameterlist *parameters,
00272             enum uves_chip chip,
00273             const char *recipe_id,
00274             bool DEBUG,
00275             cpl_image **background)
00276 
00277 {
00278     cpl_image *master_flat        = NULL; /* Result */
00279     cpl_image *current_flat       = NULL;
00280     cpl_imagelist *preproc_images = NULL;
00281     int i;
00282 
00283     /* First process each input image and store the results in a new image list */
00284 
00285     preproc_images = cpl_imagelist_new();
00286     for (i = 0; i < cpl_imagelist_get_size(raw_images); i++)
00287     {
00288         double exposure_time = 0.0;
00289 
00290         const uves_propertylist *current_header = NULL;
00291 
00292         current_flat   = cpl_image_duplicate(irplib_imagelist_get_const(raw_images, i));
00293         current_header = raw_headers[i];
00294         
00295         /* Subtract master bias */
00296         if (master_bias != NULL)
00297         {
00298             uves_msg("Subtracting master bias");
00299             check( uves_subtract_bias(current_flat, master_bias), 
00300                "Error subtracting master bias");
00301         }
00302         else
00303         {
00304             uves_msg("Skipping bias subtraction");
00305         }
00306         
00307         /* Normalize to unit exposure time */
00308         check( exposure_time = uves_pfits_get_exptime(current_header), 
00309            "Error reading exposure time");
00310         
00311         uves_msg("Normalizing flat from %f s to unit exposure time", exposure_time);
00312         check( cpl_image_divide_scalar(current_flat, exposure_time),
00313            "Error normalizing flat field");
00314         check( uves_pfits_set_exptime(master_flat_header, 1.0),
00315            "Error writing master frame exposure time");
00316         
00317         /* Append to imagelist */
00318         check( cpl_imagelist_set(preproc_images,     /* Image list */
00319                      current_flat,       /* Image to insert */
00320                      i),                 /* Position (number_of_images=>append) */
00321            "Could not insert image into image list");
00322         
00323         /* Don't deallocate the image. It will be deallocated when
00324            the image list is deallocated */
00325         current_flat = NULL;
00326     }
00327     
00328     /* Take median of all input flats */
00329     uves_msg("Calculating stack median");
00330     check( master_flat = cpl_imagelist_collapse_median_create(preproc_images), 
00331        "Error computing median");
00332     
00333     /* Subtract master dark if present */
00334     if (master_dark != NULL)
00335     {
00336         uves_msg("Subtracting master dark");
00337         check( uves_subtract_dark(master_flat, master_flat_header,
00338                       master_dark, mdark_header), 
00339            "Error subtracting master dark");
00340     }
00341     else
00342     {
00343         uves_msg("Skipping dark subtraction");
00344     }
00345 
00346     if (DEBUG && !flames)
00347     {
00348         check( uves_save_image_local("Pre-background subtracted master flat", "pre",
00349                      master_flat, chip, -1, -1, master_flat_header), 
00350            "Error saving image");
00351     }
00352     
00353     /* Subtract background from master flat */
00354     if (!flames)
00355     {
00356         uves_msg("Subtracting background");
00357         
00358         check( uves_backsub_spline(master_flat, 
00359                        /* Info about chip (wavelength, ...) is 
00360                       stored in any raw header,
00361                       so just pass the first one   */
00362                        raw_headers[0],                
00363                        ordertable, order_locations, 
00364                        parameters, recipe_id,
00365                        chip,
00366                        true,     /* Use flat-field parameters? */
00367                        background),
00368            "Error subtracting background from master flat");
00369     }
00370     else
00371     {
00372         uves_msg("Skipping background subtraction");
00373     }
00374         
00375   cleanup:
00376     uves_free_imagelist(&preproc_images);
00377     uves_free_image(&current_flat);
00378     if (cpl_error_get_code() != CPL_ERROR_NONE)
00379     {
00380         uves_free_image(&master_flat);
00381     }
00382     
00383     return master_flat;
00384 }
00385 
00386 /*----------------------------------------------------------------------------*/
00398 /*----------------------------------------------------------------------------*/
00399 void
00400 uves_mflat_exe_body(cpl_frameset *frames, 
00401             const cpl_parameterlist *parameters,
00402             const char *starttime,
00403             const char *recipe_id)
00404 {
00405     /* Do FLAMES reduction if SFLAT frame is given */
00406     if  (irplib_frameset_find(frames, UVES_SFLAT(true )) != NULL ||
00407      irplib_frameset_find(frames, UVES_SFLAT(false)) != NULL) 
00408     {
00409         check(uves_msflats(frames, parameters, recipe_id, starttime),
00410           "find same sflats failed");
00411     } 
00412     else 
00413     {
00414         bool flames = false;
00415         check(uves_mflat_one(frames, parameters, flames, recipe_id, 
00416                  starttime, ""),
00417           "Master flat one failed");
00418     }
00419     
00420  cleanup:
00421     return;
00422 }
00423 
00424 /*----------------------------------------------------------------------------*/
00430 /*----------------------------------------------------------------------------*/
00431 static cpl_error_code
00432 uves_msflats(cpl_frameset * set, const cpl_parameterlist *parameters,
00433          const char *recipe_id,
00434          const char *starttime)
00435 {
00436   /* Pseudocode:
00437      extract raw frames from set
00438      extract cdb frames from set
00439      identifies how many different Y position we have 
00440      for each Y pos:
00441          extract from the raw_set the raw frames corresponding to each Y pos 
00442          merge in a new wrk_set the cdb_set 
00443          computes the corresponding master flat 
00444          put the products in the final set 
00445      endfor 
00446   */
00447   cpl_frameset* raw=NULL;
00448   cpl_frameset* cdb=NULL;
00449   cpl_frameset* pro=NULL;
00450   int status=0;
00451   int x1enc=0;
00452   int x2enc=0;
00453 
00454   cpl_table* encoder_tbl=NULL;
00455   int nset=0;
00456   int i=0;
00457 
00458   check(uves_extract_frames_group_type(set,&raw,CPL_FRAME_GROUP_RAW),
00459     "Extract raw frames failed");
00460   check(uves_extract_frames_group_type(set,&cdb,CPL_FRAME_GROUP_CALIB),
00461     "Extract cdb frames failed");
00462   check(uves_sflats_get_encoder_steps(raw,&encoder_tbl,&nset),
00463     "Get encoder steps failed");
00464   uves_msg("Check Slit Flat Field Y nominal positions within each set");
00465   for(i=0;i<nset;i++) {
00466 
00467          uves_msg("Slit Flat field set %d: x1enc = %d x2enc = %d",
00468               i+1,
00469               cpl_table_get_int(encoder_tbl,"x1enc",i,&status),
00470               cpl_table_get_int(encoder_tbl,"x2enc",i,&status));
00471 
00472   }
00473 
00474   for(i=0;i<nset;i++) {
00475     x1enc=cpl_table_get_int(encoder_tbl,"x1enc",i,&status);
00476     x2enc=cpl_table_get_int(encoder_tbl,"x2enc",i,&status);
00477 
00478     uves_msg("Processing set %d", i+1);
00479 
00480     check(uves_mflat_at_ypos(set,parameters,recipe_id,starttime,raw,cdb,x1enc,x2enc,i+1),
00481       "Master flat one failed");
00482   }
00483 
00484   cleanup:
00485   uves_free_table(&encoder_tbl);
00486   uves_free_frameset(&raw);
00487   uves_free_frameset(&cdb);
00488   uves_free_frameset(&pro);
00489 
00490     return cpl_error_get_code();
00491 }
00492 
00493 
00494 /*----------------------------------------------------------------------------*/
00500 /*----------------------------------------------------------------------------*/
00501 static cpl_error_code
00502 uves_mflat_at_ypos(cpl_frameset* set,
00503            const cpl_parameterlist* parameters,
00504            const char *recipe_id,
00505            const char *starttime,
00506                    const cpl_frameset* raw,
00507                    const cpl_frameset* cdb,
00508                    const int ref_x1enc,
00509                    const int ref_x2enc,
00510                    const int set_no)
00511 {
00512 
00513     const cpl_frame* frm_tmp=NULL;
00514   char* file=NULL;
00515   uves_propertylist* plist=NULL;
00516   int i=0;
00517   const int threshold = 5;
00518   cpl_frame* frm_dup=NULL;
00519   cpl_frameset* tmp=NULL;
00520   cpl_frameset* pro=NULL;
00521   int x1enc=0;
00522   int x2enc=0;
00523   char prefix[255];
00524   bool flames = true;
00525 
00526   check_nomsg(tmp=cpl_frameset_new());
00527    for(i=0;i<cpl_frameset_get_size(raw);i++)
00528     {
00529     check_nomsg(frm_tmp=irplib_frameset_get_frame_const(raw,i));
00530     check_nomsg(file=cpl_strdup(cpl_frame_get_filename(frm_tmp)));
00531     check_nomsg(plist=uves_propertylist_load(file,0));
00532     check_nomsg(x1enc=uves_pfits_get_slit3_x1encoder(plist));
00533     check_nomsg(x2enc=uves_pfits_get_slit3_x2encoder(plist));
00534     
00535     if( (fabs(x1enc - ref_x1enc) <= threshold) &&
00536         (fabs(x2enc - ref_x2enc) <= threshold) ) {
00537       uves_msg_debug("file=%s x1enc=%d x2enc=%d",file,x1enc,x2enc);
00538       check(frm_dup = cpl_frame_duplicate(frm_tmp),"duplicate");
00539       check(cpl_frameset_insert(tmp,frm_dup),"insert");
00540     }
00541     cpl_free(file);
00542     uves_free_propertylist(&plist);
00543     }
00544    check_nomsg(uves_frameset_merge(tmp,cdb));
00545    sprintf(prefix,"%s%d%s","set",set_no,"_");
00546    check(uves_mflat_one(tmp,parameters, flames, recipe_id, starttime,prefix),"Master flat one failed");
00547    check_nomsg(uves_extract_frames_group_type(tmp,&pro,CPL_FRAME_GROUP_PRODUCT));
00548    check_nomsg(uves_frameset_merge(set,pro));
00549 
00550  cleanup:
00551    uves_free_frameset(&tmp);
00552    uves_free_frameset(&pro);
00553    uves_free_propertylist(&plist);
00554   
00555     return cpl_error_get_code();
00556 }
00557 /*----------------------------------------------------------------------------*/
00570 /*----------------------------------------------------------------------------*/
00571 static void
00572 uves_mflat_one(cpl_frameset *frames,
00573            const cpl_parameterlist *parameters, 
00574            bool flames,
00575            const char *recipe_id,
00576            const char *starttime,
00577                const char* prefix)
00578 {
00579     /* Do flat-fielding */
00580     check_nomsg( uves_reduce_mflat(frames, parameters, 
00581                    flames, recipe_id,
00582                    starttime, prefix) );
00583 
00584   cleanup:
00585     return;
00586 }
00587 
00588 /*----------------------------------------------------------------------------*/
00599 /*----------------------------------------------------------------------------*/
00600 static void
00601 uves_reduce_mflat(cpl_frameset *frames, const cpl_parameterlist *parameters,
00602           bool flames,
00603           const char *recipe_id, 
00604           const char *starttime,
00605           const char *prefix)
00606 {
00607     bool DEBUG;
00608 
00609     /* Input */
00610     cpl_imagelist       *raw_images[2] = {NULL, NULL}; /* An image list for both chips */
00611     uves_propertylist  **raw_headers[2] = {NULL, NULL}; /* Two arrays of pointers */
00612 
00613     /* Master bias */
00614     cpl_image *master_bias               = NULL;
00615     uves_propertylist *master_bias_header = NULL;
00616 
00617     /* Master dark */
00618     cpl_image *master_dark               = NULL;
00619     uves_propertylist *master_dark_header = NULL;
00620 
00621     /* Order table */
00622     cpl_table        *ordertable            = NULL;
00623     uves_propertylist *ordertable_header     = NULL;
00624     polynomial       *order_locations       = NULL;
00625     cpl_table        *traces                = NULL;
00626     
00627     /* Reference master flat */
00628     cpl_image        *ref_flat              = NULL;
00629     uves_propertylist *ref_flat_header       = NULL;
00630 
00631     /* Output */
00632     cpl_table *qclog[]                  = {NULL, NULL};
00633     cpl_image *master_flat              = NULL;
00634     cpl_image *background               = NULL;
00635     uves_propertylist *product_header[]  = {NULL, NULL};
00636     cpl_image *ratio                    = NULL;
00637     
00638     /* Local variables */
00639     char *product_filename = NULL;
00640     char pro_filename[255];
00641     const char *product_tag[2] = {NULL, NULL};
00642     bool blue;
00643     enum uves_chip chip;
00644 
00645     /* Read recipe parameters */
00646     {
00647     /* General */
00648     check( uves_get_parameter(parameters, NULL, "uves", "debug", CPL_TYPE_BOOL  , &DEBUG ), 
00649            "Could not read parameter");
00650     }
00651 
00652     /* Load and check raw flat images and headers, identify arm (blue/red) */
00653     /* On success, 'raw_headers' will be an array with the same size as 'raw_images' */
00654     /* Set product tags to match input tag */
00655     if (irplib_frameset_find(frames, UVES_FLAT(true )) != NULL ||
00656     irplib_frameset_find(frames, UVES_FLAT(false)) != NULL)
00657     {
00658         check( uves_load_raw_imagelist(frames, 
00659                        flames,
00660                        UVES_FLAT(true), UVES_FLAT(false),
00661                        CPL_TYPE_DOUBLE,
00662                        raw_images, raw_headers, product_header, 
00663                        &blue), "Error loading raw flat frames");
00664         
00665         for (chip = uves_chip_get_first(blue); chip != UVES_CHIP_INVALID; 
00666          chip = uves_chip_get_next(chip))
00667         {
00668             product_tag[uves_chip_get_index(chip)] = UVES_MASTER_FLAT(chip);
00669         }
00670     }
00671     else if (irplib_frameset_find(frames, UVES_DFLAT(true )) != NULL ||
00672          irplib_frameset_find(frames, UVES_DFLAT(false)) != NULL)
00673     {
00674         check( uves_load_raw_imagelist(frames, 
00675                        flames,
00676                        UVES_DFLAT(true), UVES_DFLAT(false),
00677                        CPL_TYPE_DOUBLE,
00678                        raw_images, raw_headers, product_header, 
00679                        &blue), "Error loading raw flat frames");
00680         for (chip = uves_chip_get_first(blue); 
00681          chip != UVES_CHIP_INVALID; 
00682          chip = uves_chip_get_next(chip))
00683         {
00684             product_tag[uves_chip_get_index(chip)] = UVES_MASTER_DFLAT(chip);
00685         }
00686     }
00687     else if  (irplib_frameset_find(frames, UVES_IFLAT(true )) != NULL ||
00688           irplib_frameset_find(frames, UVES_IFLAT(false)) != NULL)
00689     {
00690         check( uves_load_raw_imagelist(frames, 
00691                        flames,
00692                        UVES_IFLAT(true), UVES_IFLAT(false),
00693                        CPL_TYPE_DOUBLE,
00694                        raw_images, raw_headers, product_header, 
00695                        &blue), "Error loading raw flat frames");
00696         for (chip = uves_chip_get_first(blue); 
00697          chip != UVES_CHIP_INVALID; 
00698          chip = uves_chip_get_next(chip))
00699         {
00700             product_tag[uves_chip_get_index(chip)] = UVES_MASTER_IFLAT(chip);
00701         }
00702     }
00703     else if  (irplib_frameset_find(frames, UVES_TFLAT(true )) != NULL ||
00704           irplib_frameset_find(frames, UVES_TFLAT(false)) != NULL)
00705     {
00706         check( uves_load_raw_imagelist(frames, 
00707                        flames,
00708                        UVES_TFLAT(true), UVES_TFLAT(false),
00709                        CPL_TYPE_DOUBLE,
00710                        raw_images, raw_headers, product_header, 
00711                        &blue), "Error loading raw flat frames");
00712         for (chip = uves_chip_get_first(blue); 
00713          chip != UVES_CHIP_INVALID; 
00714          chip = uves_chip_get_next(chip))
00715         {
00716             product_tag[uves_chip_get_index(chip)] = UVES_MASTER_TFLAT(chip);
00717         }
00718     }
00719     else if  (irplib_frameset_find(frames, UVES_SCREEN_FLAT(true )) != NULL ||
00720           irplib_frameset_find(frames, UVES_SCREEN_FLAT(false)) != NULL)
00721     {
00722         check( uves_load_raw_imagelist(frames, 
00723                        flames,
00724                        UVES_SCREEN_FLAT(true), UVES_SCREEN_FLAT(false),
00725                        CPL_TYPE_DOUBLE,
00726                        raw_images, raw_headers, product_header, 
00727                        &blue), "Error loading raw flat frames");
00728         for (chip = uves_chip_get_first(blue); 
00729          chip != UVES_CHIP_INVALID; 
00730          chip = uves_chip_get_next(chip))
00731         {
00732             product_tag[uves_chip_get_index(chip)] = UVES_MASTER_SCREEN_FLAT(chip);
00733         }
00734     }
00735     else if  (irplib_frameset_find(frames, UVES_SFLAT(true )) != NULL ||
00736           irplib_frameset_find(frames, UVES_SFLAT(false)) != NULL)
00737     {
00738         check( uves_load_raw_imagelist(frames, 
00739                        flames,
00740                        UVES_SFLAT(true), UVES_SFLAT(false),
00741                        CPL_TYPE_DOUBLE,
00742                        raw_images, raw_headers, product_header, 
00743                        &blue), "Error loading raw flat frames");
00744         for (chip = uves_chip_get_first(blue); 
00745          chip != UVES_CHIP_INVALID; 
00746          chip = uves_chip_get_next(chip))
00747         {
00748             product_tag[uves_chip_get_index(chip)] = UVES_MASTER_SFLAT(chip);
00749         }
00750     }
00751     else 
00752     {
00753         assure(false, CPL_ERROR_DATA_NOT_FOUND,
00754            "Missing input flat frame: "
00755            "%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s or %s expected",
00756            UVES_FLAT(true) , UVES_FLAT(false),
00757            UVES_DFLAT(true), UVES_DFLAT(false),
00758            UVES_IFLAT(true), UVES_IFLAT(false),
00759            UVES_TFLAT(true), UVES_TFLAT(false),
00760            UVES_SCREEN_FLAT(true), UVES_SCREEN_FLAT(false),
00761            UVES_SFLAT(true), UVES_SFLAT(false));
00762     }
00763 
00764     /* Loop over one or two chips */
00765     for (chip = uves_chip_get_first(blue); 
00766      chip != UVES_CHIP_INVALID; 
00767      chip = uves_chip_get_next(chip))
00768     {
00769         const char *ordertable_filename = "";
00770         const char *master_bias_filename = "";
00771         const char *master_dark_filename = "";
00772         const char *chip_name = "";
00773         
00774         int raw_index = uves_chip_get_index(chip);
00775         
00776         uves_msg("Processing %s chip", uves_chip_tostring_upper(chip));
00777 
00778         /* Chip name of first input frame */
00779         check_nomsg( chip_name = uves_pfits_get_chipid(raw_headers[raw_index][0], chip));
00780 
00781         /* Load master bias, set pointer to NULL if not present */
00782         uves_free_image(&master_bias);
00783         uves_free_propertylist(&master_bias_header);
00784         if (irplib_frameset_find(frames, UVES_MASTER_BIAS(chip)) != NULL)
00785         {
00786             uves_free_image(&master_bias);
00787             uves_free_propertylist(&master_bias_header);
00788             check( uves_load_mbias(frames,
00789                        chip_name,
00790                        &master_bias_filename, &master_bias,
00791                        &master_bias_header, chip), 
00792                "Error loading master bias");
00793             
00794             uves_msg_low("Using master bias in '%s'", master_bias_filename);
00795         }
00796         else
00797         {
00798             uves_msg_low("No master bias in SOF. Bias subtraction not done");
00799         }
00800     
00801         /* Load master dark, set pointer to NULL if not present */
00802         uves_free_image(&master_dark);
00803         uves_free_propertylist(&master_dark_header);
00804         if (irplib_frameset_find(frames, UVES_MASTER_DARK(chip))  != NULL ||
00805         irplib_frameset_find(frames, UVES_MASTER_PDARK(chip)) != NULL)
00806         {
00807             uves_free_image(&master_dark);
00808             uves_free_propertylist(&master_dark_header);
00809             check( uves_load_mdark(frames, chip_name,
00810                        &master_dark_filename, &master_dark,
00811                        &master_dark_header, chip), 
00812                "Error loading master dark");
00813             
00814             uves_msg_low("Using master dark in '%s'", master_dark_filename);
00815         }
00816         else
00817         {
00818             uves_msg_low("No master dark in SOF. Dark subtraction not done");
00819         }
00820     
00821         /* Load the order table for this chip */
00822         if (flames)
00823         /* FLAMES does not do background subtraction (here)
00824            and therefore does not need an ordertable */
00825         {
00826             if (irplib_frameset_find(frames, UVES_ORDER_TABLE(flames, chip)) != NULL)
00827             {
00828                 uves_msg_warning("Order table (%s) is not used in FLAMES reduction",
00829                          UVES_ORDER_TABLE(flames, chip));
00830             }
00831         }
00832         else
00833         {
00834             uves_free_table       (&ordertable);
00835             uves_free_propertylist(&ordertable_header);
00836             uves_polynomial_delete(&order_locations);
00837             uves_free_table       (&traces);
00838             
00839             check( uves_load_ordertable(frames,
00840                         flames,
00841                         chip_name,
00842                         &ordertable_filename, 
00843                                                 &ordertable,
00844                         &ordertable_header, 
00845                                                 NULL,
00846                                                 &order_locations,
00847                         &traces, NULL, NULL,
00848                                        NULL, NULL, /* fibre_pos,fibre_mask */
00849                         chip,
00850                         false),
00851                "Could not load order table");
00852             uves_msg("Using order table in '%s'", ordertable_filename);
00853         }
00854         
00855         /* Process chip */
00856         uves_free_image(&master_flat);
00857         uves_free_image(&background);
00858         check( master_flat = uves_mflat_process_chip(
00859                raw_images[raw_index], raw_headers[raw_index],
00860                product_header[raw_index],
00861                master_bias,
00862                master_dark, master_dark_header,
00863                ordertable, order_locations,
00864                flames,
00865                parameters,
00866                chip,
00867                recipe_id,
00868                DEBUG,
00869                &background),
00870            "Error processing chip");
00871 
00872         /* Finished. Compute QC parameters and save */
00873         uves_msg("Computing QC parameters");
00874             uves_qclog_delete(&qclog[0]);
00875             qclog[0] = uves_qclog_init(raw_headers[raw_index][0], chip);
00876 
00877             check(uves_mflat_qclog(raw_images[raw_index],
00878                    qclog[0]),"error computing qclog");
00879     
00880         uves_msg("Saving products");
00881     
00882         cpl_free(product_filename);
00883         check( product_filename = uves_masterflat_filename(chip), 
00884            "Error getting filename");
00885             strcpy(pro_filename,prefix);
00886             strcat(pro_filename,product_filename);
00887         check( uves_frameset_insert(frames,
00888                     master_flat,
00889                     CPL_FRAME_GROUP_PRODUCT,
00890                     CPL_FRAME_TYPE_IMAGE,
00891                     CPL_FRAME_LEVEL_INTERMEDIATE,
00892                     pro_filename,
00893                     product_tag[raw_index],
00894                     raw_headers[raw_index][0],
00895                     product_header[raw_index],
00896                     NULL,
00897                     parameters,
00898                     recipe_id,
00899                     PACKAGE "/" PACKAGE_VERSION, qclog,
00900                     starttime, true, UVES_ALL_STATS),
00901            "Could not add master flat '%s' to frameset", product_filename);
00902         uves_msg("Master flat '%s' added to frameset", product_filename);
00903 
00904         /* Save background image */
00905         if (!flames)
00906         {
00907             cpl_free(product_filename);
00908             check( product_filename = uves_masterflat_bkg_filename(chip), 
00909                "Error getting filename");
00910             strcpy(pro_filename,prefix);
00911             strcat(pro_filename,product_filename);
00912             
00913             check( uves_frameset_insert(frames,
00914                         background,
00915                         CPL_FRAME_GROUP_PRODUCT,
00916                         CPL_FRAME_TYPE_IMAGE,
00917                         CPL_FRAME_LEVEL_INTERMEDIATE,
00918                         pro_filename,
00919                         UVES_BKG_FLAT(chip),
00920                         raw_headers[raw_index][0],
00921                         product_header[raw_index],
00922                         NULL,
00923                         parameters,
00924                         recipe_id,
00925                         PACKAGE "/" PACKAGE_VERSION, NULL,
00926                         starttime, false, 
00927                         CPL_STATS_MIN | CPL_STATS_MAX),
00928                "Could not add background image '%s' to frameset", 
00929                product_filename);
00930             uves_msg("Master flat background '%s' added to frameset", 
00931                  product_filename);
00932                 }
00933 
00934         /* Compute and save ratio MASTER_TFLAT / REF_TFLAT */
00935         if (strcmp(recipe_id, make_str(UVES_TFLAT_ID)) == 0)
00936         {
00937             const char *ref_flat_filename;
00938 
00939             uves_free_image(&ref_flat);
00940             uves_free_propertylist(&ref_flat_header);
00941 
00942             check( uves_load_ref_flat(frames, chip_name, &ref_flat_filename, 
00943                           &ref_flat, &ref_flat_header, 
00944                           chip),
00945                "Error loading reference flat field");
00946             
00947             uves_msg("Using reference flat field in '%s'", ref_flat_filename);
00948 
00949             check( ratio = cpl_image_divide_create(master_flat, ref_flat),
00950                "Error computing ratio of master and reference flat");
00951 
00952             cpl_free(product_filename);
00953             check( product_filename = uves_flat_ratio_filename(chip), 
00954                "Error getting filename");
00955             
00956             check( uves_frameset_insert(frames,
00957                         ratio,
00958                         CPL_FRAME_GROUP_PRODUCT,
00959                         CPL_FRAME_TYPE_IMAGE,
00960                         CPL_FRAME_LEVEL_INTERMEDIATE,
00961                         product_filename,
00962                         UVES_RATIO_TFLAT(chip),
00963                         raw_headers[raw_index][0],
00964                         product_header[raw_index],
00965                         NULL,
00966                         parameters,
00967                         recipe_id,
00968                         PACKAGE "/" PACKAGE_VERSION,
00969                         qclog,
00970                         starttime, false, 
00971                         UVES_ALL_STATS),
00972                "Could not add ratio image '%s' to frameset", product_filename);
00973 
00974             uves_msg("Master flat ratio '%s' added to frameset", product_filename);
00975         }
00976     
00977     } /* For each chip */
00978     
00979   cleanup:
00980     /* Input */
00981     if (raw_images[0] != NULL)
00982     {
00983         int i;
00984         for (i = 0; i < cpl_imagelist_get_size(raw_images[0]); i++) 
00985         {
00986             if (raw_headers[0] != NULL) uves_free_propertylist(&raw_headers[0][i]);
00987             if (raw_headers[1] != NULL) uves_free_propertylist(&raw_headers[1][i]);
00988         }
00989         cpl_free(raw_headers[0]); raw_headers[0] = NULL;
00990         cpl_free(raw_headers[1]); raw_headers[1] = NULL;
00991     }
00992 
00993     uves_free_imagelist(&raw_images[0]);
00994     uves_free_imagelist(&raw_images[1]);
00995 
00996     /* Master bias */
00997     uves_free_image(&master_bias);
00998     uves_free_propertylist(&master_bias_header);
00999 
01000     /* Master dark */
01001     uves_free_image(&master_dark);
01002     uves_free_propertylist(&master_dark_header);
01003 
01004     /* Order table */
01005     uves_free_table(&ordertable);
01006     uves_free_propertylist(&ordertable_header);
01007     uves_polynomial_delete(&order_locations);
01008     uves_free_table(&traces);
01009 
01010     /* Reference master flat */
01011     uves_free_image(&ref_flat);
01012     uves_free_propertylist(&ref_flat_header);
01013     
01014     /* Output */
01015     uves_qclog_delete(&qclog[0]);
01016     uves_free_image(&master_flat);
01017     uves_free_image(&background);
01018     uves_free_image(&ratio);
01019     uves_free_propertylist(&product_header[0]);
01020     uves_free_propertylist(&product_header[1]);
01021     cpl_free(product_filename);
01022     
01023     return;
01024 }
01025 
01026 
01027 /*----------------------------------------------------------------------------*/
01033 /*----------------------------------------------------------------------------*/
01034 
01035 static void
01036 uves_mflat_qclog(const cpl_imagelist* raw_images,
01037          cpl_table* qclog)
01038 {
01039   int nraw=0;
01040 
01041   check_nomsg(uves_qclog_add_string(qclog,
01042                         "QC TEST1 ID",
01043                         "Test-on-Master-Flat",
01044                         "Name of QC test",
01045                         "%s"));
01046   check_nomsg(nraw=cpl_imagelist_get_size(raw_images));
01047 
01048   check_nomsg(uves_qclog_add_int(qclog,
01049                         "PRO DATANCOM",
01050                         nraw,
01051                         "Number of frames combined",
01052                         "%d"));
01053  cleanup:
01054   return;
01055 }

Generated on Tue Jun 19 14:39:17 2007 for UVES Pipeline Reference Manual by  doxygen 1.4.6