
# ifndef LONEOS_H
# define LONEOS_H

/* image data modes in RegImage */
# define MODE_NONE   0  /* not defined */
# define MODE_MEF    1  /* chip of mef image */
# define MODE_SPLIT  2  /* chip of split image */
# define MODE_SINGLE 3  /* single chip, not mosaic */
# define MODE_CUBE   4  /* cube entry */
# define MODE_SLICE  5  /* slice of a cube */
# define MODE_MODES  6  /* not used? */

# define TYPE_NONE   0
# define TYPE_OBJECT 1
# define TYPE_DARK   2
# define TYPE_BIAS   3
# define TYPE_FLAT   4

/** these are no longer used by imregister-3.0 
    status:imrough uses the imregister-3.0 values
    status:imsearch should migrate to the imregister.h version 
    or be removed!
**/

# define IMREG_DIST  0x01 /* image distributed, only imregister-3.0 */

/* catalog values to be loaded */
# define LOAD_AVES 0x01
# define LOAD_MEAS 0x02
# define LOAD_MISS 0x04
# define LOAD_SECF 0x08

/* invalid mag value */
# define NO_MAG    0x7fff

/* photometry code types */
# define PHOT_PRI 0x01
# define PHOT_SEC 0x02
# define PHOT_DEP 0x03
# define PHOT_REF 0x04
# define PHOT_ALT 0x05  /* never stored, only for look-ups */

/* Image.code values.  these are codes to note bad images */
# define ID_IMAGE_NEW   0x0000  /* no nrphot attempted */
# define ID_IMAGE_NOCAL 0x0001  /* used within nrphot to mean "don't apply fit" */
# define ID_IMAGE_POOR  0x0002  /* relphot says image is bad */
# define ID_IMAGE_SKIP  0x0004  /* external information image is bad */
# define ID_IMAGE_FEW   0x0008  /* currently too few measurements for good value */

/* Measure.flags values */
# define ID_MEAS_NOCAL        0x0001
# define ID_MEAS_POOR         0x0002
# define ID_MEAS_SKIP         0x0004
# define ID_MEAS_AREA         0x0008
# define BLEND_IMAGE          0x0100 
# define BLEND_CATALOG        0x0200
# define BLEND_IMAGE_NEIGHBOR 0x1000
# define ID_MEAS_TRAIL        0x2000
# define ID_MEAS_GHOST        0x4000

/* Average.code values */
# define ID_STAR_FEW   0x0001 /* used within relphot: skip star */
# define ID_STAR_POOR  0x0002 /* used within relphot: skip star */
# define ID_PROPER     0x0400 /* star with large proper motion */
# define ID_TRANSIENT  0x1000 /* is this mutually exclusive with USNO?  */
# define ID_VARIABLE   0x2000 /* not currently set? */
# define ID_ASTEROID   0x2000 /* identified with an asteroid */
# define ID_BAD_OBJECT 0x4000 /* if all measurements are bad, set this bit */
# define ID_MOVING     0x8000
# define ID_ROCK       0xa000 /* 0x8000 + 0x2000 */
# define ID_GHOST      0xc001 /* 0x8000 + 0x4000 + 0x0001 */
# define ID_TRAIL      0xc002 /* 0x8000 + 0x4000 + 0x0002 */
# define ID_BLEED      0xc003 /* 0x8000 + 0x4000 + 0x0003 */ 
# define ID_COSMIC     0xc004 /* 0x8000 + 0x4000 + 0x0004 */ 

/* 
   BLEND_IMAGE: the star on an image is matched with more 
      than one star in the catalog (image has worse seeing than catalog)
   BLEND_CATALOG: the star in the catalog is matched with more 
      than one star on the image (image has better seeing than catalog)
   CALIBRATED: relative photometry has been performed on this measurement
   BLEND_IMAGE_NEIGHBOR: the star on an image is matched with more 
      than one star in the catalog, but not in the same catalog file.
*/

/* structure for data on a catalog region */
typedef struct {
  char filename[256];
  double DEC[2], RA[2];
} GSCRegion;

