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 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.2.1'
32
- __version_tuple__ = version_tuple = (0, 2, 1)
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
- mean_nu:float=0,
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
- mean_nu: [Optional] mean anomaly in degrees
655
- Default is 0, which represents an orbit that is beginning at periapsis
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 mean_nu > 360 or mean_nu < 0: #noqa: PLR2004
709
- logger.error("Mean anomaly, %s, is out of range, should be 0 < mean_nu < 360", mean_nu)
710
- raise exceptions.OutOfRangeError(f"Mean anomaly, {mean_nu}, is out of range, "
711
- f"should be 0 < mean_nu < 360")
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
- mean_nu * astropy_units.one * astropy_units.deg)
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[[idx]]
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.2.1
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
- mean_nu=0,
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
- mean_nu=0,
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=vYqoJTG51NOUmYyL0xt8asRK8vUT4lGAdal_EZ59mvw,704
4
- spherapy/orbit.py,sha256=MyRa1U5cEdzP1yhFLbp25T1kHqTpZVnj75Siwfe6vbo,32607
5
- spherapy/timespan.py,sha256=xc5JEYtDcG4zZdsbdW9lcIX_PXzXzNJ-xGD_bCWJFDs,14438
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=IgSBumtS28JajLLkMLq-ST-qypoicqMdybXoAPTsjmo,3880
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.2.1.dist-info/licenses/LICENSE.md,sha256=9a5OXeKpk6GnCRhlQAPa5JQjl3PaFqseA1p2_DhXEbA,1055
18
- spherapy-0.2.1.dist-info/METADATA,sha256=UiluR8rndZ4AuF8R_J3c7aJRyZC4lr9HgTgx_geORfQ,7756
19
- spherapy-0.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
20
- spherapy-0.2.1.dist-info/entry_points.txt,sha256=WpE3jlS6iiug9ZqUrAHQuLEhbDTpbnAtBz8b0yXJJOU,150
21
- spherapy-0.2.1.dist-info/top_level.txt,sha256=X4rv7pGR9bAfVWOokUyHeDb6Z0jfIQCN6zDfh5f2NK4,9
22
- spherapy-0.2.1.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5