/* @file pmBias.h
 * @brief Subtract the overscan, bias and dark
 *
 * @author George Gusciora, MHPCC
 * @author Paul Price, IfA
 *
 * @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
 * @date $Date: 2007-01-24 02:54:15 $
 * Copyright 2004--2006 Institute for Astronomy, University of Hawaii
 */

#ifndef PM__BIAS_H
#define PM__BIAS_H

/// @addtogroup detrend Detrend Creation and Application
/// @{

#include <pslib.h>

#include "pmFPA.h"

/// Type of fit to perform
typedef enum {
    PM_FIT_NONE,                        ///< No fit
    PM_FIT_POLY_ORD,                    ///< Fit ordinary polynomial
    PM_FIT_POLY_CHEBY,                  ///< Fit Chebyshev polynomial
    PM_FIT_SPLINE                       ///< Fit cubic splines
} pmFit;

/// Options for overscan subtraction
///
/// The overscan subtraction may be performed by reducing all overscan regions to a single value (e.g., if
/// there is no structure); or the overscan may be fit perpendicular to the read direction (usually the
/// columns) with a particular functional form; or a single value may be subtracted for each read/scan without
/// fitting (if the structure defies characterisation).  In any case, statistics are required to reduce
/// multiple values to a single value (either for the scan, or for the entire overscan regions).
typedef struct
{
    // Inputs
    bool single;                ///< Reduce all overscan regions to a single value?
    pmFit fitType;              ///< Type of fit to overscan
    unsigned int order;         ///< Order of polynomial, or number of spline pieces
    psStats *stat;              ///< Statistic to use when reducing the minor direction
    // Outputs
    psPolynomial1D *poly;       ///< Result of polynomial fit
    psSpline1D *spline;         ///< Result of spline fit
}
pmOverscanOptions;

/// Allocator for overscan options
pmOverscanOptions *pmOverscanOptionsAlloc(bool single, ///< Reduce all overscan regions to a single value?
        pmFit fitType, ///< Type of fit to overscan
        unsigned int order, ///< Order of polynomial, or number of splines
        psStats *stat ///< Statistic to use
                                         );

/// Subtract the overscan, bias and/or dark
///
/// Subtracts the overscan, as measured from the bias member of the input readout (if options are non-NULL),
/// bias (if non-NULL) and dark (if non-NULL) scaled by the CELL.DARKTIME concept.
bool pmBiasSubtract(pmReadout *in,      ///< Input readout, to be overscan/bias/dark corrected
                    pmOverscanOptions *overscanOpts, ///< Options for overscan subtraction, or NULL
                    const pmReadout *bias, ///< Bias image to subtract, or NULL
                    const pmReadout *dark ///< Dark image to scale and subtract, or NULL
                   );

/// @}
#endif