/* structure for Image Registration Database */
typedef struct {
  char filename[64];
  char pathname[128];
  char filter[32];
  char instrument[32];
  char ccd;                        /* an identifier for CCD in mosaic (0 for single ccd) */
  char mode;                       /* MEF, SINGLE, SPLIT */
  char type;                       /* image type */
  char flag;                       /* image status flags */
  char junk[24];
 
  float exptime;
  float airmass;
  float sky;
  float bias;
  float fwhm;

  float telfocus;
  float xprobe, yprobe, zprobe;
  float dettemp;
  float teltemp[4];
  float rotangle;
  float ra, dec;

  unsigned long int obstime;
  unsigned long int regtime;
} RegImage;  /* 360 bytes / image */

/* structure for Image Registration Database */
typedef struct {
  float sky;
  float bias;
  float fwhm;
  float exptime;
  float airmass;
  unsigned long int obstime;
  short int ccdnum;
  char junk1, junk2;
  char filter[32];
} RufImage;  /* 60 bytes */

/* Old Detrend Database structure */
typedef struct {
  unsigned long int tstart;
  unsigned long int tstop;
  unsigned long int treg;
  float sigma, clipsigma;
  int type;
  int filter;
  int ccd;
  char filename[254];
  char flag1, flag2;
} DetRegOld;    /* 288 bytes */

/* Detrend Database structure */
typedef struct {
  unsigned long int tstart;
  unsigned long int tstop;
  unsigned long int treg;
  float exptime;
  int type;
  int filter;
  int ccd;
  int Nentry;
  int Norder;
  char mode;
  char altpath;   /* true: data on alt db paths */
  char dummy[58]; /* for future expansion */
  char label[64];
  char filename[256];
} DetReg;    /* 416 bytes */

/* Instant Zeropoint structure */
typedef struct {
  float ZP;                   /* measured zero point */
  float ZPo;                  /* expected zero point */
  float dZP;                  /* error on zero point */
  float K;                    /* airmass term used */
  float X;                    /* color term used */
  unsigned long int tstart;   /* start time of observation */
  unsigned long int tstop;    /* end time of observation */
  short int c1;               /* photcode for color term */
  short int c2;               /* photcode for color term */
  short int photcode;         /* appropriate photcode */
  char label[66];
} OldPhotPars;    /* 100 bytes */

/* Instant Zeropoint structure */
typedef struct {
  float ZP;                   /* measured zero point */
  float ZPo;                  /* expected zero point */
  float dZP;                  /* error on zero point */
  float K;                    /* airmass term used */
  float X;                    /* color term used */
  unsigned long int tstart;   /* start time of observation */
  unsigned long int tstop;    /* end time of observation */
  short int c1;               /* photcode for color term */
  short int c2;               /* photcode for color term */
  short int photcode;         /* appropriate photcode */
  char label[64];
  short int refcode;          /* reference photometry system */
  int Ntime;                  /* number of measurement times */
  int Nmeas;                  /* number of data points */
} PhotPars;    /* 108 bytes */

/* average data as stored in the LONEOS database */
typedef struct {
  float R;                    /* RA  in decimal degrees */
  float D;                    /* DEC in decimal degrees */
  short int M;                /* thousandths of mag (-32.000 to 32.000 valid range) */
  unsigned short int Nm, Nn;  /* number of measurements, missing */
  short int Xp;               /* scatter in 1/100 arcsec (-327.67 to +327.67 valid range) */
  short int Xm;               /* chisq for primary mag [1000*value] */
  unsigned short int code;    /* an ID code (ie, star, ghost, satelite, etc) */
  signed int offset;          /* offset to first measurement */
  signed int missing;         /* offset to first missing obs */
  short int dM;               /* formal error on pri mag   [1000*log(value)] */
  short int Xg;               /* 'best' chisq value */
} Average; /* 32 bytes / Average */

