spherapy 0.2.1__py3-none-any.whl → 0.3.1__py3-none-any.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.
- spherapy/_version.py +2 -2
- spherapy/orbit.py +26 -8
- spherapy/timespan.py +12 -2
- spherapy/util/epoch_u.py +63 -0
- {spherapy-0.2.1.dist-info → spherapy-0.3.1.dist-info}/METADATA +4 -3
- {spherapy-0.2.1.dist-info → spherapy-0.3.1.dist-info}/RECORD +10 -10
- {spherapy-0.2.1.dist-info → spherapy-0.3.1.dist-info}/WHEEL +1 -1
- {spherapy-0.2.1.dist-info → spherapy-0.3.1.dist-info}/entry_points.txt +0 -0
- {spherapy-0.2.1.dist-info → spherapy-0.3.1.dist-info}/licenses/LICENSE.md +0 -0
- {spherapy-0.2.1.dist-info → spherapy-0.3.1.dist-info}/top_level.txt +0 -0
spherapy/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.
|
|
32
|
-
__version_tuple__ = version_tuple = (0,
|
|
31
|
+
__version__ = version = '0.3.1'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 3, 1)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
spherapy/orbit.py
CHANGED
|
@@ -626,7 +626,8 @@ class Orbit:
|
|
|
626
626
|
inc:float=0,
|
|
627
627
|
raan:float=0,
|
|
628
628
|
argp:float=0,
|
|
629
|
-
|
|
629
|
+
true_nu:float=0,
|
|
630
|
+
epoch:dt.datetime|None=None,
|
|
630
631
|
name:str='Analytical',
|
|
631
632
|
astrobodies:bool=True,
|
|
632
633
|
unsafe:bool=False) -> 'Orbit':
|
|
@@ -651,8 +652,11 @@ class Orbit:
|
|
|
651
652
|
argp: [Optional] argument of the perigee in degrees
|
|
652
653
|
Default is 0, which represents an orbit with its semimajor axis in
|
|
653
654
|
the plane of the Earth's equator
|
|
654
|
-
|
|
655
|
-
Default is 0, which represents an orbit that is beginning
|
|
655
|
+
true_nu: [Optional] true anomaly at epoch in degrees
|
|
656
|
+
Default is 0, which represents an orbit that is beginning
|
|
657
|
+
at periapsis on the epoch
|
|
658
|
+
epoch: [Optional] epoch for orbit
|
|
659
|
+
Default is the first timestep of the timespan
|
|
656
660
|
name: [Optional] string giving the name of the orbit
|
|
657
661
|
Default is 'Analytical'
|
|
658
662
|
astrobodies: [Optional] Flag to calculate Sun and Moon positions at timestamps
|
|
@@ -705,13 +709,25 @@ class Orbit:
|
|
|
705
709
|
raise exceptions.OutOfRangeError(f"Argument of periapsis, {raan}, is out of "
|
|
706
710
|
f"range, should be 0 < argp < 360")
|
|
707
711
|
|
|
708
|
-
if
|
|
709
|
-
logger.error("
|
|
710
|
-
raise exceptions.OutOfRangeError(f"
|
|
711
|
-
f"should be 0 <
|
|
712
|
+
if true_nu > 360 or true_nu < 0: #noqa: PLR2004
|
|
713
|
+
logger.error("True anomaly, %s, is out of range, should be 0 < true_nu < 360", true_nu)
|
|
714
|
+
raise exceptions.OutOfRangeError(f"True anomaly, {true_nu}, is out of range, "
|
|
715
|
+
f"should be 0 < true_nu < 360")
|
|
716
|
+
|
|
717
|
+
if epoch is None:
|
|
718
|
+
epoch = timespan[0]
|
|
719
|
+
if isinstance(epoch, dt.datetime):
|
|
720
|
+
astropy_epoch = astropyTime(epoch, scale='utc')
|
|
721
|
+
else:
|
|
722
|
+
logger.error("epoch, %s must be of type dt.datetime|astropyTime but"
|
|
723
|
+
" is of type %s", epoch, type(epoch))
|
|
724
|
+
raise TypeError(f"epoch, {epoch} must be of type "
|
|
725
|
+
f"dt.datetime|astropyTime but is of type {type(epoch)}")
|
|
712
726
|
|
|
713
727
|
attr_dct = _createEmptyOrbitAttrDict()
|
|
714
728
|
|
|
729
|
+
|
|
730
|
+
|
|
715
731
|
logger.info("Creating analytical orbit")
|
|
716
732
|
orb = hapsiraOrbit.from_classical(central_body,
|
|
717
733
|
a * astropy_units.one * astropy_units.km,
|
|
@@ -719,7 +735,9 @@ class Orbit:
|
|
|
719
735
|
inc * astropy_units.one * astropy_units.deg,
|
|
720
736
|
raan * astropy_units.one * astropy_units.deg,
|
|
721
737
|
argp * astropy_units.one * astropy_units.deg,
|
|
722
|
-
|
|
738
|
+
true_nu * astropy_units.one * astropy_units.deg,
|
|
739
|
+
astropy_epoch
|
|
740
|
+
)
|
|
723
741
|
|
|
724
742
|
|
|
725
743
|
logger.info("Creating ephemeris for orbit, using timespan")
|
spherapy/timespan.py
CHANGED
|
@@ -6,7 +6,7 @@ This module provides:
|
|
|
6
6
|
import datetime as dt
|
|
7
7
|
import logging
|
|
8
8
|
|
|
9
|
-
from typing import cast
|
|
9
|
+
from typing import cast, overload
|
|
10
10
|
from typing_extensions import Self
|
|
11
11
|
|
|
12
12
|
from astropy.time import Time as astropyTime
|
|
@@ -112,6 +112,16 @@ class TimeSpan:
|
|
|
112
112
|
"""Returns the internal _timearr when the TimeSpan is called."""
|
|
113
113
|
return self._timearr
|
|
114
114
|
|
|
115
|
+
@overload
|
|
116
|
+
def __getitem__(self, idx: None) -> np.ndarray[tuple[int], np.dtype[np.datetime64]]: ...
|
|
117
|
+
|
|
118
|
+
@overload
|
|
119
|
+
def __getitem__(self, idx: int | np.integer) -> dt.datetime: ...
|
|
120
|
+
|
|
121
|
+
@overload
|
|
122
|
+
def __getitem__(self, idx: slice | list[int] | tuple[int, ...] | np.ndarray) \
|
|
123
|
+
-> np.ndarray[tuple[int], np.dtype[np.datetime64]]: ...
|
|
124
|
+
|
|
115
125
|
def __getitem__(self, idx:None|int|np.integer|tuple|list|np.ndarray|slice=None) \
|
|
116
126
|
-> None|dt.datetime|np.ndarray[tuple[int], np.dtype[np.datetime64]]: # noqa: PLR0911
|
|
117
127
|
"""Returns an index or slice of the TimeSpan as an array of datetime objects."""
|
|
@@ -124,7 +134,7 @@ class TimeSpan:
|
|
|
124
134
|
return self._timearr[idx[0]:idx[1]]
|
|
125
135
|
return self._timearr[idx[0]:idx[1]:idx[2]]
|
|
126
136
|
if isinstance(idx, list):
|
|
127
|
-
return self._timearr[
|
|
137
|
+
return self._timearr[idx]
|
|
128
138
|
if isinstance(idx, np.ndarray):
|
|
129
139
|
return self._timearr[idx]
|
|
130
140
|
if isinstance(idx,slice):
|
spherapy/util/epoch_u.py
CHANGED
|
@@ -147,3 +147,66 @@ def getStoredEpochs(tle_path:pathlib.Path) -> None|tuple[dt.datetime, dt.datetim
|
|
|
147
147
|
last_epoch_dt = epoch2datetime(last_tle_line_1['fields'][3])
|
|
148
148
|
|
|
149
149
|
return (first_epoch_dt, last_epoch_dt)
|
|
150
|
+
|
|
151
|
+
def getAllStoredEpochs(tle_path:pathlib.Path) -> None|list[dt.datetime]:
|
|
152
|
+
"""Return the all TLE epochs for tle_path.
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
tle_path: tle file
|
|
156
|
+
|
|
157
|
+
Returns:
|
|
158
|
+
list of datetime object equivalent to the TLE epoch for each TLE
|
|
159
|
+
None if no spacetrack tle stored for sat_id
|
|
160
|
+
"""
|
|
161
|
+
if not tle_path.exists():
|
|
162
|
+
return None
|
|
163
|
+
|
|
164
|
+
with tle_path.open('r') as fp:
|
|
165
|
+
lines = fp.readlines()
|
|
166
|
+
|
|
167
|
+
tle_epochs_dt = []
|
|
168
|
+
for ii in range(1,len(lines),3):
|
|
169
|
+
tle_line = elements_u.split3LELineIntoFields(lines[ii])
|
|
170
|
+
tle_epochs_dt.append(epoch2datetime(tle_line['fields'][3]))
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
return tle_epochs_dt
|
|
174
|
+
|
|
175
|
+
def getStoredTLEByIdx(tle_path:pathlib.Path,
|
|
176
|
+
idx_list:int|list[int],
|
|
177
|
+
string_only:bool=True) \
|
|
178
|
+
-> list[dict[int, elements_u.ElementsLineDict]]|list[str]|None:
|
|
179
|
+
"""Return the TLE at the Idx within tle_path specifed by idx_list.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
tle_path: tle file
|
|
183
|
+
idx_list: list of TLE indices within tle_path
|
|
184
|
+
string_only: if true, return only the raw TLE string,
|
|
185
|
+
if false returns a dict of each field within each line
|
|
186
|
+
|
|
187
|
+
Returns:
|
|
188
|
+
list of tle_data
|
|
189
|
+
"""
|
|
190
|
+
if not tle_path.exists():
|
|
191
|
+
return None
|
|
192
|
+
|
|
193
|
+
if isinstance(idx_list, int):
|
|
194
|
+
idx_list = [idx_list]
|
|
195
|
+
|
|
196
|
+
with tle_path.open('r') as fp:
|
|
197
|
+
lines = fp.readlines()
|
|
198
|
+
|
|
199
|
+
tles = []
|
|
200
|
+
for idx in idx_list:
|
|
201
|
+
tle_line_0 = elements_u.split3LELineIntoFields(lines[idx*3+0])
|
|
202
|
+
tle_line_1 = elements_u.split3LELineIntoFields(lines[idx*3+1])
|
|
203
|
+
tle_line_2 = elements_u.split3LELineIntoFields(lines[idx*3+2])
|
|
204
|
+
|
|
205
|
+
if string_only:
|
|
206
|
+
tle_data = f"{tle_line_0['line_str']}{tle_line_1['line_str']}{tle_line_2['line_str']}"
|
|
207
|
+
else:
|
|
208
|
+
tle_data = {0:tle_line_0, 1:tle_line_1, 2:tle_line_2} #type:ignore
|
|
209
|
+
|
|
210
|
+
tles.append(tle_data)
|
|
211
|
+
|
|
212
|
+
return tles
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: spherapy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: An orbital propagator wrapper and TLE fetcher
|
|
5
5
|
Author-email: Robert Mearns <rz.mearns@gmail.com>
|
|
6
6
|
Maintainer-email: Robert Mearns <rz.mearns@gmail.com>
|
|
@@ -21,6 +21,7 @@ Requires-Dist: spacetrack==1.2.0
|
|
|
21
21
|
Requires-Dist: keyring>=25.0.0
|
|
22
22
|
Requires-Dist: platformdirs==4.3.8
|
|
23
23
|
Requires-Dist: importlib_resources>=6.5.2
|
|
24
|
+
Requires-Dist: coverage>=7.6.1
|
|
24
25
|
Provides-Extra: dev
|
|
25
26
|
Requires-Dist: line-profiler==4.2.0; extra == "dev"
|
|
26
27
|
Requires-Dist: pytest==8.4.1; extra == "dev"
|
|
@@ -87,7 +88,7 @@ o = spherapy.orbit.Orbit.fromAnalyticalOrbitalParam(timespan, body='Earth',
|
|
|
87
88
|
inc=0,
|
|
88
89
|
raan=0,
|
|
89
90
|
argp=0,
|
|
90
|
-
|
|
91
|
+
true_nu=0,
|
|
91
92
|
name='My Analytical Orbit',
|
|
92
93
|
astrobodies=True)
|
|
93
94
|
```
|
|
@@ -115,7 +116,7 @@ o = spherapy.orbit.Orbit.fromAnalyticalOrbitalParam(timespan, body='Earth',
|
|
|
115
116
|
inc=0,
|
|
116
117
|
raan=0,
|
|
117
118
|
argp=0,
|
|
118
|
-
|
|
119
|
+
true_nu=0,
|
|
119
120
|
name='My Analytical Orbit',
|
|
120
121
|
astrobodies=True)
|
|
121
122
|
```
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
spherapy/__init__.py,sha256=v1n13-2Uuy8GEWkB_B5mu2tSkAOVEPVP2eF0GixSPtI,2865
|
|
2
2
|
spherapy/__main__.py,sha256=YOcE__6OgX-e7lJ6UpeGS8Iw5igG0jEraTq8KOqGuDA,374
|
|
3
|
-
spherapy/_version.py,sha256=
|
|
4
|
-
spherapy/orbit.py,sha256=
|
|
5
|
-
spherapy/timespan.py,sha256=
|
|
3
|
+
spherapy/_version.py,sha256=gGLpQUQx-ty9SEy9PYw9OgJWWzJLBnCpfJOfzL7SjlI,704
|
|
4
|
+
spherapy/orbit.py,sha256=AIJVG5XUeHmIIrwlSZMWB-HdaOokQyaiXUezyFO40sU,33180
|
|
5
|
+
spherapy/timespan.py,sha256=LwBJ4InQrrsFcIVF5mT0Tp6AlTLk9rzhO6lL66ypTRU,14780
|
|
6
6
|
spherapy/updater.py,sha256=pkZg3ZlFbCa2iDJ2CP9al8t0BoDGRnppte54Vqkw1M4,3215
|
|
7
7
|
spherapy/data/TLEs/25544.tle,sha256=D-kndlhtWawbxR8tCU-7QZB1VZxROzutUBgc1ZwO4C0,7873403
|
|
8
8
|
spherapy/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -10,13 +10,13 @@ spherapy/util/celestrak.py,sha256=9uFtau90NOpXGc-Vkww4uKiFcrEnriXQjb-hfO50kaE,22
|
|
|
10
10
|
spherapy/util/constants.py,sha256=sm53FCsupvkUC3eajfn-haFIqnonJHykOL3klWTikaA,1810
|
|
11
11
|
spherapy/util/credentials.py,sha256=NS5eIdjEOumzZ8BqzRZ9mWp8BhRdfGWbY6qQkMjzS90,4057
|
|
12
12
|
spherapy/util/elements_u.py,sha256=ycHTu0-p6ZNI8WHpNPanGf0a-WOLY7PaWphyG_AEJ28,2058
|
|
13
|
-
spherapy/util/epoch_u.py,sha256=
|
|
13
|
+
spherapy/util/epoch_u.py,sha256=8lNTwP9bng1V_SABqDK4bEKLUUewKT_TrpjwE1sKh3c,5539
|
|
14
14
|
spherapy/util/exceptions.py,sha256=rDqYIhNdKnYBkbkxdhndSYI4mq4ENKtW01jEfZ7Yykk,215
|
|
15
15
|
spherapy/util/orbital_u.py,sha256=GKTNpiMTB7NAX-0TtD3lcHz5rFY2P_91odUnEBX-CJA,1760
|
|
16
16
|
spherapy/util/spacetrack.py,sha256=Kbh8IVgFN1UMegWxI1thxHx2gY5fEJ6ofT692-JmKA8,8165
|
|
17
|
-
spherapy-0.
|
|
18
|
-
spherapy-0.
|
|
19
|
-
spherapy-0.
|
|
20
|
-
spherapy-0.
|
|
21
|
-
spherapy-0.
|
|
22
|
-
spherapy-0.
|
|
17
|
+
spherapy-0.3.1.dist-info/licenses/LICENSE.md,sha256=9a5OXeKpk6GnCRhlQAPa5JQjl3PaFqseA1p2_DhXEbA,1055
|
|
18
|
+
spherapy-0.3.1.dist-info/METADATA,sha256=RTT0299ARVjTKiMmWXtWVyB5H_DtgrdUU5fuYdljPVs,7787
|
|
19
|
+
spherapy-0.3.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
20
|
+
spherapy-0.3.1.dist-info/entry_points.txt,sha256=WpE3jlS6iiug9ZqUrAHQuLEhbDTpbnAtBz8b0yXJJOU,150
|
|
21
|
+
spherapy-0.3.1.dist-info/top_level.txt,sha256=X4rv7pGR9bAfVWOokUyHeDb6Z0jfIQCN6zDfh5f2NK4,9
|
|
22
|
+
spherapy-0.3.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|