anise 0.9.2__cp313-cp313-win_amd64.whl → 0.9.3__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
anise/__init__.pyi CHANGED
@@ -5,43 +5,44 @@ import typing
5
5
  class Aberration:
6
6
  """Represents the aberration correction options in ANISE.
7
7
 
8
- In space science and engineering, accurately pointing instruments (like optical cameras or radio antennas) at a target is crucial. This task is complicated by the finite speed of light, necessitating corrections for the apparent position of the target.
8
+ In space science and engineering, accurately pointing instruments (like optical cameras or radio antennas) at a target is crucial. This task is complicated by the finite speed of light, necessitating corrections for the apparent position of the target.
9
9
 
10
- This structure holds parameters for aberration corrections applied to a target's position or state vector. These corrections account for the difference between the target's geometric (true) position and its apparent position as observed.
10
+ This structure holds parameters for aberration corrections applied to a target's position or state vector. These corrections account for the difference between the target's geometric (true) position and its apparent position as observed.
11
11
 
12
- # Rule of tumb
13
- In most Earth orbits, one does _not_ need to provide any aberration corrections. Light time to the target is less than one second (the Moon is about one second away).
14
- In near Earth orbits, e.g. inner solar system, preliminary analysis can benefit from enabling unconverged light time correction. Stellar aberration is probably not required.
15
- For deep space missions, preliminary analysis would likely require both light time correction and stellar aberration. Mission planning and operations will definitely need converged light-time calculations.
12
+ # Rule of tumb
13
+ In most Earth orbits, one does _not_ need to provide any aberration corrections. Light time to the target is less than one second (the Moon is about one second away).
14
+ In near Earth orbits, e.g. inner solar system, preliminary analysis can benefit from enabling unconverged light time correction. Stellar aberration is probably not required.
15
+ For deep space missions, preliminary analysis would likely require both light time correction and stellar aberration. Mission planning and operations will definitely need converged light-time calculations.
16
16
 
17
- For more details, <https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/abcorr.html>.
17
+ For more details, <https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/abcorr.html>.
18
18
 
19
- # SPICE Validation
19
+ # SPICE Validation
20
+
21
+ The validation test `validate_jplde_de440s_aberration_lt` checks 101,000 pairs of ephemeris computations and shows that the unconverged Light Time computation matches the SPICE computations almost all the time.
22
+ More specifically, the 99th percentile of error is less than 5 meters, the 75th percentile is less than one meter, and the median error is less than 2 millimeters."""
20
23
 
21
- The validation test `validate_jplde_de440s_aberration_lt` checks 101,000 pairs of ephemeris computations and shows that the unconverged Light Time computation matches the SPICE computations almost all the time.
22
- More specifically, the 99th percentile of error is less than 5 meters, the 75th percentile is less than one meter, and the median error is less than 2 millimeters."""
23
24
  converged: bool
24
25
  stellar: bool
25
26
  transmit_mode: bool
26
27
 
27
- def __init__(self, name: str) -> Aberration:
28
+ def __new__(cls, name: str) -> Aberration:
28
29
  """Represents the aberration correction options in ANISE.
29
30
 
30
- In space science and engineering, accurately pointing instruments (like optical cameras or radio antennas) at a target is crucial. This task is complicated by the finite speed of light, necessitating corrections for the apparent position of the target.
31
+ In space science and engineering, accurately pointing instruments (like optical cameras or radio antennas) at a target is crucial. This task is complicated by the finite speed of light, necessitating corrections for the apparent position of the target.
31
32
 
32
- This structure holds parameters for aberration corrections applied to a target's position or state vector. These corrections account for the difference between the target's geometric (true) position and its apparent position as observed.
33
+ This structure holds parameters for aberration corrections applied to a target's position or state vector. These corrections account for the difference between the target's geometric (true) position and its apparent position as observed.
33
34
 
34
- # Rule of tumb
35
- In most Earth orbits, one does _not_ need to provide any aberration corrections. Light time to the target is less than one second (the Moon is about one second away).
36
- In near Earth orbits, e.g. inner solar system, preliminary analysis can benefit from enabling unconverged light time correction. Stellar aberration is probably not required.
37
- For deep space missions, preliminary analysis would likely require both light time correction and stellar aberration. Mission planning and operations will definitely need converged light-time calculations.
35
+ # Rule of tumb
36
+ In most Earth orbits, one does _not_ need to provide any aberration corrections. Light time to the target is less than one second (the Moon is about one second away).
37
+ In near Earth orbits, e.g. inner solar system, preliminary analysis can benefit from enabling unconverged light time correction. Stellar aberration is probably not required.
38
+ For deep space missions, preliminary analysis would likely require both light time correction and stellar aberration. Mission planning and operations will definitely need converged light-time calculations.
38
39
 
39
- For more details, <https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/abcorr.html>.
40
+ For more details, <https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/abcorr.html>.
40
41
 
41
- # SPICE Validation
42
+ # SPICE Validation
42
43
 
43
- The validation test `validate_jplde_de440s_aberration_lt` checks 101,000 pairs of ephemeris computations and shows that the unconverged Light Time computation matches the SPICE computations almost all the time.
44
- More specifically, the 99th percentile of error is less than 5 meters, the 75th percentile is less than one meter, and the median error is less than 2 millimeters."""
44
+ The validation test `validate_jplde_de440s_aberration_lt` checks 101,000 pairs of ephemeris computations and shows that the unconverged Light Time computation matches the SPICE computations almost all the time.
45
+ More specifically, the 99th percentile of error is less than 5 meters, the 75th percentile is less than one meter, and the median error is less than 2 millimeters."""
45
46
 
46
47
  def __eq__(self, value: typing.Any) -> bool:
47
48
  """Return self==value."""
@@ -71,76 +72,113 @@ More specifically, the 99th percentile of error is less than 5 meters, the 75th
71
72
  class Almanac:
72
73
  """An Almanac contains all of the loaded SPICE and ANISE data. It is the context for all computations."""
73
74
 
74
- def __init__(self, path: str) -> Almanac:
75
+ def __new__(cls, path: str) -> Almanac:
75
76
  """An Almanac contains all of the loaded SPICE and ANISE data. It is the context for all computations."""
76
77
 
77
- def angular_velocity_deg_s(self, from_frame: Frame, to_frame: Frame, epoch: Epoch) -> numpy.array:
78
+ def angular_velocity_deg_s(
79
+ self, from_frame: Frame, to_frame: Frame, epoch: Epoch
80
+ ) -> numpy.array:
78
81
  """Returns the angular velocity vector in deg/s of the from_frame wrt to the to_frame.
79
82
 
80
- This can be used to compute the angular velocity of the Earth ITRF93 frame with respect to the J2000 frame for example."""
83
+ This can be used to compute the angular velocity of the Earth ITRF93 frame with respect to the J2000 frame for example."""
81
84
 
82
- def angular_velocity_rad_s(self, from_frame: Frame, to_frame: Frame, epoch: Epoch) -> numpy.array:
85
+ def angular_velocity_rad_s(
86
+ self, from_frame: Frame, to_frame: Frame, epoch: Epoch
87
+ ) -> numpy.array:
83
88
  """Returns the angular velocity vector in rad/s of the from_frame wrt to the to_frame.
84
89
 
