/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.TYPE		Header
.NAME		astropos.h
.LANGUAGE	C
.AUTHOR		Francois Ochsenbein [ESO-IPG]
.CATEGORY	Astronomic definitions
.COMMENTS	This module include astronomical declarations.
.ENVIRONMENT
.VERSION 1.0	02-Mar-1987: Creation
.VERSION 1.1	24-Oct-1988: New definitions, including editions
.VERSION 1.2	26-May-1989: Includes trigo
.VERSION 4.0	24-Apr-1994: Includes many projections
.VERSION 4.1	15-Feb-1995: ANSI-compatible
.VERSION 4.2	01-Jul-1998: ICRS system !
.VERSION 4.3	18-Mar-1999: tr_setframe

------------------------------------------------------------*/

#ifndef ASTROPOS_DEF
#define ASTROPOS_DEF	0

#ifndef _ARGS
#ifdef __STDC__
#define _ARGS(A)	A       /* ANSI */
#else
#define _ARGS(A)	()      /* Traditional */
#define const
#endif
#endif

#include <trigo.h>	/* Basic tr_ou / tr_uo in trigo.h */

/*===========================================================================
 *                        Naming Conventions
 *===========================================================================*/

/*+++++++++++++++
	
	a[]:  ASCII string
	c3[3][3]: Covariance (symetric) matrix
	e[3]: Unit Vector in Ecliptic Frame
	e3[3]: error ellipse (semi-major/minor axis, posangle)
	e6[6]: error ellipses position + proper motion 
	f4[3]: Fundamental (FK4, B1950) Unit Vector
	f5[3]: Fundamental (FK5, J2000) Unit Vector
	g[3]: Galactic Unit Vector
	G[3]: Supergalactic Unit Vector
	o[2]: Angles in degrees
	p[2]: projections
	P[2]: projections in Gnomonic
	q[2]: eQuatorial Angles in degrees
	q6[6]: HIPPARCOS vector: RA,Dec(deg), plx(mas), pmRA,pmDE,pm0(mas/yr)
	R[3][3]: Rotation matrix
	s[8]: Structure spos (u, udot, epoch, equinox)
	u[3]: Unit vector in Any Frame
	v[3]: Velocity vector, in arc.sec/yr
		v[0]=RV*kms_pc*plx, v[1]=mua*cos(delta), v[2]=mud

Time:
	tm = time structure (cf time.h)
	t  = Unix time (seconds since 1970)
	JD = Julian date
	Jy = Julian year 
------------------*/

struct spos {
	double u[3];	/* Position vector	*/
	double ud[3];	/* Derivatives of u	*/
	double epoch;	/* Epoch (Julian Years)	*/
	double equinox;	/* Equinox Julian Years	(Original Epoch for ICRS) */
	char   frame;	/* Coordinate system	*/
	char   precision; /* Precision indicator:
			   0 = unknown position
			   1 = 1 degree, 2 = 0.1degree
			   3 = 1 arcmin, 4 = 0.1arcmin
			   5 = 1 arcsec, 6 = 0.1arcsec, 7=10mas, 8=1mas
			   9 = 0.1mas   10 = 0.01mas  11=micro-arcsec
			  */
  	short flags ;		/* 1    = parallax 	*/
  				/* 2    = RVelocity	*/
  				/* 4    = PMotions	*/
  				/* 0x10 = cov Position	*/
  				/* 0x20 = cov PMotions	*/
	short flagset ;		/* Set by tr_setframe   */
	short unused ;
	double epocho;	/* Epoch of observation (with minimal uncertainty) */
	double plx ;		/*   Parallax in mas	*/
	double e_plx ;		/* Mean error on plx	*/
	double rv;		/* Radial Velocity km/s (when plx=0) */
	double e_rv;		/* Mean error on rv     (when plx=0) */
	double cov[6][6]; 	/*  Cov. Matrix	(mas)	*/
	};

/*===========================================================================
 *             Coordinate Systems
 *===========================================================================*/

