/* @file  pmObjects.h
 * @brief Functions to define and manipulate object models
 *
 * @author GLG, MHPCC
 * @author EAM, IfA
 *
 * @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
 * @date $Date: 2007-01-24 02:54:15 $
 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii
 */

# ifndef PM_MODEL_H
# define PM_MODEL_H

/// @addtogroup Objects Object Detection / Analysis Functions
/// @{

// type of model carried by the pmModel structure
typedef int pmModelType;

typedef enum {
    PM_MODEL_UNTRIED,   ///< model fit not yet attempted
    PM_MODEL_SUCCESS,   ///< model fit succeeded
    PM_MODEL_NONCONVERGE,  ///< model fit did not converge
    PM_MODEL_OFFIMAGE,   ///< model fit drove out of range
    PM_MODEL_BADARGS   ///< model fit called with invalid args
} pmModelStatus;

/** pmModel data structure
 *
 * Every source may have two types of models: a PSF model and a EXT (extended-source)
 * model. The PSF model represents the best fit of the image PSF to the specific
 * object. In this case, the PSF-dependent parameters are specified for the
 * object by the PSF, not by the fit. The EXT model represents the best fit of
 * the given model to the object, with all shape parameters floating in the fit.
 *
 */
typedef struct
{
    pmModelType type;   ///< Model to be used.
    psVector *params;   ///< Paramater values.
    psVector *dparams;   ///< Parameter errors.
    float chisq;   ///< Fit chi-squared.
    float chisqNorm;   ///< re-normalized fit chi-squared.
    int nDOF;    ///< number of degrees of freedom
    int nIter;    ///< number of iterations to reach min
    pmModelStatus status;  ///< fit status
    float radiusFit;   ///< fit radius actually used
}
pmModel;

/** Symbolic names for the elements of [d]params
 * Note: these are #defines not enums as a given element of [d]params
 * may/will correspond to different parameters in different contexts
 */
#define PM_PAR_SKY 0   ///< Sky
#define PM_PAR_I0 1   ///< Central intensity
#define PM_PAR_XPOS 2   ///< X centre of object
#define PM_PAR_YPOS 3   ///< Y centre of object
#define PM_PAR_SXX 4   ///< shape X^2 moment
#define PM_PAR_SYY 5   ///< shape Y^2 moment
#define PM_PAR_SXY 6   ///< shape XY moment
#define PM_PAR_7 7   ///< ??? Unknown parameter
#define PM_PAR_8 8   ///< ??? Unknown parameter

/** pmModelAlloc()
 *
 */
pmModel *pmModelAlloc(pmModelType type);

// copy model to a new structure
pmModel *pmModelCopy (pmModel *model);

psF32 pmModelEval(pmModel *model, psImage *image, psS32 col, psS32 row);

/** pmModelAdd()
 *
 * Add the given source model flux to/from the provided image. The boolean
 * option center selects if the source is re-centered to the image center or if
 * it is placed at its centroid location. The boolean option sky selects if the
 * background sky is applied (TRUE) or not. The pixel range in the target image
 * is at most the pixel range specified by the source.pixels image. The success
 * status is returned.
 *
 */
bool pmModelAdd(
    psImage *image,   ///< The output image (float)
    psImage *mask,   ///< The image pixel mask (valid == 0)
    pmModel *model,   ///< The input pmModel
    bool center,   ///< A boolean flag that determines whether pixels are centered
    bool sky    ///< A boolean flag that determines if the sky is subtracted
);


/** pmModelSub()
 *
 * Subtract the given source model flux to/from the provided image. The
 * boolean option center selects if the source is re-centered to the image center
 * or if it is placed at its centroid location. The boolean option sky selects if
 * the background sky is applied (TRUE) or not. The pixel range in the target
 * image is at most the pixel range specified by the source.pixels image. The
 * success status is returned.
 *
 */
bool pmModelSub(
    psImage *image,   ///< The output image (float)
    psImage *mask,   ///< The image pixel mask (valid == 0)
    pmModel *model,   ///< The input pmModel
    bool center,   ///< A boolean flag that determines whether pixels are centered
    bool sky    ///< A boolean flag that determines if the sky is subtracted
);

/** pmModelFitStatus()
 *
 * This function wraps the call to the model-specific function returned by
 * pmModelFitStatusFunc_GetFunction.  The model-specific function examines the
 * model parameters, parameter errors, Chisq, S/N, and other parameters available
 * from model to decide if the particular fit was successful or not.
 *
 * XXX: Must code this.
 *
 */
bool pmModelFitStatus(
    pmModel *model                      ///< Model to be used
);

/// @}
# endif /* PM_MODEL_H */
