00001
00002
00003
00004
00005 #ifndef LOCAL_SOLEPHEM_INCL
00006 #include "solephem.c"
00007 #endif
00008
00009 static int sds_flip (void *data, long length, int size) {
00010 long i,j;
00011 char *c, t;
00012 unsigned short *s;
00013 unsigned int *l;
00014
00015 if (data == NULL) return 1;
00016
00017 if (size == 2) {
00018 s = (unsigned short *)data;
00019 for (i=0; i<length; i++, s++) *s = (*s<<8) | (*s>>8);
00020 } else if (size == 4) {
00021 l = (unsigned int *)data;
00022 for (i=0; i<length; i++, l++)
00023 *l = (*l<<24) | ((*l&0xff00)<<8) | ((*l&0xff0000)>>8) | (*l>>24);
00024 } else {
00025 c = (char *)data;
00026 for (i=0; i<length; i++, c+=size)
00027 for (j=0; j<(size/2); j++) {
00028 t = *(c+j);
00029 *(c+j) = *(c+size-j-1);
00030 *(c+size-j-1) = t;
00031 }
00032 }
00033
00034 return 0;
00035 }
00036
00037 #define SUMMARY_FILE ("/home/soi/CM/tables/ephemeris/summary")
00038 #define TABLE_DT (600.0)
00039 #define SUMMARY_REC (6)
00040
00041 int soho_ephemeris (TIME obs_time, double *r, double *b, double *l,
00042 double *vr, double *vn, double *vw, TIME *table_mod_time) {
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 static FILE *sumfile = NULL;
00054 static int firstcall = 1;
00055 static TIME tab_start, tab_stop;
00056 struct stat stat_buf;
00057 double obs_vel0[SUMMARY_REC], obs_vel1[SUMMARY_REC];
00058 double dt, f0, f1;
00059 int gap, offset, reclen = SUMMARY_REC * sizeof (double);
00060
00061 if (firstcall) {
00062 stat (SUMMARY_FILE, &stat_buf);
00063 *table_mod_time = stat_buf.st_mtime + UNIX_EPOCH;
00064 sumfile = fopen (SUMMARY_FILE, "r");
00065 if (sumfile) {
00066 fread (&tab_start, sizeof (TIME), 1, sumfile);
00067 fread (&tab_stop, sizeof (TIME), 1, sumfile);
00068 #if __BYTE_ORDER == __LITTLE_ENDIAN
00069 sds_flip ((void *)&tab_start, 1, sizeof (TIME));
00070 sds_flip ((void *)&tab_stop, 1, sizeof (TIME));
00071 #endif
00072 }
00073 firstcall = 0;
00074 }
00075
00076 if (!sumfile || obs_time < tab_start || obs_time > (tab_stop + TABLE_DT)) {
00077 double p1, p2;
00078 double ephem[EPHEM_SIZE];
00079 calc_sun_ephemeris (obs_time, ephem, 0.0, 0.0);
00080 *r = 0.99 * ephem[EPHEM_DIST];
00081 *l = 360.0 - fmod (ephem[EPHEM_L0], 360.0);
00082 *b = ephem[EPHEM_B0] * 180.0 / M_PI;
00083 *vw = ephem[EPHEM_VEARTH];
00084 *vn = ephem[EPHEM_B0V];
00085 calc_sun_ephemeris (obs_time - 1.0e5, ephem, 0.0, 0.0);
00086 p1 = ephem[EPHEM_DIST];
00087 calc_sun_ephemeris (obs_time + 1.0e5, ephem, 0.0, 0.0);
00088 p2 = ephem[EPHEM_DIST];
00089 *vr = (1.496e11)*(p2 - p1)/2.0e5;
00090 return (sumfile ? -1 : -2);
00091 }
00092 if (obs_time >= tab_stop) {
00093 fseek (sumfile, -reclen, SEEK_END);
00094 fread (obs_vel0, sizeof (double), SUMMARY_REC, sumfile);
00095 #if __BYTE_ORDER == __LITTLE_ENDIAN
00096 sds_flip ((void *)obs_vel0, SUMMARY_REC, sizeof (double));
00097 #endif
00098 *vw = obs_vel0[4];
00099 *vn = obs_vel0[5];
00100 *r = obs_vel0[0];
00101 *vr = obs_vel0[3];
00102 *b = obs_vel0[2];
00103 *l = obs_vel0[1];
00104 return (1);
00105 }
00106 offset = reclen * floor ((obs_time - tab_start) / TABLE_DT) +
00107 2 * sizeof (TIME);
00108 fseek (sumfile, offset, SEEK_SET);
00109 fread (obs_vel0, sizeof (double), SUMMARY_REC, sumfile);
00110 fread (obs_vel1, sizeof (double), SUMMARY_REC, sumfile);
00111 #if __BYTE_ORDER == __LITTLE_ENDIAN
00112 sds_flip ((void *)obs_vel0, SUMMARY_REC, sizeof (double));
00113 sds_flip ((void *)obs_vel1, SUMMARY_REC, sizeof (double));
00114 #endif
00115 dt = fmod ((obs_time - tab_start), TABLE_DT) / TABLE_DT;
00116 f1 = dt; f0 = 1.0 - f1;
00117 *r = f0 * obs_vel0[0] + f1 * obs_vel1[0];
00118 while (obs_vel1[1] > obs_vel0[1]) obs_vel1[1] -= 360.0;
00119 *l = f0 * obs_vel0[1] + f1 * obs_vel1[1];
00120 while (*l < 0.0) *l += 360.0;
00121 *b = f0 * obs_vel0[2] + f1 * obs_vel1[2];
00122 *vr = f0 * obs_vel0[3] + f1 * obs_vel1[3];
00123 *vw = f0 * obs_vel0[4] + f1 * obs_vel1[4];
00124 *vn = f0 * obs_vel0[5] + f1 * obs_vel1[5];
00125 return (0);
00126 }
00127
00128 #define CARRINGTON_EPOCH ("1853.11.09_12:00")
00129 #define CARR_ROT_SYNODIC (27.275311 * 86400.0)
00130
00131
00132 double carrington_rots (TIME obs_time, int forsoho) {
00133 TIME upd;
00134 double ephem[EPHEM_SIZE];
00135 double car_rot, clong, clest;
00136 double r, lat, lon, vr, vn, vw;
00137 int carr_ct;
00138
00139 car_rot = 1.0 + (obs_time - sscan_time (CARRINGTON_EPOCH)) / CARR_ROT_SYNODIC;
00140 carr_ct = car_rot;
00141 clest = car_rot - carr_ct;
00142 if (forsoho)
00143 soho_ephemeris (obs_time, &r, &lat, &lon, &vr, &vn, &vw, &upd);
00144 else {
00145 calc_sun_ephemeris (obs_time, ephem, 0.0, 0.0);
00146 lon = 360.0 - fmod (ephem[EPHEM_L0], 360.0);
00147 }
00148 clong = 1.0 - lon / 360.0;
00149 if ((clong - clest) > 0.5) carr_ct--;
00150 if ((clest - clong) > 0.5) carr_ct++;
00151 return (carr_ct + clong);
00152 }
00153
00154 #define CRR0 (1650)
00155 #define ERR (0.0000770)
00156 #define LONN0 (357.895)
00157 #define K (6546.07464)
00158
00159
00160
00161 TIME SOHO_meridian_crossing (double lonn, int crr) {
00162
00163
00164
00165
00166 TIME modt;
00167 double au, lon, lat, vr, vn, vw;
00168 double phi, secapp;
00169
00170 secapp = ((crr - CRR0) * 360.0 - (lonn - LONN0)) * K;
00171 soho_ephemeris (secapp, &au, &lat, &lon, &vr, &vn, &vw, &modt);
00172
00173 while (lonn >= 360.0) lonn -= 360.0;
00174 while (lonn < 0.0) lonn += 360.0;
00175 phi = lon - lonn;
00176 while (phi > 180.0) phi -= 360.0;
00177 while (phi < -180.0) phi += 360.0;
00178 while (fabs (phi) > ERR) {
00179 secapp += phi * K;
00180 soho_ephemeris (secapp, &au, &lat, &lon, &vr, &vn, &vw, &modt);
00181 phi = lon - lonn;
00182 while (phi > 180.0) phi -= 360.0;
00183 while (phi < -180.0) phi += 360.0;
00184 }
00185 return secapp;
00186 }