#define _COO_FK4_	1	/* FK4 system (equatorial)	*/
#define _COO_FK5_	5	/* FK5 system (equatorial)	*/
#define _COO_GAL_	2	/* Galactic coordinates		*/
#define _COO_SUPERGAL_	3	/* SuperGalactic coordinates	*/
#define _COO_ECL_	4	/* Ecliptic coordinates		*/
#define _COO_ICRS_	6	/* HIPPARCOS Frame		*/

/* Flags indicating ESTIMATED values (returned by tr_s2) 	*/
#define _COO_EST_plx_		(1<<8)
#define _COO_EST_rv_		(2<<8)
#define _COO_EST_pm_		(4<<8)
#define _COO_EST_me_pos_	(0x10<<8)
#define _COO_EST_me_pm_		(0x20<<8)

/*===========================================================================
 *             Proper Motions Transformations
 *===========================================================================*/

#define kms_pc			(1./4.740470446)	/* km/s/pc to "/yr	*/

#define rv2v0(Vr,plx)		((Vr)*(plx)*(kms_pc))			\
				/* Radial Velocity (km/s) to velocity v[0] */
			
/*===========================================================================
 *             Projections definitions
 *===========================================================================*/

#define _PROJ_TAN_	 1	/* Gnomonic projection*/
#define _PROJ_TAN2_	 2	/* Stereographic projection*/
#define _PROJ_STG_	 2	
#define _PROJ_SIN_	 3	/* Orthographic		*/
#define _PROJ_SIN2_	 4	/* Equal-area 		*/
#define _PROJ_ZEA_	 4	/* Zenithal Equal-area 	*/
#define _PROJ_ARC_	 5	/* For Schmidt plates	*/
#define _PROJ_SCHMIDT_	 5	/* For Schmidt plates	*/
#define _PROJ_AITOFF_	 6	/* Aitoff Projection	*/
#define _PROJ_AIT_	 6	/* Aitoff Projection	*/
#define _PROJ_GLS_	 7	/* Global Sin (Sanson)	*/
#define _PROJ_MERCATOR_	 8
#define _PROJ_MER_	 8	
#define _PROJ_LAM_	 9	/* Lambert Projection	*/
#define _PROJ_LAMBERT_	 9	
#define _PROJ_TSC_	10	/* Tangent Sph. Cube	*/
#define _PROJ_QSC_	11	/* QuadCube Sph. Cube	*/

/*===========================================================================
 *            Time Transformations (see also trtime.h)
 *===========================================================================*/

#define JD_offset	2400000.5e0	/* Origin of Modified Julian Date  */
#define JDtoMJD(x)	(x-JD_offset)
#define MJDtoJD(x)	(x+JD_offset)

#define BYr		365.242198781e0		  /* Days in Besselian Year */
#define JYr		365.25e0		  /* Days in Julian    Year */

#define JD_J2000	2451545.e0		  /* Julian date of J2000   */
#define JD_B1900	2415020.31352e0		  /* Julian date of B1900   */
#define JD_B1950	BYtoJD(1950.e0)		  /* Julian date of B1950   */
#define JD_HIP		2448349.0625	          /* HIPPARCOS 1991.25 Ep.  */
#define JD1970		2440587.5e0	/* JD   of 00:00:00 Jan. 1, 1970    */

#define JYtoJD(jy)	(JD_J2000+(jy-2000.e0)*JYr)  /* Julian Year to JD   */
#define BYtoJD(by)	(JD_B1900+(by-1900.e0)*BYr)  /* Besselian Year to JD*/

#define JDtoJY(jd)	(2000.e0+(jd-JD_J2000)/JYr)  /* JD to Julian Year   */
#define JDtoBY(jd)	(1900.e0+(jd-JD_B1900)/BYr)  /* JD to Besselian Year*/