/* average data as stored in the LONEOS database -- must be translated on load */
typedef struct {
  float R;                    /* RA  in decimal degrees */
  float D;                    /* DEC in decimal degrees */
  short int M;                /* thousandths of mag (-32.000 to 32.000 valid range) */
  unsigned short int Nm, Nn;  /* number of measurements, missing */
  short int Xp;               /* scatter in 1/100 arcsec (-327.67 to +327.67 valid range) */
  short int Xm;               /* 1000*log(chisq) for magnitude measurement */
  unsigned short int code;    /* an ID code (ie, star, ghost, satelite, etc) */
  signed int offset;          /* offset to first measurement */
  signed int missing;         /* offset to first missing obs */
} OldAverage; /* 28 bytes / Average */

/* data for individual measurement for each star */
/* OLD LONEOS VERSION.  NOT BYTE COMPATIBLE WITH NEW VERSION 
   (can be loaded with translation, losing the exptime,
   and limited the number of Naverage to 0xffffff - in load_catalog) */
typedef struct {
  short int dR, dD;           /* 1/100 of arcsec (-327.67 to +327.67 valid range) */
  short int M;                /* thousandths of mag (-32.767 to 32.767 valid range) */
  short int Mcal;             /* image cal mag, thousandths of mag (-32.767 to 32.767 valid range) */
  unsigned char dM;           /* thousandths of mag (0.000 to 0.255 valid range) */
  char dophot;                /* dophot type (1-9) */
  unsigned short int source;  /* code to identify photometry source */
  unsigned int   t;           /* time in seconds (0 - 143 years valid range) */
  unsigned int average;       /* reference to corresponding average entry, upper byte of Measure.average stores flags */
} OldMeasure; /* 20 bytes / Measure */

/* data for individual measurement for each star */
typedef struct {
  short int dR, dD;           /* 1/100 of arcsec (-327.67 to +327.67 valid range) */
  short int M;                /* thousandths of mag (-32.767 to 32.767 valid range) */
  short int Mcal;             /* image cal mag, thousandths of mag (-32.767 to 32.767 valid range) */
  short int Mgal;             /* 'galaxy' mag, thousandths of mag (-32.767 to 32.767 valid range) */
  short int airmass;          /* (airmass - 1), thousandths of mag (-32.767 to 32.767 valid range) */
  short int FWx;              /* object fwhm major axis - 1/100 of arcsec */
  unsigned char dM;           /* thousandths of mag (0.000 to 0.255 valid range) */
  unsigned char fwy, theta;   /* object fwhm minor/major axes ratio, angle wrt ccd X dir (0xff/360 deg precision) */
  char dophot;                /* dophot type (1-9) */
  unsigned short int source;  /* code to identify photometry source */
  unsigned int   t;           /* time in seconds (0 - 143 years valid range) */
  unsigned int averef;        /* reference to corresponding average entry, upper byte of Measure.average stores flags */
  short int dt;               /* exposure time in units of 2500*log(exptime) (millimags!) */
  unsigned short int flags;   /* 16 bit-flags for various uses */ 
} Measure; /* 32 bytes / Measure */

# if (0)
/* data for individual measurement for each star */
typedef struct {
  short int dR, dD;           /* 1/100 of arcsec (-327.67 to +327.67 valid range) */
  short int M;                /* thousandths of mag (-32.767 to 32.767 valid range) */
  short int Mcal;             /* image cal mag, thousandths of mag (-32.767 to 32.767 valid range) */
  unsigned char dM;           /* thousandths of mag (0.000 to 0.255 valid range) */
  char dophot;                /* dophot type (1-9) */
  unsigned short int source;  /* code to identify photometry source */
  unsigned int   t;           /* time in seconds (0 - 143 years valid range) */
  unsigned int averef;        /* reference to corresponding average entry, upper byte of Measure.average stores flags */
  short int dt;               /* exposure time in units of 2500*log(exptime) (millimags!) */
  unsigned short int flags;   /* 16 bit-flags for various uses */ 
} Measure; /* 24 bytes / Measure */
# endif

/* data on missing stars */
typedef struct {
  unsigned int   t;           /* time in seconds (0 - 143 years valid range) */
} Missing; /* 4 byte / Missing */