85
- This can be used to compute the angular velocity of the Earth ITRF93 frame with respect to the J2000 frame for example."""
90
+ This can be used to compute the angular velocity of the Earth ITRF93 frame with respect to the J2000 frame for example."""
86
91
 
87
- def angular_velocity_wrt_j2000_deg_s(self, from_frame: Frame, epoch: Epoch) -> numpy.array:
92
+ def angular_velocity_wrt_j2000_deg_s(
93
+ self, from_frame: Frame, epoch: Epoch
94
+ ) -> numpy.array:
88
95
  """Returns the angular velocity vector in deg/s of the from_frame wrt to the J2000 frame."""
89
96
 
90
- def angular_velocity_wrt_j2000_rad_s(self, from_frame: Frame, epoch: Epoch) -> numpy.array:
97
+ def angular_velocity_wrt_j2000_rad_s(
98
+ self, from_frame: Frame, epoch: Epoch
99
+ ) -> numpy.array:
91
100
  """Returns the angular velocity vector in rad/s of the from_frame wrt to the J2000 frame."""
92
101
 
93
- def azimuth_elevation_range_sez(self, rx: Orbit, tx: Orbit, obstructing_body: Frame=None, ab_corr: Aberration=None) -> AzElRange:
102
+ def azimuth_elevation_range_sez(
103
+ self,
104
+ rx: Orbit,
105
+ tx: Orbit,
106
+ obstructing_body: Frame = None,
107
+ ab_corr: Aberration = None,
108
+ ) -> AzElRange:
94
109
  """Computes the azimuth (in degrees), elevation (in degrees), and range (in kilometers) of the
95
- receiver state (`rx`) seen from the transmitter state (`tx`), once converted into the SEZ frame of the transmitter.
96
-
97
- # Warning
98
- The obstructing body _should_ be a tri-axial ellipsoid body, e.g. IAU_MOON_FRAME.
99
-
100
- # Algorithm
101
- 1. If any obstructing_bodies are provided, ensure that none of these are obstructing the line of sight between the receiver and transmitter.
102
- 2. Compute the SEZ (South East Zenith) frame of the transmitter.
103
- 3. Rotate the receiver position vector into the transmitter SEZ frame.
104
- 4. Rotate the transmitter position vector into that same SEZ frame.
105
- 5. Compute the range as the norm of the difference between these two position vectors.
106
- 6. Compute the elevation, and ensure it is between +/- 180 degrees.
107
- 7. Compute the azimuth with a quadrant check, and ensure it is between 0 and 360 degrees."""
108
-
109
- def azimuth_elevation_range_sez_from_location(self, rx: Orbit, location: Location, obstructing_body: Frame=None, ab_corr: Aberration=None) -> AzElRange:
110
+ receiver state (`rx`) seen from the transmitter state (`tx`), once converted into the SEZ frame of the transmitter.
111
+
112
+ # Warning
113
+ The obstructing body _should_ be a tri-axial ellipsoid body, e.g. IAU_MOON_FRAME.
114
+
115
+ # Algorithm
116
+ 1. If any obstructing_bodies are provided, ensure that none of these are obstructing the line of sight between the receiver and transmitter.
117
+ 2. Compute the SEZ (South East Zenith) frame of the transmitter.
118
+ 3. Rotate the receiver position vector into the transmitter SEZ frame.
119
+ 4. Rotate the transmitter position vector into that same SEZ frame.
120
+ 5. Compute the range as the norm of the difference between these two position vectors.
121
+ 6. Compute the elevation, and ensure it is between +/- 180 degrees.
122
+ 7. Compute the azimuth with a quadrant check, and ensure it is between 0 and 360 degrees."""
123
+
124
+ def azimuth_elevation_range_sez_from_location(
125
+ self,
126
+ rx: Orbit,
127
+ location: Location,
128
+ obstructing_body: Frame = None,
129
+ ab_corr: Aberration = None,
130
+ ) -> AzElRange:
110
131
  """Computes the azimuth (in degrees), elevation (in degrees), and range (in kilometers) of the