#define BYtoJY(y)	JDtoJY(BYtoJD(y))	  /* Besselian to Julian yr */
#define JYtoBY(y)	JDtoBY(JYtoJD(y))	  /* Julian to Besselian yr */

/*===========================================================================
 *             Basic Coordinates Transformations
 *===========================================================================*/

int    tr_qvs	_ARGS((double q[2] , double v[3] , struct spos *s));
int    tr_sqv	_ARGS((struct spos *s , double q[2] , double v[3]));
						/* out=r1*r2*/
int    tr_vare3 _ARGS((double variance[3], double ellipse[3])) ;
int    tr_e3var _ARGS((double ellipse[3],  double variance[3])) ;
int    tr_setframe _ARGS((struct spos *s, int frame, int precision, 
			double equinox, double epoch)) ;
int    tr_2s    _ARGS((double epoch[2], double q[2], double qe3[3], 
			double p[2], double pe3[3],
			double plx[2], double rv[2], 
			struct spos *s));
int    tr_s2    _ARGS((struct spos *s, double epoch[2], 
			double q[2], double qe3[3], 
			double p[2], double pe3[3],
			double plx[2], double rv[2])) ;
int    icrs_2s  _ARGS((double epoch[2], double q[2], double e3q[3], 
			double p[2], double e3p[3], 
			double plx[2], double rv[2], 
			struct spos *s)) ;
int    hip_2s   _ARGS((double a[5], double c[15], double rv[2], 
			struct spos *s));
int    fk4_2s   _ARGS((double epoch[2], double q[2], double qe3[3], 
			double p[2], double pe3[3],
			double plx[2], double rv[2], 
			struct spos *s));
int    fk5_2s   _ARGS((double epoch[2], double q[2], double qe3[3], 
			double p[2], double pe3[3],
			double plx[2], double rv[2], 
			struct spos *s));

/* Interpret especially important astrometric catalogues */
struct spos *hip_s _ARGS((char *HIP_record, double rv[2])) ;
struct spos *ppm_s _ARGS((char *PPM_record, double plx[2], double rv[2])) ;

#define tr_qq	tr_oo
#define tr_qq1	tr_oo1
#define tr_qR	tr_oR
#define tr_qu	tr_ou
#define tr_uq	tr_uo

/*===========================================================================
 * 	            Projections
 *===========================================================================*/
/*	(All return 0 / -1)	*/

int 	tr_op 	_ARGS((int proj_mode, double o[2], double p[2]));
int 	tr_po 	_ARGS((int proj_mode, double p[2], double o[2]));
int 	tr_up 	_ARGS((int proj_mode, double u[3], double p[2]));
int 	tr_pu 	_ARGS((int proj_mode, double p[2], double u[3]));

	/* Standard projection P = Gnomonic */
	
#define tr_oP(o,P)	tr_op(_PROJ_TAN_, o, P)
#define tr_Po(P,o)	tr_po(_PROJ_TAN_, P, o)
#define tr_uP(u,P)	tr_up(_PROJ_TAN_, u, P)
#define tr_Pu(P,u)	tr_pu(_PROJ_TAN_, P, u)

#define tr_pq		tr_po
#define tr_qp		tr_op
#define tr_Pq		tr_Po
#define tr_qP		tr_oP

/*===========================================================================
 *             Coordinate Transformations
 *===========================================================================*/

#if 0
/************ Note: The Global symbols may be used:**********************/
extern double gal_2000[3][3];		/* J2000 to Galactic		*/
extern double gal_1950[3][3];		/* B1950 to Galactic		*/
extern double ecl_2000[3][3];		/* J2000 to J2000 Ecliptic	*/
extern double supergal[3][3];		/* Galactic to Supergalactic	*/
/************************************************************************/
#endif

		/* ========= Galactic ==============*/

