#ifdef __cplusplus extern "C" { #endif #ifndef GENORBFILE_INCLUDED #define GENORBFILE_INCLUDED #include "fitsio.h" /* Define these constants for searching for orbit times and setting the velocity units to the speed of light. */ #define UNINITIALIZED_ORBFILE_ROW -1 #define ORBFILE_LOCAL_SEARCH_LIMIT 100 #define ORBFILE_TIME_EPSILON 0.001 /* #define LIGHT_SPEED_KM_PER_S 299792.458 */ /* List the valid orbit formats. */ #define NUM_ORB_FORMATS 9 #define MAX_NUM_POS_COLS 3 #define MAX_NUM_VEL_COLS 3 #define MAX_NUM_KEP_COLS 6 typedef enum { ORBU_LEN_UNKNOWN, /* Units are unknown */ ORBU_LEN_M, /* Units are m and m/s */ ORBU_LEN_KM /* Units are km and km/s */ } ORBLENUNIT; typedef enum { ORBU_ANG_UNKNOWN, /* Units are unknown */ ORBU_ANG_DEG, /* Units are degrees */ ORBU_ANG_RAD /* Units are radians */ } ORBANGUNIT; typedef enum { ORBF_UNKNOWN, /* Unknown orbit format */ ORBF_COMPONENTS, /* Cartesian components, one in each of 6 columns, position in km, velocity in km/s */ ORBF_VECTOR, /* Cartesian components, in 2 vector columns, position in km, velocity in km/s */ ORBF_COMPONENTS_POS, /* Cartesian components, one in each of 3 columns, position in km */ ORBF_VECTOR_POS, /* Cartesian components, all in 1 vector column, position in km */ ORBF_COMPONENTS_VEL, /* Cartesian components, one in each of 3 columns, velocity in km/s */ ORBF_VECTOR_VEL, /* Cartesian components, all in 1 vector columns, velocity in km/s */ ORBF_KEPLERIAN, /* Keplerian elements */ ORBF_KEPLERIAN_NODUP /* Keplerian, duplicate time not permitted */ } ORBFORMAT; typedef enum { ORBI_UNKNOWN, /* Unknown interpolation method */ ORBI_WEIGHTED, /* Linear interpolation with respect to time */ ORBI_TAYLOR, /* Taylor expansion from acceleration and velocity */ ORBI_NEAREST /* Use previous time point - no interpolation */ } ORBINTERP; /* Define a struct to store their corresponding numbers of elements and names. Used by getOrbFormatInfo(). */ typedef struct { int num_pos_cols; int num_pos_elements; int num_vel_cols; int num_vel_elements; int num_kep_cols; int num_kep_elements; } ORB_FORMAT_INFO; /* Define an orbital velocity structure. */ typedef struct { double v[3]; /* 3-vector of x, y, z velocity components */ } ORBVELOCITY; /* Define an orbital position structure. */ typedef struct { double p[3]; /* 3-vector of x, y, z position components */ } ORBPOSITION; /* Define an orbital elements structure. */ typedef struct { double a, e, i, an, ap, ma; /* Keplerian orbital elements */ } ORBKEPLERIAN; /* Define a struct to store orbit file information and results of * latest time/velocity look-up. */ typedef struct { fitsfile* fp; /* FITS file pointer */ char* filename; /* Orbit file name */ char* ext_name; /* Orbit extension name */ char* telescope; /* Value of TELESCOP keyword */ char* time_col_name; /* Time column name */ int time_col_num; /* Time column number */ ORBFORMAT orb_format_num; /* Orbit format number */ ORBLENUNIT orb_len_unit_num; /* Enum for km or m */ ORBANGUNIT orb_ang_unit_num; /* Enum for km or m */ ORBINTERP interp_method_num; /* Interpolation method to be used */ char** vel_col_names; /* Array of velocity column names */ int* vel_col_nums; /* Array of velocity column numbers */ int* num_vel_col_elements; /* Array of numbers of velocity column elements */ int num_vel_cols; /* Number of velocity columns */ char** pos_col_names; /* Array of position column names */ int* pos_col_nums; /* Array of position column numbers */ int* num_pos_col_elements; /* Array of numbers of position column elements */ int num_pos_cols; /* Number of position columns */ char** kep_col_names; /* Array of Keplerian element column names */ int* kep_col_nums; /* Array of position column numbers */ int* num_kep_col_elements; /* Array of numbers of position column elements */ int num_kep_cols; /* Number of position columns */ double tstart; /* Time of first row */ double tstop; /* Time of last row */ double duration; /* tstop - tstart */ double min_extrapolated_time; /* Earliest valid extrapolated time */ double max_extrapolated_time; /* Latest valid extrapolated time */ long num_rows; /* Number of rows in orbit extension. */ long search_row; /* Most recent search result row */ double search_timem1; /* Time value at row (search_row - 1) */ double search_time0; /* Time value at row search_row */ double search_time1; /* Time value at row (search_row + 1) */ double search_timep1; ORBVELOCITY* search_velm1; /* Orbital velocity at row (search_row - 1) */ ORBVELOCITY* search_velm2; ORBVELOCITY* search_vel0; /* Orbital velocity at row search_row */ ORBVELOCITY* search_vel1; /* Orbital velocity at row (search_row + 1) */ ORBPOSITION* search_pos0; /* Orbital position at row search_row */ ORBPOSITION* search_pos1; /* Orbital position at row (search_row + 1) */ ORBPOSITION* search_posm1; ORBKEPLERIAN* search_kep0; /* Keplerian elements at row search_row */ ORBKEPLERIAN* search_kep1; /* Keplerian elements at row (search_row + 1) */ int last_search_is_reliable; /* Track if last search_* variables are still reliable */ double mjdref; /* MJDREF from orbit file header */ } GENORBFILE; /* ================================================================== */ /* Create a GENORBFILE structure and open the orbit file. */ GENORBFILE* openGenOrbFile( /* Returns a pointer to a new GENORBFILE * struct. The pointer is NULL if the file * cannot be opened. */ char* filename, /* Orbit filename */ char* ext_name, /* Extension containing orbital velocity */ char** orb_col_names, /* Array of velocity column names. */ ORBFORMAT orb_format, /* Enumerated velocity format. */ ORBINTERP interp_method /* Enumerated interpolation method. */ ); /* Close an orbit file and free a GENORBFILE structure. */ void closeGenOrbFile(GENORBFILE* file); /* Print the contents of a GENORBFILE structure to a stream. */ void printGenOrbFile(GENORBFILE* file, FILE* stream); /* Handle FITSIO errors while reading the orbit file. Display error messages but do not terminate execution. */ void checkGenOrbFileFITSErrors ( int status, /* CFITSIO status */ char* doing, /* present participle string of last action */ GENORBFILE* file /* Orbit file structure */ ); /* Set flag in the file structure for the distance unit, m or km */ void setGenOrbFileUnits ( GENORBFILE* file, /* Pointer to file structure */ char* tunit_pos[3], /* TUNIT strings for position columns */ char* tunit_vel[3], /* TUNIT strings for velocity columns */ char* tunit_kep[6] /* TUNIT strings for Keplerian columns */ ); /* Find out whether the orbit file contains position */ int checkGenOrbFileHasPosition(GENORBFILE* file); /* Find out whether the orbit file contains velocity */ int checkGenOrbFileHasVelocity(GENORBFILE* file); /* Read the time from a certain row of the orbit extension. */ double readTimeFromGenOrbFile(GENORBFILE* file, long row); /* Locate the consecutive rows of the orbit table that bracket the input time. */ long findTimeInGenOrbFile(GENORBFILE* file, double time); /* Determine if the time is within the orbit file time range (not * extended by the time margin). Returns 1 (yes) or 0 (no). */ int isTimeWithinGenOrbFile(GENORBFILE* file, double time); /* Set the extrapolated time limits of the orbit table. */ void setGenOrbFileExtrapolationLimits(GENORBFILE* file, double margin); /* Return 1 if time is within the extrapolated time range of the orbit file. Return 0 if not. */ int isInExtrapolatedGenOrbFile(GENORBFILE* file, double time); /* Read the orbital position in units of km from the * orbit table row. Returns the CFITSIO status. */ int readOrbPositionFromGenOrbFile(GENORBFILE* file, ORBPOSITION* orbpos, long row); /* Find the interpolated orbital position at a certain time from an * orbit file. The position is in units of km. */ int findOrbPositionInGenOrbFile(GENORBFILE* file, ORBPOSITION* orbpos, double time); /* Find the interpolated orbital position at a certain time from an * orbit file, with the magnitude and unit vector returned separately. * The position is in units of km. */ int findSplitOrbPositionInGenOrbFile(GENORBFILE* file, double* p_mag, double* p_unit, double time); /* Read the orbital velocity in units of km/s from the * orbit table row. Returns the CFITSIO status. */ int readOrbVelocityFromGenOrbFile(GENORBFILE* file, ORBVELOCITY* orbvel, long row); /* Find the interpolated orbital velocity at a certain time from an * orbit file. The velocity is in units of km/s. */ int findOrbVelocityInGenOrbFile(GENORBFILE* file, ORBVELOCITY* orbvel, double time); /* Find the interpolated orbital velocity at a certain time from an * orbit file, with the magnitude and unit vector returned separately. * The velocity is in units of km/s. */ int findSplitOrbVelocityInGenOrbFile(GENORBFILE* file, double* v_mag, double* v_unit, double time); /* Read the Keplerian orbital elements from the * orbit table row. Returns the CFITSIO status. */ int readOrbKeplerianFromGenOrbFile(GENORBFILE* file, ORBKEPLERIAN* orbkep, long row); /* Compute position and velocity from the Keplerian elements. */ void computePosVelFromKeplerian(ORBPOSITION* pos, ORBVELOCITY* vel, ORBKEPLERIAN* kep); /* Find the interpolated Keplerian orbital elements at a certain time from an * orbit file. */ int findOrbKeplerianInGenOrbFile(GENORBFILE* file, ORBKEPLERIAN* orbkep, double time); /* Linearly interpolate (component-wise) between the start and stop * positions at a time fraction tfrac of the time between the start * and stop positions. */ void interpolateOrbPosition(ORBPOSITION* pos_out, ORBPOSITION* pos_start, ORBPOSITION* pos_stop, double tfrac); /* Use the Taylor series expansion to interpolate the orbital position * (component-wise) about the middle point of three points in time. The output * point is at time dt from the start time, and dtacc is the difference between * start and stop times. The position at the middle time is used, together * with the velocities at all three times. */ void interpolateOrbPositionTaylor(ORBPOSITION* pos_out, ORBPOSITION* pos_middle, ORBVELOCITY* vel_start, ORBVELOCITY* vel_middle, ORBVELOCITY* vel_stop, double dt, double dtacc); /* Linearly interpolate (component-wise) between the start and stop * velocities at a time fraction tfrac of the time between the start * and stop velocities. */ void interpolateOrbVelocity(ORBVELOCITY* vel_out, ORBVELOCITY* vel_start, ORBVELOCITY* vel_stop, double tfrac); /* Linearly interpolate between the start and stop * Keplerian elements at a time fraction tfrac of the time between the start * and stop times. */ void interpolateOrbKeplerian(ORBKEPLERIAN* kep_out, ORBKEPLERIAN* kep_start, ORBKEPLERIAN* kep_stop, double tfrac); /* Linearly interpolate between two angles in degrees. */ double interpolateAngle(double tfrac, double ang_start, double ang_stop); /* Allocate an orbital position vector. */ ORBPOSITION* allocateOrbPosition(); /* Allocate an orbital velocity vector. */ ORBVELOCITY* allocateOrbVelocity(); /* Allocate an orbital elements vector. */ ORBKEPLERIAN* allocateOrbKeplerian(); /* Free an orbital position vector. */ void destroyOrbPosition(ORBPOSITION* orbpos); /* Free an orbital velocity vector. */ void destroyOrbVelocity(ORBVELOCITY* orbvel); /* Free an orbital elements vector. */ void destroyOrbKeplerian(ORBKEPLERIAN* orbkep); /* Set the orbital position from its components. */ void setOrbPosition(ORBPOSITION* orbpos, double px, double py, double pz); /* Set the orbital velocity from its components. */ void setOrbVelocity(ORBVELOCITY* orbvel, double vx, double vy, double vz); /* Set the Keplerian orbital elements structure from its components. */ void setOrbKeplerian(ORBKEPLERIAN* orbkep, double kep_a, double kep_e, double kep_i, double kep_an, double kep_ap, double kep_ma); /* Set the orbital position to zero. */ void setOrbPositionToZero(ORBPOSITION* orbpos); /* Set the orbital velocity to zero. */ void setOrbVelocityToZero(ORBVELOCITY* orbvel); /* Set the Keplerian orbital elements to zero. */ void setOrbKeplerianToZero(ORBKEPLERIAN* orbkep); /* Get the orbital velocity magnitude. */ double getOrbVelocityMagnitude(ORBVELOCITY* orbvel); /* Get the orbital velocity unit vector as a 3-element array. Returns * 1 if magnitude of orbvel is 0, otherwise returns 1. */ int getOrbVelocityUnitVector(ORBVELOCITY* orbvel, double* unit_vector); /* Return 1 if all components of orbvel are 0, otherwise return 0. */ /* int isOrbVelocityNull(ORBVELOCITY* orbvel); */ /* Print the orbital position to a stream. */ void printOrbPosition(ORBPOSITION* orbpos, FILE* stream); /* Print the orbital velocity to a stream. */ void printOrbVelocity(ORBVELOCITY* orbvel, FILE* stream); /* Print the Keplerian orbital elements to a stream. */ void printOrbKeplerian(ORBKEPLERIAN* orbkep, FILE* stream); /* Return an array of pointers to structures containing the numbers of * columns and elements within a column for each orbit format. Use * the ORBFORMAT values as array indices, for example, * orb_format_info[ORB_VECTOR]->num_elements. */ ORB_FORMAT_INFO** getOrbFormatInfo(); #endif /* GENORBFILE_INCLUDED */ #ifdef __cplusplus } /* end extern "C" */ #endif /* ====================================================================== */ /* Revision log $Log: genorbfile.h,v $ Revision 1.7 2015/11/17 20:15:47 driethmi Number of orbit formats is now 9, instead of 8, since we've added the ORBF_KEPLERIAN_NODUP type. Revision 1.6 2015/11/13 18:59:29 driethmi If the orbit format is ORBF_KEPLERIAN_NODUP, then we're in a mode that forbids duplicate rows in the orbit file. In this case, automatically set all weights to 1.0, and don't bother looking for the weights column. Revision 1.5 2015/10/01 19:11:00 driethmi Implemented genorbfile changes as prescribed by HAK in the coordevt TRF, 15-09-23. Revision 1.4 2015/06/19 23:38:26 rshill Added Taylor interpolation method; fixed some inconsistencies in variable names and also between findOrbPositionInGenOrbFile and findOrbVelocityInGenOrbFile. Revision 1.3 2015/04/03 22:55:36 rshill Automatic processing of orbital units: m vs. km, rad vs. deg. Revision 1.2 2015/03/18 23:04:42 rshill Support orbital position and Keplerian elements. Revision 1.1 2014/07/14 19:56:05 rshill General orbit file handling */