|
1 | 1 | module CalcephEphemeris |
2 | 2 |
|
3 | 3 | export CalcephProvider, |
4 | | - load, ephem_compute!, ephem_orient!, ephem_position_records, ephem_orient_records |
| 4 | + load, |
| 5 | + ephem_compute!, |
| 6 | + ephem_orient!, |
| 7 | + ephem_position_records, |
| 8 | + ephem_orient_records |
5 | 9 |
|
6 | | -using CALCEPH: |
7 | | - Ephem as CalcephEphemHandler, |
8 | | - prefetch, |
9 | | - timespan, |
10 | | - timeScale, |
11 | | - positionRecords, |
12 | | - orientationRecords, |
13 | | - unsafe_compute!, |
14 | | - unsafe_orient!, |
15 | | - useNaifId, |
16 | | - unitKM, |
17 | | - unitSec, |
18 | | - unitRad, |
19 | | - OrientationRecord, |
20 | | - PositionRecord |
| 10 | +using CALCEPH_jll: libcalceph |
21 | 11 |
|
22 | 12 | import JSMDInterfaces.Ephemeris as jEph |
23 | 13 |
|
24 | | -""" |
25 | | - CalcephProvider(file::String) |
26 | | - CalcephProvider(files::Vector{String}) |
27 | | - |
28 | | -Create a `CalcephProvider` instance by loading a single or multiples ephemeris kernel |
29 | | -files specified by `files`. |
30 | | -
|
31 | | -!!! note |
32 | | - Since this object is immutable, kernels cannot be added nor removed from the generated |
33 | | - `CalcephProvider` instance. |
34 | | -
|
35 | | -### Example |
36 | | -```julia-repl |
37 | | -julia> eph1 = CalcephProvider("PATH_TO_KERNEL") |
38 | | -1-kernel CalcephProvider |
39 | | - "PATH_TO_KERNEL" |
40 | | -
|
41 | | -julia> eph2 = CalcephProvider(["PATH_TO_KERNEL_1", "PATH_TO_KERNEL_2"]) |
42 | | -2-kernel CalcephProvider: |
43 | | - "PATH_TO_KERNEL_1" |
44 | | - "PATH_TO_KERNEL_2" |
45 | | -``` |
46 | | -""" |
47 | | -struct CalcephProvider <: jEph.AbstractEphemerisProvider |
48 | | - ptr::CalcephEphemHandler |
49 | | - files::Vector{String} |
50 | | - function CalcephProvider(files::Vector{<:AbstractString}) |
51 | | - filepaths = unique(files) |
52 | | - ptr = CalcephEphemHandler(filepaths) |
53 | | - prefetch(ptr) |
54 | | - return new(ptr, filepaths) |
55 | | - end |
56 | | -end |
57 | | - |
58 | | -CalcephProvider(file::AbstractString) = CalcephProvider([file]) |
59 | | - |
60 | | -function Base.show(io::IO, eph::CalcephProvider) |
61 | | - print(io, "$(length(eph.files))-kernel CalcephProvider") |
62 | | -end |
63 | | - |
64 | | -function Base.show(io::IO, ::MIME"text/plain", eph::CalcephProvider) |
65 | | - println(io, eph, ":") |
66 | | - for file in eph.files |
67 | | - println(io, " $(repr(file))") |
68 | | - end |
69 | | -end |
70 | | - |
71 | | -jEph.load(::Type{CalcephProvider}, file::AbstractString) = CalcephProvider(file) |
72 | | - |
73 | | -function jEph.load(::Type{CalcephProvider}, files::Vector{<:AbstractString}) |
74 | | - return CalcephProvider(files) |
75 | | -end |
76 | | - |
77 | | -function Base.convert(::Type{jEph.EphemPointRecord}, r::PositionRecord) |
78 | | - return jEph.EphemPointRecord(r.target, r.center, r.startEpoch, r.stopEpoch, r.frame) |
79 | | -end |
80 | | - |
81 | | -function Base.convert(::Type{jEph.EphemAxesRecord}, r::OrientationRecord) |
82 | | - return jEph.EphemAxesRecord(r.target, r.startEpoch, r.stopEpoch, r.frame) |
83 | | -end |
84 | | - |
85 | | -""" |
86 | | - ephem_position_records(eph::CalcephProvider) |
87 | | -
|
88 | | -Get an array of `EphemPointRecord`, providing detailed informations on the |
89 | | -position content of the ephemeris file. |
90 | | -""" |
91 | | -function jEph.ephem_position_records(eph::CalcephProvider) |
92 | | - try |
93 | | - convert.(jEph.EphemPointRecord, positionRecords(eph.ptr)) |
94 | | - catch |
95 | | - jEph.EphemPointRecord[] |
96 | | - end |
97 | | -end |
98 | | - |
99 | | -""" |
100 | | - ephem_available_points(eph::CalcephProvider) |
101 | | -
|
102 | | -Return a list of NAIFIds representing bodies with available ephemeris data. |
103 | | -""" |
104 | | -function jEph.ephem_available_points(eph::CalcephProvider) |
105 | | - rec = jEph.ephem_position_records(eph) |
106 | | - tids = map(x -> x.target, rec) |
107 | | - cids = map(x -> x.center, rec) |
108 | | - |
109 | | - return unique(Int64[tids..., cids...]) |
110 | | -end |
111 | | - |
112 | | -""" |
113 | | - ephem_orient_records(eph::CalcephProvider) |
114 | | -
|
115 | | -Get an array of `EphemAxesRecord`, providing detailed |
116 | | -informations on the orientation content of the ephemeris file. |
117 | | -""" |
118 | | -function jEph.ephem_orient_records(eph::CalcephProvider) |
119 | | - try |
120 | | - convert.(jEph.EphemAxesRecord, orientationRecords(eph.ptr)) |
121 | | - catch |
122 | | - jEph.EphemAxesRecord[] |
123 | | - end |
124 | | -end |
125 | | - |
126 | | -""" |
127 | | - ephem_available_points(eph::CalcephProvider) |
128 | | -
|
129 | | -Return a list of Frame IDs representing axes with available orientation data. |
130 | | -""" |
131 | | -function jEph.ephem_available_axes(eph::CalcephProvider) |
132 | | - rec = jEph.ephem_orient_records(eph) |
133 | | - |
134 | | - tids = map(x -> x.target, rec) |
135 | | - cids = map(x -> x.axes, rec) |
136 | | - |
137 | | - return unique(Int64[tids..., cids...]) |
138 | | -end |
139 | | - |
140 | | -""" |
141 | | - ephem_timespan(eph::CalcephProvider) |
142 | | -
|
143 | | -Returns the first and last time available in the ephemeris file associated to |
144 | | -an ephemeris file. It returns a tuple containing: |
145 | | -
|
146 | | -- `firsttime` -- Julian date of the first time. |
147 | | -- `lasttime` -- Julian date of the last time. |
148 | | -- `continuous` -- Information about the availability of the quantities over the |
149 | | - time span. It equals: |
150 | | - |
151 | | - - `1`: if the quantities of all bodies are available for any time between |
152 | | - the first and last time. |
153 | | - - `2`: if the quantities of some bodies are available on discontinuous time |
154 | | - intervals between the first and last time. |
155 | | - - `3`: if the quantities of each body are available on a continuous time |
156 | | - interval between the first and last time, but not available for any |
157 | | - time between the first and last time. |
158 | | -
|
159 | | -""" |
160 | | -jEph.ephem_timespan(eph::CalcephProvider) = timespan(eph.ptr) |
161 | | - |
162 | | -""" |
163 | | - ephem_timescale(eph::CalcephProvider) |
164 | | -
|
165 | | -Retrieve a timescale ID associated with the ephemeris handler `eph`. |
166 | | -It returns 1 for Barycentric Dynamical Time (TDB) and 2 for Barycentric Coordinate Time (TCB). |
167 | | -
|
168 | | -!!! warning |
169 | | - An error is thrown if the timescale is neither TDB nor TCB. |
170 | | -""" |
171 | | -function jEph.ephem_timescale(eph::CalcephProvider) |
172 | | - tsid = timeScale(eph.ptr) |
173 | | - |
174 | | - if tsid == 1 || tsid == 2 |
175 | | - return tsid |
176 | | - else |
177 | | - throw(jEph.EphemerisError("unknown time scale identifier: $tsid")) |
178 | | - end |
179 | | -end |
180 | | - |
181 | | -""" |
182 | | - ephem_compute!(res, eph, jd0, time, target, center, order) |
183 | | -
|
184 | | -Interpolate the position and/or its derivatives up to `order` for one body `target` relative |
185 | | -to another `center` at the time `jd0` + `time`, expressed as a Julian Date. This function reads |
186 | | -the ephemeris files associated to `eph` and stores the results to `res`. |
187 | | -
|
188 | | -The returned array `res` must be large enough to store the results. The size of this array |
189 | | -must be equal to 3*order: |
190 | | -
|
191 | | -- res[1:3] contain the position (x, y, z) and is always valid |
192 | | -- res[4:6] contain the velocity (dx/dt, dy/dt, dz/dt) for order ≥ 1 |
193 | | -- res[7:9] contain the acceleration (d²x/dt², d²y/dt², d²z/dt²) for order ≥ 2 |
194 | | -- res[10:12] contain the jerk (d³x/dt³, d³y/dt³, d³z/dt³) for order ≥ 3 |
195 | | -
|
196 | | -The values stores in `res` are always returned in km, km/s, km/s², km/s³ |
197 | | -""" |
198 | | -function jEph.ephem_compute!( |
199 | | - res, |
200 | | - eph::CalcephProvider, |
201 | | - jd0::Number, |
202 | | - time::Number, |
203 | | - target::Int, |
204 | | - center::Int, |
205 | | - order::Int, |
206 | | -) |
207 | | - stat = unsafe_compute!( |
208 | | - res, |
209 | | - eph.ptr, |
210 | | - Float64(jd0), |
211 | | - Float64(time), |
212 | | - target, |
213 | | - center, |
214 | | - useNaifId + unitKM + unitSec, |
215 | | - order, |
216 | | - ) |
217 | | - stat == 0 && throw( |
218 | | - jEph.EphemerisError( |
219 | | - "ephemeris data for point with NAIFId $target with respect to point " * |
220 | | - "$center is not available at JD $(jd0+time)" |
221 | | - ), |
222 | | - ) |
223 | | - return nothing |
224 | | -end |
225 | | - |
226 | | -""" |
227 | | - ephem_orient!(res, eph, jd0, time, target, center, order) |
228 | | -
|
229 | | -Interpolate the orientation and its derivatives up to `order` for the `target` body at the |
230 | | -time `jd0` + `time`, expressed as a Julian Date. This function reads the ephemeris files |
231 | | -associated to `eph` and stores the results to `res`. |
232 | | -
|
233 | | -The returned array `res` must be large enough to store the results. The size of this array |
234 | | -must be equal to 3*order: |
235 | | -
|
236 | | -- res[1:3] contain the angles |
237 | | -- res[4:6] contain the 1st derivative for order ≥ 1 |
238 | | -- res[7:9] contain the 2nd derivative for order ≥ 2 |
239 | | -- res[10:12] contain the 3rd derivative for order ≥ 3 |
240 | | -
|
241 | | -The values stores in `res` are always returned in rad, rad/s, rad/s², rad/s³ |
242 | | -
|
243 | | -!!! note |
244 | | - The `center` argument is only requested for compatibility reasons but is neglected |
245 | | - by CALCEPH. |
246 | | -""" |
247 | | -function jEph.ephem_orient!( |
248 | | - res, eph::CalcephProvider, jd0::Number, time::Number, target::Int, ::Int, order::Int |
249 | | -) |
250 | | - stat = unsafe_orient!( |
251 | | - res, |
252 | | - eph.ptr, |
253 | | - Float64(jd0), |
254 | | - Float64(time), |
255 | | - target, |
256 | | - useNaifId + unitRad + unitSec, |
257 | | - order, |
258 | | - ) |
259 | | - stat == 0 && throw( |
260 | | - jEph.EphemerisError( |
261 | | - "ephemeris data for frame with NAIFId $target is not available at " * |
262 | | - "JD $(jd0+time)", |
263 | | - ) |
264 | | - ) |
265 | | - return nothing |
266 | | -end |
| 14 | +include("internals.jl") |
| 15 | +include("interfaces.jl") |
267 | 16 |
|
268 | 17 | end |
0 commit comments