uves_redchain_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: 2007/11/13 16:19:55 $
00023  * $Revision: 1.39 $
00024  * $Name: uves-3_4_5 $
00025  * $Log: uves_redchain_impl.c,v $
00026  * Revision 1.39  2007/11/13 16:19:55  amodigli
00027  * adding DATAMD5 to calib products
00028  *
00029  * Revision 1.38  2007/10/05 16:01:45  amodigli
00030  * using proces_chip parameter to process or not a given RED chip
00031  *
00032  * Revision 1.37  2007/08/21 13:08:26  jmlarsen
00033  * Removed irplib_access module, largely deprecated by CPL-4
00034  *
00035  * Revision 1.36  2007/06/28 09:19:24  jmlarsen
00036  * Do not compute master dark if provided
00037  *
00038  * Revision 1.35  2007/06/11 13:28:26  jmlarsen
00039  * Changed recipe contact address to cpl at eso.org
00040  *
00041  * Revision 1.34  2007/06/08 13:06:16  jmlarsen
00042  * Send bug reports to Andrea
00043  *
00044  * Revision 1.33  2007/06/06 08:17:33  amodigli
00045  * replace tab with 4 spaces
00046  *
00047  * Revision 1.32  2007/05/22 09:11:06  jmlarsen
00048  * Reverse logic bugfix
00049  *
00050  * Revision 1.31  2007/05/22 08:13:19  amodigli
00051  * allow to process only blu or red data
00052  *
00053  * Revision 1.30  2007/05/14 08:09:48  amodigli
00054  * updated input frames and tag description in recipe man page
00055  *
00056  * Revision 1.29  2007/05/03 16:03:58  jmlarsen
00057  * uves_obs_redchain: Implemented option to skip final science reduction
00058  *
00059  * Revision 1.28  2007/02/09 13:40:26  jmlarsen
00060  * Use defines for recipe id
00061  *
00062  * Revision 1.27  2007/02/09 08:58:51  jmlarsen
00063  * Use define's rather than hard-coded recipe names
00064  *
00065  * Revision 1.26  2006/11/24 16:21:39  jmlarsen
00066  * Added FIB_LINE_TABLE_x
00067  *
00068  * Revision 1.25  2006/11/15 15:02:15  jmlarsen
00069  * Implemented const safe workarounds for CPL functions
00070  *
00071  * Revision 1.23  2006/11/15 14:04:08  jmlarsen
00072  * Removed non-const version of parameterlist_get_first/last/next which is
00073  * already in CPL, added const-safe wrapper, unwrapper and deallocator functions
00074  *
00075  * Revision 1.22  2006/11/13 12:47:08  jmlarsen
00076  * Changed syntax of UVES_ARC_LAMP to support FLAMES
00077  *
00078  * Revision 1.21  2006/11/06 15:19:41  jmlarsen
00079  * Removed unused include directives
00080  *
00081  * Revision 1.20  2006/10/24 14:06:27  jmlarsen
00082  * Added flames=false where relevant
00083  *
00084  * Revision 1.19  2006/10/19 13:53:25  jmlarsen
00085  * Changed guess line table tag to LINE_GUESS_TAB
00086  *
00087  * Revision 1.18  2006/10/17 12:33:02  jmlarsen
00088  * Added semicolon at UVES_RECIPE_DEFINE invocation
00089  *
00090  * Revision 1.17  2006/10/09 13:01:13  jmlarsen
00091  * Use macro to define recipe interface functions
00092  *
00093  * Revision 1.16  2006/10/02 08:37:49  jmlarsen
00094  * Added REF_TFLAT
00095  *
00096  * Revision 1.15  2006/09/27 15:08:45  jmlarsen
00097  * Fixed doc. bug
00098  *
00099  * Revision 1.14  2006/09/14 08:46:51  jmlarsen
00100  * Added support for TFLAT, SCREEN_FLAT frames
00101  *
00102  * Revision 1.13  2006/08/17 13:56:53  jmlarsen
00103  * Reduced max line length
00104  *
00105  * Revision 1.12  2006/08/16 11:58:02  jmlarsen
00106  * Fixed trivial but harmful buffer overrun
00107  *
00108  * Revision 1.11  2006/08/11 14:56:05  amodigli
00109  * removed Doxygen warnings
00110  *
00111  * Revision 1.10  2006/07/14 12:30:34  jmlarsen
00112  * Compute PRO CATG depending on DO CATG
00113  *
00114  * Revision 1.9  2006/07/03 13:27:10  jmlarsen
00115  * Minor doc update
00116  *
00117  * Revision 1.8  2006/07/03 13:16:47  amodigli
00118  * updated description
00119  *
00120  * Revision 1.7  2006/06/16 08:25:45  jmlarsen
00121  * Manually propagate ESO.DET. keywords from 1st/2nd input header
00122  *
00123  * Revision 1.6  2006/06/13 12:00:54  jmlarsen
00124  * Support ORDER_GUESS_TAB
00125  *
00126  * Revision 1.5  2006/04/24 09:23:33  jmlarsen
00127  * Recognize PDARK, DFLAT, IFLAT as products
00128  *
00129  * Revision 1.4  2006/04/06 12:56:50  jmlarsen
00130  * Added support for PDARK, IFLAT, DLFAT frames
00131  *
00132  * Revision 1.3  2006/04/06 11:48:17  jmlarsen
00133  * Support for SCI_POINT_-, SCI_EXTND_- and SCI_SLICER-frames
00134  *
00135  * Revision 1.2  2006/04/06 08:47:16  jmlarsen
00136  * Support DFLAT, IFLAT, PDARK
00137  *
00138  * Revision 1.1  2006/02/03 07:46:30  jmlarsen
00139  * Moved recipe implementations to ./uves directory
00140  *
00141  * Revision 1.14  2006/01/19 08:47:24  jmlarsen
00142  * Inserted missing doxygen end tag
00143  *
00144  * Revision 1.13  2005/12/20 08:11:44  jmlarsen
00145  * Added CVS  entry
00146  *
00147  */
00148 
00149 #ifdef HAVE_CONFIG_H
00150 #  include <config.h>
00151 #endif
00152 
00153 
00154 /*----------------------------------------------------------------------------*/
00160 /*----------------------------------------------------------------------------*/
00161 
00162 /*-----------------------------------------------------------------------------
00163                                 Includes
00164  -----------------------------------------------------------------------------*/
00165 
00166 #include <uves.h>
00167 
00168 #include <uves_parameters.h>
00169 #include <uves_utils.h>
00170 #include <uves_utils_wrappers.h>
00171 #include <uves_dfs.h>
00172 #include <uves_recipe.h>
00173 #include <uves_error.h>
00174 #include <uves_msg.h>
00175 
00176 /* Library */
00177 #include <cpl.h>
00178 
00179 /*-----------------------------------------------------------------------------
00180                             Local constants
00181  -----------------------------------------------------------------------------*/
00182 static const bool flames = false;  /* This recipe is only for UVES */
00183 
00184 /*-----------------------------------------------------------------------------
00185                             Functions prototypes
00186  -----------------------------------------------------------------------------*/
00187 static bool frame_is_needed(bool blue, const cpl_frame *f);
00188 static cpl_error_code execute_recipe(const char *recipe_id, 
00189                                      cpl_frameset *frames, const cpl_parameterlist *parameters,
00190                                      const char *products[], int n_products, bool reclassify);
00191 static bool is_missing(const cpl_frameset *frames, const char *frame1, const char *frame2);
00192 static void remove_input_frame(cpl_frameset *frames, const char *tag);
00193 
00194 static int uves_redchain_define_parameters(cpl_parameterlist *parameters);
00195 
00196 /*-----------------------------------------------------------------------------
00197                             Recipe standard code
00198  -----------------------------------------------------------------------------*/
00199 #define cpl_plugin_get_info uves_redchain_get_info
00200 UVES_RECIPE_DEFINE(
00201     UVES_REDCHAIN_ID, UVES_REDCHAIN_DOM, uves_redchain_define_parameters,
00202     "Jonas M. Larsen", "cpl@eso.org",
00203     "Runs the full UVES reduction chain",
00204     "This recipe does a complete science reduction. It runs all necessary\n"
00205     "calibration recipes depending on the availability of raw/processed\n"
00206     "calibration frames.\n"
00207     "Input frames are all UVES raw and reference frames:\n"
00208     "formatchecks, ARC_LAMP_FORM_xxxx, xxxx=BLUE or RED,\n"
00209     "order definition frames, ORDER_FLAT_xxx,\n"
00210     "biases, BIAS_xxx,\n"
00211     "darks, DARK_xxx,\n"
00212     "flats, FLAT_xxx,\n"
00213     "arc lamps, ARC_LAMP_xxx,\n"
00214     "standard stars, STANDARD_xxx\n"
00215     "a wavelength catalogue table,LINE_REFER_TABLE, \n"
00216     "and optionally a wavelength table of bright lines,LINE_INTMON_TABLE, \n"
00217     "used only for computing Quality Control parameters.\n"
00218     "a reference standard star flux table, FLUX_STD_TABLE, \n"
00219     "a table describing the atmospheric extintion,EXTCOEFF_TABLE.\n"
00220     "optionally, science frames, SCIENCE_xxx, or UVES_SCI_POINT_xxx, \n"
00221     "or UVES_SCI_EXTND_xxx, or UVES_SCI_SLICER_xxx.\n"
00222     "For further details on the data reduction and the input frame types\n"
00223     "refer to the man page of the individual recipes.\n");
00224 
00227 /*-----------------------------------------------------------------------------
00228                               Functions code
00229  -----------------------------------------------------------------------------*/
00230 /*----------------------------------------------------------------------------*/
00236 /*----------------------------------------------------------------------------*/
00237 static int
00238 uves_redchain_define_parameters(cpl_parameterlist *parameters)
00239 {
00240     const char *recipe_id = make_str(UVES_REDCHAIN_ID);
00241     const char *subcontext = NULL;
00242 
00243     uves_par_new_value("scired",
00244                        CPL_TYPE_BOOL,
00245                        "Whether or not to do science reduction. "
00246                        "If false, only master calibration frames "
00247                        "are created. If false, either zero or all "
00248                        "necessary calibration frames must be provided "
00249                        "for each arm",
00250                        true);
00251 
00252     /*****************
00253      *    General    *
00254      *****************/
00255     if (uves_define_global_parameters(parameters) != CPL_ERROR_NONE)
00256         {
00257             return -1;
00258         }
00259 
00260     /******************
00261      *   Master bias  *
00262      ******************/
00263     if (uves_propagate_parameters(
00264             make_str(UVES_MBIAS_ID), parameters, make_str(UVES_REDCHAIN_ID), NULL) != 0)
00265         {
00266             return -1;
00267         }
00268 
00269     /******************
00270      *   Master dark  *
00271      ******************/
00272     if (uves_propagate_parameters(
00273             make_str(UVES_MDARK_ID), parameters, make_str(UVES_REDCHAIN_ID), NULL) != 0)
00274         {
00275             return -1;
00276         }
00277 
00278     /******************
00279      * Physical model *
00280      ******************/
00281     if (uves_propagate_parameters(
00282             make_str(UVES_PHYSMOD_ID), parameters, make_str(UVES_REDCHAIN_ID), NULL) != 0)
00283         {
00284             return -1;
00285         }
00286 
00287     /******************
00288      * Order position *
00289      ******************/
00290     if (uves_propagate_parameters(
00291             make_str(UVES_ORDERPOS_ID), parameters, make_str(UVES_REDCHAIN_ID), NULL) != 0)
00292         {
00293             return -1;
00294         }
00295 
00296     /******************
00297      *   Master flat  *
00298      ******************/
00299     if (uves_propagate_parameters(
00300             make_str(UVES_MFLAT_ID), parameters, make_str(UVES_REDCHAIN_ID), NULL) != 0)
00301         {
00302             return -1;
00303         }
00304 
00305     /******************
00306      *   Wave.cal.    *
00307      ******************/
00308     if (uves_propagate_parameters(
00309             make_str(UVES_WAVECAL_ID), parameters, make_str(UVES_REDCHAIN_ID), NULL) != 0)
00310         {
00311             return -1;
00312         }
00313 
00314     /******************
00315      *    Response    *
00316      ******************/
00317     if (uves_propagate_parameters(
00318             make_str(UVES_RESPONSE_ID), parameters, make_str(UVES_REDCHAIN_ID), NULL) != 0)
00319         {
00320             return -1;
00321         }
00322 
00323     /******************
00324      *    Scired      *
00325      ******************/
00326     if (uves_propagate_parameters(
00327             make_str(UVES_SCIRED_ID), parameters, make_str(UVES_REDCHAIN_ID), NULL) != 0)
00328         {
00329             return -1;
00330         }
00331 
00332     return (cpl_error_get_code() != CPL_ERROR_NONE);
00333 }
00334 
00335 /*----------------------------------------------------------------------------*/
00344 /*----------------------------------------------------------------------------*/
00345 static void
00346 IRPLIB_CONCAT2X(UVES_REDCHAIN_ID,exe)(cpl_frameset *frames,
00347                       const cpl_parameterlist *parameters, 
00348                       const char *starttime)
00349 {
00350     cpl_frameset *blue_frames = NULL;
00351     cpl_frameset *red_frames = NULL;
00352     cpl_frameset *common_frames = NULL;
00353  
00354 
00355     bool blue;
00356     bool do_science;
00357 
00358     bool run_mbias[2];     /* index 0 (==false): red  arm */
00359     bool run_mdark[2];     /* index 1 (==true ): blue arm  */
00360     bool run_mflat[2];
00361     bool run_physmod[2];
00362     bool run_orderpos[2];
00363     bool run_wavecal[2];
00364     bool run_response[2];
00365     bool run_scired[2];
00366     bool nraw_arm[2];      /* Do we have frames used exclusively
00367                               for this arm? */
00368     const char* PROCESS_CHIP=NULL;
00369 
00370     /* Exceptionally, this parameter is not used because this
00371        recipe does not create any products on its own. Suppress
00372        warning about unused variable */
00373     starttime = starttime;
00374 
00375     check( uves_get_parameter(parameters, NULL, make_str(UVES_REDCHAIN_ID), "scired", 
00376                               CPL_TYPE_BOOL, &do_science), "Could not read parameter");
00377 
00378     /* Check for at least one science frame */
00379     assure(!do_science ||
00380            cpl_frameset_find(frames, UVES_SCIENCE(true ))    != NULL ||
00381            cpl_frameset_find(frames, UVES_SCIENCE(false))    != NULL ||
00382            cpl_frameset_find(frames, UVES_SCI_EXTND(true ))  != NULL ||
00383            cpl_frameset_find(frames, UVES_SCI_EXTND(false))  != NULL ||
00384            cpl_frameset_find(frames, UVES_SCI_POINT(true ))  != NULL ||
00385            cpl_frameset_find(frames, UVES_SCI_POINT(false))  != NULL ||
00386            cpl_frameset_find(frames, UVES_SCI_SLICER(true )) != NULL ||
00387            cpl_frameset_find(frames, UVES_SCI_SLICER(false)) != NULL,
00388            CPL_ERROR_DATA_NOT_FOUND, "No %s, %s, %s, %s, %s, %s, %s or %s in frame set", 
00389            UVES_SCIENCE(true),
00390            UVES_SCIENCE(false),
00391            UVES_SCI_EXTND(true),
00392            UVES_SCI_EXTND(false),
00393            UVES_SCI_POINT(true),
00394            UVES_SCI_POINT(false),
00395            UVES_SCI_SLICER(true),
00396            UVES_SCI_SLICER(false));
00397         
00398     blue_frames = cpl_frameset_new();
00399     red_frames = cpl_frameset_new();
00400     common_frames = cpl_frameset_new();
00401 
00402     check( uves_get_parameter(parameters, NULL, "uves", "process_chip", CPL_TYPE_STRING, &PROCESS_CHIP),
00403                "Could not read parameter");
00404 
00405     /* Split in blue/red frames */
00406     {
00407         cpl_frame *f = NULL;
00408 
00409         for (f = cpl_frameset_get_first(frames);
00410              f != NULL;
00411              f = cpl_frameset_get_next(frames))
00412             {
00413 
00414 
00415                 if (frame_is_needed(true, f))    /* Used in blue arm? */
00416                     {
00417                         uves_msg_debug("Found blue frame: '%s'", cpl_frame_get_tag(f));
00418                         check( cpl_frameset_insert(blue_frames, cpl_frame_duplicate(f)),
00419                                "Error extracting frame '%s' from frame set",
00420                                cpl_frame_get_tag(f));
00421                     }
00422                 if (frame_is_needed(false, f))  /* Used in red arm? */
00423                     {
00424                         uves_msg_debug("Found red frame: '%s'", cpl_frame_get_tag(f));
00425                         check( cpl_frameset_insert(red_frames, cpl_frame_duplicate(f)),
00426                                "Error extracting frame '%s' from frame set",
00427                                cpl_frame_get_tag(f));
00428                     }
00429 
00430                 if (frame_is_needed(true, f) && 
00431                     frame_is_needed(false, f))  /* Used in both arms? */
00432                     {
00433                         uves_msg_debug("Found common frame: '%s'", cpl_frame_get_tag(f));
00434                         check( cpl_frameset_insert(common_frames, cpl_frame_duplicate(f)),
00435                                "Error extracting frame '%s' from frame set",
00436                                cpl_frame_get_tag(f));
00437                     }
00438 
00439             }
00440 
00441         /* Remove all frames from input frame set */
00442         while ((f = cpl_frameset_get_first(frames)) != NULL)
00443             {
00444                 cpl_frameset_erase_frame(frames, f);
00445             }
00446     }
00447 
00448     /* Algorithm:
00449        (with purpose of failing early if we have to fail.)
00450 
00451        1) Find out which recipes to run
00452        2) Check for necessary input frames
00453        3) Execute
00454     */
00455 
00456     blue = true;
00457     do {
00458         enum uves_chip chip1 = (blue) ? UVES_CHIP_BLUE : UVES_CHIP_REDL;
00459         enum uves_chip chip2 = (blue) ? UVES_CHIP_BLUE : UVES_CHIP_REDU;
00460         
00461         cpl_frameset *fms = (blue) ? blue_frames : red_frames;
00462 
00463         nraw_arm[blue] = 
00464             cpl_frameset_get_size(fms) > 
00465             cpl_frameset_get_size(common_frames);
00466         
00467         uves_msg_debug("nraw_arm=%d (%s arm)", nraw_arm[blue], blue ? "blue" : "red");
00468         
00469         run_scired[blue] = do_science &&
00470             !(is_missing(fms, UVES_SCIENCE(blue), NULL) &&
00471               is_missing(fms, UVES_SCI_EXTND(blue), NULL) &&
00472               is_missing(fms, UVES_SCI_POINT(blue), NULL) &&
00473               is_missing(fms, UVES_SCI_SLICER(blue), NULL));
00474         
00475         /* If calibrations must be produced for this arm */
00476         if (run_scired[blue]
00477             ||
00478             (!do_science && nraw_arm[blue])) {
00479             
00480             /* Require master bias */
00481             run_mbias[blue] = is_missing(fms, 
00482                                          UVES_MASTER_BIAS(chip1),
00483                                          UVES_MASTER_BIAS(chip2)
00484                 );
00485             
00486             /* Run master dark, only if raw frames are available */ 
00487             run_mdark[blue] = 
00488                 is_missing(fms,
00489                            UVES_MASTER_DARK(chip1),
00490                            UVES_MASTER_DARK(chip2)) 
00491                 &&
00492                 is_missing(fms,
00493                            UVES_MASTER_PDARK(chip1),
00494                            UVES_MASTER_PDARK(chip2))
00495                 &&(
00496                     !is_missing(fms, UVES_DARK(blue), NULL) ||
00497                     !is_missing(fms, UVES_PDARK(blue), NULL));
00498             
00499             /* Run orderpos if either order table is missing, 
00500                or raw frame available */
00501             run_orderpos[blue] = is_missing(fms,
00502                                             UVES_ORDER_TABLE(flames, chip1),
00503                                             UVES_ORDER_TABLE(flames, chip2)
00504                 ) ||
00505                 !is_missing(fms, UVES_ORDER_FLAT(flames, blue), NULL);
00506             
00507             /* Run master flat recipe if master flat frame is missing */
00508             run_mflat[blue] = 
00509                 is_missing(fms,
00510                            UVES_MASTER_FLAT(chip1),
00511                            UVES_MASTER_FLAT(chip2))
00512                 &&
00513                 is_missing(fms,
00514                            UVES_MASTER_DFLAT(chip1),
00515                            UVES_MASTER_DFLAT(chip2))
00516                 &&
00517                 is_missing(fms,
00518                            UVES_MASTER_IFLAT(chip1),
00519                            UVES_MASTER_IFLAT(chip2))
00520                 &&
00521                 is_missing(fms,
00522                            UVES_MASTER_SCREEN_FLAT(chip1),
00523                            UVES_MASTER_SCREEN_FLAT(chip2))
00524                 &&
00525                 is_missing(fms,
00526                            UVES_REF_TFLAT(chip1),
00527                            UVES_REF_TFLAT(chip2));
00528             
00529             
00530             /* Line tables are used as both input and output
00531                for wavecal recipe. A provided line table is 
00532                interpreted as an input table if an arc lamp 
00533                frame is also available, otherwise as output.
00534                Line tables produce by the physmod recipe are
00535                input tables. The logic is
00536                
00537                if !linetable
00538                  physmod=yes
00539                  wavecal=yes
00540                if linetable
00541                  physmod=no
00542                  if !arclamp
00543                    wavecal=no   // line table is final
00544                  if arclamp
00545                    wavecal=yes  // line table is guess
00546             */
00547             
00548             /* Run physical model if there's no
00549                line table */
00550             run_physmod[blue] = is_missing(fms,
00551                                            UVES_LINE_TABLE(flames, chip1),
00552                                            UVES_LINE_TABLE(flames, chip2))
00553                 &&
00554         is_missing(fms,
00555                UVES_GUESS_LINE_TABLE(flames, chip1),
00556                UVES_GUESS_LINE_TABLE(flames, chip2))
00557                 &&
00558                 (
00559                     is_missing(fms,
00560                                UVES_LINE_TABLE_MIDAS(chip1, 1), 
00561                                UVES_LINE_TABLE_MIDAS(chip2, 1)) ||
00562                     is_missing(fms,
00563                                UVES_LINE_TABLE_MIDAS(chip1, 2),
00564                                UVES_LINE_TABLE_MIDAS(chip2, 2)) ||
00565                     is_missing(fms,
00566                                UVES_LINE_TABLE_MIDAS(chip1, 3),
00567                                UVES_LINE_TABLE_MIDAS(chip2, 3))
00568                     );
00569                     
00570             /* Run wavecal if no line table,
00571                or if there's an arc lamp frame
00572             */
00573             run_wavecal[blue] = 
00574                 run_physmod[blue]
00575                 ||
00576         (
00577             is_missing(fms,
00578                    UVES_LINE_TABLE(flames, chip1),
00579                    UVES_LINE_TABLE(flames, chip2))
00580             &&
00581             (
00582             is_missing(fms,
00583                    UVES_LINE_TABLE_MIDAS(chip1, 1), 
00584                    UVES_LINE_TABLE_MIDAS(chip2, 1)) ||
00585             is_missing(fms,
00586                    UVES_LINE_TABLE_MIDAS(chip1, 2),
00587                    UVES_LINE_TABLE_MIDAS(chip2, 2)) ||
00588             is_missing(fms,
00589                    UVES_LINE_TABLE_MIDAS(chip1, 3),
00590                    UVES_LINE_TABLE_MIDAS(chip2, 3))
00591             )
00592             )
00593         ||
00594         (
00595             !is_missing(fms,
00596                                 UVES_ARC_LAMP(flames, blue), NULL) ||
00597                     !is_missing(fms,
00598                                 UVES_ECH_ARC_LAMP(blue), NULL)
00599                     );
00600         
00601             /* Run response only if there's a standard star.
00602                Otherwise no response correction is done */
00603             run_response[blue] = !is_missing(fms,
00604                                              UVES_STD_STAR(blue), NULL);
00605                     
00606                     
00607             uves_msg("Reduction strategy for %s arm:", (blue) ? "BLUE" : "RED");
00608             uves_msg("Run %-13s: %s", make_str(UVES_MBIAS_ID)   , (run_mbias[blue]   ) ? "Yes" : "No");
00609             uves_msg("Run %-13s: %s", make_str(UVES_MDARK_ID)   , (run_mdark[blue]   ) ? "Yes" : "No");
00610             uves_msg("Run %-13s: %s", make_str(UVES_PHYSMOD_ID) , (run_physmod[blue] ) ? "Yes" : "No");
00611             uves_msg("Run %-13s: %s", make_str(UVES_ORDERPOS_ID), (run_orderpos[blue]) ? "Yes" : "No");
00612             uves_msg("Run %-13s: %s", make_str(UVES_MFLAT_ID)   , (run_mflat[blue]   ) ? "Yes" : "No");
00613             uves_msg("Run %-13s: %s", make_str(UVES_WAVECAL_ID) , (run_wavecal[blue] ) ? "Yes" : "No");
00614             uves_msg("Run %-13s: %s", make_str(UVES_RESPONSE_ID), (run_response[blue]) ? "Yes" : "No");
00615             uves_msg("Run %-13s: %s", make_str(UVES_SCIRED_ID)  , (run_scired[blue]  ) ? "Yes" : "No");
00616     
00617         }  /* if reduce this arm */
00618         else {
00619             uves_msg("Skipping %s arm", 
00620                      (blue) ? "BLUE" : "RED");
00621 
00622             run_mbias[blue] = false;
00623             run_mdark[blue] = false;
00624             run_mflat[blue] = false;
00625             run_physmod[blue] = false;
00626             run_orderpos[blue] = false;
00627             run_wavecal[blue] = false;
00628             run_response[blue] = false;
00629         }
00630             
00631         blue = !blue;
00632     }
00633     while (!blue);
00634 
00635     /* As a service to the user, assure that required
00636        raw frames and catalogue calibration frames
00637        exist *before* doing the reduction */
00638     
00639     blue = true;
00640     do
00641         {
00642             cpl_frameset *fms = (blue) ? blue_frames : red_frames;
00643 
00644             assure( !run_mbias[blue] || !is_missing(fms, UVES_BIAS(blue), NULL), 
00645                     CPL_ERROR_DATA_NOT_FOUND,
00646                     "One or more '%s' frames needed for recipe '%s'",
00647                     UVES_BIAS(blue), make_str(UVES_MBIAS_ID));
00648             
00649             assure( !run_mdark[blue] || 
00650                     !is_missing(fms, UVES_DARK(blue), NULL) ||
00651                     !is_missing(fms, UVES_PDARK(blue), NULL),
00652                     CPL_ERROR_DATA_NOT_FOUND, 
00653                     "One or more '%s' or '%s' frames needed for recipe '%s'",
00654                     UVES_DARK(blue), UVES_PDARK(blue), make_str(UVES_MDARK_ID));
00655             
00656             assure( !run_physmod[blue] || !is_missing(fms, UVES_FORMATCHECK(flames, blue), NULL),
00657                     CPL_ERROR_DATA_NOT_FOUND, "Frame '%s' needed for recipe '%s'",
00658                     UVES_FORMATCHECK(flames, blue), make_str(UVES_PHYSMOD_ID));
00659             
00660             assure( !run_orderpos[blue] || !is_missing(fms, UVES_ORDER_FLAT(flames, blue), NULL),
00661                     CPL_ERROR_DATA_NOT_FOUND, "Frame '%s' needed for recipe '%s'",
00662                     UVES_ORDER_FLAT(flames, blue), make_str(UVES_ORDERPOS_ID));
00663             
00664             assure( !run_mflat[blue] || 
00665                     !is_missing(fms, UVES_FLAT(blue), NULL) ||
00666                     !is_missing(fms, UVES_IFLAT(blue), NULL) ||
00667                     !is_missing(fms, UVES_SCREEN_FLAT(blue), NULL) ||
00668                     !is_missing(fms, UVES_DFLAT(blue), NULL) ||
00669                     !is_missing(fms, UVES_TFLAT(blue), NULL),
00670                     CPL_ERROR_DATA_NOT_FOUND, 
00671                     "One or more '%s', '%s', '%s', '%s' or '%s' frames needed for recipe '%s'",
00672                     UVES_FLAT(blue), 
00673                     UVES_IFLAT(blue), 
00674                     UVES_SCREEN_FLAT(blue), 
00675                     UVES_DFLAT(blue), 
00676                     UVES_TFLAT(blue), 
00677                     make_str(UVES_MFLAT_ID));
00678             
00679             assure( !run_wavecal[blue] || (
00680                         !is_missing(fms, UVES_ARC_LAMP(flames, blue), NULL) ||
00681                         !is_missing(fms, UVES_ECH_ARC_LAMP(blue), NULL)),
00682                     CPL_ERROR_DATA_NOT_FOUND, "Frame '%s' or '%s' needed for recipe '%s'",
00683                     UVES_ARC_LAMP(flames, blue), UVES_ECH_ARC_LAMP(blue), make_str(UVES_WAVECAL_ID));
00684             assure( !run_wavecal[blue] || !is_missing(fms, UVES_LINE_REFER_TABLE, NULL),
00685                     CPL_ERROR_DATA_NOT_FOUND, "Frame '%s' needed for recipe '%s'",
00686                     UVES_LINE_REFER_TABLE, make_str(UVES_WAVECAL_ID));
00687             
00688             assure( !run_response[blue] || !is_missing(fms, UVES_STD_STAR(blue), NULL), 
00689                     CPL_ERROR_DATA_NOT_FOUND, "Frame '%s' needed for recipe '%s'",
00690                     UVES_STD_STAR(blue), make_str(UVES_RESPONSE_ID));
00691             assure( !run_response[blue] || !is_missing(fms, UVES_FLUX_STD_TABLE, NULL), 
00692                     CPL_ERROR_DATA_NOT_FOUND, "Frame '%s' needed for recipe '%s'",
00693                     UVES_FLUX_STD_TABLE, make_str(UVES_RESPONSE_ID));
00694             assure( !run_response[blue] || !is_missing(fms, UVES_EXTCOEFF_TABLE, NULL), 
00695                     CPL_ERROR_DATA_NOT_FOUND, "Frame '%s' needed for recipe '%s'",
00696                     UVES_EXTCOEFF_TABLE, make_str(UVES_RESPONSE_ID));
00697             
00698             blue = !blue;
00699         }
00700     while (!blue);
00701    
00702     /* We now know which recipes to run and
00703      * that required input frames exist. Execute
00704      * chain; re-classify PRODUCT->CALIB under way
00705      */
00706     
00707     blue = true;
00708     do
00709         {
00710             enum uves_chip chip1 = (blue) ? UVES_CHIP_BLUE : UVES_CHIP_REDL;
00711             enum uves_chip chip2 = (blue) ? UVES_CHIP_BLUE : UVES_CHIP_REDU;
00712 
00713             cpl_frameset *fms = (blue) ? blue_frames : red_frames;
00714 
00715             if (run_mbias[blue])
00716                 {
00717                     const char *products[2];
00718                     
00719                     int nprod = sizeof(products) / sizeof (char *);
00720                     
00721                     products[0] = UVES_MASTER_BIAS(chip1);
00722                     products[1] = UVES_MASTER_BIAS(chip2);
00723                     
00724                     if (blue) nprod /= 2;
00725                     
00726                     check( execute_recipe(make_str(UVES_MBIAS_ID), fms, parameters, products, nprod, true),
00727                            "Recipe execution failed");
00728                 }
00729             
00730             check( remove_input_frame(fms, UVES_BIAS(blue)), "Error removing input frames");
00731             
00732             if (run_mdark[blue])
00733                 {
00734                     const char *products[4];
00735                     
00736                     int nprod = sizeof(products) / sizeof (char *);
00737                     
00738                     products[0] = UVES_MASTER_DARK(chip1);
00739                     products[1] = UVES_MASTER_PDARK(chip1);
00740                     products[2] = UVES_MASTER_DARK(chip2);
00741                     products[3] = UVES_MASTER_PDARK(chip2);
00742                     
00743                     if (blue) nprod /= 2;
00744 
00745                     check( execute_recipe(
00746                                make_str(UVES_MDARK_ID), fms, parameters, products, nprod, true), 
00747                            "Recipe execution failed");
00748                 }
00749             
00750             check( remove_input_frame(fms, UVES_DARK(blue)), "Error removing input frames");
00751             check( remove_input_frame(fms, UVES_PDARK(blue)), "Error removing input frames");
00752             
00753             if (run_physmod[blue])
00754                 {
00755                     const char *products[4];
00756                     int nprod = sizeof(products) / sizeof (char *);
00757                     
00758                     products[0] = UVES_GUESS_LINE_TABLE (flames, chip1);
00759                     products[1] = UVES_GUESS_ORDER_TABLE(flames, chip1);
00760                     products[2] = UVES_GUESS_LINE_TABLE (flames, chip2);
00761                     products[3] = UVES_GUESS_ORDER_TABLE(flames, chip2);
00762                     
00763                     if (blue) nprod /= 2;
00764                     
00765                     check( execute_recipe(
00766                                make_str(UVES_PHYSMOD_ID), 
00767                                fms, parameters, products, nprod, true), 
00768                            "Recipe execution failed");
00769                 }
00770             
00771             check( remove_input_frame(fms, UVES_FORMATCHECK(flames, blue)), 
00772                    "Error removing input frames");
00773             
00774             if (run_orderpos[blue])
00775                 {
00776                     const char *products[2];
00777                     int nprod = sizeof(products) / sizeof (char *);
00778                     
00779                     products[0] = UVES_ORDER_TABLE(flames, chip1);
00780                     products[1] = UVES_ORDER_TABLE(flames, chip2);
00781                     
00782                     if (blue) nprod /= 2;
00783                             
00784                     check( execute_recipe(
00785                                make_str(UVES_ORDERPOS_ID), 
00786                                fms, parameters, products, nprod, true), 
00787                            "Recipe execution failed");
00788                 }
00789 
00790             check( remove_input_frame(fms, UVES_ORDER_FLAT(flames, blue)),
00791                    "Error removing input frames");
00792                     
00793             if (run_mflat[blue])
00794                 {
00795                     const char *products[10];
00796                             
00797                     int nprod = sizeof(products) / sizeof (char *);
00798 
00799                     products[0] = UVES_MASTER_FLAT(chip1);
00800                     products[1] = UVES_MASTER_DFLAT(chip1);
00801                     products[2] = UVES_MASTER_IFLAT(chip1);
00802                     products[3] = UVES_MASTER_TFLAT(chip1);
00803                     products[4] = UVES_MASTER_SCREEN_FLAT(chip1);
00804                     products[5] = UVES_MASTER_FLAT(chip2);
00805                     products[6] = UVES_MASTER_DFLAT(chip2);
00806                     products[7] = UVES_MASTER_IFLAT(chip2);
00807                     products[8] = UVES_MASTER_TFLAT(chip2);
00808                     products[9] = UVES_MASTER_SCREEN_FLAT(chip2);
00809                             
00810                     if (blue) nprod /= 2;
00811                             
00812                     check( execute_recipe(make_str(UVES_MFLAT_ID), 
00813                                           fms, parameters, products, nprod, true), 
00814                            "Recipe execution failed");
00815                 }
00816                     
00817             check( remove_input_frame(fms, UVES_FLAT(blue)), "Error removing input frames");
00818             check( remove_input_frame(fms, UVES_IFLAT(blue)), "Error removing input frames");
00819             check( remove_input_frame(fms, UVES_DFLAT(blue)), "Error removing input frames");
00820             check( remove_input_frame(fms, UVES_TFLAT(blue)), "Error removing input frames");
00821             check( remove_input_frame(fms, UVES_SCREEN_FLAT(blue)), "Error removing input frames");
00822                     
00823             if (run_wavecal[blue])
00824                 {
00825                     const char *products[2];
00826                             
00827                     int nprod = sizeof(products) / sizeof (char *);
00828 
00829                     products[0] = UVES_LINE_TABLE(flames, chip1);
00830                     products[1] = UVES_LINE_TABLE(flames, chip2);
00831                             
00832                     if (blue) nprod /= 2;
00833                     
00834                     check( execute_recipe(make_str(UVES_WAVECAL_ID), 
00835                                           fms, parameters, products, nprod, true), 
00836                            "Recipe execution failed");
00837                 }
00838 
00839             check( remove_input_frame(fms, UVES_ARC_LAMP(flames, blue)), 
00840            "Error removing input frames");
00841             check( remove_input_frame(fms, UVES_ECH_ARC_LAMP(blue)), 
00842            "Error removing input frames");
00843             check( remove_input_frame(fms, UVES_LINE_REFER_TABLE), 
00844            "Error removing input frames");
00845                     
00846             if (run_response[blue])
00847                 {
00848                     const char *products[2];
00849                             
00850                     int nprod = sizeof(products) / sizeof (char *);
00851 
00852                     products[0] = UVES_INSTR_RESPONSE(chip1);
00853                     products[1] = UVES_INSTR_RESPONSE(chip2);
00854                             
00855                     if (blue) nprod /= 2;
00856                             
00857                     check( execute_recipe(make_str(UVES_RESPONSE_ID), 
00858                                           fms, parameters, products, nprod, true),
00859                            "Recipe execution failed");
00860                 }
00861 
00862             check( remove_input_frame(fms, UVES_STD_STAR(blue)), "Error removing input frames");
00863             check( remove_input_frame(fms, UVES_FLUX_STD_TABLE), "Error removing input frames");
00864 
00865             if (run_scired[blue])
00866                 {
00867                     const char *products[2];
00868                             
00869                     int nprod = sizeof(products) / sizeof (char *);
00870 
00871                     products[0] = blue ? "RED_SCIENCE_BLUE" : "RED_SCIENCE_REDL";
00872                     products[1] = blue ? "RED_SCIENCE_BLUE" : "RED_SCIENCE_REDU";
00873                             
00874                     if (blue) nprod /= 2;
00875 
00876                     check( execute_recipe(make_str(UVES_SCIRED_ID), 
00877                                           fms, parameters, products, nprod, false),
00878                            "Recipe execution failed");
00879                 }
00880                     
00881             check( remove_input_frame(fms, UVES_SCIENCE(blue))   , "Error removing input frames");
00882             check( remove_input_frame(fms, UVES_SCI_EXTND(blue)) , "Error removing input frames");
00883             check( remove_input_frame(fms, UVES_SCI_POINT(blue)) , "Error removing input frames");
00884             check( remove_input_frame(fms, UVES_SCI_SLICER(blue)), "Error removing input frames");
00885                     
00886             /* Insert all product frames into recipe frame set */
00887             {
00888                 cpl_frame *f = NULL;
00889                 
00890                 for (f = cpl_frameset_get_first(fms);
00891                      f != NULL;
00892                      f = cpl_frameset_get_next(fms))
00893                     {
00894                         if (cpl_frame_get_group(f) == CPL_FRAME_GROUP_PRODUCT)
00895                             {
00896                                 check( cpl_frameset_insert(frames, cpl_frame_duplicate(f)),
00897                                        "Error inserting product '%s' into frame set",
00898                                        cpl_frame_get_tag(f));
00899                             }
00900                     }
00901             }
00902             
00903             blue = !blue;
00904         }
00905     while(!blue);     /* For each arm */
00906     
00907   cleanup:
00908     uves_free_frameset(&blue_frames);
00909     uves_free_frameset(&red_frames);
00910     uves_free_frameset(&common_frames);
00911 
00912     return;
00913 }
00914 
00915 /* Returns true, iff frame is used for blue/red arm
00916    (note that some frames like UVES_FLUX_STD_TABLE are
00917    used for both arms) */
00918 static bool
00919 frame_is_needed(bool blue, const cpl_frame *f)
00920 {
00921     const char *tag = cpl_frame_get_tag(f);
00922     
00923     bool result = (strcmp(tag, UVES_ORDER_FLAT (flames, blue)) == 0 ||
00924                    strcmp(tag, UVES_BIAS       (blue)) == 0 ||
00925                    strcmp(tag, UVES_DARK       (blue)) == 0 ||
00926                    strcmp(tag, UVES_PDARK      (blue)) == 0 ||
00927                    strcmp(tag, UVES_FLAT       (blue)) == 0 ||
00928                    strcmp(tag, UVES_IFLAT      (blue)) == 0 ||
00929                    strcmp(tag, UVES_DFLAT      (blue)) == 0 ||
00930                    strcmp(tag, UVES_TFLAT      (blue)) == 0 ||
00931                    strcmp(tag, UVES_SCREEN_FLAT(blue)) == 0 ||
00932                    strcmp(tag, UVES_STD_STAR   (blue)) == 0 ||
00933                    strcmp(tag, UVES_FORMATCHECK(flames, blue)) == 0 ||
00934                    strcmp(tag, UVES_STD_STAR   (blue)) == 0 ||
00935                    strcmp(tag, UVES_SCIENCE    (blue)) == 0 ||
00936                    strcmp(tag, UVES_SCI_EXTND  (blue)) == 0 ||
00937                    strcmp(tag, UVES_SCI_POINT  (blue)) == 0 ||
00938                    strcmp(tag, UVES_SCI_SLICER (blue)) == 0 ||
00939                    strcmp(tag, UVES_ARC_LAMP   (flames, blue)) == 0 ||
00940                    strcmp(tag, UVES_ECH_ARC_LAMP(blue)) == 0);
00941     
00942     enum uves_chip chip;
00943     
00944     /* Loop through all blue or red chips  (1 or 2) */
00945     for (chip = uves_chip_get_first(blue); 
00946          chip != UVES_CHIP_INVALID; 
00947          chip = uves_chip_get_next(chip))
00948         {
00949             result = result || (strcmp(tag, UVES_DRS_SETUP(flames, chip)) == 0 ||
00950                                 strcmp(tag, UVES_ORDER_TABLE(flames, chip)) == 0 ||
00951                                 strcmp(tag, UVES_GUESS_ORDER_TABLE(flames, chip)) == 0 ||
00952                                 strcmp(tag, UVES_MASTER_BIAS(chip)) == 0 ||
00953                                 strcmp(tag, UVES_MASTER_DARK(chip)) == 0 ||
00954                                 strcmp(tag, UVES_MASTER_PDARK(chip)) == 0 ||
00955                                 strcmp(tag, UVES_MASTER_FLAT(chip)) == 0 ||
00956                                 strcmp(tag, UVES_MASTER_DFLAT(chip)) == 0 ||
00957                                 strcmp(tag, UVES_MASTER_IFLAT(chip)) == 0 ||
00958                                 strcmp(tag, UVES_MASTER_TFLAT(chip)) == 0 ||
00959                                 strcmp(tag, UVES_REF_TFLAT(chip)) == 0 ||
00960                                 strcmp(tag, UVES_MASTER_SCREEN_FLAT(chip)) == 0 ||
00961                                 strcmp(tag, UVES_LINE_TABLE (flames, chip)) == 0 ||
00962                                 strcmp(tag, UVES_GUESS_LINE_TABLE(flames, chip)) == 0 ||
00963                                 strcmp(tag, UVES_LINE_TABLE_MIDAS(chip, 1)) == 0 ||
00964                                 strcmp(tag, UVES_LINE_TABLE_MIDAS(chip, 2)) == 0 ||
00965                                 strcmp(tag, UVES_LINE_TABLE_MIDAS(chip, 3)) == 0 ||
00966                                 strcmp(tag, UVES_LINE_REFER_TABLE ) == 0 ||
00967                                 strcmp(tag, UVES_FLUX_STD_TABLE   ) == 0 ||
00968                                 strcmp(tag, UVES_EXTCOEFF_TABLE   ) == 0);
00969         }
00970     return result;
00971 }
00972 
00973 /* Execute a recipe and re-classify its products as calibration frames */
00974 static cpl_error_code
00975 execute_recipe(const char *recipe_id, 
00976                cpl_frameset *frames, const cpl_parameterlist *parameters,
00977                const char *products[],
00978                int n_products,
00979                bool reclassify)              /* Re-classify products? */
00980 {
00981   int i;
00982   cpl_frame *f = NULL;
00983 
00984   /* Remove (from frame set) any product
00985      frames already present */
00986   for (i = 0; i < n_products; i++)
00987       {
00988           if ((f = cpl_frameset_find(frames, products[i])) != NULL)
00989               {
00990                   if (cpl_frame_get_group(f) == CPL_FRAME_GROUP_PRODUCT)
00991                       {
00992                           cpl_msg_warning(__func__, "Ignoring %s frame in '%s'. "
00993                                           "A new %s frame will now be calculated",
00994                                           products[i], cpl_frame_get_filename(f),
00995                                           products[i]);
00996                           
00997                           cpl_frameset_erase_frame(frames, f);
00998                       }
00999               }
01000       }
01001   
01002   /* Execute */
01003   check( uves_invoke_recipe(recipe_id, parameters, frames, make_str(UVES_REDCHAIN_ID), NULL),
01004          "Recipe '%s' failed", recipe_id);
01005             
01006   check(cpl_dfs_update_product_header(frames),"Error updating pipe products' header");
01007   if (reclassify)
01008       {
01009           /* Now re-classify PRODUCT->CALIB to be used in the remaining
01010              reduction chain. Before doing that, we have to remove any
01011              calibration frame with same tag as a product (such as line tables),
01012              in order not to confuse the re-classified products with the
01013              previous calibration frames */
01014           
01015           for (i = 0; i < n_products; i++)
01016               {
01017                   if ((f = cpl_frameset_find(frames, products[i])) != NULL &&
01018                       cpl_frame_get_group(f) != CPL_FRAME_GROUP_PRODUCT)
01019                       {
01020                           uves_msg("Removing %s frame in '%s' from frameset. "
01021                                    "It is not tagged as a product",
01022                                    products[i], cpl_frame_get_filename(f));
01023                           
01024                           cpl_frameset_erase_frame(frames, f);
01025                       }
01026               }
01027           
01028           /*
01029            * Re-classify products
01030            */
01031           for (i = 0; i < n_products; i++)
01032               {
01033                   cpl_frame *found = NULL;
01034                   for (f = cpl_frameset_get_first(frames);
01035                        f != NULL;
01036                        f = cpl_frameset_get_next(frames))
01037                       {
01038                           if (cpl_frame_get_group(f) == CPL_FRAME_GROUP_PRODUCT)
01039                               {
01040                                   if (strcmp(cpl_frame_get_tag(f), products[i]) == 0)
01041                                       {
01042                                           found = f;
01043                                       }
01044                               }
01045                       }
01046                   
01047                   if (found != NULL)
01048                       {
01049                           /* Re-classify the product as calibration frames */
01050                           uves_msg("Re-classifying %s product in '%s' PRODUCT->CALIB",
01051                                    products[i], cpl_frame_get_filename(found));
01052                           
01053                           cpl_frame_set_group(found, CPL_FRAME_GROUP_CALIB);
01054                       }
01055               }
01056           
01057           /*
01058            * Remove other products that 
01059            * are not used later  (e.g. BKG_FLAT_xxxx)
01060            */
01061           for (f = cpl_frameset_get_first(frames);
01062                f != NULL;
01063                f = cpl_frameset_get_next(frames))
01064               {
01065                   if (cpl_frame_get_group(f) == CPL_FRAME_GROUP_PRODUCT)
01066                       {
01067                           /* Remove this product */
01068                           uves_msg("Removing product %s in '%s' from frameset. "
01069                                    "Not needed later",
01070                                    cpl_frame_get_tag(f), cpl_frame_get_filename(f));
01071                           
01072                           cpl_frameset_erase_frame(frames, f);
01073                           
01074                       }
01075               }  
01076       } /* if re-classify... */  
01077 
01078   cleanup:
01079   return cpl_error_get_code();
01080 }
01081   
01082 
01083 /* Retruns true if either frame 1 or frame 2 is not in the
01084    provided frame set 
01085 
01086    fixme: reverse the logic of this function, i.e. rename to 'contains'
01087 */
01088 static bool
01089 is_missing(const cpl_frameset *frames, const char *frame1, const char *frame2)
01090 {
01091     bool result = false;
01092     if (cpl_frameset_find_const(frames, frame1) == NULL)
01093         {
01094             uves_msg("checking for %s... no", frame1);
01095             result = true;
01096         }
01097     else
01098         {
01099             uves_msg("checking for %s... yes", frame1);
01100         }
01101     
01102     if (frame2 != NULL && strcmp(frame1, frame2) != 0)
01103         {
01104             if (cpl_frameset_find_const(frames, frame2) == NULL)
01105                 {
01106                     uves_msg("checking for %s... no", frame2);
01107                     result = true;
01108                 }
01109             else
01110                 {
01111                     uves_msg("checking for %s... yes", frame2);
01112                 }
01113         }
01114     
01115   return result;
01116 }
01117 
01118 
01119 /* Remove input frames (e.g. bias frames) along the way */
01120 static void
01121 remove_input_frame(cpl_frameset *frames, const char *tag)
01122 {
01123     int removed = cpl_frameset_erase(frames, tag);
01124 
01125     if (removed > 0)
01126         {
01127             uves_msg("Removing %d %s frame(s) from frame set", removed, tag);
01128         }
01129 
01130     return;
01131 }

Generated on Thu Nov 15 14:32:30 2007 for UVES Pipeline Reference Manual by  doxygen 1.5.1