/* data on missing stars */
typedef struct {
  short int M;                /* other mags - thousandths of mag (-32.767 to 32.767 valid range) */
  short int Xm;               /* chisq on alt mag */
  short int dM;               /* scatter on alt mag */
} SecFilt; /* 6 byte / SecFilt */

/* data on missing stars */
typedef struct {
  short int M;                /* other mags - thousandths of mag (-32.767 to 32.767 valid range) */
  short int Xm;               /* chisq on alt mag */
} OldSecFilt; /* 4 byte / SecFilt */

/* a catalog contains this data */
typedef struct {
  /* data in the file: */
  Average *average;
  Measure *measure; 
  Missing *missing; 
  SecFilt *secfilt;
  Header  header;
  int Naverage, Nmeasure, Nmissing, Nsecfilt;
  /* description of the catalog file: */
  char *filename;
  int lockmode;
  FILE *f;
  /* pointers for data manipulation */
  int *found;
  int *image;
  int *mosaic;
  float *X;
  float *Y;
} Catalog;

/* the standard astrometric coordinates structure */
typedef struct {
  double   crval1, crval2;
  float    crpix1, crpix2;
  float    cdelt1, cdelt2;
  float    pc1_1, pc1_2;
  float    pc2_1, pc2_2;
  float    polyterms[7][2];
  char     ctype[15];
  char     Npolyterms;
} Coords;  /* 120 bytes / Coords */

typedef struct {
  unsigned short int code;   /* code number (stored in Measure.source) */
  char name[32];             /* name for filter combination */
  char type;                 /* primary, secondary, dependent, reference */
  short int C, dC, dX;       /* primary phot calibration terms (millimags) */
  float K;                   /* secondary phot calibration terms (millimags) */
  int  c1, c2;               /* color is average.M[c1] - average.M[c2] */
  int  equiv;                /* this dependent filter is equivalent to equiv primary/secondary */
  int  Nc;                   /* number of color terms */
  float X[4];                /* color terms X[0]*mc + X[1]*mc^2 + X[2]*mc^3, etc */
} PhotCode;

typedef struct {
  int Ncode;
  int Nsecfilt;
  int hashcode[0x10000];
  int hashNsec[0x10000];
  PhotCode *code;
} PhotCodeData;

/* image structure for binary data storage of image data */
typedef struct {
  Coords         coords;            /* 120 bytes */
  unsigned int   tzero;             /* readout time row 0 in sec (0 - 142 years valid range) */
  unsigned int   nstar;             /* number of stars on image */
  short int      secz;              /* thousanths of airmass (valid range -32.000 -- 32.000) */
  short int      NX, NY;            /* dimensions of image */
  short int      apmifit, dapmifit; /* aperture correction and error in thousandths of mag */
  short int      source;            /* identifier for CCD (each ever used will have a unique letter) */
  short int      Mcal;              /* thousandths of mag (-32.000 -- 32.000 valid range) */
  short int      dMcal;             /* thousandths of mag (-32.000 -- 32.000 valid range) */
  short int      Xm;                /* 10*log(image chi-square) */
  char           name[32];          /* name of original image */
  unsigned char  detection_limit;   /* tenths of mag (0.0 - 25.6 valid range) */
  unsigned char  saturation_limit;  /* tenths of mag (0.0 - 25.6 valid range) */
  unsigned char  cerror;            /* astrometric error: 1/50 of arcsec (0 -- 5.12 valid range) */
  unsigned char  fwhm_x, fwhm_y;    /* PSF terms in 25*arcsec (valid range 0.0 -- 10.2" ") */
  unsigned char  trate;             /* 10000 * scan rate in sec/pix (0 -- 0.0256 valid range, 
				       typically 0.0146. this is used only to determine the time
				       of the observation, not to find the coordinates.  1 byte
				       gives 0.11 sec accuracy */
  float          exptime;           /* exposure time, seconds */
  char           code;              /* flag to mark an image as bad or whatever */
  unsigned char  ccdnum;            /* mosaic CCD ID number (IMAGEID) */ 
  char           dummy[20];         /* extra space for the future */
  short int      order;             /* number of terms used for Mrel */
  short int      Mx, My;
  short int      Mxx, Mxy, Myy;
  short int      Mxxx, Mxxy, Mxyy, Myyy;
  short int      Mxxxx, Mxxxy, Mxxyy, Mxyyy, Myyyy;
} Image;  /* 240 bytes / Image */
/* Image needs to be aligned with 8-byte boundaries on Suns */

