/*                                                                              *
 *   This file is part of the ESO UVES Pipeline                                 *
 *   Copyright (C) 2004,2005 European Southern Observatory                      *
 *                                                                              *
 *   This library is free software; you can redistribute it and/or modify       *
 *   it under the terms of the GNU General Public License as published by       *
 *   the Free Software Foundation; either version 2 of the License, or          *
 *   (at your option) any later version.                                        *
 *                                                                              *
 *   This program is distributed in the hope that it will be useful,            *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of             *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
 *   GNU General Public License for more details.                               *
 *                                                                              *
 *   You should have received a copy of the GNU General Public License          *
 *   along with this program; if not, write to the Free Software                *
 *   Foundation, 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA          *
 */
 
/*
 * $Author: amodigli $
 * $Date: 2010-12-16 16:57:23 $
 * $Revision: 1.11 $
 * $Name: not supported by cvs2svn $
 * $Log: not supported by cvs2svn $
 * Revision 1.10  2010/09/24 09:32:02  amodigli
 * put back QFITS dependency to fix problem spot by NRI on FIBER mode (with MIDAS calibs) data
 *
 * Revision 1.8  2010/06/11 11:39:14  amodigli
 * added bias (stack) and qcdark parameters in input params
 *
 * Revision 1.7  2008/03/28 08:53:36  amodigli
 * IRPLIB_CONCAT2X-->UVES_CONCAT2X
 *
 * Revision 1.6  2007/08/21 13:08:26  jmlarsen
 * Removed irplib_access module, largely deprecated by CPL-4
 *
 * Revision 1.5  2007/06/11 13:28:26  jmlarsen
 * Changed recipe contact address to cpl at eso.org
 *
 * Revision 1.4  2007/06/08 13:06:16  jmlarsen
 * Send bug reports to Andrea
 *
 * Revision 1.3  2007/06/06 08:17:33  amodigli
 * replace tab with 4 spaces
 *
 * Revision 1.2  2007/05/14 08:09:48  amodigli
 * updated input frames and tag description in recipe man page
 *
 * Revision 1.1  2007/02/09 13:34:25  jmlarsen
 * Added mkmaster+spatred recipes
 *
 * Revision 1.37  2006/12/08 07:41:43  jmlarsen
 * Minor doc. change
 *
 * Revision 1.36  2006/11/15 15:02:14  jmlarsen
 * Implemented const safe workarounds for CPL functions
 *
 * Revision 1.34  2006/11/15 14:04:08  jmlarsen
 * Removed non-const version of parameterlist_get_first/last/next which is already
 * in CPL, added const-safe wrapper, unwrapper and deallocator functions
 *
 * Revision 1.33  2006/11/15 08:57:32  amodigli
 * clearer message on slit FF encoder positions
 *
 * Revision 1.32  2006/11/13 12:45:32  jmlarsen
 * Count SFLAT sets from 1 rather than 0
 *
 * Revision 1.31  2006/11/06 15:19:41  jmlarsen
 * Removed unused include directives
 *
 * Revision 1.30  2006/11/03 14:57:44  jmlarsen
 * Changed message
 *
 * Revision 1.29  2006/10/17 12:33:02  jmlarsen
 * Added semicolon at UVES_RECIPE_DEFINE invocation
 *
 * Revision 1.28  2006/10/09 13:01:13  jmlarsen
 * Use macro to define recipe interface functions
 *
 * Revision 1.27  2006/09/27 13:20:51  jmlarsen
 * Factored out flat reduction
 *
 * Revision 1.26  2006/09/19 14:31:20  jmlarsen
 * uves_insert_frame(): use bitmap to specify which image statistics keywords must be computed
 *
 * Revision 1.25  2006/09/19 06:55:58  jmlarsen
 * Changed interface of uves_frameset to optionally write image statistics kewwords
 *
 * Revision 1.24  2006/09/14 08:46:51  jmlarsen
 * Added support for TFLAT, SCREEN_FLAT frames
 *
 * Revision 1.23  2006/08/24 11:36:37  jmlarsen
 * Write recipe start/stop time to header
 *
 * Revision 1.22  2006/08/17 13:56:53  jmlarsen
 * Reduced max line length
 *
 * Revision 1.21  2006/08/11 14:56:05  amodigli
 * removed Doxygen warnings
 *
 * Revision 1.20  2006/07/14 12:19:28  jmlarsen
 * Support multiple QC tests per product
 *
 * Revision 1.19  2006/07/03 13:09:24  amodigli
 * adjusted description display layout
 *
 * Revision 1.18  2006/07/03 13:02:18  jmlarsen
 * Threshold to zero after bias subtraction
 *
 * Revision 1.17  2006/06/16 08:25:45  jmlarsen
 * Manually propagate ESO.DET. keywords from 1st/2nd input header
 *
 * Revision 1.16  2006/06/13 11:57:02  jmlarsen
 * Check that calibration frames are from the same chip ID
 *
 * Revision 1.15  2006/06/01 14:21:27  amodigli
 * frm --> frm_tmp, dup --> frm_dup
 *
 * Revision 1.14  2006/06/01 12:02:56  jmlarsen
 * Return proper error_code in the function uves_mflat
 *
 * Revision 1.13  2006/05/22 10:01:04  amodigli
 * fixed some bug in msflat generation
 *
 * Revision 1.12  2006/05/22 06:47:15  amodigli
 * fixed some bugs on msflat
 *
 * Revision 1.10  2006/05/19 13:07:52  amodigli
 * modified to support SFLATs
 *
 * Revision 1.9  2006/05/17 09:58:25  amodigli
 * fixed warning
 *
 * Revision 1.8  2006/05/17 09:56:36  amodigli
 * fixed syntax bug
 *
 * Revision 1.7  2006/05/17 09:54:55  amodigli
 * added supposr SFLATs
 *
 * Revision 1.6  2006/05/09 07:42:18  amodigli
 * added QC-LOG
 *
 * Revision 1.5  2006/04/06 12:57:43  jmlarsen
 * Added support for IFLAT, DFLAT -> MASTER_IFLAT, MASTER_DFLAT frames
 *
 * Revision 1.4  2006/04/06 09:48:15  amodigli
 * changed uves_frameset_insert interface to have QC log
 *
 * Revision 1.3  2006/04/06 08:37:48  jmlarsen
 * Support reading MASTER_PDARK
 *
 * Revision 1.2  2006/03/24 14:15:18  jmlarsen
 * Save intermediate result to disk
 *
 * Revision 1.1  2006/02/03 07:46:30  jmlarsen
 * Moved recipe implementations to ./uves directory
 *
 * Revision 1.39  2006/01/19 08:47:24  jmlarsen
 * Inserted missing doxygen end tag
 *
 * Revision 1.38  2005/12/19 16:17:55  jmlarsen
 * Replaced bool -> int
 *
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

/*----------------------------------------------------------------------------*/
/**
 * @defgroup uves_cal_mkmaster    Recipe: Make master
 *
 * This recipe calculates master bias/dark/flat frames.
 * See man-page for details.
 */
