satkit 0.2.5__tar.gz → 0.2.6__tar.gz
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.
- {satkit-0.2.5 → satkit-0.2.6}/Cargo.toml +1 -1
- {satkit-0.2.5/python/satkit.egg-info → satkit-0.2.6}/PKG-INFO +1 -1
- {satkit-0.2.5 → satkit-0.2.6}/pyproject.toml +8 -8
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit/__init__.pyi +2 -2
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit/frametransform/__init__.pyi +91 -46
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit/utils/__init__.pyi +1 -1
- {satkit-0.2.5 → satkit-0.2.6/python/satkit.egg-info}/PKG-INFO +1 -1
- {satkit-0.2.5 → satkit-0.2.6}/python/test/test.py +39 -1
- {satkit-0.2.5 → satkit-0.2.6}/src/consts.rs +16 -16
- {satkit-0.2.5 → satkit-0.2.6}/src/duration.rs +3 -1
- {satkit-0.2.5 → satkit-0.2.6}/src/frametransform/mod.rs +1 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/mod_utils.rs +23 -4
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/pyastrotime.rs +32 -14
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/pyconsts.rs +1 -1
- satkit-0.2.6/src/pybindings/pyduration.rs +237 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/pyframetransform.rs +50 -18
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/pyutils.rs +2 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/utils/datadir.rs +2 -2
- {satkit-0.2.5 → satkit-0.2.6}/src/utils/mod.rs +7 -0
- satkit-0.2.5/src/pybindings/pyduration.rs +0 -97
- {satkit-0.2.5 → satkit-0.2.6}/LICENSE +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/MANIFEST.in +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/README.md +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit/__init__.py +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit/astro-data/py.typed +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit/density/__init__.pyi +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit/density/py.typed +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit/frametransform/py.typed +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit/jplephem/__init__.pyi +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit/jplephem/py.typed +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit/moon/__init__.py +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit/moon/py.typed +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit/py.typed +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit/satprop/__init__.pyi +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit/satprop/py.typed +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit/sun/__init__.pyi +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit/sun/py.typed +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit/utils/py.typed +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit.egg-info/SOURCES.txt +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit.egg-info/dependency_links.txt +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit.egg-info/requires.txt +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/satkit.egg-info/top_level.txt +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/test/download_data.py +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/test/download_from_json.py +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/test/download_testvecs.py +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/test/orbitprop_gps_fit.py +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/python/test/sp3file.py +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/setup.cfg +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/astrotime.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/earth_orientation_params.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/earthgravity.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/frametransform/ierstable.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/frametransform/qcirs2gcrs.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/itrfcoord.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/jplephem.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/lib.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/lpephem/mod.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/lpephem/moon.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/lpephem/sun.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/nrlmsise.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/ode/harmonic_oscillator.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/ode/mod.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/ode/nalgebra.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/ode/rk_adaptive.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/ode/rk_adaptive_settings.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/ode/rk_explicit.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/ode/rkf45.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/ode/rkts54.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/ode/rkv65.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/ode/rkv65_table.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/ode/rkv87.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/ode/rkv87_table.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/ode/rkv98.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/ode/rkv98_nointerp.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/ode/rkv98_nointerp_table.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/ode/rkv98_table.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/ode/types.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/orbitprop/drag.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/orbitprop/mod.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/orbitprop/point_gravity.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/orbitprop/propagator.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/orbitprop/satproperties.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/orbitprop/satstate.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/orbitprop/settings.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/mod.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/pydensity.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/pygravity.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/pyitrfcoord.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/pyjplephem.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/pylpephem_moon.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/pylpephem_sun.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/pynrlmsise.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/pypropagate.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/pypropsettings.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/pyquaternion.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/pysatproperties.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/pysatstate.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/pysgp4.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/pysolarsystem.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/pybindings/pytle.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/sgp4/dpper.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/sgp4/dscom.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/sgp4/dsinit.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/sgp4/dspace.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/sgp4/getgravconst.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/sgp4/initl.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/sgp4/mod.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/sgp4/satrec.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/sgp4/sgp4.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/sgp4/sgp4_lowlevel.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/sgp4/sgp4init.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/solarsystem.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/spaceweather.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/tle.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/types.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/utils/download.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/utils/skerror.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/utils/test.rs +0 -0
- {satkit-0.2.5 → satkit-0.2.6}/src/utils/update_data.rs +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "satkit"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.6"
|
|
8
8
|
dependencies = ["numpy>=1.20.0"]
|
|
9
9
|
requires-python = ">= 3.8"
|
|
10
10
|
authors = [{ name = "Steven Michael", email = "ssmichael@gmail.com" }]
|
|
@@ -43,6 +43,9 @@ find = { where = ["python"] }
|
|
|
43
43
|
|
|
44
44
|
[tool.cibuildwheel]
|
|
45
45
|
build = ["cp312-*", "cp311-* cp310-* cp39-* cp38-*"]
|
|
46
|
+
test-skip = "*-macosx_arm64 *-macosx_universal2:arm64"
|
|
47
|
+
skip = ["pp*", "*_i686", "*_s390x", "*_aarch64", "*_ppc64le", "*-musllinux*"]
|
|
48
|
+
|
|
46
49
|
|
|
47
50
|
[tool.cibuildwheel.macos]
|
|
48
51
|
archs = ["x86_64", "arm64"]
|
|
@@ -54,17 +57,15 @@ before-build = [
|
|
|
54
57
|
]
|
|
55
58
|
environment = { PATH = "$PATH:$HOME/.cargo/bin" }
|
|
56
59
|
# Skip trying to test arm64 builds on Intel Macs
|
|
57
|
-
test-skip = "*-macosx_arm64 *-macosx_universal2:arm64"
|
|
58
60
|
test-requires = "pytest"
|
|
59
61
|
test-command = [
|
|
60
|
-
"
|
|
62
|
+
"SATKIT_DATA={package}/astro-data SATKIT_TESTVEC_ROOT={package}/satkit-testvecs pytest {project}/python/test/test.py",
|
|
61
63
|
]
|
|
62
64
|
|
|
63
65
|
|
|
64
66
|
[tool.cibuildwheel.linux]
|
|
65
67
|
environment = { PATH = "$PATH:$HOME/.cargo/bin" }
|
|
66
68
|
archs = ["x86_64"]
|
|
67
|
-
skip = ["pp*", "*_i686", "*_s390x", "*_aarch64", "*_ppc64le", "*-musllinux*"]
|
|
68
69
|
before-build = [
|
|
69
70
|
"pip install -U setuptools-rust",
|
|
70
71
|
"curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain=stable --profile=minimal -y",
|
|
@@ -72,7 +73,7 @@ before-build = [
|
|
|
72
73
|
]
|
|
73
74
|
test-requires = "pytest"
|
|
74
75
|
test-command = [
|
|
75
|
-
"
|
|
76
|
+
"SATKIT_DATA={package}/astro-data SATKIT_TESTVEC_ROOT={package}/satkit-testvecs pytest {project}/python/test/test.py",
|
|
76
77
|
]
|
|
77
78
|
|
|
78
79
|
[tool.cibuildwheel.windows]
|
|
@@ -85,14 +86,13 @@ before-build = [
|
|
|
85
86
|
"rustup show",
|
|
86
87
|
]
|
|
87
88
|
archs = ["AMD64"]
|
|
88
|
-
skip = ["pp*"]
|
|
89
89
|
test-requires = "pytest"
|
|
90
90
|
before-test = [
|
|
91
|
-
"set
|
|
91
|
+
"set SATKIT_DATA={package}\\astro-data",
|
|
92
92
|
"set SATKIT_TESTVEC_ROOT={package}\\satkit-testvecs",
|
|
93
93
|
]
|
|
94
94
|
test-command = [
|
|
95
|
-
"set
|
|
95
|
+
"set SATKIT_DATA={package}\\astro-data&&set SATKIT_TESTVEC_ROOT={package}\\satkit-testvecs&&pytest {project}\\python\\test\\test.py",
|
|
96
96
|
]
|
|
97
97
|
|
|
98
98
|
|
|
@@ -537,8 +537,8 @@ class timescale:
|
|
|
537
537
|
are needed to compute precise rotations between various inertial and
|
|
538
538
|
Earth-fixed coordinate frames
|
|
539
539
|
|
|
540
|
-
For
|
|
541
|
-
https://
|
|
540
|
+
For an excellent overview, see:
|
|
541
|
+
https://spsweb.fltops.jpl.nasa.gov/portaldataops/mpg/MPG_Docs/MPG%20Book/Release/Chapter2-TimeScales.pdf
|
|
542
542
|
|
|
543
543
|
# Options:
|
|
544
544
|
|
|
@@ -19,80 +19,125 @@ import satkit
|
|
|
19
19
|
import datetime
|
|
20
20
|
|
|
21
21
|
def gmst(
|
|
22
|
-
tm: satkit.time | npt.ArrayLike[satkit.time],
|
|
22
|
+
tm: satkit.time | npt.ArrayLike[satkit.time] | datetime.datetime | npt.ArrayLike[datetime.datetime],
|
|
23
23
|
) -> float | npt.ArrayLike[np.float]:
|
|
24
24
|
"""
|
|
25
25
|
Greenwich Mean Sidereal Time
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
Vallado algorithm 15:
|
|
28
|
-
|
|
29
|
-
GMST = 67310.5481 + (876600h + 8640184.812866) * tᵤₜ₁ * (0.983104 + tᵤₜ₁ *
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
|
|
29
|
+
GMST = 67310.5481 + (876600h + 8640184.812866) * tᵤₜ₁ * (0.983104 + tᵤₜ₁ * −6.2e−6)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# Arguments
|
|
33
|
+
|
|
34
|
+
* `tm`: scalar, list, or numpy array of astro.time or datetime.datetime
|
|
35
|
+
representing time at which to calculate output
|
|
36
|
+
|
|
37
|
+
# Returns
|
|
38
|
+
|
|
39
|
+
* Greenwich Mean Sideral Time, radians, at intput time(s)
|
|
40
|
+
|
|
35
41
|
"""
|
|
36
42
|
|
|
37
43
|
def gast(
|
|
38
|
-
tm: satkit.time | npt.ArrayLike[satkit.time],
|
|
44
|
+
tm: satkit.time | npt.ArrayLike[satkit.time] | datetime.datetime | npt.ArrayLike[datetime.datetime],
|
|
39
45
|
) -> float | npt.ArrayLike[np.float]:
|
|
40
46
|
"""
|
|
41
|
-
Greenwich
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
Greenwich apparant sidereal time, radians
|
|
48
|
+
|
|
49
|
+
# Arguments:
|
|
50
|
+
|
|
51
|
+
* `tm`: scalar, list, or numpy array of astro.time or datetime.datetime
|
|
52
|
+
representing time at which to calculate output
|
|
53
|
+
|
|
54
|
+
# Returns:
|
|
55
|
+
|
|
56
|
+
* Greenwich apparant sidereal time, radians, at input time(s)
|
|
57
|
+
|
|
47
58
|
"""
|
|
48
59
|
|
|
49
60
|
def earth_rotation_angle(
|
|
50
|
-
tm: satkit.time | npt.ArrayLike[satkit.time],
|
|
61
|
+
tm: satkit.time | npt.ArrayLike[satkit.time] | datetime.datetime | npt.ArrayLike[datetime.datetime],
|
|
51
62
|
) -> float | npt.ArrayLike[np.float]:
|
|
52
63
|
"""
|
|
53
|
-
Earth
|
|
54
|
-
|
|
55
|
-
See
|
|
56
|
-
https://www.iers.org/SharedDocs/Publikationen/EN/IERS/Publications/tn/TechnNote36/tn36_043.pdf?__blob=publicationFile&v=1
|
|
57
|
-
|
|
64
|
+
Earth Rotation Angle
|
|
65
|
+
|
|
66
|
+
See
|
|
67
|
+
[IERS Technical Note 36, Chapter 5](https://www.iers.org/SharedDocs/Publikationen/EN/IERS/Publications/tn/TechnNote36/tn36_043.pdf?__blob=publicationFile&v=1)
|
|
58
68
|
Equation 5.15
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
|
|
70
|
+
# Arguments:
|
|
71
|
+
|
|
72
|
+
* `tm`: scalar, list, or numpy array of astro.time or datetime.datetime
|
|
73
|
+
representing time at which to calculate output
|
|
74
|
+
|
|
75
|
+
# Returns:
|
|
76
|
+
|
|
77
|
+
* Earth rotation angle, in radians, at input time(s)
|
|
78
|
+
|
|
79
|
+
# Calculation Details
|
|
80
|
+
|
|
81
|
+
* Let t be UT1 Julian date
|
|
82
|
+
* let f be fractional component of t (fraction of day)
|
|
83
|
+
* ERA = 2𝜋 ((0.7790572732640 + f + 0.00273781191135448 * (t − 2451545.0))
|
|
84
|
+
|
|
64
85
|
"""
|
|
65
86
|
|
|
66
87
|
def qitrf2tirs(
|
|
67
|
-
tm: satkit.time | npt.ArrayLike[satkit.time],
|
|
88
|
+
tm: satkit.time | npt.ArrayLike[satkit.time] | datetime.datetime | npt.ArrayLike[datetime.datetime],
|
|
68
89
|
) -> satkit.quaternion | npt.ArrayLike[satkit.quaternion]:
|
|
69
90
|
"""
|
|
70
|
-
Rotation from
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
91
|
+
Rotation from Terrestrial Intermediate Reference System to
|
|
92
|
+
Celestial Intermediate Reference Systems
|
|
93
|
+
|
|
94
|
+
# Arguments:
|
|
95
|
+
|
|
96
|
+
* `tm`: scalar, list, or numpy array of astro.time or datetime.datetime
|
|
97
|
+
representing time at which to calculate output
|
|
98
|
+
|
|
99
|
+
# Returns:
|
|
100
|
+
|
|
101
|
+
* Quaternion representing rotation from TIRS to CIRS at input time(s)
|
|
102
|
+
|
|
78
103
|
"""
|
|
79
104
|
|
|
80
105
|
@typing.overload
|
|
81
|
-
def qcirs2gcrf(tm: satkit.time) -> satkit.quaternion:
|
|
82
|
-
"""
|
|
83
|
-
|
|
106
|
+
def qcirs2gcrf(tm: satkit.time | datetime.datetime) -> satkit.quaternion:
|
|
107
|
+
"""
|
|
108
|
+
Rotation from Celestial Intermediate Reference System
|
|
84
109
|
to Geocentric Celestial Reference Frame
|
|
110
|
+
|
|
111
|
+
# Arguments:
|
|
112
|
+
|
|
113
|
+
* `tm`: scalar, list, or numpy array of astro.time or datetime.datetime
|
|
114
|
+
representing time at which to calculate output
|
|
115
|
+
|
|
116
|
+
# Returns:
|
|
117
|
+
|
|
118
|
+
* Quaternion representing rotation from CIRS to GCRF at input time(s)
|
|
119
|
+
|
|
85
120
|
"""
|
|
86
121
|
|
|
87
122
|
@typing.overload
|
|
88
|
-
def qcirs2gcrf(tm: npt.ArrayLike[satkit.time]) -> npt.ArrayLike[satkit.quaternion]:
|
|
123
|
+
def qcirs2gcrf(tm: npt.ArrayLike[satkit.time] | npt.ArrayLike[datetime.datetime]) -> npt.ArrayLike[satkit.quaternion]:
|
|
89
124
|
"""
|
|
90
|
-
|
|
125
|
+
Rotation from Celestial Intermediate Reference System
|
|
91
126
|
to Geocentric Celestial Reference Frame
|
|
127
|
+
|
|
128
|
+
# Arguments:
|
|
129
|
+
|
|
130
|
+
* `tm`: scalar, list, or numpy array of astro.time or datetime.datetime
|
|
131
|
+
representing time at which to calculate output
|
|
132
|
+
|
|
133
|
+
# Returns:
|
|
134
|
+
|
|
135
|
+
* Quaternion representing rotation from CIRS to GCRF at input time(s)
|
|
136
|
+
|
|
92
137
|
"""
|
|
93
138
|
|
|
94
139
|
def qtirs2cirs(
|
|
95
|
-
tm: satkit.time | npt.ArrayLike[satkit.time],
|
|
140
|
+
tm: satkit.time | npt.ArrayLike[satkit.time] | datetime.datetime | npt.ArrayLike[datetime.datetime],
|
|
96
141
|
) -> satkit.quaternion | npt.ArrayLike[satkit.quaternion]:
|
|
97
142
|
"""
|
|
98
143
|
Rotation from Terrestrial Intermediate Reference System (TIRS)
|
|
@@ -106,7 +151,7 @@ def qtirs2cirs(
|
|
|
106
151
|
"""
|
|
107
152
|
|
|
108
153
|
def qgcrf2itrf_approx(
|
|
109
|
-
tm: satkit.time | npt.ArrayLike[satkit.time],
|
|
154
|
+
tm: satkit.time | npt.ArrayLike[satkit.time] | datetime.datetime | npt.ArrayLike[datetime.datetime],
|
|
110
155
|
) -> satkit.quaternion | npt.ArrayLike[satkit.quaternion]:
|
|
111
156
|
"""
|
|
112
157
|
Quaternion representing approximate rotation from the
|
|
@@ -128,7 +173,7 @@ def qgcrf2itrf_approx(
|
|
|
128
173
|
"""
|
|
129
174
|
|
|
130
175
|
def qitrf2gcrf_approx(
|
|
131
|
-
tm: satkit.time | npt.ArrayLike[satkit.time],
|
|
176
|
+
tm: satkit.time | npt.ArrayLike[satkit.time] | datetime.datetime | npt.ArrayLike[datetime.datetime],
|
|
132
177
|
) -> satkit.quaternion | npt.ArrayLike[satkit.quaternion]:
|
|
133
178
|
"""
|
|
134
179
|
Quaternion representing approximate rotation from the
|
|
@@ -175,7 +220,7 @@ def qgcrf2itrf(
|
|
|
175
220
|
"""
|
|
176
221
|
|
|
177
222
|
def qitrf2gcrf(
|
|
178
|
-
tm: satkit.time | npt.ArrayLike[satkit.time],
|
|
223
|
+
tm: satkit.time | npt.ArrayLike[satkit.time] | datetime.datetime | npt.ArrayLike[datetime.datetime],
|
|
179
224
|
) -> satkit.quaternion | npt.ArrayLike[satkit.quaternion]:
|
|
180
225
|
"""
|
|
181
226
|
Quaternion representing rotation from the
|
|
@@ -200,7 +245,7 @@ def qitrf2gcrf(
|
|
|
200
245
|
"""
|
|
201
246
|
|
|
202
247
|
def qteme2itrf(
|
|
203
|
-
tm: satkit.time | npt.ArrayLike[satkit.time],
|
|
248
|
+
tm: satkit.time | npt.ArrayLike[satkit.time] | datetime.datetime | npt.ArrayLike[datetime.datetime],
|
|
204
249
|
) -> satkit.quaternion | npt.ArrayLike[satkit.quaternion]:
|
|
205
250
|
"""
|
|
206
251
|
Quaternion representing rotation from the
|
|
@@ -5,12 +5,50 @@ import numpy as np
|
|
|
5
5
|
import math as m
|
|
6
6
|
import os
|
|
7
7
|
from sp3file import read_sp3file
|
|
8
|
-
|
|
8
|
+
from datetime import datetime, timezone
|
|
9
9
|
|
|
10
10
|
testvec_dir = os.getenv(
|
|
11
11
|
"SATKIT_TESTVEC_ROOT", default="." + os.path.sep + "satkit-testvecs" + os.path.sep
|
|
12
12
|
)
|
|
13
13
|
|
|
14
|
+
class TestDateTime:
|
|
15
|
+
"""
|
|
16
|
+
Check that function calls with satkit.time and datetime.datetime return
|
|
17
|
+
the same result
|
|
18
|
+
"""
|
|
19
|
+
def test_scalar_times(self):
|
|
20
|
+
|
|
21
|
+
# Create times and show that they are equal
|
|
22
|
+
tm1 = sk.time(2023, 3, 4, 12, 5, 6)
|
|
23
|
+
tm2 = datetime(2023, 3, 4, 12, 5, 6, tzinfo=timezone.utc)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
assert(tm1.datetime() == tm2)
|
|
27
|
+
# Check that function calls work
|
|
28
|
+
# Pick gmst as the test function call for time
|
|
29
|
+
# it can be anything since under the hood the same function call is used
|
|
30
|
+
# to get time inputs for all python functions in package
|
|
31
|
+
g1 = sk.frametransform.gmst(tm1)
|
|
32
|
+
g2 = sk.frametransform.gmst(tm2)
|
|
33
|
+
assert g1 == pytest.approx(g2, rel=1e-10)
|
|
34
|
+
|
|
35
|
+
def test_list_times(self):
|
|
36
|
+
timearr = range(10)
|
|
37
|
+
tm1 = [sk.time(2023, 3, x+1, 12, 0, 0) for x in timearr]
|
|
38
|
+
tm2 = [datetime(2023, 3, x+1, 12, 0, 0, tzinfo=timezone.utc) for x in timearr]
|
|
39
|
+
g1 = sk.frametransform.gmst(tm1)
|
|
40
|
+
g2 = sk.frametransform.gmst(tm2)
|
|
41
|
+
assert g1 == pytest.approx(g2)
|
|
42
|
+
|
|
43
|
+
def test_numpy_times(self):
|
|
44
|
+
timearr = range(10)
|
|
45
|
+
tm1 = np.array([sk.time(2023, 3, x+1, 12, 0, 0) for x in timearr])
|
|
46
|
+
tm2 = np.array([datetime(2023, 3, x+1, 12, 0, 0, tzinfo=timezone.utc) for x in timearr])
|
|
47
|
+
g1 = sk.frametransform.gmst(tm1)
|
|
48
|
+
g2 = sk.frametransform.gmst(tm2)
|
|
49
|
+
assert g1 == pytest.approx(g2)
|
|
50
|
+
|
|
51
|
+
|
|
14
52
|
class TestTime:
|
|
15
53
|
def test_mjd(self):
|
|
16
54
|
"""
|
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
#[allow(non_upper_case_globals)]
|
|
2
|
-
/// WGS-84 semiparameter, in meters
|
|
2
|
+
/// WGS-84 semiparameter, in meters
|
|
3
3
|
pub const WGS84_A: f64 = 6378137.0;
|
|
4
|
-
/// WGS-84 flattening
|
|
4
|
+
/// WGS-84 flattening
|
|
5
5
|
pub const WGS84_F: f64 = 0.003352810664747;
|
|
6
6
|
/// WGS-84 Earth radius, meters
|
|
7
7
|
pub const EARTH_RADIUS: f64 = WGS84_A;
|
|
8
|
-
/// Gravitational parameter of Earth, m^3/s^2
|
|
8
|
+
/// Gravitational parameter of Earth, m^3/s^2
|
|
9
9
|
pub const MU_EARTH: f64 = 3.986004418E14;
|
|
10
|
-
/// Gravitational parameter of Moon, m^3/s^2
|
|
10
|
+
/// Gravitational parameter of Moon, m^3/s^2
|
|
11
11
|
pub const MU_MOON: f64 = 4.9048695E12;
|
|
12
|
-
/// Gravitational parameter of Sun, m^3/s^2
|
|
12
|
+
/// Gravitational parameter of Sun, m^3/s^2
|
|
13
13
|
pub const MU_SUN: f64 = 1.32712440018E20;
|
|
14
|
-
/// Alternate name for gravitational parameter
|
|
14
|
+
/// Alternate name for gravitational parameter
|
|
15
15
|
pub const GM: f64 = MU_EARTH;
|
|
16
|
-
/// Earth rotation rate, radians / second
|
|
16
|
+
/// Earth rotation rate, radians / second
|
|
17
17
|
pub const OMEGA_EARTH: f64 = 7.292115090E-5;
|
|
18
|
-
/// speed of light, m/s
|
|
18
|
+
/// speed of light, m/s
|
|
19
19
|
pub const C: f64 = 299792458.0;
|
|
20
|
-
/// Astronomical unit, meters
|
|
20
|
+
/// Astronomical unit, meters
|
|
21
21
|
pub const AU: f64 = 1.4959787069999998807907104492E11;
|
|
22
|
-
/// Sun radius in meters
|
|
22
|
+
/// Sun radius in meters
|
|
23
23
|
pub const SUN_RADIUS: f64 = 695500000.0;
|
|
24
|
-
/// Moon radius, meters
|
|
24
|
+
/// Moon radius, meters
|
|
25
25
|
pub const MOON_RADIUS: f64 = 1737400.0;
|
|
26
|
-
/// Ratio of earth mass to moon mass
|
|
26
|
+
/// Ratio of earth mass to moon mass
|
|
27
27
|
pub const EARTH_MOON_MASS_RATIO: f64 = 81.30056822149721540427;
|
|
28
|
-
/// Geosynchronous Distance
|
|
28
|
+
/// Geosynchronous Distance
|
|
29
29
|
pub const GEO_R: f64 = 42164172.58422766;
|
|
30
|
-
/// JGM3 Gravitational parameter of Earth, m^3/s^2
|
|
30
|
+
/// JGM3 Gravitational parameter of Earth, m^3/s^2
|
|
31
31
|
pub const JGM3_MU: f64 = 0.3986004415E+15;
|
|
32
|
-
/// JGM3 Semimajor axis of Earth, m
|
|
32
|
+
/// JGM3 Semimajor axis of Earth, m
|
|
33
33
|
pub const JGM3_A: f64 = 0.6378136300E+07;
|
|
34
|
-
/// JGM3 J2 term
|
|
34
|
+
/// JGM3 J2 term
|
|
35
35
|
pub const JGM3_J2: f64 = -0.0010826360229829945;
|
|
36
36
|
//jgm3_J2:f64 = -sqrt(5.) * -0.484169548456e-03;
|
|
@@ -77,7 +77,9 @@ impl Duration {
|
|
|
77
77
|
// e.g. if seconds = 59.999..., rather than round up and
|
|
78
78
|
// display "seconds" in second field, show 0 and increment
|
|
79
79
|
// minutes...
|
|
80
|
-
secs
|
|
80
|
+
if secs % 60.0 > 59.9995 {
|
|
81
|
+
secs = secs + 5.0e-4;
|
|
82
|
+
}
|
|
81
83
|
|
|
82
84
|
if secs < 1.0 {
|
|
83
85
|
format!("Duration: {}{:.3} microseconds", sign, (secs % 1.0) * 1.0e6)
|
|
@@ -54,11 +54,22 @@ fn update_datafiles(kwds: Option<&PyDict>) -> PyResult<()> {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
///
|
|
58
|
-
/// necessary data files for the directory
|
|
57
|
+
/// Get directory where astronomy data is stored
|
|
59
58
|
///
|
|
60
|
-
///
|
|
61
|
-
///
|
|
59
|
+
/// Tries the following paths in order, and stops when the
|
|
60
|
+
/// files are found
|
|
61
|
+
///
|
|
62
|
+
/// * "SATKIT_DATA" environment variable
|
|
63
|
+
/// * ${HOME}/astro-data
|
|
64
|
+
/// * ${HOME}
|
|
65
|
+
/// * /usr/share/astro-data
|
|
66
|
+
/// * On Mac Only:
|
|
67
|
+
/// * /Library/Application Support/astro-data
|
|
68
|
+
/// * ${Home}/Library/Application Support/astro-data
|
|
69
|
+
///
|
|
70
|
+
/// Returns:
|
|
71
|
+
///
|
|
72
|
+
/// * string representing directory where files are stored
|
|
62
73
|
///
|
|
63
74
|
#[pyfunction]
|
|
64
75
|
fn datadir() -> PyResult<PyObject> {
|
|
@@ -76,6 +87,13 @@ fn githash() -> PyResult<String> {
|
|
|
76
87
|
Ok(String::from(crate::utils::githash()))
|
|
77
88
|
}
|
|
78
89
|
|
|
90
|
+
// Version of satkit
|
|
91
|
+
#[pyfunction]
|
|
92
|
+
fn version() -> PyResult<String> {
|
|
93
|
+
Ok(String::from(crate::utils::gittag()))
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
79
97
|
#[pyfunction]
|
|
80
98
|
fn dylib_path() -> PyResult<PyObject> {
|
|
81
99
|
pyo3::Python::with_gil(|py| -> PyResult<PyObject> {
|
|
@@ -100,6 +118,7 @@ pub fn utils(_py: Python, m: &PyModule) -> PyResult<()> {
|
|
|
100
118
|
m.add_function(wrap_pyfunction!(update_datafiles, m)?)
|
|
101
119
|
.unwrap();
|
|
102
120
|
m.add_function(wrap_pyfunction!(githash, m)?).unwrap();
|
|
121
|
+
m.add_function(wrap_pyfunction!(version, m)?).unwrap();
|
|
103
122
|
m.add_function(wrap_pyfunction!(build_date, m)?).unwrap();
|
|
104
123
|
Ok(())
|
|
105
124
|
}
|
|
@@ -2,7 +2,6 @@ use pyo3::prelude::*;
|
|
|
2
2
|
use pyo3::types::timezone_utc;
|
|
3
3
|
use pyo3::types::PyDateTime;
|
|
4
4
|
use pyo3::types::PyTuple;
|
|
5
|
-
use pyo3::types::PyTzInfo;
|
|
6
5
|
|
|
7
6
|
use crate::astrotime::{self, AstroTime, Scale};
|
|
8
7
|
|
|
@@ -17,8 +16,8 @@ use numpy as np;
|
|
|
17
16
|
/// are needed to compute precise rotations between various inertial and
|
|
18
17
|
/// Earth-fixed coordinate frames
|
|
19
18
|
///
|
|
20
|
-
/// For
|
|
21
|
-
/// https://
|
|
19
|
+
/// For an excellent overview, see:
|
|
20
|
+
/// https://spsweb.fltops.jpl.nasa.gov/portaldataops/mpg/MPG_Docs/MPG%20Book/Release/Chapter2-TimeScales.pdf
|
|
22
21
|
///
|
|
23
22
|
/// UTC = Universal Time Coordinate
|
|
24
23
|
/// TT = Terrestrial Time
|
|
@@ -327,10 +326,10 @@ impl PyAstroTime {
|
|
|
327
326
|
fn datetime(&self, utc: bool) -> PyResult<PyObject> {
|
|
328
327
|
pyo3::Python::with_gil(|py| -> PyResult<PyObject> {
|
|
329
328
|
let timestamp: f64 = self.to_unixtime();
|
|
330
|
-
let
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
}
|
|
329
|
+
let tz = match utc {
|
|
330
|
+
false => None,
|
|
331
|
+
true => Some(timezone_utc(py)),
|
|
332
|
+
};
|
|
334
333
|
Ok(PyDateTime::from_timestamp(py, timestamp, tz)?.into_py(py))
|
|
335
334
|
})
|
|
336
335
|
}
|
|
@@ -636,13 +635,27 @@ impl ToTimeVec for &PyAny {
|
|
|
636
635
|
let tm: PyAstroTime = self.extract().unwrap();
|
|
637
636
|
Ok(vec![tm.inner.clone()])
|
|
638
637
|
}
|
|
638
|
+
else if self.is_instance_of::<PyDateTime>() {
|
|
639
|
+
let dt: &PyDateTime = self.extract().unwrap();
|
|
640
|
+
Ok(vec![PyAstroTime::from_datetime(dt).unwrap().inner])
|
|
641
|
+
}
|
|
639
642
|
// List case
|
|
640
643
|
else if self.is_instance_of::<pyo3::types::PyList>() {
|
|
641
644
|
match self.extract::<Vec<PyAstroTime>>() {
|
|
642
645
|
Ok(v) => Ok(v.iter().map(|x| x.inner).collect::<Vec<_>>()),
|
|
643
|
-
Err(e) =>
|
|
644
|
-
|
|
645
|
-
|
|
646
|
+
Err(e) => {
|
|
647
|
+
match self.extract::<Vec<&PyDateTime>>() {
|
|
648
|
+
Ok(v) => Ok(v.iter().map(|x|
|
|
649
|
+
PyAstroTime::from_datetime(x.extract().unwrap()).unwrap().inner)
|
|
650
|
+
.collect::<Vec<_>>()),
|
|
651
|
+
Err(e) => {
|
|
652
|
+
Err(pyo3::exceptions::PyTypeError::new_err(format!(
|
|
653
|
+
"Not a list of satkit.time or datetime.datetime: {e}"
|
|
654
|
+
)))
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
|
|
646
659
|
}
|
|
647
660
|
}
|
|
648
661
|
// numpy array case
|
|
@@ -656,13 +669,18 @@ impl ToTimeVec for &PyAny {
|
|
|
656
669
|
.map(|p| -> Result<AstroTime, _> {
|
|
657
670
|
match p.extract::<PyAstroTime>(py) {
|
|
658
671
|
Ok(v2) => Ok(v2.inner),
|
|
659
|
-
Err(
|
|
672
|
+
Err(_) => match p.extract::<&PyDateTime>(py) {
|
|
673
|
+
Ok(v3) => Ok(PyAstroTime::from_datetime(v3.extract().unwrap()).unwrap().inner),
|
|
674
|
+
Err(_) => Err(pyo3::exceptions::PyTypeError::new_err(format!(
|
|
675
|
+
"Input numpy array must contain satkit.time elements or datetime.datetime elements"
|
|
676
|
+
))),
|
|
660
677
|
}
|
|
678
|
+
}
|
|
661
679
|
})
|
|
662
680
|
.collect();
|
|
663
681
|
if !tmarray.is_ok() {
|
|
664
682
|
Err(pyo3::exceptions::PyRuntimeError::new_err(
|
|
665
|
-
"Invalid
|
|
683
|
+
"Invalid satkit.time input",
|
|
666
684
|
))
|
|
667
685
|
} else {
|
|
668
686
|
Ok(tmarray.unwrap())
|
|
@@ -670,12 +688,12 @@ impl ToTimeVec for &PyAny {
|
|
|
670
688
|
}),
|
|
671
689
|
|
|
672
690
|
Err(e) => Err(pyo3::exceptions::PyRuntimeError::new_err(format!(
|
|
673
|
-
"Invalid
|
|
691
|
+
"Invalid satkit.time or datetime.datetime input: {e}"
|
|
674
692
|
))),
|
|
675
693
|
}
|
|
676
694
|
} else {
|
|
677
695
|
Err(pyo3::exceptions::PyRuntimeError::new_err(
|
|
678
|
-
"Invalid
|
|
696
|
+
"Invalid satkit.time or datetime.datetime input",
|
|
679
697
|
))
|
|
680
698
|
}
|
|
681
699
|
}
|
|
@@ -18,7 +18,7 @@ impl Consts {
|
|
|
18
18
|
/// WGS-84 Earth radius, meters
|
|
19
19
|
const earth_radius: f64 = cconsts::EARTH_RADIUS;
|
|
20
20
|
|
|
21
|
-
/// Gravitational parameter of Earth, m^3/s^2
|
|
21
|
+
/// Gravitational parameter of Earth, m^3/s^2
|
|
22
22
|
#[classattr]
|
|
23
23
|
const mu_earth: f64 = cconsts::MU_EARTH;
|
|
24
24
|
/// Gravitational parameter of moon, m^3/s^2
|