/**** prototypes ****/

int lock_catalog (Catalog *catalog, int lockmode);
int unlock_catalog (Catalog *catalog);
int load_catalog (Catalog *catalog, char mode, int VERBOSE);
int save_catalog (Catalog *catalog, char VERBOSE);
Measure *FixOldMeasure (OldMeasure *in, int Nvalues);
Average *FixOldAverage (OldAverage *in, int Nvalues);
SecFilt *FixOldSecFilt (OldSecFilt *in, int Nvalues);

int  XY_to_RD (double *ra, double *dec, double x,  double y,   Coords *coords);
int  RD_to_XY (double *x,  double *y,   double ra, double dec, Coords *coords);
int  fXY_to_RD (float *ra, float *dec, double x,  double y,   Coords *coords);
int  fRD_to_XY (float *x,  float *y,   double ra, double dec, Coords *coords);
int  GetCoords (Coords *coords, Header *header);
short int putMi (double value);
double getMi (short int value);
void returnMcal (Image *image, double *c);
void assignMcal (Image *image, double *c, int order);
double applyMcal (Image *image, double x, double y);
double findscatter (double *X, double *Y, double *M, double *dM, int N, double *c, int order);

PhotCode *GetPhotcodebyName (char *name);
PhotCode *GetPhotcodeEquivbyName (char *name);
PhotCode *GetPhotcodebyCode (int code);
PhotCode *GetPhotcodeEquivbyCode (int code);
char *GetPhotcodeNamebyCode (int code);

double PhotInst (Measure *measure);
double PhotAbs (Measure *measure);
double PhotCat (Measure *measure);
double PhotSys (Measure *measure, Average *average, SecFilt *secfilt);
double PhotRel (Measure *measure, Average *average, SecFilt *secfilt);
double PhotCal (Measure *thisone, Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code);
double PhotAve (PhotCode *code, Average *average, SecFilt *secfilt);
double PhotRef (PhotCode *code, Average *average, SecFilt *secfilt, Measure *measure);
double PhotXm (PhotCode *code, Average *average, SecFilt *secfilt);
double PhotdM (PhotCode *code, Average *average, SecFilt *secfilt);

short iPhotInst (Measure *measure);
short iPhotAbs (Measure *measure);
short iPhotCat (Measure *measure);
short iPhotSys (Measure *measure, Average *average, SecFilt *secfilt);
short iPhotRel (Measure *measure, Average *average, SecFilt *secfilt);
short iPhotCal (Measure *thisone, Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code);
short iPhotAve (PhotCode *code, Average *average, SecFilt *secfilt);
short iPhotRef (PhotCode *code, Average *average, SecFilt *secfilt, Measure *measure);
short iPhotXm (PhotCode *code, Average *average, SecFilt *secfilt);
short iPhotdM (PhotCode *code, Average *average, SecFilt *secfilt);

short iPhotColor (Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code);
int PhotColor (Average *average, SecFilt *secfilt, Measure *measure, int c1, int c2, double *color);

int LoadPhotcodes (char *filename);
int GetPhotcodeCodebyName (char *name);
int GetPhotcodeEquivCodebyName (char *name);
int GetPhotcodeEquivCodebyCode (int code);
int GetPhotcodeNsec (int code);
int GetPhotcodeNsecfilt ();
void SetZeroPoint (double ZP);
int *GetPhotcodeEquivList (int code, int *nlist);
void ParseColorTerms (char *terms, float *X, int *N);

void coords_precess (double *ra, double *dec, double in_epoch, double out_epoch);

# endif
