forked from Bill-Gray/jpl_eph
-
Notifications
You must be signed in to change notification settings - Fork 0
/
eph2asc.cpp
127 lines (108 loc) · 4.58 KB
/
eph2asc.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/* eph2asc.cpp: convert binary JPL ephemerides back to ASCII
Copyright (C) 2011, Project Pluto
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
This program is possibly useless. It is the opposite of the quite
useful 'asc2eph': given a _binary_ JPL ephemeris file, it can recreate
the ASCII ephemeris files from which the binary version was made. Usage
is described in error_exit( ) below.
The ASCII files will sometimes differ from the original input in the
last decimal place. */
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "jpleph.h"
#define jpl_get_cache( ephem) (*(double **)((char *)ephem + 224 + 48))
/* The format of doubles in JPL ASCII ephemeris files is a little strange. */
/* The usual 'E' exponent is replaced with 'D'. A leading zero is used, */
/* so that 3.14159E+000 would become 0.314159D+01. Two-digit exponents */
/* are used instead of three-digit ones. Put it all together, and you */
/* have the need for the following: */
static void put_in_buff( char *buff, const double val)
{
int exponent;
snprintf( buff, 26, "%25.15E", val);
exponent = atoi( buff + 21) + 1;
assert( exponent > -90 && exponent < 90);
snprintf( buff + 20, 13, "D%+03d", exponent);
buff[1] = buff[2]; /* grab minus sign if any */
buff[4] = buff[3];
buff[2] = '0'; /* insert leading zero */
buff[3] = '.';
}
static void error_exit( const int exit_code)
{
printf( "'eph2asc' requires as command line arguments the name of a\n");
printf( "JPL DE binary ephemeris and a starting and ending year. For\n");
printf( "example:\n\neph2asc unix.405 1950 1975\n\n");
printf( "would result in an ASCII ephemeris covering the years 1950 to 1975\n");
printf( "being written to the standard output.\n");
exit( exit_code);
}
/* The conversion works as follows:
The (binary) ephemeris is opened, and the command-line years are converted
to JD. We figure out what the "real" starting JD is, given the ephemeris
step size. Then we step through, one block at a time (i.e., jd += ephem_step)
and compute the positions of Jupiter and Saturn for a time at the center of
the current block. The only reason we do so is that it results in the block
of coefficients being loaded up in a cache, accessible via jpl_get_cache( ).
So we can just write them out in ASCII form.
Eventually, 'jd' reaches the ending year specified on the command line,
and we're done. */
int main( const int argc, const char **argv)
{
void *eph;
int rval = -1;
if( argc < 4)
error_exit( -1);
eph = jpl_init_ephemeris( argv[1], NULL, NULL);
if( !eph)
{
printf( "Ephemeris '%s' not opened; error %d\n",
argv[1], jpl_init_error_code( ));
error_exit( -2);
}
else
{
const double ephem_step = jpl_get_double( eph, JPL_EPHEM_STEP);
const double start_jd = jpl_get_double( eph, JPL_EPHEM_START_JD);
const double J2000 = 2451545.0;
const int n_coeffs = jpl_get_long( eph, JPL_EPHEM_KERNEL_NCOEFF);
const int n_to_write = ((n_coeffs + 2) / 3) * 3;
double jd = (atof( argv[2]) - 2000.) * 365.25 + J2000, vect[6];
const double jd_end = (atof( argv[3]) - 2000.) * 365.25 + J2000;
double *coeffs = jpl_get_cache( eph);
int zval, i, rec_num = 1;
jd = floor( (jd - start_jd) / ephem_step) * ephem_step + start_jd;
while( jd <= jd_end)
{
zval = jpl_pleph( eph, jd + ephem_step / 2., 5, 6, vect, 0);
if( !zval)
{
printf( "%6d%6d\n", rec_num, n_coeffs);
rec_num++;
for( i = 0; i < n_to_write; i++)
{
char buff[40];
put_in_buff( buff, (i < n_coeffs) ? coeffs[i] : 0.);
printf( " %s%s", buff, (i % 3 == 2) ? "\n" : "");
}
}
jd += ephem_step;
}
jpl_close_ephemeris( eph);
rval = 0;
}
return( rval);
}