int tr_gf5  _ARGS((double g[3], double f[3])); /* Galactic to J2000         */
int tr_f5g  _ARGS((double f[3], double g[3])); /* Galactic to J2000         */
int tr_gf4  _ARGS((double g[3], double f[3])); /* Galactic to B1950	    */
int tr_f4g  _ARGS((double f[3], double g[3])); /* Galactic to B1950         */
int tr_gsup _ARGS((double g[3], double G[3])); /* Galactic to SuperGalactic */
int tr_supg _ARGS((double G[3], double g[3])); /* SuperGalactic to Galactic */

		/* ========= Ecliptic ==============*/

int ecl_R   _ARGS((double R[3][3], double yr));
					/* Julian Year to Ecliptic Matrix */
int tr_ef    _ARGS((double e[3] , double f[3] , double y))  ;
int tr_fe    _ARGS((double f[3] , double e[3] , double y))  ;

		/* ========= Precession, Old =======*/
		
int preb_R   _ARGS((double R[3][3], double yr0, double yr1));
int preb_q   _ARGS((double q0[2], double q1[2], double yr0, double yr1));
int preb_u   _ARGS((double u0[3], double u1[3], double yr0, double yr1));

		/* ========= Precession, New =======*/
		
int prej_R   _ARGS((double R[3][3], double yr0, double yr1));
int prej_q   _ARGS((double q0[2], double q1[2], double yr0, double yr1));
int prej_u   _ARGS((double u0[3], double u1[3], double yr0, double yr1));

		/* ========= FK4 / FK5 change ======*/
		
int fk4_5q   _ARGS((double qb[2], double vb[3], double qj[2], double vj[2]));
int fk4_qv0  _ARGS((double qb[2], double vb[3]));
int fk4_5s   _ARGS((struct spos *sb, struct spos *sj));
int fk4_s0   _ARGS((struct spos *sb));
int fk5_4q   _ARGS((double qj[2], double vj[3], double qb[2], double vb[2]));
int fk5_4s   _ARGS((struct spos *sj, struct spos *sb));

		/* ========= General Change ========*/
		
int tr_ss   _ARGS((struct spos *s_in, struct spos *s_out));
int tr_s    _ARGS((struct spos *s_in, int frame, double equinox, double epoch));


#define	tr_gG(g,G)			tr_gsup(g,G)			\
					/* Galactic to SuperGalactic */
#define	tr_Gg(G,g)			tr_supg(G,g)			\
					/* SuperGalactic to Galactic */

/*=========================================================================
		Distances
 *=========================================================================*/
double s2d_o	_ARGS((double o1[2], double o2[2]));
double s2d_p	_ARGS((double p1[2], double p2[2]));
double s2d_u	_ARGS((double u1[3], double u2[3]));
double dist_o	_ARGS((double o1[2], double o2[2]));
double dist_p	_ARGS((double p1[2], double p2[2]));
double dist_u	_ARGS((double u1[3], double u2[3]));


/*=========================================================================
		Coordinates Editions
 *=========================================================================*/

int	ed_o1  _ARGS((char *buf, double g[2], int precision, int coo));
int	ed_o   _ARGS((char *buf, double g[2], int precision));
int	ed_q1  _ARGS((char *buf, double q[2], int precision, int coo));
int	ed_q   _ARGS((char *buf, double q[2], int precision));
int	tr_ao0 _ARGS((char *str, int len, double *x));
int	tr_ao  _ARGS((char *str, int len, double x[2]));
int	tr_aq  _ARGS((char *str, int len, double x[2]));

char  *cooname _ARGS((int cootype, double equinox));

/*=========================================================================
		Time transformations
 *=========================================================================*/

#if 0
#include <time.h>
int    tr_ttm  _ARGS((time_t t, struct tm *dtime));
int    tr_tmt  _ARGS((struct tm *dtime, time_t t));
int    tr_tm   _ARGS((struct tm *dtime));		/* Add missing items */
int    tr_jdt  _ARGS((double jd, struct tm *dtime));	/* convert JD to U   */
int    tr_jdtm _ARGS((double jd, time_t *t));	/* convert JD to date-time   */
int    tr_atm  _ARGS((char *text, int len, struct tm *dtime));
int    tr_at   _ARGS((char *text, int len, time_t *t));
double t2jd    _ARGS((time_t t));
double tm2jd   _ARGS((struct tm *dtime));
time_t jd2t    _ARGS((double jd));