/*----------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------------
                                Includes
 -----------------------------------------------------------------------------*/

#include <uves_reduce_mflat.h>
#include <uves_mbias_impl.h>
#include <uves_mdark_impl.h>
#include <uves_dfs.h>
#include <uves_parameters.h>
#include <uves_recipe.h>
#include <uves.h>
#include <uves_error.h>

#include <cpl.h>

/*-----------------------------------------------------------------------------
                            Functions prototypes
 -----------------------------------------------------------------------------*/

static int uves_cal_mkmaster_define_parameters(cpl_parameterlist *parameters);

/*-----------------------------------------------------------------------------
                            Recipe standard code
 -----------------------------------------------------------------------------*/
#define cpl_plugin_get_info uves_cal_mkmaster_get_info
UVES_RECIPE_DEFINE(
    UVES_MKMASTER_ID, UVES_MKMASTER_DOM, uves_cal_mkmaster_define_parameters,
    "Jonas M. Larsen", "cpl@eso.org",
    "Creates the master bias/dark/flat frame",
    "This recipe calls " make_str(UVES_MBIAS_ID) " if any raw BIAS frame is provided\n"
    "otherwise " make_str(UVES_MDARK_ID) " if any raw DARK frame is provided, otherwise\n"
    "it calls " make_str(UVES_MFLAT_ID) " Pls refer to those recipes for more details\n");

