
/** @file  psCCD.h
 *
 *  @brief Contains basic CCD image definitions and operations
 *
 *  This file defines the basic types for astronomical imagery, including
 *  the concepts of: Readout, Cell, Chip, Focal Plane, and Exposure Information.
 *
 *  @ingroup AstroImage
 *
 *  @author Robert DeSonia, MHPCC
 *
 *  @version $Revision: 1.1 $ $Name:  $
 *  @date $Date: 2004/07/16 02:15:51 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
 */

# ifndef PS_CCD_H
# define PS_CCD_H

#include "psType.h"
#include "psImage.h"
#include "psList.h"

typedef void psMetadata;        // not yet defined/implemented.
typedef void psPlaneTransform;  // not yet defined/implemented.
typedef void psPlaneDistort;    // not yet defined/implemented.
typedef void psFixedPattern;    // not yet defined/implemented.
typedef void psPhotSystem;      // not yet defined/implemented.

struct psCell;
struct psChip;
struct psFPA;
struct psExposure;

/// @addtogroup Image
/// @{

/** Readout data structure.
 *
 *  A readout is the result of a single read of a cell (or a portion thereof). 
 *  It contains a pointer to the pixel data, and additional pointers to the 
 *  objects found in the readout, and the readout metadata.  It also contains
 *  the offset from the lower-left corner of the chip, in the case that the
 *  CCD was windowed.
 *
 */
typedef struct
{
    const unsigned int colBins;        ///< Amount of binning in x-dimension
    const unsigned int rowBins;        ///< Amount of binning in y-dimension
    const int col0;                    ///< Offset from the left of chip.
    const int row0;                    ///< Offset from the bottom of chip.

    psImage* image;                    ///< imaging area of Readout
    psList*  objects;                  ///< objects derived from Readout
    psMetadata* metadata;              ///< readout-level metadata
}
psReadout;

/** Cell data structure
 * 
 *  A cell consists of one or more readouts.  It also contains a pointer to the
 *  cell's metadata, and its parent chip.  On the astrometry side, it also 
 *  contains coordinate transforms from the cell to chip, from the cell to 
 *  focal-plane, as well as a "quick and dirty" tranform from the cell to
 *  sky coordinates.
 *
 */
typedef struct psCell
{
    psArray* readouts;                 ///< readouts from the cell
    psMetadata* metadata;              ///< cell-level metadata

    psPlaneTransform* toChip;          ///< transformations from cell to chip coordinates
    psPlaneTransform* toFPA;           ///< transformations from cell to FPA coordinates
    psPlaneTransform* toSky;           ///< transformations from cell to sky coordinates

    struct psChip* parent;             ///< chip in which contains this cell
}
psCell;

/** Chip data structure
 *
 *  A chip consists of one or more cells (according to the number of amplifiers
 *  on the CCD). It contains a pointer to the chip's metadata, and a pointer    
 *  to the parent focal plane.  For astrometry, ot contains a coordinate
 *  transform from the chip to the focal plane, and vis-versa.
 *
 */
typedef struct psChip
{
    psArray* cells;                    ///< cells in the chip
    psMetadata* metadata;              ///< chip-level metadata

    psPlaneTransform* toFPA;           ///< transformation from chip to FPA coordinates
    psPlaneTransform* fromFPA;         ///< transformation from FPA to chip coordinates

    struct psFPA* parent;              ///< FPA which contains this chip
}
psChip;

/** A Focal-Plane
 *
 *  A focal plane consists of one or more chips (according to the number of
 *  contiguous silicon).  It contains pointers to the focal-plane's metadata
 *  and the exposure information.  For astrometry, it contains a transformation
 *  from the focal plane to the tangent plane and the fixed pattern residuals.
 *  Since colors are involved in the transformation, it is necessary to specify
 *  the color the transformation is defined.  We also include some values to
 *  characterize the quality of the transformation: the root square deviation
 *  for the x and y transformation fits, and the chi-squared for the 
 *  transformation fit.
 *
 */
typedef struct psFPA
{
    psArray* chips;                    ///< chips in the focal plane array
    psMetadata* metadata;              ///< focal-plane's metadata

    psPlaneDistort* fromTangentPlane;  ///< transformation from tangent plane to focal plane
    psPlaneDistort* toTangentPlane;    ///< transformation from focal plane to tangent plane
    psFixedPattern* pattern;           ///< fixed pattern residual offsets

    const struct psExposure* exposure; ///< information about this exposure

    psPhotSystem* colorPlus;           ///< Color reference
    psPhotSystem* colorMinus;          ///< Color reference

    float rmsX;                        ///< RMS for x transformation fits
    float rmsY;                        ///< RMS for y transformation fits
    float chi2;                        ///< chi^2 of astrometric solution
}
psFPA;

/** Exposure Information
 *
 *  Several quantities from the telescope in order to make a first guess at 
 *  the astrometric solution.  From these quantities, further quantities can 
 *  be derivedand stored for later use.
 *
 */

typedef struct psExposure
{
    const double ra;                  ///< Telescope boresight, right ascention
    const double dec;                 ///< Telescope boresight, declination
    const double hourAngle;           ///< Hour angle
    const double zenith;              ///< Zenith distance
    const double azimuth;             ///< Azimuth
    const double localTime;           ///< Local Sidereal Time
    const float date;                 ///< Modified Jullian Date of observation
    const float rotAngle;             ///< Rotator position angle
    const float temperature;          ///< Air temperature, for estimating refraction
    const float pressure;             ///< Air pressure, for calculating refraction
    const float humidity;             ///< Relative humidity, for refraction
    const float exposureTime;         ///< Exposure time

    /* Derived quantities */
    const float positionAngle;        ///< Position angle
    const float parallacticAngle;     ///< Parallactic angle
    const float airmass;              ///< Airmass, calculated from zenith distance
    const float parallacticFactor;    ///< Parallactic factor
    const char *cameraName;           ///< name of camera which provided exposure
    const char *telescopeName;        ///< name of telescope which provided exposure
}
psExposure;

psExposure* psExposureAlloc(
    double ra,                         ///< Telescope boresight, right ascention
    double dec,                        ///< Telescope boresight, declination
    double hourAngle,                  ///< Hour angle
    double zenith,                     ///< Zenith distance
    double azimuth,                    ///< Azimuth
    double localTime,                  ///< Local Sidereal Time
    float date,                        ///< MJD
    float rotAngle,                    ///< Rotator position angle
    float temperature,                 ///< Temperature
    float pressure,                    ///< Pressure
    float humidity,                    ///< Relative humidity
    float exposureTime                 ///< Exposure time
);

#endif