time_t a2tm _ARGS((char *text));
struct tm *a2tm _ARGS((char *text));

char  *tm2a   _ARGS((struct tm *dtime));		/* edition of date */
char  *t2a    _ARGS((time_t t));
#endif

#ifdef int4
char *t2a _ARGS((int4 t));
int4 a2t _ARGS((char *str));
#else
char *t2a _ARGS((int t));
int a2t _ARGS((char *str));
#endif

/* file astime.c */
void astime_tdb_tcb _ARGS((double *value, double *error)); 
void astime_tt_tcb _ARGS((double *value, double *error));
void astime_tdt_tcb _ARGS((double *value, double *error));
void astime_tai_tcb _ARGS((double *value, double *error));
void astime_iat_tcb _ARGS((double *value, double *error));
void astime_ut_tcb _ARGS((double *value, double *error));
void astime_utc_tcb _ARGS((double *value, double *error));
void astime_gmt_tcb _ARGS((double *value, double *error));
void astime_gps_tcb _ARGS((double *value, double *error));
void astime_unknown_tcb _ARGS((double *value, double *error));
void astime_tcb_tdb _ARGS((double *value, double *error));
void astime_tcb_tt _ARGS((double *value, double *error));
void astime_tcb_tdt _ARGS((double *value, double *error));
void astime_tcb_tai _ARGS((double *value, double *error));
void astime_tcb_iat _ARGS((double *value, double *error));
void astime_tcb_ut _ARGS((double *value, double *error));
void astime_tcb_utc _ARGS((double *value, double *error));
void astime_tcb_gmt _ARGS((double *value, double *error));
void astime_tcb_gps _ARGS((double *value, double *error));

void astime_helio_baryc _ARGS((double *value, double *error));
void astime_topo_baryc _ARGS((double *value, double *error));
void astime_geo_baryc _ARGS((double *value, double *error));
void astime_gal_baryc _ARGS((double *value, double *error));
void astime_emb_baryc _ARGS((double *value, double *error));
void astime_mercury_baryc _ARGS((double *value, double *error));
void astime_venus_baryc _ARGS((double *value, double *error));
void astime_mars_baryc _ARGS((double *value, double *error));
void astime_jupyter_baryc _ARGS((double *value, double *error));
void astime_saturn_baryc _ARGS((double *value, double *error));
void astime_uranus_baryc _ARGS((double *value, double *error));
void astime_neptune_baryc _ARGS((double *value, double *error));
void astime_unknown_baryc _ARGS((double *value, double *error));
void astime_baryc_topo _ARGS((double *v, double *e));
void astime_baryc_geo _ARGS((double *v, double *e));
void astime_baryc_gal _ARGS((double *v, double *e));
void astime_baryc_emb _ARGS((double *v, double *e));
void astime_baryc_mercury _ARGS((double *v, double *e));
void astime_baryc_venus _ARGS((double *v, double *e));
void astime_baryc_mars _ARGS((double *v, double *e));
void astime_baryc_jupyter _ARGS((double *v, double *e));
void astime_baryc_saturn _ARGS((double *v, double *e));
void astime_baryc_uranus _ARGS((double *v, double *e));
void astime_baryc_neptune _ARGS((double *v, double *e));

void time_scale_to_tcb _ARGS((double *value, double *error, char *scale));
void time_scale_tcb_to _ARGS((double *value, double *error, char *cale));
void time_frame_to_barycenter _ARGS((double *value, double *error, char *frame));
#define astime_frame_barycenter_to(v,e,f) astime_frame_to_barycenter(v,e,f)

/* file asunit.c */
int asunit_cds_to_vounits _ARGS((char *in, char *out, int len));

#endif
