swe4r 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/swe4r/extconf.rb +3 -0
- data/ext/swe4r/src/swemptab.c +10642 -0
- data/ext/swe4r/swe4r.c +129 -0
- data/ext/swe4r/swecl.c +4948 -0
- data/ext/swe4r/swedate.c +590 -0
- data/ext/swe4r/swedate.h +82 -0
- data/ext/swe4r/swehel.c +3445 -0
- data/ext/swe4r/swehouse.c +1727 -0
- data/ext/swe4r/swehouse.h +85 -0
- data/ext/swe4r/swejpl.c +937 -0
- data/ext/swe4r/swejpl.h +105 -0
- data/ext/swe4r/swemmoon.c +1824 -0
- data/ext/swe4r/swemplan.c +959 -0
- data/ext/swe4r/swenut2000a.h +2820 -0
- data/ext/swe4r/sweodef.h +325 -0
- data/ext/swe4r/sweph.c +6241 -0
- data/ext/swe4r/sweph.h +556 -0
- data/ext/swe4r/swephexp.h +749 -0
- data/ext/swe4r/swephlib.c +2581 -0
- data/ext/swe4r/swephlib.h +177 -0
- data/lib/swe4r.rb +2 -0
- metadata +66 -0
data/ext/swe4r/swejpl.c
ADDED
@@ -0,0 +1,937 @@
|
|
1
|
+
|
2
|
+
/*
|
3
|
+
| $Header: /home/dieter/sweph/RCS/swejpl.c,v 1.76 2008/08/26 13:55:36 dieter Exp $
|
4
|
+
|
|
5
|
+
| Subroutines for reading JPL ephemerides.
|
6
|
+
| derived from testeph.f as contained in DE403 distribution July 1995.
|
7
|
+
| works with DE200, DE102, DE403, DE404, DE405, DE406.
|
8
|
+
| (attention, DE102 has 1950 reference frame and also DE4* has slightly
|
9
|
+
| different reference frame from DE200. With DE4*, use routine
|
10
|
+
| IERS_FK5().)
|
11
|
+
|
12
|
+
Authors: Dieter Koch and Alois Treindl, Astrodienst Zurich
|
13
|
+
|
14
|
+
************************************************************/
|
15
|
+
/* Copyright (C) 1997 - 2008 Astrodienst AG, Switzerland. All rights reserved.
|
16
|
+
|
17
|
+
License conditions
|
18
|
+
------------------
|
19
|
+
|
20
|
+
This file is part of Swiss Ephemeris.
|
21
|
+
|
22
|
+
Swiss Ephemeris is distributed with NO WARRANTY OF ANY KIND. No author
|
23
|
+
or distributor accepts any responsibility for the consequences of using it,
|
24
|
+
or for whether it serves any particular purpose or works at all, unless he
|
25
|
+
or she says so in writing.
|
26
|
+
|
27
|
+
Swiss Ephemeris is made available by its authors under a dual licensing
|
28
|
+
system. The software developer, who uses any part of Swiss Ephemeris
|
29
|
+
in his or her software, must choose between one of the two license models,
|
30
|
+
which are
|
31
|
+
a) GNU public license version 2 or later
|
32
|
+
b) Swiss Ephemeris Professional License
|
33
|
+
|
34
|
+
The choice must be made before the software developer distributes software
|
35
|
+
containing parts of Swiss Ephemeris to others, and before any public
|
36
|
+
service using the developed software is activated.
|
37
|
+
|
38
|
+
If the developer choses the GNU GPL software license, he or she must fulfill
|
39
|
+
the conditions of that license, which includes the obligation to place his
|
40
|
+
or her whole software project under the GNU GPL or a compatible license.
|
41
|
+
See http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
42
|
+
|
43
|
+
If the developer choses the Swiss Ephemeris Professional license,
|
44
|
+
he must follow the instructions as found in http://www.astro.com/swisseph/
|
45
|
+
and purchase the Swiss Ephemeris Professional Edition from Astrodienst
|
46
|
+
and sign the corresponding license contract.
|
47
|
+
|
48
|
+
The License grants you the right to use, copy, modify and redistribute
|
49
|
+
Swiss Ephemeris, but only under certain conditions described in the License.
|
50
|
+
Among other things, the License requires that the copyright notices and
|
51
|
+
this notice be preserved on all copies.
|
52
|
+
|
53
|
+
Authors of the Swiss Ephemeris: Dieter Koch and Alois Treindl
|
54
|
+
|
55
|
+
The authors of Swiss Ephemeris have no control or influence over any of
|
56
|
+
the derived works, i.e. over software or services created by other
|
57
|
+
programmers which use Swiss Ephemeris functions.
|
58
|
+
|
59
|
+
The names of the authors or of the copyright holder (Astrodienst) must not
|
60
|
+
be used for promoting any software, product or service which uses or contains
|
61
|
+
the Swiss Ephemeris. This copyright notice is the ONLY place where the
|
62
|
+
names of the authors can legally appear, except in cases where they have
|
63
|
+
given special permission in writing.
|
64
|
+
|
65
|
+
The trademarks 'Swiss Ephemeris' and 'Swiss Ephemeris inside' may be used
|
66
|
+
for promoting such software, products or services.
|
67
|
+
*/
|
68
|
+
|
69
|
+
|
70
|
+
#include <string.h>
|
71
|
+
#include "swephexp.h"
|
72
|
+
#include "sweph.h"
|
73
|
+
#include "swejpl.h"
|
74
|
+
|
75
|
+
#define DEBUG_DO_SHOW FALSE
|
76
|
+
|
77
|
+
#ifndef NO_JPL
|
78
|
+
/*
|
79
|
+
* local globals
|
80
|
+
*/
|
81
|
+
struct jpl_save {
|
82
|
+
char *jplfname;
|
83
|
+
char *jplfpath;
|
84
|
+
FILE *jplfptr;
|
85
|
+
short do_reorder;
|
86
|
+
double eh_cval[400];
|
87
|
+
double eh_ss[3], eh_au, eh_emrat;
|
88
|
+
int32 eh_denum, eh_ncon, eh_ipt[39];
|
89
|
+
char ch_cnam[6*400];
|
90
|
+
double pv[78];
|
91
|
+
double pvsun[6];
|
92
|
+
double buf[1500];
|
93
|
+
double pc[18], vc[18], ac[18], jc[18];
|
94
|
+
short do_km;
|
95
|
+
};
|
96
|
+
|
97
|
+
static struct jpl_save *FAR js;
|
98
|
+
|
99
|
+
static int state (double et, int32 *list, int do_bary,
|
100
|
+
double *pv, double *pvsun, double *nut, char *serr);
|
101
|
+
static int interp(double FAR *buf, double t, double intv, int32 ncfin,
|
102
|
+
int32 ncmin, int32 nain, int32 ifl, double *pv);
|
103
|
+
static int32 fsizer(char *serr);
|
104
|
+
static void reorder(char *x, int size, int number);
|
105
|
+
static int read_const_jpl(double *ss, char *serr);
|
106
|
+
|
107
|
+
/* information about eh_ipt[] and buf[]
|
108
|
+
DE200 DE102 DE403
|
109
|
+
3 3 ipt[0] 3 body 0 (mercury) starts at buf[2]
|
110
|
+
12 15 ipt[1] 14 body 0, ncf = coefficients per component
|
111
|
+
4 2 ipt[2] 4 na = nintervals, tot 14*4*3=168
|
112
|
+
147 93 ipt[3] 171 body 1 (venus) starts at buf[170]
|
113
|
+
12 15 ipt[4] 10 ncf = coefficients per component
|
114
|
+
1 1 ipt[5] 2 total 10*2*3=60
|
115
|
+
183 138 ipt[6] 231 body 2 (earth) starts at buf[230]
|
116
|
+
15 15 ipt[7] 13 ncf = coefficients per component
|
117
|
+
2 2 ipt[8] 2 total 13*2*3=78
|
118
|
+
273 228 ipt[9] 309 body 3 (mars) starts at buf[308]
|
119
|
+
10 10 ipt[10] 11 ncf = coefficients per component
|
120
|
+
1 1 ipt[11] 1 total 11*1*3=33
|
121
|
+
303 258 ipt[12] 342 body 4 (jupiter) at buf[341]
|
122
|
+
9 9 ipt[13] 8 total 8 * 1 * 3 = 24
|
123
|
+
1 1 ipt[14] 1
|
124
|
+
330 285 ipt[15] 366 body 5 (saturn) at buf[365]
|
125
|
+
8 8 ipt[16] 7 total 7 * 1 * 3 = 21
|
126
|
+
1 1 ipt[17] 1
|
127
|
+
354 309 ipt[18] 387 body 6 (uranus) at buf[386]
|
128
|
+
8 8 ipt[19] 6 total 6 * 1 * 3 = 18
|
129
|
+
1 1 ipt[20] 1
|
130
|
+
378 333 ipt[21] 405 body 7 (neptune) at buf[404]
|
131
|
+
6 6 ipt[22] 6 total 18
|
132
|
+
1 1 ipt[23] 1
|
133
|
+
396 351 ipt[24] 423 body 8 (pluto) at buf[422]
|
134
|
+
6 6 ipt[25] 6 total 18
|
135
|
+
1 1 ipt[26] 1
|
136
|
+
414 369 ipt[27] 441 body 9 (moon) at buf[440]
|
137
|
+
12 15 ipt[28] 13 total 13 * 8 * 3 = 312
|
138
|
+
8 8 ipt[29] 8
|
139
|
+
702 729 ipt[30] 753 SBARY SUN, starts at buf[752]
|
140
|
+
15 15 ipt[31] 11 SBARY SUN, ncf = coeff per component
|
141
|
+
1 1 ipt[32] 2 total 11*2*3=66
|
142
|
+
747 774 ipt[33] 819 nutations, starts at buf[818]
|
143
|
+
10 0 ipt[34] 10 total 10 * 4 * 2 = 80
|
144
|
+
4 0 ipt[35] 4 (nutation only two coordinates)
|
145
|
+
0 0 ipt[36] 899 librations, start at buf[898]
|
146
|
+
0 0 ipt[37] 10 total 10 * 4 * 3 = 120
|
147
|
+
0 0 ipt[38] 4
|
148
|
+
|
149
|
+
last element of buf[1017]
|
150
|
+
buf[0] contains start jd and buf[1] end jd of segment;
|
151
|
+
each segment is 32 days in de403, 64 days in DE102, 32 days in DE200
|
152
|
+
|
153
|
+
Length of blocks: DE406 = 1456*4=5824 bytes = 728 double
|
154
|
+
DE405 = 2036*4=8144 bytes = 1018 double
|
155
|
+
DE404 = 1456*4=5824 bytes = 728 double
|
156
|
+
DE403 = 2036*4=8144 bytes = 1018 double
|
157
|
+
DE200 = 1652*4=6608 bytes = 826 double
|
158
|
+
DE102 = 1546*4=6184 bytes = 773 double
|
159
|
+
each DE102 record has 53*8=424 fill bytes so that
|
160
|
+
the records have the same length as DE200.
|
161
|
+
*/
|
162
|
+
|
163
|
+
/*
|
164
|
+
* This subroutine opens the file jplfname, with a phony record length,
|
165
|
+
* reads the first record, and uses the info to compute ksize,
|
166
|
+
* the number of single precision words in a record.
|
167
|
+
* RETURN: ksize (record size of ephemeris data)
|
168
|
+
* jplfptr is opened on return.
|
169
|
+
* note 26-aug-2008: now record size is computed by fsizer(), not
|
170
|
+
* set to a fixed value depending as in previous releases. The caller of
|
171
|
+
* fsizer() will verify by data comparison whether it computed correctly.
|
172
|
+
*/
|
173
|
+
static int32 fsizer(char *serr)
|
174
|
+
{
|
175
|
+
/* Local variables */
|
176
|
+
int32 ncon;
|
177
|
+
double emrat;
|
178
|
+
int32 numde;
|
179
|
+
double au, ss[3];
|
180
|
+
int i, kmx, khi, nd;
|
181
|
+
int32 ksize, lpt[3];
|
182
|
+
char ttl[6*14*3];
|
183
|
+
if ((js->jplfptr = swi_fopen(SEI_FILE_PLANET, js->jplfname, js->jplfpath, serr)) == NULL) {
|
184
|
+
return NOT_AVAILABLE;
|
185
|
+
}
|
186
|
+
/* ttl = ephemeris title, e.g.
|
187
|
+
* "JPL Planetary Ephemeris DE404/LE404
|
188
|
+
* Start Epoch: JED= 625296.5-3001 DEC 21 00:00:00
|
189
|
+
* Final Epoch: JED= 2817168.5 3001 JAN 17 00:00:00c */
|
190
|
+
fread((void *) &ttl[0], 1, 252, js->jplfptr);
|
191
|
+
/* cnam = names of constants */
|
192
|
+
fread((void *) js->ch_cnam, 1, 6*400, js->jplfptr);
|
193
|
+
/* ss[0] = start epoch of ephemeris
|
194
|
+
* ss[1] = end epoch
|
195
|
+
* ss[2] = segment size in days */
|
196
|
+
fread((void *) &ss[0], sizeof(double), 3, js->jplfptr);
|
197
|
+
/* reorder ? */
|
198
|
+
if (ss[2] < 1 || ss[2] > 200)
|
199
|
+
js->do_reorder = TRUE;
|
200
|
+
else
|
201
|
+
js->do_reorder = 0;
|
202
|
+
for (i = 0; i < 3; i++)
|
203
|
+
js->eh_ss[i] = ss[i];
|
204
|
+
if (js->do_reorder)
|
205
|
+
reorder((char *) &js->eh_ss[0], sizeof(double), 3);
|
206
|
+
/* plausibility test of these constants. Start and end date must be
|
207
|
+
* between -20000 and +20000, segment size >= 1 and <= 200 */
|
208
|
+
if (js->eh_ss[0] < -5583942 || js->eh_ss[1] > 9025909 || js->eh_ss[2] < 1 || js->eh_ss[2] > 200) {
|
209
|
+
if (serr != NULL)
|
210
|
+
sprintf(serr, "alleged ephemeris file (%s) has invalid format.", js->jplfname);
|
211
|
+
return(NOT_AVAILABLE);
|
212
|
+
}
|
213
|
+
/* ncon = number of constants */
|
214
|
+
fread((void *) &ncon, sizeof(int32), 1, js->jplfptr);
|
215
|
+
if (js->do_reorder)
|
216
|
+
reorder((char *) &ncon, sizeof(int32), 1);
|
217
|
+
/* au = astronomical unit */
|
218
|
+
fread((void *) &au, sizeof(double), 1, js->jplfptr);
|
219
|
+
if (js->do_reorder)
|
220
|
+
reorder((char *) &au, sizeof(double), 1);
|
221
|
+
/* emrat = earth moon mass ratio */
|
222
|
+
fread((void *) &emrat, sizeof(double), 1, js->jplfptr);
|
223
|
+
if (js->do_reorder)
|
224
|
+
reorder((char *) &emrat, sizeof(double), 1);
|
225
|
+
/* ipt[i+0]: coefficients of planet i start at buf[ipt[i+0]-1]
|
226
|
+
* ipt[i+1]: number of coefficients (interpolation order - 1)
|
227
|
+
* ipt[i+2]: number of intervals in segment */
|
228
|
+
fread((void *) &js->eh_ipt[0], sizeof(int32), 36, js->jplfptr);
|
229
|
+
if (js->do_reorder)
|
230
|
+
reorder((char *) &js->eh_ipt[0], sizeof(int32), 36);
|
231
|
+
/* numde = number of jpl ephemeris "404" with de404 */
|
232
|
+
fread((void *) &numde, sizeof(int32), 1, js->jplfptr);
|
233
|
+
if (js->do_reorder)
|
234
|
+
reorder((char *) &numde, sizeof(int32), 1);
|
235
|
+
/* read librations */
|
236
|
+
fread(&lpt[0], sizeof(int32), 3, js->jplfptr);
|
237
|
+
if (js->do_reorder)
|
238
|
+
reorder((char *) &lpt[0], sizeof(int32), 3);
|
239
|
+
/* fill librations into eh_ipt[36]..[38] */
|
240
|
+
for (i = 0; i < 3; ++i)
|
241
|
+
js->eh_ipt[i + 36] = lpt[i];
|
242
|
+
rewind(js->jplfptr);
|
243
|
+
/* find the number of ephemeris coefficients from the pointers */
|
244
|
+
/* re-activated this code on 26-aug-2008 */
|
245
|
+
kmx = 0;
|
246
|
+
khi = 0;
|
247
|
+
for (i = 0; i < 13; i++) {
|
248
|
+
if (js->eh_ipt[i * 3] > kmx) {
|
249
|
+
kmx = js->eh_ipt[i * 3];
|
250
|
+
khi = i + 1;
|
251
|
+
}
|
252
|
+
}
|
253
|
+
if (khi == 12)
|
254
|
+
nd = 2;
|
255
|
+
else
|
256
|
+
nd = 3;
|
257
|
+
ksize = (js->eh_ipt[khi * 3 - 3] + nd * js->eh_ipt[khi * 3 - 2] * js->eh_ipt[khi * 3 - 1] - 1L) * 2L;
|
258
|
+
/*
|
259
|
+
* de102 files give wrong ksize, because they contain 424 empty bytes
|
260
|
+
* per record. Fixed by hand!
|
261
|
+
*/
|
262
|
+
if (ksize == 1546)
|
263
|
+
ksize = 1652;
|
264
|
+
#if 0 /* we prefer to compute ksize to be comaptible
|
265
|
+
with new DE releases */
|
266
|
+
switch (numde) {
|
267
|
+
case 403:
|
268
|
+
case 405:
|
269
|
+
case 410:
|
270
|
+
case 413:
|
271
|
+
case 414:
|
272
|
+
case 418:
|
273
|
+
case 421:
|
274
|
+
ksize = 2036;
|
275
|
+
break;
|
276
|
+
case 404:
|
277
|
+
case 406:
|
278
|
+
ksize = 1456;
|
279
|
+
break;
|
280
|
+
case 200:
|
281
|
+
ksize = 1652;
|
282
|
+
break;
|
283
|
+
case 102:
|
284
|
+
ksize = 1652; /* de102 is filled with blanks to length of de200 */
|
285
|
+
break;
|
286
|
+
default:
|
287
|
+
if (serr != NULL)
|
288
|
+
sprintf(serr,"unknown numde value %d;", numde);
|
289
|
+
return ERR;
|
290
|
+
}
|
291
|
+
#endif
|
292
|
+
if (ksize < 1000 || ksize > 5000) {
|
293
|
+
if (serr != NULL)
|
294
|
+
sprintf(serr, "JPL ephemeris file does not provide valid ksize (%d)", ksize);/**/
|
295
|
+
return NOT_AVAILABLE;
|
296
|
+
}
|
297
|
+
return ksize;
|
298
|
+
}
|
299
|
+
|
300
|
+
/*
|
301
|
+
* This subroutine reads the jpl planetary ephemeris
|
302
|
+
* and gives the position and velocity of the point 'ntarg'
|
303
|
+
* with respect to 'ncent'.
|
304
|
+
* calling sequence parameters:
|
305
|
+
* et = d.p. julian ephemeris date at which interpolation
|
306
|
+
* is wanted.
|
307
|
+
* ** note the entry dpleph for a doubly-dimensioned time **
|
308
|
+
* the reason for this option is discussed in the
|
309
|
+
* subroutine state
|
310
|
+
* ntarg = integer number of 'target' point.
|
311
|
+
* ncent = integer number of center point.
|
312
|
+
* the numbering convention for 'ntarg' and 'ncent' is:
|
313
|
+
* 0 = mercury 7 = neptune
|
314
|
+
* 1 = venus 8 = pluto
|
315
|
+
* 2 = earth 9 = moon
|
316
|
+
* 3 = mars 10 = sun
|
317
|
+
* 4 = jupiter 11 = solar-system barycenter
|
318
|
+
* 5 = saturn 12 = earth-moon barycenter
|
319
|
+
* 6 = uranus 13 = nutations (longitude and obliq)
|
320
|
+
* 14 = librations, if on eph file
|
321
|
+
* (if nutations are wanted, set ntarg = 13. for librations,
|
322
|
+
* set ntarg = 14. set ncent=0.)
|
323
|
+
* rrd = output 6-word d.p. array containing position and velocity
|
324
|
+
* of point 'ntarg' relative to 'ncent'. the units are au and
|
325
|
+
* au/day. for librations the units are radians and radians
|
326
|
+
* per day. in the case of nutations the first four words of
|
327
|
+
* rrd will be set to nutations and rates, having units of
|
328
|
+
* radians and radians/day.
|
329
|
+
* The option is available to have the units in km and km/sec.
|
330
|
+
* For this, set do_km=TRUE (default FALSE).
|
331
|
+
*/
|
332
|
+
int swi_pleph(double et, int ntarg, int ncent, double *rrd, char *serr)
|
333
|
+
{
|
334
|
+
int i, retc;
|
335
|
+
int32 list[12];
|
336
|
+
double FAR *pv = js->pv;
|
337
|
+
double FAR *pvsun = js->pvsun;
|
338
|
+
for (i = 0; i < 6; ++i)
|
339
|
+
rrd[i] = 0.0;
|
340
|
+
if (ntarg == ncent)
|
341
|
+
return 0;
|
342
|
+
for (i = 0; i < 12; ++i)
|
343
|
+
list[i] = 0;
|
344
|
+
/* check for nutation call */
|
345
|
+
if (ntarg == J_NUT) {
|
346
|
+
if (js->eh_ipt[34] > 0) {
|
347
|
+
list[10] = 2;
|
348
|
+
return(state(et, list, FALSE, pv, pvsun, rrd, serr));
|
349
|
+
} else {
|
350
|
+
if (serr != NULL)
|
351
|
+
sprintf(serr,"No nutations on the JPL ephemeris file;");
|
352
|
+
return (NOT_AVAILABLE);
|
353
|
+
}
|
354
|
+
}
|
355
|
+
if (ntarg == J_LIB) {
|
356
|
+
if (js->eh_ipt[37] > 0) {
|
357
|
+
list[11] = 2;
|
358
|
+
if ((retc = state(et, list, FALSE, pv, pvsun, rrd, serr)) != OK)
|
359
|
+
return (retc);
|
360
|
+
for (i = 0; i < 6; ++i)
|
361
|
+
rrd[i] = pv[i + 60];
|
362
|
+
return 0;
|
363
|
+
} else {
|
364
|
+
if (serr != NULL)
|
365
|
+
sprintf(serr,"No librations on the ephemeris file;");
|
366
|
+
return (NOT_AVAILABLE);
|
367
|
+
}
|
368
|
+
}
|
369
|
+
/* set up proper entries in 'list' array for state call */
|
370
|
+
if (ntarg < J_SUN)
|
371
|
+
list[ntarg] = 2;
|
372
|
+
if (ntarg == J_MOON) /* Mooon needs Earth */
|
373
|
+
list[J_EARTH] = 2;
|
374
|
+
if (ntarg == J_EARTH) /* Earth needs Moon */
|
375
|
+
list[J_MOON] = 2;
|
376
|
+
if (ntarg == J_EMB) /* EMB needs Earth */
|
377
|
+
list[J_EARTH] = 2;
|
378
|
+
if (ncent < J_SUN)
|
379
|
+
list[ncent] = 2;
|
380
|
+
if (ncent == J_MOON) /* Mooon needs Earth */
|
381
|
+
list[J_EARTH] = 2;
|
382
|
+
if (ncent == J_EARTH) /* Earth needs Moon */
|
383
|
+
list[J_MOON] = 2;
|
384
|
+
if (ncent == J_EMB) /* EMB needs Earth */
|
385
|
+
list[J_EARTH] = 2;
|
386
|
+
if ((retc = state(et, list, TRUE, pv, pvsun, rrd, serr)) != OK)
|
387
|
+
return (retc);
|
388
|
+
if (ntarg == J_SUN || ncent == J_SUN) {
|
389
|
+
for (i = 0; i < 6; ++i)
|
390
|
+
pv[i + 6*J_SUN] = pvsun[i];
|
391
|
+
}
|
392
|
+
if (ntarg == J_SBARY || ncent == J_SBARY) {
|
393
|
+
for (i = 0; i < 6; ++i) {
|
394
|
+
pv[i + 6*J_SBARY] = 0.;
|
395
|
+
}
|
396
|
+
}
|
397
|
+
if (ntarg == J_EMB || ncent == J_EMB) {
|
398
|
+
for (i = 0; i < 6; ++i)
|
399
|
+
pv[i + 6*J_EMB] = pv[i + 6*J_EARTH];
|
400
|
+
}
|
401
|
+
if ((ntarg==J_EARTH && ncent==J_MOON) || (ntarg == J_MOON && ncent==J_EARTH)){
|
402
|
+
for (i = 0; i < 6; ++i)
|
403
|
+
pv[i + 6*J_EARTH] = 0.;
|
404
|
+
|
405
|
+
} else {
|
406
|
+
if (list[J_EARTH] == 2) {
|
407
|
+
for (i = 0; i < 6; ++i)
|
408
|
+
pv[i + 6*J_EARTH] -= pv[i + 6*J_MOON] / (js->eh_emrat + 1.);
|
409
|
+
}
|
410
|
+
if (list[J_MOON] == 2) {
|
411
|
+
for (i = 0; i < 6; ++i) {
|
412
|
+
pv[i + 6*J_MOON] += pv[i + 6*J_EARTH];
|
413
|
+
}
|
414
|
+
}
|
415
|
+
}
|
416
|
+
for (i = 0; i < 6; ++i)
|
417
|
+
rrd[i] = pv[i + ntarg * 6] - pv[i + ncent * 6];
|
418
|
+
return OK;
|
419
|
+
}
|
420
|
+
|
421
|
+
/*
|
422
|
+
* This subroutine differentiates and interpolates a
|
423
|
+
* set of chebyshev coefficients to give pos, vel, acc, and jerk
|
424
|
+
* calling sequence parameters:
|
425
|
+
* input:
|
426
|
+
* buf 1st location of array of d.p. chebyshev coefficients of position
|
427
|
+
* t is dp fractional time in interval covered by
|
428
|
+
* coefficients at which interpolation is wanted, 0 <= t <= 1
|
429
|
+
* intv is dp length of whole interval in input time units.
|
430
|
+
* ncf number of coefficients per component
|
431
|
+
* ncm number of components per set of coefficients
|
432
|
+
* na number of sets of coefficients in full array
|
433
|
+
* (i.e., number of sub-intervals in full interval)
|
434
|
+
* ifl int flag: =1 for positions only
|
435
|
+
* =2 for pos and vel
|
436
|
+
* =3 for pos, vel, and acc
|
437
|
+
* =4 for pos, vel, acc, and jerk
|
438
|
+
* output:
|
439
|
+
* pv d.p. interpolated quantities requested.
|
440
|
+
* assumed dimension is pv(ncm,fl).
|
441
|
+
*/
|
442
|
+
static int interp(double FAR *buf, double t, double intv, int32 ncfin,
|
443
|
+
int32 ncmin, int32 nain, int32 ifl, double *pv)
|
444
|
+
{
|
445
|
+
/* Initialized data */
|
446
|
+
static int FAR np, nv;
|
447
|
+
static int FAR nac;
|
448
|
+
static int FAR njk;
|
449
|
+
static double FAR twot = 0.;
|
450
|
+
double FAR *pc = js->pc;
|
451
|
+
double FAR *vc = js->vc;
|
452
|
+
double FAR *ac = js->ac;
|
453
|
+
double FAR *jc = js->jc;
|
454
|
+
int ncf = (int) ncfin;
|
455
|
+
int ncm = (int) ncmin;
|
456
|
+
int na = (int) nain;
|
457
|
+
/* Local variables */
|
458
|
+
double temp;
|
459
|
+
int i, j, ni;
|
460
|
+
double tc;
|
461
|
+
double dt1, bma;
|
462
|
+
double bma2, bma3;
|
463
|
+
/*
|
464
|
+
| get correct sub-interval number for this set of coefficients and then
|
465
|
+
| get normalized chebyshev time within that subinterval.
|
466
|
+
*/
|
467
|
+
if (t >= 0)
|
468
|
+
dt1 = floor(t);
|
469
|
+
else
|
470
|
+
dt1 = -floor(-t);
|
471
|
+
temp = na * t;
|
472
|
+
ni = (int) (temp - dt1);
|
473
|
+
/* tc is the normalized chebyshev time (-1 <= tc <= 1) */
|
474
|
+
tc = (fmod(temp, 1.0) + dt1) * 2. - 1.;
|
475
|
+
/*
|
476
|
+
* check to see whether chebyshev time has changed,
|
477
|
+
* and compute new polynomial values if it has.
|
478
|
+
* (the element pc(2) is the value of t1(tc) and hence
|
479
|
+
* contains the value of tc on the previous call.)
|
480
|
+
*/
|
481
|
+
if (tc != pc[1]) {
|
482
|
+
np = 2;
|
483
|
+
nv = 3;
|
484
|
+
nac = 4;
|
485
|
+
njk = 5;
|
486
|
+
pc[1] = tc;
|
487
|
+
twot = tc + tc;
|
488
|
+
}
|
489
|
+
/*
|
490
|
+
* be sure that at least 'ncf' polynomials have been evaluated
|
491
|
+
* and are stored in the array 'pc'.
|
492
|
+
*/
|
493
|
+
if (np < ncf) {
|
494
|
+
for (i = np; i < ncf; ++i)
|
495
|
+
pc[i] = twot * pc[i - 1] - pc[i - 2];
|
496
|
+
np = ncf;
|
497
|
+
}
|
498
|
+
/* interpolate to get position for each component */
|
499
|
+
for (i = 0; i < ncm; ++i) {
|
500
|
+
pv[i] = 0.;
|
501
|
+
for (j = ncf-1; j >= 0; --j)
|
502
|
+
pv[i] += pc[j] * buf[j + (i + ni * ncm) * ncf];
|
503
|
+
}
|
504
|
+
if (ifl <= 1)
|
505
|
+
return 0;
|
506
|
+
/*
|
507
|
+
* if velocity interpolation is wanted, be sure enough
|
508
|
+
* derivative polynomials have been generated and stored.
|
509
|
+
*/
|
510
|
+
bma = (na + na) / intv;
|
511
|
+
vc[2] = twot + twot;
|
512
|
+
if (nv < ncf) {
|
513
|
+
for (i = nv; i < ncf; ++i)
|
514
|
+
vc[i] = twot * vc[i - 1] + pc[i - 1] + pc[i - 1] - vc[i - 2];
|
515
|
+
nv = ncf;
|
516
|
+
}
|
517
|
+
/* interpolate to get velocity for each component */
|
518
|
+
for (i = 0; i < ncm; ++i) {
|
519
|
+
pv[i + ncm] = 0.;
|
520
|
+
for (j = ncf-1; j >= 1; --j)
|
521
|
+
pv[i + ncm] += vc[j] * buf[j + (i + ni * ncm) * ncf];
|
522
|
+
pv[i + ncm] *= bma;
|
523
|
+
}
|
524
|
+
if (ifl == 2)
|
525
|
+
return 0;
|
526
|
+
/* check acceleration polynomial values, and */
|
527
|
+
/* re-do if necessary */
|
528
|
+
bma2 = bma * bma;
|
529
|
+
ac[3] = pc[1] * 24.;
|
530
|
+
if (nac < ncf) {
|
531
|
+
nac = ncf;
|
532
|
+
for (i = nac; i < ncf; ++i)
|
533
|
+
ac[i] = twot * ac[i - 1] + vc[i - 1] * 4. - ac[i - 2];
|
534
|
+
}
|
535
|
+
/* get acceleration for each component */
|
536
|
+
for (i = 0; i < ncm; ++i) {
|
537
|
+
pv[i + ncm * 2] = 0.;
|
538
|
+
for (j = ncf-1; j >= 2; --j)
|
539
|
+
pv[i + ncm * 2] += ac[j] * buf[j + (i + ni * ncm) * ncf];
|
540
|
+
pv[i + ncm * 2] *= bma2;
|
541
|
+
}
|
542
|
+
if (ifl == 3)
|
543
|
+
return 0;
|
544
|
+
/* check jerk polynomial values, and */
|
545
|
+
/* re-do if necessary */
|
546
|
+
bma3 = bma * bma2;
|
547
|
+
jc[4] = pc[1] * 192.;
|
548
|
+
if (njk < ncf) {
|
549
|
+
njk = ncf;
|
550
|
+
for (i = njk; i < ncf; ++i)
|
551
|
+
jc[i] = twot * jc[i - 1] + ac[i - 1] * 6. - jc[i - 2];
|
552
|
+
}
|
553
|
+
/* get jerk for each component */
|
554
|
+
for (i = 0; i < ncm; ++i) {
|
555
|
+
pv[i + ncm * 3] = 0.;
|
556
|
+
for (j = ncf-1; j >= 3; --j)
|
557
|
+
pv[i + ncm * 3] += jc[j] * buf[j + (i + ni * ncm) * ncf];
|
558
|
+
pv[i + ncm * 3] *= bma3;
|
559
|
+
}
|
560
|
+
return 0;
|
561
|
+
}
|
562
|
+
|
563
|
+
/*
|
564
|
+
| ********** state ********************
|
565
|
+
| this subroutine reads and interpolates the jpl planetary ephemeris file
|
566
|
+
| calling sequence parameters:
|
567
|
+
| input:
|
568
|
+
| et dp julian ephemeris epoch at which interpolation is wanted.
|
569
|
+
| list 12-word integer array specifying what interpolation
|
570
|
+
| is wanted for each of the bodies on the file.
|
571
|
+
| list(i)=0, no interpolation for body i
|
572
|
+
| =1, position only
|
573
|
+
| =2, position and velocity
|
574
|
+
| the designation of the astronomical bodies by i is:
|
575
|
+
| i = 0: mercury
|
576
|
+
| = 1: venus
|
577
|
+
| = 2: earth-moon barycenter, NOT earth!
|
578
|
+
| = 3: mars
|
579
|
+
| = 4: jupiter
|
580
|
+
| = 5: saturn
|
581
|
+
| = 6: uranus
|
582
|
+
| = 7: neptune
|
583
|
+
| = 8: pluto
|
584
|
+
| = 9: geocentric moon
|
585
|
+
| =10: nutations in longitude and obliquity
|
586
|
+
| =11: lunar librations (if on file)
|
587
|
+
| If called with list = NULL, only the header records are read and
|
588
|
+
| stored in the global areas.
|
589
|
+
| do_bary short, if true, barycentric, if false, heliocentric.
|
590
|
+
| only the 9 planets 0..8 are affected by it.
|
591
|
+
| output:
|
592
|
+
| pv dp 6 x 11 array that will contain requested interpolated
|
593
|
+
| quantities. the body specified by list(i) will have its
|
594
|
+
| state in the array starting at pv(1,i). (on any given
|
595
|
+
| call, only those words in 'pv' which are affected by the
|
596
|
+
| first 10 'list' entries (and by list(11) if librations are
|
597
|
+
| on the file) are set. the rest of the 'pv' array
|
598
|
+
| is untouched.) the order of components starting in
|
599
|
+
| pv is: x,y,z,dx,dy,dz.
|
600
|
+
| all output vectors are referenced to the earth mean
|
601
|
+
| equator and equinox of epoch. the moon state is always
|
602
|
+
| geocentric; the other nine states are either heliocentric
|
603
|
+
| or solar-system barycentric, depending on the setting of
|
604
|
+
| common flags (see below).
|
605
|
+
| lunar librations, if on file, are put into pv(k,10) if
|
606
|
+
| list(11) is 1 or 2.
|
607
|
+
| pvsun dp 6-word array containing the barycentric position and
|
608
|
+
| velocity of the sun.
|
609
|
+
| nut dp 4-word array that will contain nutations and rates,
|
610
|
+
| depending on the setting of list(10). the order of
|
611
|
+
| quantities in nut is:
|
612
|
+
| d psi (nutation in longitude)
|
613
|
+
| d epsilon (nutation in obliquity)
|
614
|
+
| d psi dot
|
615
|
+
| d epsilon dot
|
616
|
+
| globals used:
|
617
|
+
| do_km logical flag defining physical units of the output states.
|
618
|
+
| TRUE = return km and km/sec, FALSE = return au and au/day
|
619
|
+
| default value = FALSE (km determines time unit
|
620
|
+
| for nutations and librations. angle unit is always radians.)
|
621
|
+
*/
|
622
|
+
static int state(double et, int32 *list, int do_bary,
|
623
|
+
double *pv, double *pvsun, double *nut, char *serr)
|
624
|
+
{
|
625
|
+
int i, j, k;
|
626
|
+
int32 flen, nseg, nb;
|
627
|
+
double FAR *buf = js->buf;
|
628
|
+
double aufac, s, t, intv, ts[4];
|
629
|
+
int32 nrecl, ksize;
|
630
|
+
int32 nr;
|
631
|
+
double et_mn, et_fr;
|
632
|
+
int32 FAR *ipt = js->eh_ipt;
|
633
|
+
char ch_ttl[252];
|
634
|
+
static int32 irecsz;
|
635
|
+
static int32 nrl, lpt[3], ncoeffs;
|
636
|
+
if (js->jplfptr == NULL) {
|
637
|
+
ksize = fsizer(serr); /* the number of single precision words in a record */
|
638
|
+
nrecl = 4;
|
639
|
+
if (ksize == NOT_AVAILABLE)
|
640
|
+
return NOT_AVAILABLE;
|
641
|
+
irecsz = nrecl * ksize; /* record size in bytes */
|
642
|
+
ncoeffs = ksize / 2; /* # of coefficients, doubles */
|
643
|
+
/* ttl = ephemeris title, e.g.
|
644
|
+
* "JPL Planetary Ephemeris DE404/LE404
|
645
|
+
* Start Epoch: JED= 625296.5-3001 DEC 21 00:00:00
|
646
|
+
* Final Epoch: JED= 2817168.5 3001 JAN 17 00:00:00c */
|
647
|
+
fread((void *) ch_ttl, 1, 252, js->jplfptr);
|
648
|
+
/* cnam = names of constants */
|
649
|
+
fread((void *) js->ch_cnam, 1, 2400, js->jplfptr);
|
650
|
+
/* ss[0] = start epoch of ephemeris
|
651
|
+
* ss[1] = end epoch
|
652
|
+
* ss[2] = segment size in days */
|
653
|
+
fread((void *) &js->eh_ss[0], sizeof(double), 3, js->jplfptr);
|
654
|
+
if (js->do_reorder)
|
655
|
+
reorder((char *) &js->eh_ss[0], sizeof(double), 3);
|
656
|
+
/* ncon = number of constants */
|
657
|
+
fread((void *) &js->eh_ncon, sizeof(int32), 1, js->jplfptr);
|
658
|
+
if (js->do_reorder)
|
659
|
+
reorder((char *) &js->eh_ncon, sizeof(int32), 1);
|
660
|
+
/* au = astronomical unit */
|
661
|
+
fread((void *) &js->eh_au, sizeof(double), 1, js->jplfptr);
|
662
|
+
if (js->do_reorder)
|
663
|
+
reorder((char *) &js->eh_au, sizeof(double), 1);
|
664
|
+
/* emrat = earth moon mass ratio */
|
665
|
+
fread((void *) &js->eh_emrat, sizeof(double), 1, js->jplfptr);
|
666
|
+
if (js->do_reorder)
|
667
|
+
reorder((char *) &js->eh_emrat, sizeof(double), 1);
|
668
|
+
/* ipt[i+0]: coefficients of planet i start at buf[ipt[i+0]-1]
|
669
|
+
* ipt[i+1]: number of coefficients (interpolation order - 1)
|
670
|
+
* ipt[i+2]: number of intervals in segment */
|
671
|
+
fread((void *) &ipt[0], sizeof(int32), 36, js->jplfptr);
|
672
|
+
if (js->do_reorder)
|
673
|
+
reorder((char *) &ipt[0], sizeof(int32), 36);
|
674
|
+
/* numde = number of jpl ephemeris "404" with de404 */
|
675
|
+
fread((void *) &js->eh_denum, sizeof(int32), 1, js->jplfptr);
|
676
|
+
if (js->do_reorder)
|
677
|
+
reorder((char *) &js->eh_denum, sizeof(int32), 1);
|
678
|
+
fread((void *) &lpt[0], sizeof(int32), 3, js->jplfptr);
|
679
|
+
if (js->do_reorder)
|
680
|
+
reorder((char *) &lpt[0], sizeof(int32), 3);
|
681
|
+
/* cval[]: other constants in next record */
|
682
|
+
fseek(js->jplfptr, 1L * irecsz, 0);
|
683
|
+
fread((void *) &js->eh_cval[0], sizeof(double), 400, js->jplfptr);
|
684
|
+
if (js->do_reorder)
|
685
|
+
reorder((char *) &js->eh_cval[0], sizeof(double), 400);
|
686
|
+
/* new 26-aug-2008: verify correct block size */
|
687
|
+
#if 0
|
688
|
+
sp = strstr(js->ch_cnam, "EMRAT ");
|
689
|
+
if (sp == NULL) {
|
690
|
+
if (serr != NULL)
|
691
|
+
sprintf(serr, "JPL ephemeris file strange, constant name 'EMRAT' missing");
|
692
|
+
return ERR;
|
693
|
+
}
|
694
|
+
i = (sp - js->ch_cnam);
|
695
|
+
if (i % 6 != 0) {
|
696
|
+
if (serr != NULL)
|
697
|
+
sprintf(serr, "JPL ephemeris file strange, constant name 'EMRAT' not at multiple of 6");
|
698
|
+
return ERR;
|
699
|
+
}
|
700
|
+
i = i / 6; /* position of EMRAT in constant array eh_cval */
|
701
|
+
if (js->eh_cval[i] != js->eh_emrat) {
|
702
|
+
if (serr != NULL)
|
703
|
+
sprintf(serr, "JPL ephemeris file error, record size failed EMRAT check");
|
704
|
+
return ERR;
|
705
|
+
}
|
706
|
+
#endif
|
707
|
+
for (i = 0; i < 3; ++i)
|
708
|
+
ipt[i + 36] = lpt[i];
|
709
|
+
nrl = 0;
|
710
|
+
/* is file length correct? */
|
711
|
+
/* file length */
|
712
|
+
fseek(js->jplfptr, 0L, SEEK_END);
|
713
|
+
flen = ftell(js->jplfptr);
|
714
|
+
/* # of segments in file */
|
715
|
+
nseg = (int32) ((js->eh_ss[1] - js->eh_ss[0]) / js->eh_ss[2]);
|
716
|
+
/* sum of all cheby coeffs of all planets and segments */
|
717
|
+
for(i = 0, nb = 0; i < 13; i++) {
|
718
|
+
k = 3;
|
719
|
+
if (i == 11)
|
720
|
+
k = 2;
|
721
|
+
nb += (ipt[i*3+1] * ipt[i*3+2]) * k * nseg;
|
722
|
+
}
|
723
|
+
/* add start and end epochs of segments */
|
724
|
+
nb += 2 * nseg;
|
725
|
+
/* doubles to bytes */
|
726
|
+
nb *= 8;
|
727
|
+
/* add size of header and constants section */
|
728
|
+
nb += 2 * ksize * nrecl;
|
729
|
+
#if 0
|
730
|
+
printf("hallo %d %d\n", nb, flen);
|
731
|
+
printf("hallo %d %d\n", nb-flen, ksize);
|
732
|
+
#endif
|
733
|
+
if (flen != nb
|
734
|
+
/* some of our files are one record too long */
|
735
|
+
&& flen - nb != ksize * nrecl) {
|
736
|
+
if (serr != NULL) {
|
737
|
+
sprintf(serr, "JPL ephemeris file is mutilated; length = %d instead of %d.", flen, nb);
|
738
|
+
if (strlen(serr) + strlen(js->jplfname) < AS_MAXCH - 1)
|
739
|
+
sprintf(serr, "JPL ephemeris file %s is mutilated; length = %d instead of %d.", js->jplfname, flen, nb);
|
740
|
+
}
|
741
|
+
return(NOT_AVAILABLE);
|
742
|
+
}
|
743
|
+
/* check if start and end dates in segments are the same as in
|
744
|
+
* file header */
|
745
|
+
fseek(js->jplfptr, 2L * irecsz, 0);
|
746
|
+
fread((void *) &ts[0], sizeof(double), 2, js->jplfptr);
|
747
|
+
if (js->do_reorder)
|
748
|
+
reorder((char *) &ts[0], sizeof(double), 2);
|
749
|
+
fseek(js->jplfptr, (nseg + 2 - 1) * irecsz, 0);
|
750
|
+
fread((void *) &ts[2], sizeof(double), 2, js->jplfptr);
|
751
|
+
if (js->do_reorder)
|
752
|
+
reorder((char *) &ts[2], sizeof(double), 2);
|
753
|
+
if (ts[0] != js->eh_ss[0] || ts[3] != js->eh_ss[1]) {
|
754
|
+
if (serr != NULL)
|
755
|
+
strcpy(serr, "JPL ephemeris file is corrupt; start/end date check failed.");
|
756
|
+
return NOT_AVAILABLE;
|
757
|
+
}
|
758
|
+
}
|
759
|
+
if (list == NULL)
|
760
|
+
return 0;
|
761
|
+
s = et - .5;
|
762
|
+
et_mn = floor(s);
|
763
|
+
et_fr = s - et_mn; /* fraction of days since previous midnight */
|
764
|
+
et_mn += .5; /* midnight before epoch */
|
765
|
+
/* error return for epoch out of range */
|
766
|
+
if (et < js->eh_ss[0] || et > js->eh_ss[1]) {
|
767
|
+
if (serr != NULL)
|
768
|
+
sprintf(serr,"jd %f outside JPL eph. range %.2f .. %.2f;", et, js->eh_ss[0], js->eh_ss[1]);
|
769
|
+
return BEYOND_EPH_LIMITS;
|
770
|
+
}
|
771
|
+
/* calculate record # and relative time in interval */
|
772
|
+
nr = (int32) ((et_mn - js->eh_ss[0]) / js->eh_ss[2]) + 2;
|
773
|
+
if (et_mn == js->eh_ss[1])
|
774
|
+
--nr; /* end point of ephemeris, use last record */
|
775
|
+
t = (et_mn - ((nr - 2) * js->eh_ss[2] + js->eh_ss[0]) + et_fr) / js->eh_ss[2];
|
776
|
+
/* read correct record if not in core */
|
777
|
+
if (nr != nrl) {
|
778
|
+
nrl = nr;
|
779
|
+
if (fseek(js->jplfptr, nr * irecsz, 0) != 0) {
|
780
|
+
if (serr != NULL)
|
781
|
+
sprintf(serr, "Read error in JPL eph. at %f\n", et);
|
782
|
+
return NOT_AVAILABLE;
|
783
|
+
}
|
784
|
+
for (k = 1; k <= ncoeffs; ++k) {
|
785
|
+
if ( fread((void *) &buf[k - 1], sizeof(double), 1, js->jplfptr) != 1) {
|
786
|
+
if (serr != NULL)
|
787
|
+
sprintf(serr, "Read error in JPL eph. at %f\n", et);
|
788
|
+
return NOT_AVAILABLE;
|
789
|
+
}
|
790
|
+
if (js->do_reorder)
|
791
|
+
reorder((char *) &buf[k-1], sizeof(double), 1);
|
792
|
+
}
|
793
|
+
}
|
794
|
+
if (js->do_km) {
|
795
|
+
intv = js->eh_ss[2] * 86400.;
|
796
|
+
aufac = 1.;
|
797
|
+
} else {
|
798
|
+
intv = js->eh_ss[2];
|
799
|
+
aufac = 1. / js->eh_au;
|
800
|
+
}
|
801
|
+
/* interpolate ssbary sun */
|
802
|
+
interp(&buf[(int) ipt[30] - 1], t, intv, ipt[31], 3L, ipt[32], 2L, pvsun);
|
803
|
+
for (i = 0; i < 6; ++i) {
|
804
|
+
pvsun[i] *= aufac;
|
805
|
+
}
|
806
|
+
/* check and interpolate whichever bodies are requested */
|
807
|
+
for (i = 0; i < 10; ++i) {
|
808
|
+
if (list[i] > 0) {
|
809
|
+
interp(&buf[(int) ipt[i * 3] - 1], t, intv, ipt[i * 3 + 1], 3L,
|
810
|
+
ipt[i * 3 + 2], list[i], &pv[i * 6]);
|
811
|
+
for (j = 0; j < 6; ++j) {
|
812
|
+
if (i < 9 && ! do_bary) {
|
813
|
+
pv[j + i * 6] = pv[j + i * 6] * aufac - pvsun[j];
|
814
|
+
} else {
|
815
|
+
pv[j + i * 6] *= aufac;
|
816
|
+
}
|
817
|
+
}
|
818
|
+
}
|
819
|
+
}
|
820
|
+
/* do nutations if requested (and if on file) */
|
821
|
+
if (list[10] > 0 && ipt[34] > 0) {
|
822
|
+
interp(&buf[(int) ipt[33] - 1], t, intv, ipt[34], 2L, ipt[35],
|
823
|
+
list[10], nut);
|
824
|
+
}
|
825
|
+
/* get librations if requested (and if on file) */
|
826
|
+
if (list[11] > 0 && ipt[37] > 0) {
|
827
|
+
interp(&buf[(int) ipt[36] - 1], t, intv, ipt[37], 3L, ipt[38], list[1],
|
828
|
+
&pv[60]);
|
829
|
+
}
|
830
|
+
return OK;
|
831
|
+
}
|
832
|
+
|
833
|
+
/*
|
834
|
+
* this entry obtains the constants from the ephemeris file
|
835
|
+
* call state to initialize the ephemeris and read in the constants
|
836
|
+
*/
|
837
|
+
static int read_const_jpl(double *ss, char *serr)
|
838
|
+
{
|
839
|
+
int i, retc;
|
840
|
+
retc = state(0.0, NULL, FALSE, NULL, NULL, NULL, serr);
|
841
|
+
if (retc != OK)
|
842
|
+
return (retc);
|
843
|
+
for (i = 0; i < 3; i++)
|
844
|
+
ss[i] = js->eh_ss[i];
|
845
|
+
#if DEBUG_DO_SHOW
|
846
|
+
{
|
847
|
+
static char FAR *bname[] = {
|
848
|
+
"Mercury", "Venus", "EMB", "Mars", "Jupiter", "Saturn",
|
849
|
+
"Uranus", "Neptune", "Pluto", "Moon", "SunBary", "Nut", "Libr"};
|
850
|
+
int j, k;
|
851
|
+
int32 nb, nc;
|
852
|
+
printf(" JPL TEST-EPHEMERIS program. Version October 1995.\n");
|
853
|
+
for (i = 0; i < 13; i++) {
|
854
|
+
j = i * 3;
|
855
|
+
k = 3;
|
856
|
+
if (i == 11) k = 2;
|
857
|
+
nb = js->eh_ipt[j+1] * js->eh_ipt[j+2] * k;
|
858
|
+
nc = (int32) (nb * 36525L / js->eh_ss[2] * 8L);
|
859
|
+
printf("%s\t%d\tipt[%d]\t%3ld %2ld %2ld,\t",
|
860
|
+
bname[i], i, j, js->eh_ipt[j], js->eh_ipt[j+1], js->eh_ipt[j+2]);
|
861
|
+
printf("%3ld double, bytes per century = %6ld\n", nb, nc);
|
862
|
+
fflush(stdout);
|
863
|
+
}
|
864
|
+
printf("%16.2f %16.2f %16.2f\n", js->eh_ss[0], js->eh_ss[1], js->eh_ss[2]);
|
865
|
+
for (i = 0; i < js->eh_ncon; ++i)
|
866
|
+
printf("%.6s\t%24.16f\n", js->ch_cnam + i * 6, js->eh_cval[i]);
|
867
|
+
fflush(stdout);
|
868
|
+
}
|
869
|
+
#endif
|
870
|
+
return OK;
|
871
|
+
}
|
872
|
+
|
873
|
+
static void reorder(char *x, int size, int number)
|
874
|
+
{
|
875
|
+
int i, j;
|
876
|
+
char s[8];
|
877
|
+
char *sp1 = x;
|
878
|
+
char *sp2 = &s[0];
|
879
|
+
for (i = 0; i < number; i++) {
|
880
|
+
for (j = 0; j < size; j++)
|
881
|
+
*(sp2 + j) = *(sp1 + size - j - 1);
|
882
|
+
for (j = 0; j < size; j++)
|
883
|
+
*(sp1 + j) = *(sp2 + j);
|
884
|
+
sp1 += size;
|
885
|
+
}
|
886
|
+
}
|
887
|
+
|
888
|
+
void swi_close_jpl_file(void)
|
889
|
+
{
|
890
|
+
if (js != NULL) {
|
891
|
+
if (js->jplfptr != NULL)
|
892
|
+
fclose(js->jplfptr);
|
893
|
+
if (js->jplfname != NULL)
|
894
|
+
FREE((void *) js->jplfname);
|
895
|
+
if (js->jplfpath != NULL)
|
896
|
+
FREE((void *) js->jplfpath);
|
897
|
+
FREE((void *) js);
|
898
|
+
js = NULL;
|
899
|
+
}
|
900
|
+
}
|
901
|
+
|
902
|
+
int swi_open_jpl_file(double *ss, char *fname, char *fpath, char *serr)
|
903
|
+
{
|
904
|
+
int retc = OK;
|
905
|
+
/* if open, return */
|
906
|
+
if (js != NULL && js->jplfptr != NULL)
|
907
|
+
return OK;
|
908
|
+
if ((js = (struct jpl_save *) CALLOC(1, sizeof(struct jpl_save))) == NULL
|
909
|
+
|| (js->jplfname = MALLOC(strlen(fname)+1)) == NULL
|
910
|
+
|| (js->jplfpath = MALLOC(strlen(fpath)+1)) == NULL
|
911
|
+
) {
|
912
|
+
if (serr != NULL)
|
913
|
+
strcpy(serr, "error in malloc() with JPL ephemeris.");
|
914
|
+
return ERR;
|
915
|
+
}
|
916
|
+
strcpy(js->jplfname, fname);
|
917
|
+
strcpy(js->jplfpath, fpath);
|
918
|
+
retc = read_const_jpl(ss, serr);
|
919
|
+
if (retc != OK)
|
920
|
+
swi_close_jpl_file();
|
921
|
+
else {
|
922
|
+
/* intializations for function interpol() */
|
923
|
+
js->pc[0] = 1;
|
924
|
+
js->pc[1] = 2;
|
925
|
+
js->vc[1] = 1;
|
926
|
+
js->ac[2] = 4;
|
927
|
+
js->jc[3] = 24;
|
928
|
+
}
|
929
|
+
return retc;
|
930
|
+
}
|
931
|
+
|
932
|
+
int32 swi_get_jpl_denum()
|
933
|
+
{
|
934
|
+
return js->eh_denum;
|
935
|
+
}
|
936
|
+
#endif /* NO_JPL */
|
937
|
+
|