111
- receiver state (`rx`) seen from the provided location (as transmitter state, once converted into the SEZ frame of the transmitter.
112
- Refer to [azimuth_elevation_range_sez] for algorithm details.
113
- Location terrain masks are always applied, i.e. if the terrain masks the object, all data is set to f64::NAN, unless specified otherwise in the Location."""
114
-
115
- def azimuth_elevation_range_sez_from_location_id(self, rx: Orbit, location_id: int, obstructing_body: Frame=None, ab_corr: Aberration=None) -> AzElRange:
132
+ receiver state (`rx`) seen from the provided location (as transmitter state, once converted into the SEZ frame of the transmitter.
133
+ Refer to [azimuth_elevation_range_sez] for algorithm details.
134
+ Location terrain masks are always applied, i.e. if the terrain masks the object, all data is set to f64::NAN, unless specified otherwise in the Location."""
135
+
136
+ def azimuth_elevation_range_sez_from_location_id(
137
+ self,
138
+ rx: Orbit,
139
+ location_id: int,
140
+ obstructing_body: Frame = None,
141
+ ab_corr: Aberration = None,
142
+ ) -> AzElRange:
116
143
  """Computes the azimuth (in degrees), elevation (in degrees), and range (in kilometers) of the
117
- receiver state (`rx`) seen from the location ID (as transmitter state, once converted into the SEZ frame of the transmitter.
118
- Refer to [azimuth_elevation_range_sez] for algorithm details."""
119
-
120
- def azimuth_elevation_range_sez_from_location_name(self, rx: Orbit, location_name: str, obstructing_body: Frame=None, ab_corr: Aberration=None) -> AzElRange:
144
+ receiver state (`rx`) seen from the location ID (as transmitter state, once converted into the SEZ frame of the transmitter.
145
+ Refer to [azimuth_elevation_range_sez] for algorithm details."""
146
+
147
+ def azimuth_elevation_range_sez_from_location_name(
148
+ self,
149
+ rx: Orbit,
150
+ location_name: str,
151
+ obstructing_body: Frame = None,
152
+ ab_corr: Aberration = None,
153
+ ) -> AzElRange:
121
154
  """Computes the azimuth (in degrees), elevation (in degrees), and range (in kilometers) of the
122
- receiver state (`rx`) seen from the location ID (as transmitter state, once converted into the SEZ frame of the transmitter.
123
- Refer to [azimuth_elevation_range_sez] for algorithm details."""
124
-
125
- def azimuth_elevation_range_sez_many(self, rx_tx_states: typing.List[Orbit], obstructing_body: Frame=None, ab_corr: Aberration=None) -> typing.List[AzElRange]:
155
+ receiver state (`rx`) seen from the location ID (as transmitter state, once converted into the SEZ frame of the transmitter.
156
+ Refer to [azimuth_elevation_range_sez] for algorithm details."""
157
+
158
+ def azimuth_elevation_range_sez_many(
159
+ self,
160
+ rx_tx_states: typing.List[Orbit],
161
+ obstructing_body: Frame = None,
162
+ ab_corr: Aberration = None,
163
+ ) -> typing.List[AzElRange]:
126
164
  """Computes the azimuth (in degrees), elevation (in degrees), and range (in kilometers) of the
127
- receiver states (first item in tuple) seen from the transmitter state (second item in states tuple), once converted into the SEZ frame of the transmitter.
165
+ receiver states (first item in tuple) seen from the transmitter state (second item in states tuple), once converted into the SEZ frame of the transmitter.
128
166
 
129
- Note: if any computation fails, the error will be printed to the stderr.
130
- Note: the output AER will be chronologically sorted, regardless of transmitter.
167
+ Note: if any computation fails, the error will be printed to the stderr.
168
+ Note: the output AER will be chronologically sorted, regardless of transmitter.
131
169
 
132
- Refer to [azimuth_elevation_range_sez] for details."""
170
+ Refer to [azimuth_elevation_range_sez] for details."""
133
171
 
134
- def beta_angle_deg(self, state: Orbit, ab_corr: Aberration=None) -> float:
172
+ def beta_angle_deg(self, state: Orbit, ab_corr: Aberration = None) -> float:
135
173
  """Computes the Beta angle (β) for a given orbital state, in degrees. A Beta angle of 0° indicates that the orbit plane is edge-on to the Sun, leading to maximum eclipse time. Conversely, a Beta angle of +90° or -90° means the orbit plane is face-on to the Sun, resulting in continuous sunlight exposure and no eclipses.
136
174
 
137
- The Beta angle (β) is defined as the angle between the orbit plane of a spacecraft and the vector from the central body (e.g., Earth) to the Sun. In simpler terms, it measures how much of the time a satellite in orbit is exposed to direct sunlight.
138
- The mathematical formula for the Beta angle is: β=arcsin(h⋅usun\u200b)
139
- Where:
140
- - h is the unit vector of the orbital momentum.
141
- - usun\u200b is the unit vector pointing from the central body to the Sun.
175
+ The Beta angle (β) is defined as the angle between the orbit plane of a spacecraft and the vector from the central body (e.g., Earth) to the Sun. In simpler terms, it measures how much of the time a satellite in orbit is exposed to direct sunlight.
176
+ The mathematical formula for the Beta angle is: β=arcsin(h⋅usun\u200b)
177
+ Where:
178
+ - h is the unit vector of the orbital momentum.
179
+ - usun\u200b is the unit vector pointing from the central body to the Sun.
142
180
 
143
- Original code from GMAT, <https://github.com/ChristopherRabotin/GMAT/blob/GMAT-R2022a/src/gmatutil/util/CalculationUtilities.cpp#L209-L219>"""
181
+ Original code from GMAT, <https://github.com/ChristopherRabotin/GMAT/blob/GMAT-R2022a/src/gmatutil/util/CalculationUtilities.cpp#L209-L219>"""
144
182
 
145
183
  def bpc_domain(self, id: int) -> typing.Tuple:
146
184
  """Returns the applicable domain of the request id, i.e. start and end epoch that the provided id has loaded data."""
@@ -148,30 +186,40 @@ Original code from GMAT, <https://github.com/ChristopherRabotin/GMAT/blob/GMAT-R
148
186
  def bpc_domains(self) -> typing.Dict:
149
187
  """Returns a map of each loaded BPC ID to its domain validity.
150
188
 
151
- # Warning
152
- This function performs a memory allocation."""
189
+ # Warning
190
+ This function performs a memory allocation."""
153
191
 
154
192
  def bpc_summaries(self, id: int) -> typing.List:
155
193
  """Returns a vector of the summaries whose ID matches the desired `id`, in the order in which they will be used, i.e. in reverse loading order.
156
194
 
157
- # Warning
158
- This function performs a memory allocation."""
195
+ # Warning
196
+ This function performs a memory allocation."""
159
197
 
160
198
  def bpc_swap(self, alias: str, new_bpc_path: str, new_alias: str) -> None:
161
199
  """Load a new DAF/BPC file in place of the one in the provided alias.
162
200
 
163
- This reuses the existing memory buffer, growing it only if the new file
164
- is larger than the previous capacity. This effectively adopts a
165
- "high watermark" memory strategy, where the memory usage for this slot
166
- is determined by the largest file ever loaded into it."""
201
+ This reuses the existing memory buffer, growing it only if the new file
202
+ is larger than the previous capacity. This effectively adopts a
203
+ "high watermark" memory strategy, where the memory usage for this slot
204
+ is determined by the largest file ever loaded into it."""
167
205
 
168
206
  def bpc_unload(self, alias: str) -> None:
169
207
  """Unloads (in-place) the BPC with the provided alias.
170
- **WARNING:** This causes the order of the loaded files to be perturbed, which may be an issue if several SPKs with the same IDs are loaded."""
171
-
172
- def describe(self, spk: bool=None, bpc: bool=None, planetary: bool=None, spacecraft: bool=None, eulerparams: bool=None, locations: bool=None, time_scale: TimeScale=None, round_time: bool=None) -> None:
208
+ **WARNING:** This causes the order of the loaded files to be perturbed, which may be an issue if several SPKs with the same IDs are loaded."""
209
+
210
+ def describe(
211
+ self,
212
+ spk: bool = None,
213
+ bpc: bool = None,
214
+ planetary: bool = None,
215
+ spacecraft: bool = None,
216
+ eulerparams: bool = None,
217
+ locations: bool = None,
218
+ time_scale: TimeScale = None,
219
+ round_time: bool = None,
220
+ ) -> None:
173
221
  """Pretty prints the description of this Almanac, showing everything by default. Default time scale is TDB.
174
- If any parameter is set to true, then nothing other than that will be printed."""
222
+ If any parameter is set to true, then nothing other than that will be printed."""
175
223
 
176
224
  def frame_info(self, uid: Frame) -> Frame:
177
225
  """Returns the frame information (gravitational param, shape) as defined in this Almanac from an empty frame"""
@@ -180,37 +228,51 @@ If any parameter is set to true, then nothing other than that will be printed.""
180
228
  def from_ccsds_oem_file(path: str, naif_id: int) -> Almanac:
181
229
  """Initializes a new Almanac from a file path to CCSDS OEM file, after converting to to SPICE SPK/BSP"""
182
230
 
183
- def line_of_sight_obstructed(self, observer: Orbit, observed: Orbit, obstructing_body: Frame, ab_corr: Aberration=None) -> bool:
231
+ def line_of_sight_obstructed(
232
+ self,
233
+ observer: Orbit,
234
+ observed: Orbit,
235
+ obstructing_body: Frame,
236
+ ab_corr: Aberration = None,
237
+ ) -> bool:
184
238
  """Computes whether the line of sight between an observer and an observed Cartesian state is obstructed by the obstructing body.
185
- Returns true if the obstructing body is in the way, false otherwise.
186
-
187
- For example, if the Moon is in between a Lunar orbiter (observed) and a ground station (observer), then this function returns `true`
188
- because the Moon (obstructing body) is indeed obstructing the line of sight.
189
-
190
- ```text
191
- Observed
192
- o -
193
- + -
194
- + -
195
- + *** -
196
- * + * -
197
- * + + * + + o
198
- * * Observer
199
- ****
200
- ```
201
-
202
- Key Elements:
203
- - `o` represents the positions of the observer and observed objects.
204
- - The dashed line connecting the observer and observed is the line of sight.
205
-
206
- Algorithm (source: Algorithm 35 of Vallado, 4th edition, page 308.):
207
- - `r1` and `r2` are the transformed radii of the observed and observer objects, respectively.
208
- - `r1sq` and `r2sq` are the squared magnitudes of these vectors.
209
- - `r1dotr2` is the dot product of `r1` and `r2`.
210
- - `tau` is a parameter that determines the intersection point along the line of sight.
211
- - The condition `(1.0 - tau) * r1sq + r1dotr2 * tau <= ob_mean_eq_radius_km^2` checks if the line of sight is within the obstructing body's radius, indicating an obstruction."""
212
-
213
- def list_kernels(self, spk: bool=None, bpc: bool=None, planetary: bool=None, spacecraft: bool=None, eulerparams: bool=None, locations: bool=None) -> list:
239
+ Returns true if the obstructing body is in the way, false otherwise.
240
+
241
+ For example, if the Moon is in between a Lunar orbiter (observed) and a ground station (observer), then this function returns `true`
242
+ because the Moon (obstructing body) is indeed obstructing the line of sight.
243
+
244
+ ```text
245
+ Observed
246
+ o -
247
+ + -
248
+ + -
249
+ + *** -
250
+ * + * -
251
+ * + + * + + o
252
+ * * Observer
253
+ ****
254
+ ```
255
+
256
+ Key Elements:
257
+ - `o` represents the positions of the observer and observed objects.
258
+ - The dashed line connecting the observer and observed is the line of sight.
259
+
260
+ Algorithm (source: Algorithm 35 of Vallado, 4th edition, page 308.):
261
+ - `r1` and `r2` are the transformed radii of the observed and observer objects, respectively.
262
+ - `r1sq` and `r2sq` are the squared magnitudes of these vectors.
263
+ - `r1dotr2` is the dot product of `r1` and `r2`.
264
+ - `tau` is a parameter that determines the intersection point along the line of sight.
265
+ - The condition `(1.0 - tau) * r1sq + r1dotr2 * tau <= ob_mean_eq_radius_km^2` checks if the line of sight is within the obstructing body's radius, indicating an obstruction."""
266
+
267
+ def list_kernels(
268
+ self,
269
+ spk: bool = None,
270
+ bpc: bool = None,
271
+ planetary: bool = None,
272
+ spacecraft: bool = None,
273
+ eulerparams: bool = None,
274
+ locations: bool = None,
275
+ ) -> list:
214
276
  """Returns the list of loaded kernels"""
215
277
 
216
278
  def load(self, path: str) -> Almanac:
@@ -221,7 +283,7 @@ Algorithm (source: Algorithm 35 of Vallado, 4th edition, page 308.):
221
283
 
222
284
  def load_from_metafile(self, metafile: MetaFile, autodelete: bool) -> Almanac:
223
285
  """Load from the provided MetaFile, downloading it if necessary.
224
- Set autodelete to true to automatically delete lock files. Lock files are important in multi-threaded loads."""
286
+ Set autodelete to true to automatically delete lock files. Lock files are important in multi-threaded loads."""
225
287
 
226
288
  def load_stk_e_file(self, path: str, naif_id: int) -> Almanac:
227
289
  """Converts the provided Ansys STK .e file to SPICE SPK/BSP and loads it in the Almanac."""
@@ -232,69 +294,94 @@ Set autodelete to true to automatically delete lock files. Lock files are import
232
294
  def location_from_name(self, name: str) -> Location:
233
295
  """Returns the Location from its name, searching through all loaded location datasets in reverse order."""
234
296
 
235
- def occultation(self, back_frame: Frame, front_frame: Frame, observer: Orbit, ab_corr: Aberration=None) -> Occultation:
297
+ def occultation(
298
+ self,
299
+ back_frame: Frame,
300
+ front_frame: Frame,
301
+ observer: Orbit,
302
+ ab_corr: Aberration = None,
303
+ ) -> Occultation:
236
304
  """Computes the occultation percentage of the `back_frame` object by the `front_frame` object as seen from the observer, when according for the provided aberration correction.
237
305
 
238
- A zero percent occultation means that the back object is fully visible from the observer.
239
- A 100% percent occultation means that the back object is fully hidden from the observer because of the front frame (i.e. _umbra_ if the back object is the Sun).
240
- A value in between means that the back object is partially hidden from the observser (i.e. _penumbra_ if the back object is the Sun).
241
- Refer to the [MathSpec](https://nyxspace.com/nyxspace/MathSpec/celestial/eclipse/) for modeling details."""
306
+ A zero percent occultation means that the back object is fully visible from the observer.
307
+ A 100% percent occultation means that the back object is fully hidden from the observer because of the front frame (i.e. _umbra_ if the back object is the Sun).
308
+ A value in between means that the back object is partially hidden from the observser (i.e. _penumbra_ if the back object is the Sun).
309
+ Refer to the [MathSpec](https://nyxspace.com/nyxspace/MathSpec/celestial/eclipse/) for modeling details."""
242
310
 
243
- def report_event_arcs(self, state_spec: StateSpec, event: Event, start_epoch: Epoch, end_epoch: Epoch) -> list:
311
+ def report_event_arcs(
312
+ self, state_spec: StateSpec, event: Event, start_epoch: Epoch, end_epoch: Epoch
313
+ ) -> list:
244
314
  """Report the rising and falling edges/states where the event arc happens.
245
315
 
246
- For example, for a scalar expression less than X, this will report all of the times when the expression falls below X and rises above X.
247
- This method uses the report_events function under the hood."""
316
+ For example, for a scalar expression less than X, this will report all of the times when the expression falls below X and rises above X.
317
+ This method uses the report_events function under the hood."""
248
318
 
249
- def report_events(self, state_spec: StateSpec, event: Event, start_epoch: Epoch, end_epoch: Epoch) -> list:
319
+ def report_events(
320
+ self, state_spec: StateSpec, event: Event, start_epoch: Epoch, end_epoch: Epoch
321
+ ) -> list:
250
322
  """Report all of the states when the provided event happens.
251
- This method may only be used for equality events, minimum, and maximum events. For spanned events (e.g. Less Than/Greater Than), use report_event_arcs.
323
+ This method may only be used for equality events, minimum, and maximum events. For spanned events (e.g. Less Than/Greater Than), use report_event_arcs.
252
324
 
253
- # Method
254
- The report event function starts by lineraly scanning the whole state spec from the start to the end epoch.
255
- This uses an adaptive step scan modeled on the Runge Kutta adaptive step integrator, but the objective is to ensure that the scalar expression
256
- of the event is evaluated at steps where it is linearly changing (to within 10% of linearity). This allows finding coarse brackets where
257
- the expression changes signs exactly once.
258
- Then, each bracket it sent in parallel to a Brent's method root finder to find the exact time of the event.
325
+ # Method
326
+ The report event function starts by lineraly scanning the whole state spec from the start to the end epoch.
327
+ This uses an adaptive step scan modeled on the Runge Kutta adaptive step integrator, but the objective is to ensure that the scalar expression
328
+ of the event is evaluated at steps where it is linearly changing (to within 10% of linearity). This allows finding coarse brackets where
329
+ the expression changes signs exactly once.
330
+ Then, each bracket it sent in parallel to a Brent's method root finder to find the exact time of the event.
259
331
 
260
- # Limitation
261
- While this approach is both very robust and very fast, if you think the finder may be missing some events, you should _reduce_ the epoch precision
262
- of the event as a multiplicative factor of that precision is used to scan the trajectory linearly. Alternatively, you may export the scalars at
263
- a fixed interval using the report_scalars or report_scalars_flat function and manually analyze the results of the scalar expression."""
332
+ # Limitation
333
+ While this approach is both very robust and very fast, if you think the finder may be missing some events, you should _reduce_ the epoch precision
334
+ of the event as a multiplicative factor of that precision is used to scan the trajectory linearly. Alternatively, you may export the scalars at
335
+ a fixed interval using the report_scalars or report_scalars_flat function and manually analyze the results of the scalar expression."""
264
336
 
265
337
  def report_scalars(self, report: ReportScalars, time_series: TimeSeries) -> dict:
266
338
  """Report a set of scalar expressions, optionally with aliases, at a fixed time step defined in the TimeSeries."""
267
339
 
268
- def report_visibility_arcs(self, state_spec: StateSpec, location_id: int, start_epoch: Epoch, end_epoch: Epoch, sample_rate: Duration, obstructing_body: Frame=None) -> list:
340
+ def report_visibility_arcs(
341
+ self,
342
+ state_spec: StateSpec,
343
+ location_id: int,
344
+ start_epoch: Epoch,
345
+ end_epoch: Epoch,
346
+ sample_rate: Duration,
347
+ obstructing_body: Frame = None,
348
+ ) -> list:
269
349
  """Report the list of visibility arcs for the desired location ID."""
270
350
 
271
351
  def rotate(self, from_frame: Frame, to_frame: Frame, epoch: Epoch) -> DCM:
272
352
  """Returns the 6x6 DCM needed to rotation the `from_frame` to the `to_frame`.
273
353
 
274
- # Warning
275
- This function only performs the rotation and no translation whatsoever. Use the `transform_from_to` function instead to include rotations.
354
+ # Warning
355
+ This function only performs the rotation and no translation whatsoever. Use the `transform_from_to` function instead to include rotations.
276
356
 
277
- # Note
278
- This function performs a recursion of no more than twice the MAX_TREE_DEPTH."""
357
+ # Note
358
+ This function performs a recursion of no more than twice the MAX_TREE_DEPTH."""
279
359
 
280
360
  def rotate_to(self, state: Orbit, observer_frame: Frame) -> Orbit:
281
361
  """Rotates the provided Cartesian state into the requested observer frame
282
362
 
283
- **WARNING:** This function only performs the translation and no rotation _whatsoever_. Use the `transform_to` function instead to include rotations."""
363
+ **WARNING:** This function only performs the translation and no rotation _whatsoever_. Use the `transform_to` function instead to include rotations."""
284
364
 
285
- def solar_eclipsing(self, eclipsing_frame: Frame, observer: Orbit, ab_corr: Aberration=None) -> Occultation:
365
+ def solar_eclipsing(
366
+ self, eclipsing_frame: Frame, observer: Orbit, ab_corr: Aberration = None
367
+ ) -> Occultation:
286
368
  """Computes the solar eclipsing of the observer due to the eclipsing_frame.
287
369
 
288
- This function calls `occultation` where the back object is the Sun in the J2000 frame, and the front object
289
- is the provided eclipsing frame."""
370
+ This function calls `occultation` where the back object is the Sun in the J2000 frame, and the front object
371
+ is the provided eclipsing frame."""
290
372
 
291
- def solar_eclipsing_many(self, eclipsing_frame: Frame, observers: typing.List[Orbit], ab_corr: Aberration=None) -> typing.List[Occultation]:
373
+ def solar_eclipsing_many(
374
+ self,
375
+ eclipsing_frame: Frame,
376
+ observers: typing.List[Orbit],
377
+ ab_corr: Aberration = None,
378
+ ) -> typing.List[Occultation]:
292
379
  """Computes the solar eclipsing of all the observers due to the eclipsing_frame, computed in parallel under the hood.
293
380
 
294
- Note: if any computation fails, the error will be printed to the stderr.
295
- Note: the output AER will be chronologically sorted, regardless of transmitter.
381
+ Note: if any computation fails, the error will be printed to the stderr.
382
+ Note: the output AER will be chronologically sorted, regardless of transmitter.
296
383
 
297
- Refer to [solar_eclipsing] for details."""
384
+ Refer to [solar_eclipsing] for details."""
298
385
 
299
386
  def spk_domain(self, id: int) -> typing.Tuple:
300
387
  """Returns the applicable domain of the request id, i.e. start and end epoch that the provided id has loaded data."""
@@ -302,38 +389,49 @@ Refer to [solar_eclipsing] for details."""
302
389
  def spk_domains(self) -> typing.Dict:
303
390
  """Returns a map of each loaded SPK ID to its domain validity.
304
391
 
305
- # Warning
306
- This function performs a memory allocation."""
307
-
308
- def spk_ezr(self, target: int, epoch: Epoch, frame: int, observer: int, ab_corr: Aberration=None) -> Orbit:
392
+ # Warning
393
+ This function performs a memory allocation."""
394
+
395
+ def spk_ezr(
396
+ self,
397
+ target: int,
398
+ epoch: Epoch,
399
+ frame: int,
400
+ observer: int,
401
+ ab_corr: Aberration = None,
402
+ ) -> Orbit:
309
403
  """Alias fo SPICE's `spkezr` where the inputs must be the NAIF IDs of the objects and frames with the caveat that the aberration is moved to the last positional argument."""
310
404
 
311
405
  def spk_summaries(self, id: int) -> typing.List:
312
406
  """Returns a vector of the summaries whose ID matches the desired `id`, in the order in which they will be used, i.e. in reverse loading order.
313
407
 
314
- # Warning
315
- This function performs a memory allocation."""
408
+ # Warning
409
+ This function performs a memory allocation."""
316
410
 
317
411
  def spk_swap(self, alias: str, new_spk_path: str, new_alias: str) -> None:
318
412
  """Load a new DAF/SPK file in place of the one in the provided alias.
319
413
 
320
- This reuses the existing memory buffer, growing it only if the new file
321
- is larger than the previous capacity. This effectively adopts a
322
- "high watermark" memory strategy, where the memory usage for this slot
323
- is determined by the largest file ever loaded into it
324
- ."""
414
+ This reuses the existing memory buffer, growing it only if the new file
415
+ is larger than the previous capacity. This effectively adopts a
416
+ "high watermark" memory strategy, where the memory usage for this slot
417
+ is determined by the largest file ever loaded into it
418
+ ."""
325
419
 
326
420
  def spk_unload(self, alias: str) -> None:
327
421
  """Unloads (in-place) the SPK with the provided alias.
328
- **WARNING:** This causes the order of the loaded files to be perturbed, which may be an issue if several SPKs with the same IDs are loaded."""
422
+ **WARNING:** This causes the order of the loaded files to be perturbed, which may be an issue if several SPKs with the same IDs are loaded."""
329
423
 
330
- def state_of(self, object_id: int, observer: Frame, epoch: Epoch, ab_corr: Aberration=None) -> Orbit:
424
+ def state_of(
425
+ self, object_id: int, observer: Frame, epoch: Epoch, ab_corr: Aberration = None
426
+ ) -> Orbit:
331
427
  """Returns the Cartesian state of the object as seen from the provided observer frame (essentially `spkezr`).
332
428
 
333
- # Note
334
- The units will be those of the underlying ephemeris data (typically km and km/s)"""
429
+ # Note
430
+ The units will be those of the underlying ephemeris data (typically km and km/s)"""
335
431
 
336
- def sun_angle_deg(self, target_id: int, observer_id: int, epoch: Epoch, ab_corr: Aberration) -> float:
432
+ def sun_angle_deg(
433
+ self, target_id: int, observer_id: int, epoch: Epoch, ab_corr: Aberration
434
+ ) -> float:
337
435
  """Returns the angular separation (between 0 and 180 degrees) between the observer and the Sun, and the observer and the target body ID.
338
436
  This is formally known as the "solar elongation".
339
437
  This computes the Sun Probe Earth angle (SPE) if the probe is in a loaded SPK, its ID is the "observer_id", and the target is set to its central body.
@@ -378,70 +476,101 @@ Obs. -- Target
378
476
  2. Compute the position of the target as seen from the observer
379
477
  3. Return the arccosine of the dot product of the norms of these vectors."""
380
478
 
381
- def sun_angle_deg_from_frame(self, target: Frame, observer: Frame, epoch: Epoch, ab_corr: Aberration) -> float:
479
+ def sun_angle_deg_from_frame(
480
+ self, target: Frame, observer: Frame, epoch: Epoch, ab_corr: Aberration
481
+ ) -> float:
382
482
  """Convenience function that calls `sun_angle_deg` with the provided frames instead of the ephemeris ID."""
383
483
 
384
484
  def to_metaalmanac(self) -> MetaAlmanac:
385
485
  """Saves the current configuration to a MetaAlmanac for future reloading from the local file system.
386
486
 
387
- WARNING: If data was loaded from its raw bytes, or if a custom alias was used, then the MetaFile produced will not be usable.
388
- The alias used for each data type is expected to be a path. Further, all paths are ASSUMED to be loaded from the same directory.
389
- The Almanac does not resolve directories for you."""
390
-
391
- def transform(self, target_frame: Frame, observer_frame: Frame, epoch: Epoch, ab_corr: Aberration=None) -> Orbit:
487
+ WARNING: If data was loaded from its raw bytes, or if a custom alias was used, then the MetaFile produced will not be usable.
488
+ The alias used for each data type is expected to be a path. Further, all paths are ASSUMED to be loaded from the same directory.
489
+ The Almanac does not resolve directories for you."""
490
+
491
+ def transform(
492
+ self,
493
+ target_frame: Frame,
494
+ observer_frame: Frame,
495
+ epoch: Epoch,
496
+ ab_corr: Aberration = None,
497
+ ) -> Orbit:
392
498
  """Returns the Cartesian state needed to transform the `from_frame` to the `to_frame`.
393
499
 
394
- # SPICE Compatibility
395
- This function is the SPICE equivalent of spkezr: `spkezr(TARGET_ID, EPOCH_TDB_S, ORIENTATION_ID, ABERRATION, OBSERVER_ID)`
396
- In ANISE, the TARGET_ID and ORIENTATION are provided in the first argument (TARGET_FRAME), as that frame includes BOTH
397
- the target ID and the orientation of that target. The EPOCH_TDB_S is the epoch in the TDB time system, which is computed
398
- in ANISE using Hifitime. THe ABERRATION is computed by providing the optional Aberration flag. Finally, the OBSERVER
399
- argument is replaced by OBSERVER_FRAME: if the OBSERVER_FRAME argument has the same orientation as the TARGET_FRAME, then this call
400
- will return exactly the same data as the spkerz SPICE call.
401
-
402
- # Note
403
- The units will be those of the underlying ephemeris data (typically km and km/s)"""
404
-
405
- def transform_many(self, target_frame: Frame, observer_frame: Frame, time_series: TimeSeries, ab_corr: Aberration=None) -> typing.List[Orbit]:
500
+ # SPICE Compatibility
501
+ This function is the SPICE equivalent of spkezr: `spkezr(TARGET_ID, EPOCH_TDB_S, ORIENTATION_ID, ABERRATION, OBSERVER_ID)`
502
+ In ANISE, the TARGET_ID and ORIENTATION are provided in the first argument (TARGET_FRAME), as that frame includes BOTH
503
+ the target ID and the orientation of that target. The EPOCH_TDB_S is the epoch in the TDB time system, which is computed
504
+ in ANISE using Hifitime. THe ABERRATION is computed by providing the optional Aberration flag. Finally, the OBSERVER
505
+ argument is replaced by OBSERVER_FRAME: if the OBSERVER_FRAME argument has the same orientation as the TARGET_FRAME, then this call
506
+ will return exactly the same data as the spkerz SPICE call.
507
+
508
+ # Note
509
+ The units will be those of the underlying ephemeris data (typically km and km/s)"""
510
+
511
+ def transform_many(
512
+ self,
513
+ target_frame: Frame,
514
+ observer_frame: Frame,
515
+ time_series: TimeSeries,
516
+ ab_corr: Aberration = None,
517
+ ) -> typing.List[Orbit]:
406
518
  """Returns a chronologically sorted list of the Cartesian states that transform the `from_frame` to the `to_frame` for each epoch of the time series, computed in parallel under the hood.
407
- Note: if any transformation fails, the error will be printed to the stderr.
519
+ Note: if any transformation fails, the error will be printed to the stderr.
408
520
 
409
- Refer to [transform] for details."""
521
+ Refer to [transform] for details."""
410
522
 
411
- def transform_many_to(self, states: typing.List[Orbit], observer_frame: Frame, ab_corr: Aberration=None) -> typing.List[Orbit]:
523
+ def transform_many_to(
524
+ self,
525
+ states: typing.List[Orbit],
526
+ observer_frame: Frame,
527
+ ab_corr: Aberration = None,
528
+ ) -> typing.List[Orbit]:
412
529
  """Returns a chronologically sorted list of the provided states as seen from the observer frame, given the aberration.
413
- Note: if any transformation fails, the error will be printed to the stderr.
414
- Note: the input ordering is lost: the output states will not be in the same order as the input states if these are not chronologically sorted!
530
+ Note: if any transformation fails, the error will be printed to the stderr.
531
+ Note: the input ordering is lost: the output states will not be in the same order as the input states if these are not chronologically sorted!
415
532
 
416
- Refer to [transform_to] for details."""
533
+ Refer to [transform_to] for details."""
417
534
 
418
- def transform_to(self, state: Orbit, observer_frame: Frame, ab_corr: Aberration=None) -> Orbit:
535
+ def transform_to(
536
+ self, state: Orbit, observer_frame: Frame, ab_corr: Aberration = None
537
+ ) -> Orbit:
419
538
  """Returns the provided state as seen from the observer frame, given the aberration."""
420
539
 
421
- def translate(self, target_frame: Frame, observer_frame: Frame, epoch: Epoch, ab_corr: Aberration=None) -> Orbit:
540
+ def translate(
541
+ self,
542
+ target_frame: Frame,
543
+ observer_frame: Frame,
544
+ epoch: Epoch,
545
+ ab_corr: Aberration = None,
546
+ ) -> Orbit:
422
547
  """Returns the Cartesian state of the target frame as seen from the observer frame at the provided epoch, and optionally given the aberration correction.
423
548
 
424
- # SPICE Compatibility
425
- This function is the SPICE equivalent of spkezr: `spkezr(TARGET_ID, EPOCH_TDB_S, ORIENTATION_ID, ABERRATION, OBSERVER_ID)`
426
- In ANISE, the TARGET_ID and ORIENTATION are provided in the first argument (TARGET_FRAME), as that frame includes BOTH
427
- the target ID and the orientation of that target. The EPOCH_TDB_S is the epoch in the TDB time system, which is computed
428
- in ANISE using Hifitime. THe ABERRATION is computed by providing the optional Aberration flag. Finally, the OBSERVER
429
- argument is replaced by OBSERVER_FRAME: if the OBSERVER_FRAME argument has the same orientation as the TARGET_FRAME, then this call
430
- will return exactly the same data as the spkerz SPICE call.
549
+ # SPICE Compatibility
550
+ This function is the SPICE equivalent of spkezr: `spkezr(TARGET_ID, EPOCH_TDB_S, ORIENTATION_ID, ABERRATION, OBSERVER_ID)`
551
+ In ANISE, the TARGET_ID and ORIENTATION are provided in the first argument (TARGET_FRAME), as that frame includes BOTH
552
+ the target ID and the orientation of that target. The EPOCH_TDB_S is the epoch in the TDB time system, which is computed
553
+ in ANISE using Hifitime. THe ABERRATION is computed by providing the optional Aberration flag. Finally, the OBSERVER
554
+ argument is replaced by OBSERVER_FRAME: if the OBSERVER_FRAME argument has the same orientation as the TARGET_FRAME, then this call
555
+ will return exactly the same data as the spkerz SPICE call.
431
556
 
432
- # Warning
433
- This function only performs the translation and no rotation whatsoever. Use the `transform` function instead to include rotations.
557
+ # Warning
558
+ This function only performs the translation and no rotation whatsoever. Use the `transform` function instead to include rotations.
434
559
 
435
- # Note
436
- This function performs a recursion of no more than twice the [MAX_TREE_DEPTH]."""
560
+ # Note
561
+ This function performs a recursion of no more than twice the [MAX_TREE_DEPTH]."""
437
562
 
438
- def translate_geometric(self, target_frame: Frame, observer_frame: Frame, epoch: Epoch) -> Orbit:
563
+ def translate_geometric(
564
+ self, target_frame: Frame, observer_frame: Frame, epoch: Epoch
565
+ ) -> Orbit:
439
566
  """Returns the geometric position vector, velocity vector, and acceleration vector needed to translate the `from_frame` to the `to_frame`, where the distance is in km, the velocity in km/s, and the acceleration in km/s^2."""
440
567
 
441
- def translate_to(self, state: Orbit, observer_frame: Frame, ab_corr: Aberration=None) -> Orbit:
568
+ def translate_to(
569
+ self, state: Orbit, observer_frame: Frame, ab_corr: Aberration = None
570
+ ) -> Orbit:
442
571
  """Translates the provided Cartesian state into the requested observer frame
443
572
 
444
- **WARNING:** This function only performs the translation and no rotation _whatsoever_. Use the `transform_to` function instead to include rotations."""
573
+ **WARNING:** This function only performs the translation and no rotation _whatsoever_. Use the `transform_to` function instead to include rotations."""
445
574
 
446
575
  def translate_to_parent(self, source: Frame, epoch: Epoch) -> Orbit:
447
576
  """Performs the GEOMETRIC translation to the parent. Use translate_from_to for aberration."""
@@ -455,17 +584,13 @@ This function performs a recursion of no more than twice the [MAX_TREE_DEPTH].""
455
584
  @typing.final
456
585
  class LocationDataSet:
457
586
  """A wrapper around a location dataset kernel (PyO3 does not handle type aliases).
458
- Use this class to load and unload kernels. Manipulate using its LocationDhallSet representation."""
459
-
460
- def __init__(self) -> None:
461
- """A wrapper around a location dataset kernel (PyO3 does not handle type aliases).
462
- Use this class to load and unload kernels. Manipulate using its LocationDhallSet representation."""
587
+ Use this class to load and unload kernels. Manipulate using its LocationDhallSet representation."""
463
588
 
464
589
  @staticmethod
465
590
  def load(path: str) -> LocationDataSet:
466
591
  """Loads a Location Dataset kernel from the provided path"""
467
592
 
468
- def save_as(self, path: str, overwrite: bool=False) -> None:
593
+ def save_as(self, path: str, overwrite: bool = False) -> None:
469
594
  """Save this dataset as a kernel, optionally specifying whether to overwrite the existing file."""
470
595
 
471
596
  def to_dhallset(self) -> LocationDhallSet:
@@ -474,10 +599,8 @@ Use this class to load and unload kernels. Manipulate using its LocationDhallSet
474
599
  @typing.final
475
600
  class LocationDhallSet:
476
601
  """A Dhall-serializable Location DataSet that serves as an optional intermediate to the LocationDataSet kernels."""
477
- data: list
478
602
 
479
- def __init__(self, data: list) -> None:
480
- """A Dhall-serializable Location DataSet that serves as an optional intermediate to the LocationDataSet kernels."""
603
+ data: list
481
604
 
482
605
  def dumps(self) -> str:
483
606
  """Returns the Dhall representation of this LocationDhallSet. Equivalent to to_dhall."""
@@ -499,32 +622,31 @@ class LocationDhallSet:
499
622
  @typing.final
500
623
  class LocationDhallSetEntry:
501
624
  """Entry of a Location Dhall set"""
625
+
502
626
  alias: str
503
627
  id: int
504
628
  value: Location
505
629
 
506
- def __init__(self, value: Location, id: int=None, alias: str=None) -> None:
507
- """Entry of a Location Dhall set"""
508
-
509
630
  @typing.final
510
631
  class MetaAlmanac:
511
632
  """A structure to set up an Almanac, with automatic downloading, local storage, checksum checking, and more.
512
633
 
513
- # Behavior
514
- If the URI is a local path, relative or absolute, nothing will be fetched from a remote. Relative paths are relative to the execution folder (i.e. the current working directory).
515
- If the URI is a remote path, the MetaAlmanac will first check if the file exists locally. If it exists, it will check that the CRC32 checksum of this file matches that of the specs.
516
- If it does not match, the file will be downloaded again. If no CRC32 is provided but the file exists, then the MetaAlmanac will fetch the remote file and overwrite the existing file.
517
- The downloaded path will be stored in the "AppData" folder."""
634
+ # Behavior
635
+ If the URI is a local path, relative or absolute, nothing will be fetched from a remote. Relative paths are relative to the execution folder (i.e. the current working directory).
636
+ If the URI is a remote path, the MetaAlmanac will first check if the file exists locally. If it exists, it will check that the CRC32 checksum of this file matches that of the specs.
637
+ If it does not match, the file will be downloaded again. If no CRC32 is provided but the file exists, then the MetaAlmanac will fetch the remote file and overwrite the existing file.
638
+ The downloaded path will be stored in the "AppData" folder."""
639
+
518
640
  files: typing.List
519
641
 
520
- def __init__(self, maybe_path: str=None) -> MetaAlmanac:
642
+ def __new__(cls, maybe_path: str = None) -> MetaAlmanac:
521
643
  """A structure to set up an Almanac, with automatic downloading, local storage, checksum checking, and more.
522
644
 
523
- # Behavior
524
- If the URI is a local path, relative or absolute, nothing will be fetched from a remote. Relative paths are relative to the execution folder (i.e. the current working directory).
525
- If the URI is a remote path, the MetaAlmanac will first check if the file exists locally. If it exists, it will check that the CRC32 checksum of this file matches that of the specs.
526
- If it does not match, the file will be downloaded again. If no CRC32 is provided but the file exists, then the MetaAlmanac will fetch the remote file and overwrite the existing file.
527
- The downloaded path will be stored in the "AppData" folder."""
645
+ # Behavior
646
+ If the URI is a local path, relative or absolute, nothing will be fetched from a remote. Relative paths are relative to the execution folder (i.e. the current working directory).
647
+ If the URI is a remote path, the MetaAlmanac will first check if the file exists locally. If it exists, it will check that the CRC32 checksum of this file matches that of the specs.
648
+ If it does not match, the file will be downloaded again. If no CRC32 is provided but the file exists, then the MetaAlmanac will fetch the remote file and overwrite the existing file.
649
+ The downloaded path will be stored in the "AppData" folder."""
528
650
 
529
651
  def dumps(self) -> str:
530
652
  """Dumps the configured Meta Almanac into a Dhall string. Equivalent to to_dhall()."""
@@ -534,33 +656,33 @@ The downloaded path will be stored in the "AppData" folder."""
534
656
  """Loads this Meta Almanac from its Dhall string representation"""
535
657
 
536
658
  @staticmethod
537
- def latest(autodelete: bool=None) -> Almanac:
659
+ def latest(autodelete: bool = None) -> Almanac:
538
660
  """Returns an Almanac loaded from the latest NAIF data via the `default` MetaAlmanac.
539
- The MetaAlmanac will download the DE440s.bsp file, the PCK0008.PCA, the full Moon Principal Axis BPC (moon_pa_de440_200625) and the latest high precision Earth kernel from JPL.
661
+ The MetaAlmanac will download the DE440s.bsp file, the PCK0008.PCA, the full Moon Principal Axis BPC (moon_pa_de440_200625) and the latest high precision Earth kernel from JPL.
540
662
 
541
- # File list
542
- - <http://public-data.nyxspace.com/anise/de440s.bsp>
543
- - <http://public-data.nyxspace.com/anise/v0.5/pck08.pca>
544
- - <http://public-data.nyxspace.com/anise/moon_pa_de440_200625.bpc>
545
- - <https://naif.jpl.nasa.gov/pub/naif/generic_kernels/pck/earth_latest_high_prec.bpc>
663
+ # File list
664
+ - <http://public-data.nyxspace.com/anise/de440s.bsp>
665
+ - <http://public-data.nyxspace.com/anise/v0.5/pck08.pca>
666
+ - <http://public-data.nyxspace.com/anise/moon_pa_de440_200625.bpc>
667
+ - <https://naif.jpl.nasa.gov/pub/naif/generic_kernels/pck/earth_latest_high_prec.bpc>
546
668
 
547
- # Reproducibility
669
+ # Reproducibility
548
670
 
549
- Note that the `earth_latest_high_prec.bpc` file is regularly updated daily (or so). As such,
550
- if queried at some future time, the Earth rotation parameters may have changed between two queries.
671
+ Note that the `earth_latest_high_prec.bpc` file is regularly updated daily (or so). As such,
672
+ if queried at some future time, the Earth rotation parameters may have changed between two queries.
551
673
 
552
- Set `autodelete` to true to delete lock file if a dead lock is detected after 10 seconds."""
674
+ Set `autodelete` to true to delete lock file if a dead lock is detected after 10 seconds."""
553
675
 
554
676
  @staticmethod
555
677
  def loads(s: str) -> MetaAlmanac:
556
678
  """Loads the provided string as a Dhall configuration to build a MetaAlmanac"""
557
679
 
558
- def process(self, autodelete: bool=None) -> Almanac:
680
+ def process(self, autodelete: bool = None) -> Almanac:
559
681
  """Fetch all of the URIs and return a loaded Almanac.
560
- When downloading the data, ANISE will create a temporarily lock file to prevent race conditions
561
- where multiple processes download the data at the same time. Set `autodelete` to true to delete
562
- this lock file if a dead lock is detected after 10 seconds. Set this flag to false if you have
563
- more than ten processes which may attempt to download files in parallel."""
682
+ When downloading the data, ANISE will create a temporarily lock file to prevent race conditions
683
+ where multiple processes download the data at the same time. Set `autodelete` to true to delete
684
+ this lock file if a dead lock is detected after 10 seconds. Set this flag to false if you have
685
+ more than ten processes which may attempt to download files in parallel."""
564
686
 
565
687
  def to_dhall(self) -> str:
566
688
  """Serializes the configurated Meta Almanac into a Dhall string. Equivalent to dumps()."""
@@ -593,23 +715,24 @@ more than ten processes which may attempt to download files in parallel."""
593
715
  class MetaFile:
594
716
  """MetaFile allows downloading a remote file from a URL (http, https only), and interpolation of paths in environment variable using the Dhall syntax `env:MY_ENV_VAR`.
595
717
 
596
- The data is stored in the user's local temp directory (i.e. `~/.local/share/nyx-space/anise/` on Linux and `AppData/Local/nyx-space/anise/` on Windows).
597
- Prior to loading a remote resource, if the local resource exists, its CRC32 will be computed: if it matches the CRC32 of this instance of MetaFile,
598
- then the file will not be downloaded a second time."""
718
+ The data is stored in the user's local temp directory (i.e. `~/.local/share/nyx-space/anise/` on Linux and `AppData/Local/nyx-space/anise/` on Windows).
719
+ Prior to loading a remote resource, if the local resource exists, its CRC32 will be computed: if it matches the CRC32 of this instance of MetaFile,
720
+ then the file will not be downloaded a second time."""
721
+
599
722
  crc32: int
600
723
  uri: str
601
724
 
602
- def __init__(self, uri: str, crc32: int=None) -> MetaFile:
725
+ def __new__(cls, uri: str, crc32: int = None) -> MetaFile:
603
726
  """MetaFile allows downloading a remote file from a URL (http, https only), and interpolation of paths in environment variable using the Dhall syntax `env:MY_ENV_VAR`.
604
727
 
605
- The data is stored in the user's local temp directory (i.e. `~/.local/share/nyx-space/anise/` on Linux and `AppData/Local/nyx-space/anise/` on Windows).
606
- Prior to loading a remote resource, if the local resource exists, its CRC32 will be computed: if it matches the CRC32 of this instance of MetaFile,
607
- then the file will not be downloaded a second time."""
728
+ The data is stored in the user's local temp directory (i.e. `~/.local/share/nyx-space/anise/` on Linux and `AppData/Local/nyx-space/anise/` on Windows).
729
+ Prior to loading a remote resource, if the local resource exists, its CRC32 will be computed: if it matches the CRC32 of this instance of MetaFile,
730
+ then the file will not be downloaded a second time."""
608
731
 
609
- def process(self, autodelete: bool=None) -> None:
732
+ def process(self, autodelete: bool = None) -> None:
610
733
  """Processes this MetaFile by downloading it if it's a URL.
611
734
 
612
- This function modified `self` and changes the URI to be the path to the downloaded file."""
735
+ This function modified `self` and changes the URI to be the path to the downloaded file."""
613
736
 
614
737
  def __eq__(self, value: typing.Any) -> bool:
615
738
  """Return self==value."""
@@ -635,4 +758,7 @@ This function modified `self` and changes the URI to be the path to the download
635
758
  def __str__(self) -> str:
636
759
  """Return str(self)."""
637
760
 
638
- def exec_gui():...
761
+ def exec_gui(): ...
762
+
763
+ __author__: str = "Christopher Rabotin <christopher.rabotin@gmail.com>"
764
+ __version__: str = "0.9.3"