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

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