#ifndef TA_CALIB_OBJ_H
#define TA_CALIB_OBJ_H

#ifdef __cplusplus
extern "C" {
#endif

#include <dervish.h>
#include <astrotools.h>
#include "arObjectType.h"
#include "arPSFStatus.h"

/* Index used for arrays over the list of filters */
#define TA_NFILTERS 5
typedef enum taFilter
{
  TA_U,				/* u' */
  TA_G,				/* g' */
  TA_R,				/* r' */
  TA_I,				/* i' */
  TA_Z				/* z' */
} TA_FILTER; /* pragma SCHEMA */

/* Floating point value plus error */
typedef struct taFloatErr
{
  float val;			/* value */
  float err;			/* rms error */
} TA_FLOAT_ERR; /* pragma SCHEMA */

/* Info for a single field */
typedef struct taFieldInfo
{
  int field;			/* Field sequence number within a run */
  float seeing[5];		/* Seeing for each frame (order ugriz,
				 * FWHM, arcsecs) */
  double mjd[5];                /* MJD(TAI) when row 0 was read for each
				 * frame (order ugriz) */
  AR_PSF_STATUS status[5];      /* PSF fit status in each filter (ugriz) */
  AR_PSF_STATUS psp_status;     /* Worst (max) PSF status of all 5 filters */
  float psf_ap_correctionErr[5]; /* Photometric error due to imperfect PSF
				 * fit (mags, order ugriz) */
  float sky_frames_sub[5];      /* Global sky value after object subtraction
				 * (luptitudes/arcsec^2, order ugriz) */
} TA_FIELD_INFO; /* pragma SCHEMA */

/* Floating point value plus error and gradiant with isophote */
typedef struct taFloatGrad
{
  float val;			/* value */
  float err;			/* rms error */
  float grad;			/* gradient in value with isophote (per mag) */
} TA_FLOAT_GRAD; /* pragma SCHEMA */

/* A calibrated detection of a survey object in a single filter */
typedef struct taDetection
{
  TA_FLOAT_ERR rowc;		/* Row center (r' coordinates, pixels) */
  TA_FLOAT_ERR colc;		/* Column center (r' coordinates, pixels) */
  TA_FLOAT_ERR sky;		/* Sky flux (luptitudes/square-arcsec) */
  TA_FLOAT_ERR psfCounts;	/* PSF mag (luptitudes) */
  TA_FLOAT_ERR fiberCounts;	/* Mag in 3 arcsec diameter fiber radius
				   (luptitudes) */
  TA_FLOAT_ERR petroCounts;	/* Petrosian mag (luptitudes) */
  TA_FLOAT_ERR petroRad;	/* Petrosian radius (arcsecs) */
  TA_FLOAT_ERR petroR50;	/* Radius with 50 percent of Petrosian light
				   (arcsecs) */
  TA_FLOAT_ERR petroR90;	/* Radius with 90 percent of Petrosian light
				   (arcsecs) */
  TA_FLOAT_ERR q;		/* Stokes Q parameter */
  TA_FLOAT_ERR u;		/* Stokes U parameter */
  TA_FLOAT_GRAD iso_rowc;	/* Isophotal row centroid (pixels) */
  TA_FLOAT_GRAD iso_colc;	/* Isophotal column centroid (pixels) */
  TA_FLOAT_GRAD iso_a;		/* Isophotal major axis (arcsecs) */
  TA_FLOAT_GRAD iso_b;		/* Isophotal minor axis (arcsecs) */
  TA_FLOAT_GRAD iso_phi;	/* Isophotal position angle (degrees) */
  TA_FLOAT_ERR r_deV;		/* DeVaucouler fit scale radius (arcsecs) */
  TA_FLOAT_ERR ab_deV;		/* DeVaucouler fit a/b */
  TA_FLOAT_ERR phi_deV;		/* DeVaucouler position angle (degrees) */
  TA_FLOAT_ERR counts_deV;	/* */
  TA_FLOAT_ERR r_exp;		/* Exponential fit scale radius (arcsecs) */
  TA_FLOAT_ERR ab_exp;		/* Exponential fit a/b */
  TA_FLOAT_ERR phi_exp;		/* Exponential position angle (degrees) */
  TA_FLOAT_ERR counts_exp;	/* */
  TA_FLOAT_ERR counts_model;	/* */
  float texture;		/* Texture parameter */
  float star_L;			/* Star likelihood */
  float exp_L;			/* Exponential disk fit likelihood */
  float deV_L;			/* DeVaucouler disk fit likelihood */
  float fracPSF;		/* Fraction of light in PSF; */
  int flags;			/* Flags */
  int flags2;			/* More flags */
  AR_OBJECT_TYPE type;		/* Object type (star, galaxy, etc) */
  int nProf;			/* Number of profile bins */
  TA_FLOAT_ERR profile[15];	/* Profile bins */
} TA_DETECTION; /* pragma SCHEMA */

/* A calibrated survey object */
typedef struct taCalibObj
{
  TA_FIELD_INFO *field;		/* Pointer to field structure for field this
				   object appears in */
  int run;                      /* Run Id */
  int camCol;                   /* Camera column */
  int rerun;                    /* Rerun number */
  int fieldId;                  /* Field Id */
  int parent;			/* Id of parent --- 0 if none */
  int id;			/* Object ID, unique within its field
				   (1 indexed) */
  int nchild;			/* */
  AR_OBJECT_TYPE objc_type;	/* Object type (star, galaxy, etc) */
  int catId;			/* Known object catalog id --- 0,0 if none */
  int objc_flags;		/* Flags */
  int objc_flags2;		/* More flags */
  TA_FLOAT_ERR objc_rowc;	/* Nominal row position (r' coordinates,
				   pixels) */
  TA_FLOAT_ERR objc_colc;	/* Nominal column position (r' coordinate,
				   pixels) */
  TA_FLOAT_ERR rowv;		/* Row-component of object's velocity
				   (pixels/frame) */
  TA_FLOAT_ERR colv;		/* Column-component of object's velocity
				   (pixels/frame) */
  int status;			/* Object status within the survey */
  double ra;			/* J2000 right ascension (r', degrees) */
  double dec;			/* J2000 declination (r', degrees) */
  double lambda;		/* Survey longitude (r', degrees) */
  double eta;			/* Survey latitude (r', degrees) */
  double l;			/* Galactic longitude (lII, r', degrees) */
  double b;			/* Galactic latgitude (bII, r', degrees) */
  float offsetRa[5];            /* */
  float offsetDec[5];           /* */
  int primTarget;		/* Primary target bit mask (science samples) */
  int secTarget;		/* Secondary target bit mask */
  float reddening[5];           /* Reddening in each filter (luptitudes) */
  int   properMotionMatch;	/* match to USNOA2.0 catalog
				 * (0=no match, 1= good match) */
  float properMotionDelta;	/* distance to USNOA2.0 catalog match (asec)*/
  float properMotion;		/* proper motion arcsec/century */
  float properMotionAngle;      /* Direction of proper motion (degrees,
				 * postive north thru east) */
  float usnoBlue;               /* Blue magnitude of matching USNOA2.0 object*/
  float usnoRed;                /* Red magnitude of matching USNOA2.0 object*/
  int   firstMatch;		/* # of FIRST sources matched (0=no match)*/
  int   firstId;                /* ID of one FIRST source matched */
  double firstLambda;           /* Survey longitude of FIRST object (deg) */
  double firstEta;              /* Survey latitude of FIRST object (deg) */
  float firstDelta;		/* distance to FIRST catalog match (arcsec) */
  float firstPeak;		/* Composite FIRST peak flux (mJy) */
  float firstInt;		/* Composite FIRST integrated flux (mJy) */
  float firstrms;		/* Composite FIRST flux error (mJy) */
  float firstmajor;		/* Composite FIRST major axis (a) (arcsec) */
  float firstminor;		/* Composite FIRST minor axis (b) (arcsec) */
  float firstpa;		/* Composite FIRST pa (arcsec) */
  int   rosatMatch;		/* ID of matching ROSAT source */
  float rosatDelta;		/* distance to center of ROSAT error
				 * circle (arcsec) */
  float rosatPosErr;            /* Error in ROSAT position (arcsecs) */
  TA_FLOAT_ERR rosatCPS;	/* ROSAT source countrate (counts/sec) */
  TA_FLOAT_ERR rosatHR1;	/* ROSAT source hardness ratio 1 */
  TA_FLOAT_ERR rosatHR2;	/* ROSAT source hardness ratio 2 */
  float rosatExt;		/* ROSAT source extent parameter */
  float rosatExtLike;           /* ROSAT extent parameter likelihood */
  float rosatDetectLike;        /* ROSAT detection likelihood */
  float rosatExposure;          /* ROSAT exposure time (seconds) */
  unsigned int priority;	/* priority */
  int  matchId[10][5];		/* match link ids(run,camCol,rerun,field,id)*/
  TA_DETECTION detection[5];	/* Inidividual filter detections (in order
				   u, g, r, i, z) */
} TA_CALIB_OBJ; /* pragma SCHEMA */

/* Photometric transformation for a single field from FCALIB */
typedef struct taPTrans
{
  int field;			/* Field */
  TA_FLOAT_ERR a[5];		/* Zero-point */
  TA_FLOAT_ERR b[5];		/* Color term */
  TA_FLOAT_ERR c[5];		/* Color * extinction term */
  TA_FLOAT_ERR k[5];		/* Extinction term */
  float dZero[5];               /* Zeropoint used by photo minus current
				 * zeropoint */
} TA_PTRANS; /* pragma SCHEMA */

/* Forward declarations */
void taGenericChainDestroy(CHAIN *ch);
TBLCOL *taCalibObjsWriteToTbl(const CHAIN *chain);
RET_CODE taCalibObjsReadFromTbl(TBLCOL *tblCol, TA_FIELD_INFO *field,
				int calibrated, CHAIN *chain);
RET_CODE taObjCalibrate(TA_CALIB_OBJ *obj, const TA_PTRANS *ptrans,
			const TRANS *trans[5], const TRANS *transPhoto[5],
			double node, double incl,
			char refFilter, double expTime);

RET_CODE taExtinction(double l, double b, float *u, float *g, float *r,
		      float *i, float *z);

int taLCaliApply(double counts, double countsErr, double cCounts,
		 double cCountsErr, double intTime, double cIntTime,
		 double airmass, double zeropt, double extinct,
		 double colorTerm, double secColorTerm, int sign,
		 double cosmicColor, double cosmicError, double *calMag,
		 double *calMagErr, int *status);

int taGood(int flags);

#ifdef __cplusplus
}
#endif

#endif
