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

Generated on Mon Apr 21 10:56:56 2008 for UVES Pipeline Reference Manual by  doxygen 1.5.1