/**@{*/
/*-----------------------------------------------------------------------------
                              Functions code
  -----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/**
  @brief    Setup the recipe options    
  @param    parameters        the parameterlist to fill
  @return   0 if everything is ok
 */
/*----------------------------------------------------------------------------*/
int
uves_cal_mkmaster_define_parameters(cpl_parameterlist *parameters)
{

   int result=0;
   if (uves_master_stack_define_parameters(parameters,
                                           make_str(UVES_MKMASTER_ID))
        != CPL_ERROR_NONE)
   {
      return -1;
   }

   check_nomsg(uves_qcdark_define_parameters_body(parameters,
                                            make_str(UVES_MKMASTER_ID)));
   result=uves_mflat_define_parameters_body(parameters, 
                         make_str(UVES_MKMASTER_ID));
  cleanup:
    return result;
    /* Warning: If parameters are added to mbias/mdark recipes, they need to
       be propagated to here. Now, just copy the parameters from mflat */
}

/*----------------------------------------------------------------------------*/
/**
   @brief    Get the command line options and execute the data reduction
   @param    frames      the frames list
   @param    parameters  the parameters list
   @param    starttime   start of execution
   @return   CPL_ERROR_NONE if everything is ok

*/
/*----------------------------------------------------------------------------*/
static void
UVES_CONCAT2X(UVES_MKMASTER_ID,exe)(cpl_frameset *frames, 
                   const cpl_parameterlist *parameters,
                   const char *starttime)
{
    int blue;
    bool found_bias = false;
    bool found_dark = false;
    bool found_flat = false;

    assure( frames != NULL, CPL_ERROR_NULL_INPUT, "Null frameset given!");
    
    for (blue = 0; blue <= 1; blue++)
    {
        found_bias = found_bias || cpl_frameset_find(frames, UVES_BIAS(blue));
        found_dark = found_dark || cpl_frameset_find(frames, UVES_DARK(blue));
        found_dark = found_dark || cpl_frameset_find(frames, UVES_PDARK(blue));
        found_flat = found_flat || cpl_frameset_find(frames, UVES_FLAT(blue));
        found_flat = found_flat || cpl_frameset_find(frames, UVES_IFLAT(blue));
        found_flat = found_flat || cpl_frameset_find(frames, UVES_DFLAT(blue));
        found_flat = found_flat || cpl_frameset_find(frames, UVES_SFLAT(blue));
        found_flat = found_flat || cpl_frameset_find(frames, UVES_TFLAT(blue));
        found_flat = found_flat || cpl_frameset_find(frames, UVES_SCREEN_FLAT(blue));
    }

    if (found_bias)
    {
        uves_msg("Bias frame(s) provided");
    }

    if (found_dark)
    {
        uves_msg("Dark frame(s) provided");
    }

    if (found_flat)
    {
        uves_msg("Flat frame(s) provided");
    }

    assure( found_bias || found_dark || found_flat,
        CPL_ERROR_DATA_NOT_FOUND,
        "Missing raw bias, dark or flat-field frames");

    if (found_bias && found_dark)
    {
        uves_msg_warning("Both bias and dark frames provided. Creating only master bias");
    }
    else if (found_bias && found_flat)
    {
        uves_msg_warning("Both bias and flat frames provided. Creating only master bias");
    }
    else if (found_dark && found_flat)
    {
        uves_msg_warning("Both dark and flat frames provided. Creating only master dark");
    }

    if (found_bias)
    {
        uves_mbias_exe_body(frames, parameters, starttime, make_str(UVES_MKMASTER_ID));
    }
    else if (found_dark)
    {
        uves_mdark_exe_body(frames, parameters, starttime, make_str(UVES_MKMASTER_ID));
    }
    else if (found_flat)
    {
        uves_mflat_exe_body(frames, parameters, starttime, make_str(UVES_MKMASTER_ID));
    }
    else
    {
        /* Impossible */
        passure( false, "%d %d %d", found_bias, found_dark, found_flat);
    }

  cleanup:
    return;
}

/**@}*/
