ruststartracker 0.2.1__tar.gz → 0.2.2__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.
- {ruststartracker-0.2.1 → ruststartracker-0.2.2}/PKG-INFO +20 -5
- {ruststartracker-0.2.1 → ruststartracker-0.2.2}/README.md +16 -4
- ruststartracker-0.2.2/build_script.py +60 -0
- {ruststartracker-0.2.1 → ruststartracker-0.2.2}/pyproject.toml +11 -5
- {ruststartracker-0.2.1 → ruststartracker-0.2.2}/ruststartracker/catalog.py +14 -18
- {ruststartracker-0.2.1 → ruststartracker-0.2.2}/ruststartracker/test_integration.py +2 -28
- ruststartracker-0.2.1/rust_build.py +0 -21
- ruststartracker-0.2.1/ruststartracker/star_catalog.tsv +0 -118010
- {ruststartracker-0.2.1 → ruststartracker-0.2.2}/LICENSE +0 -0
- {ruststartracker-0.2.1 → ruststartracker-0.2.2}/ruststartracker/__init__.py +0 -0
- {ruststartracker-0.2.1 → ruststartracker-0.2.2}/ruststartracker/libruststartracker.pyi +0 -0
- {ruststartracker-0.2.1 → ruststartracker-0.2.2}/ruststartracker/py.typed +0 -0
- {ruststartracker-0.2.1 → ruststartracker-0.2.2}/ruststartracker/star.py +0 -0
- {ruststartracker-0.2.1 → ruststartracker-0.2.2}/ruststartracker/test_backend.py +0 -0
- {ruststartracker-0.2.1 → ruststartracker-0.2.2}/ruststartracker/test_catalog.py +0 -0
- {ruststartracker-0.2.1 → ruststartracker-0.2.2}/ruststartracker/test_star.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: ruststartracker
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Lightweight Python Star Tracker With Rust Backend
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Nicolas Tobler
|
|
@@ -14,6 +14,9 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.13
|
|
15
15
|
Requires-Dist: numpy (>=1.26.0,<2.0.0)
|
|
16
16
|
Requires-Dist: opencv-python-headless (>=4.9.0,<5.0.0)
|
|
17
|
+
Project-URL: GaiaAttribution, https://www.cosmos.esa.int/gaia
|
|
18
|
+
Project-URL: Homepage, https://github.com/ntobler/ruststartracker
|
|
19
|
+
Project-URL: License, https://opensource.org/licenses/MIT
|
|
17
20
|
Description-Content-Type: text/markdown
|
|
18
21
|
|
|
19
22
|
# Lightweight Python Star Tracker With Rust Backend
|
|
@@ -35,8 +38,8 @@ Features:
|
|
|
35
38
|
import ruststartracker
|
|
36
39
|
|
|
37
40
|
# Get catalog positions
|
|
38
|
-
catalog = ruststartracker.StarCatalog()
|
|
39
|
-
star_catalog_vecs = catalog.normalized_positions()
|
|
41
|
+
catalog = ruststartracker.StarCatalog(max_magnitude=...)
|
|
42
|
+
star_catalog_vecs = catalog.normalized_positions(epoch=...)
|
|
40
43
|
|
|
41
44
|
# Define opencv camera parameters, see https://docs.opencv.org/4.x/dc/dbb/tutorial_py_calibration.html
|
|
42
45
|
camera_params = ruststartracker.CameraParameters(
|
|
@@ -52,6 +55,7 @@ st = ruststartracker.StarTracker(
|
|
|
52
55
|
max_inter_star_angle=...,
|
|
53
56
|
inter_star_angle_tolerance=...,
|
|
54
57
|
n_minimum_matches=...,
|
|
58
|
+
timeout_secs=...,
|
|
55
59
|
)
|
|
56
60
|
|
|
57
61
|
# Obtain numpy array image
|
|
@@ -66,11 +70,22 @@ print(result)
|
|
|
66
70
|
|
|
67
71
|
## Installation
|
|
68
72
|
|
|
69
|
-
-
|
|
70
|
-
- Install with `pip install git+https://github.com/ntobler/ruststartracker.git`.
|
|
73
|
+
- Install with `pip install ruststartracker` (Currently only ARM/x86 Linux wheels available).
|
|
71
74
|
|
|
72
75
|
## TODOs
|
|
73
76
|
|
|
74
77
|
- Improve error messages.
|
|
75
78
|
- Return more diagnostic data.
|
|
76
79
|
|
|
80
|
+
## Attributions
|
|
81
|
+
|
|
82
|
+
### Gaia Data
|
|
83
|
+
|
|
84
|
+
This project includes data from the European Space Agency (ESA) mission [**Gaia**](https://www.cosmos.esa.int/gaia), processed by the **Gaia Data Processing and Analysis Consortium (DPAC)**.
|
|
85
|
+
Funding for the DPAC has been provided by national institutions, in particular the institutions participating in the Gaia Multilateral Agreement.
|
|
86
|
+
|
|
87
|
+
Gaia DR3 data is © European Space Agency and is released under the [**Creative Commons Attribution 4.0 International License (CC BY 4.0)**](https://creativecommons.org/licenses/by/4.0/).
|
|
88
|
+
|
|
89
|
+
> Gaia Collaboration, Vallenari et al. (2022), *A\&A* **674**, A1.
|
|
90
|
+
> [DOI: 10.1051/0004-6361/202243940](https://doi.org/10.1051/0004-6361/202243940)
|
|
91
|
+
|
|
@@ -17,8 +17,8 @@ Features:
|
|
|
17
17
|
import ruststartracker
|
|
18
18
|
|
|
19
19
|
# Get catalog positions
|
|
20
|
-
catalog = ruststartracker.StarCatalog()
|
|
21
|
-
star_catalog_vecs = catalog.normalized_positions()
|
|
20
|
+
catalog = ruststartracker.StarCatalog(max_magnitude=...)
|
|
21
|
+
star_catalog_vecs = catalog.normalized_positions(epoch=...)
|
|
22
22
|
|
|
23
23
|
# Define opencv camera parameters, see https://docs.opencv.org/4.x/dc/dbb/tutorial_py_calibration.html
|
|
24
24
|
camera_params = ruststartracker.CameraParameters(
|
|
@@ -34,6 +34,7 @@ st = ruststartracker.StarTracker(
|
|
|
34
34
|
max_inter_star_angle=...,
|
|
35
35
|
inter_star_angle_tolerance=...,
|
|
36
36
|
n_minimum_matches=...,
|
|
37
|
+
timeout_secs=...,
|
|
37
38
|
)
|
|
38
39
|
|
|
39
40
|
# Obtain numpy array image
|
|
@@ -48,10 +49,21 @@ print(result)
|
|
|
48
49
|
|
|
49
50
|
## Installation
|
|
50
51
|
|
|
51
|
-
-
|
|
52
|
-
- Install with `pip install git+https://github.com/ntobler/ruststartracker.git`.
|
|
52
|
+
- Install with `pip install ruststartracker` (Currently only ARM/x86 Linux wheels available).
|
|
53
53
|
|
|
54
54
|
## TODOs
|
|
55
55
|
|
|
56
56
|
- Improve error messages.
|
|
57
57
|
- Return more diagnostic data.
|
|
58
|
+
|
|
59
|
+
## Attributions
|
|
60
|
+
|
|
61
|
+
### Gaia Data
|
|
62
|
+
|
|
63
|
+
This project includes data from the European Space Agency (ESA) mission [**Gaia**](https://www.cosmos.esa.int/gaia), processed by the **Gaia Data Processing and Analysis Consortium (DPAC)**.
|
|
64
|
+
Funding for the DPAC has been provided by national institutions, in particular the institutions participating in the Gaia Multilateral Agreement.
|
|
65
|
+
|
|
66
|
+
Gaia DR3 data is © European Space Agency and is released under the [**Creative Commons Attribution 4.0 International License (CC BY 4.0)**](https://creativecommons.org/licenses/by/4.0/).
|
|
67
|
+
|
|
68
|
+
> Gaia Collaboration, Vallenari et al. (2022), *A\&A* **674**, A1.
|
|
69
|
+
> [DOI: 10.1051/0004-6361/202243940](https://doi.org/10.1051/0004-6361/202243940)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""Build rust backend.
|
|
2
|
+
|
|
3
|
+
This script is automatically run when the pyproject is installed.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import pathlib
|
|
7
|
+
import shutil
|
|
8
|
+
import subprocess
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def download_gaia_data(output_file: pathlib.Path) -> None:
|
|
12
|
+
"""Download Gaia data and save it to the specified output file.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
output_file: Path to save the downloaded Gaia data (csv).
|
|
16
|
+
"""
|
|
17
|
+
from astroquery.gaia import Gaia
|
|
18
|
+
|
|
19
|
+
Gaia.ROW_LIMIT = 10000
|
|
20
|
+
|
|
21
|
+
query = """
|
|
22
|
+
SELECT source_id, ra, dec, parallax, pmra, pmdec, phot_g_mean_mag
|
|
23
|
+
FROM gaiadr3.gaia_source
|
|
24
|
+
WHERE phot_g_mean_mag < 7
|
|
25
|
+
AND parallax > 0
|
|
26
|
+
AND astrometric_params_solved = 31
|
|
27
|
+
AND visibility_periods_used >= 8
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
print("Executing query on Gaia database...")
|
|
31
|
+
job = Gaia.launch_job_async(
|
|
32
|
+
query,
|
|
33
|
+
dump_to_file=True,
|
|
34
|
+
output_format="csv",
|
|
35
|
+
output_file=str(output_file.absolute()),
|
|
36
|
+
verbose=True,
|
|
37
|
+
)
|
|
38
|
+
if not job.is_finished():
|
|
39
|
+
print("Job did not finish successfully.")
|
|
40
|
+
return
|
|
41
|
+
|
|
42
|
+
print(f"Saved to: {output_file}")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def build_script() -> None:
|
|
46
|
+
"""Build rust backend and move shared library to correct folder."""
|
|
47
|
+
cwd = pathlib.Path(__file__).parent.expanduser().absolute()
|
|
48
|
+
|
|
49
|
+
gaia_file = cwd / "ruststartracker/gaia_data_j2016.csv"
|
|
50
|
+
if not gaia_file.exists():
|
|
51
|
+
download_gaia_data(gaia_file)
|
|
52
|
+
|
|
53
|
+
subprocess.check_call(["cargo", "build", "--release"], cwd=cwd) # noqa: S603, S607
|
|
54
|
+
shutil.copy(
|
|
55
|
+
cwd / "target/release/libruststartracker.so", cwd / "ruststartracker/libruststartracker.so"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
if __name__ == "__main__":
|
|
60
|
+
build_script()
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "ruststartracker"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.2"
|
|
4
4
|
description = "Lightweight Python Star Tracker With Rust Backend"
|
|
5
5
|
authors = ["Nicolas Tobler <nitobler@gmail.com>"]
|
|
6
6
|
readme = "README.md"
|
|
7
7
|
license = "MIT"
|
|
8
8
|
include = [
|
|
9
|
-
{ path = "ruststartracker/
|
|
9
|
+
{ path = "ruststartracker/gaia_data_j2016.csv", format = ["sdist", "wheel"] },
|
|
10
10
|
{ path = "ruststartracker/libruststartracker.so", format = ["wheel"] },
|
|
11
11
|
]
|
|
12
12
|
|
|
13
|
+
[tool.poetry.urls]
|
|
14
|
+
Homepage = "https://github.com/ntobler/ruststartracker"
|
|
15
|
+
License = "https://opensource.org/licenses/MIT"
|
|
16
|
+
GaiaAttribution = "https://www.cosmos.esa.int/gaia"
|
|
17
|
+
|
|
13
18
|
[tool.poetry.dependencies]
|
|
14
19
|
python = "^3.10"
|
|
15
20
|
numpy = "^1.26.0"
|
|
@@ -27,16 +32,17 @@ mypy = "^1.13.0"
|
|
|
27
32
|
scipy-stubs = "^1.14.1.5"
|
|
28
33
|
ruff = "^0.9.3"
|
|
29
34
|
bump-my-version = "^1.2.0"
|
|
35
|
+
astroquery = "^0.4.10"
|
|
30
36
|
|
|
31
37
|
[tool.poetry.build]
|
|
32
|
-
script = "
|
|
38
|
+
script = "build_script.py"
|
|
33
39
|
|
|
34
40
|
[build-system]
|
|
35
|
-
requires = ["poetry-core"]
|
|
41
|
+
requires = ["poetry-core", "astroquery>=0.4.10"]
|
|
36
42
|
build-backend = "poetry.core.masonry.api"
|
|
37
43
|
|
|
38
44
|
[tool.bumpversion]
|
|
39
|
-
current_version = "0.2.
|
|
45
|
+
current_version = "0.2.2"
|
|
40
46
|
commit = true
|
|
41
47
|
tag = true
|
|
42
48
|
tag_name = "v{new_version}"
|
|
@@ -11,7 +11,9 @@ import numpy.typing as npt
|
|
|
11
11
|
AU: float = 149597870.693
|
|
12
12
|
"""Astronomical unit."""
|
|
13
13
|
|
|
14
|
-
INTERNAL_CATALOG_FILE =
|
|
14
|
+
INTERNAL_CATALOG_FILE = (
|
|
15
|
+
pathlib.Path(__file__).parent.expanduser().absolute() / "gaia_data_j2016.csv"
|
|
16
|
+
)
|
|
15
17
|
"""Location of the internal star catalog file."""
|
|
16
18
|
|
|
17
19
|
|
|
@@ -26,7 +28,7 @@ def time_to_epoch(t: datetime.datetime) -> float:
|
|
|
26
28
|
|
|
27
29
|
|
|
28
30
|
class StarCatalog:
|
|
29
|
-
"""Star catalog from
|
|
31
|
+
"""Star catalog from Gaia data."""
|
|
30
32
|
|
|
31
33
|
_data: npt.NDArray[np.float32]
|
|
32
34
|
"""Underlying data array."""
|
|
@@ -42,7 +44,7 @@ class StarCatalog:
|
|
|
42
44
|
"""Proper motion of the declination in mad."""
|
|
43
45
|
magnitude: npt.NDArray[np.float32]
|
|
44
46
|
"""Magnitude values."""
|
|
45
|
-
epoch: float =
|
|
47
|
+
epoch: float = 2016.0
|
|
46
48
|
"""Epoch of the catalog in years."""
|
|
47
49
|
|
|
48
50
|
def __init__(
|
|
@@ -57,13 +59,10 @@ class StarCatalog:
|
|
|
57
59
|
# Use locally included star catalog is no file is given
|
|
58
60
|
filename = INTERNAL_CATALOG_FILE if filename is None else pathlib.Path(filename)
|
|
59
61
|
|
|
60
|
-
keep_columns = ("
|
|
62
|
+
keep_columns = ("ra", "dec", "parallax", "pmra", "pmdec", "phot_g_mean_mag")
|
|
61
63
|
|
|
62
64
|
with filename.open("r") as f:
|
|
63
|
-
it = csv.reader(f, delimiter="
|
|
64
|
-
|
|
65
|
-
# skip head
|
|
66
|
-
[next(it) for _ in range(52)]
|
|
65
|
+
it = csv.reader(f, delimiter=",", strict=True)
|
|
67
66
|
|
|
68
67
|
# Get columns
|
|
69
68
|
columns = next(it)
|
|
@@ -71,10 +70,7 @@ class StarCatalog:
|
|
|
71
70
|
keep_columns_indices = tuple(columns.index(x) for x in keep_columns)
|
|
72
71
|
min_length = len(keep_columns_indices)
|
|
73
72
|
|
|
74
|
-
mag_column_index = columns.index("
|
|
75
|
-
|
|
76
|
-
# Skip unit and horizontal bar
|
|
77
|
-
[next(it) for _ in range(2)]
|
|
73
|
+
mag_column_index = columns.index("phot_g_mean_mag")
|
|
78
74
|
|
|
79
75
|
rows = [
|
|
80
76
|
[float(line[j]) for j in keep_columns_indices]
|
|
@@ -83,12 +79,12 @@ class StarCatalog:
|
|
|
83
79
|
]
|
|
84
80
|
self._data = np.array(rows, dtype=np.float32)
|
|
85
81
|
|
|
86
|
-
self.ra = self._data[:, keep_columns.index("
|
|
87
|
-
self.de = self._data[:, keep_columns.index("
|
|
88
|
-
self.parallax = self._data[:, keep_columns.index("
|
|
89
|
-
self.proper_motion_ra = self._data[:, keep_columns.index("
|
|
90
|
-
self.proper_motion_de = self._data[:, keep_columns.index("
|
|
91
|
-
self.magnitude = self._data[:, keep_columns.index("
|
|
82
|
+
self.ra = self._data[:, keep_columns.index("ra")]
|
|
83
|
+
self.de = self._data[:, keep_columns.index("dec")]
|
|
84
|
+
self.parallax = self._data[:, keep_columns.index("parallax")]
|
|
85
|
+
self.proper_motion_ra = self._data[:, keep_columns.index("pmra")]
|
|
86
|
+
self.proper_motion_de = self._data[:, keep_columns.index("pmdec")]
|
|
87
|
+
self.magnitude = self._data[:, keep_columns.index("phot_g_mean_mag")]
|
|
92
88
|
|
|
93
89
|
deg2rad = math.pi / 180
|
|
94
90
|
arcsec2deg = 1 / 3600
|
|
@@ -25,7 +25,7 @@ def prepare() -> tuple[ruststartracker.StarTracker, np.ndarray]:
|
|
|
25
25
|
dist_coefs = np.array([-0.44120807, -0.15954202, 0.00767012, -0.00213292, -1.64788247])
|
|
26
26
|
|
|
27
27
|
catalog = ruststartracker.StarCatalog()
|
|
28
|
-
star_catalog_vecs = catalog.normalized_positions()
|
|
28
|
+
star_catalog_vecs = catalog.normalized_positions(epoch=2024)
|
|
29
29
|
|
|
30
30
|
camera_params = ruststartracker.CameraParameters(
|
|
31
31
|
camera_matrix=camera_matrix,
|
|
@@ -36,39 +36,13 @@ def prepare() -> tuple[ruststartracker.StarTracker, np.ndarray]:
|
|
|
36
36
|
st = ruststartracker.StarTracker(
|
|
37
37
|
star_catalog_vecs,
|
|
38
38
|
camera_params,
|
|
39
|
-
inter_star_angle_tolerance=np.radians(0.
|
|
39
|
+
inter_star_angle_tolerance=np.radians(0.05).item(),
|
|
40
40
|
n_minimum_matches=5,
|
|
41
41
|
)
|
|
42
42
|
|
|
43
43
|
return st, star_catalog_vecs
|
|
44
44
|
|
|
45
45
|
|
|
46
|
-
def test_example(prepare: tuple[ruststartracker.StarTracker, np.ndarray]):
|
|
47
|
-
os.environ["RUST_BACKTRACE"] = "1"
|
|
48
|
-
|
|
49
|
-
st, _ = prepare
|
|
50
|
-
|
|
51
|
-
obs = np.array(
|
|
52
|
-
[
|
|
53
|
-
[0.11975033, -0.02227603, 0.9925541],
|
|
54
|
-
[0.03917335, 0.04533212, 0.99820361],
|
|
55
|
-
[0.05137746, -0.01717139, 0.99853167],
|
|
56
|
-
[-0.14742009, 0.00734109, 0.98904673],
|
|
57
|
-
[0.03396359, 0.05851033, 0.99770888],
|
|
58
|
-
[-0.10286126, 0.04479652, 0.99368649],
|
|
59
|
-
[-0.050927, -0.06002669, 0.9968968],
|
|
60
|
-
[0.02815389, 0.02852981, 0.99919638],
|
|
61
|
-
[-0.1390861, 0.05684676, 0.98864731],
|
|
62
|
-
[-0.14276463, -0.13402131, 0.98064089],
|
|
63
|
-
]
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
result = st.process_observation_vectors(obs)
|
|
67
|
-
np.testing.assert_allclose(
|
|
68
|
-
result.quat, [0.1722, -0.4309, 0.8818, 0.08396], rtol=1e-3, atol=1e-3
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
|
|
72
46
|
def test_star_matcher(prepare: tuple[ruststartracker.StarTracker, np.ndarray]):
|
|
73
47
|
os.environ["RUST_BACKTRACE"] = "1"
|
|
74
48
|
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"""Build rust backend.
|
|
2
|
-
|
|
3
|
-
This script is automatically run when the pyproject is installed.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import pathlib
|
|
7
|
-
import shutil
|
|
8
|
-
import subprocess
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def rust_build() -> None:
|
|
12
|
-
"""Build rust backend and move shared library to correct folder."""
|
|
13
|
-
cwd = pathlib.Path(__file__).parent.expanduser().absolute()
|
|
14
|
-
subprocess.check_call(["cargo", "build", "--release"], cwd=cwd) # noqa: S603, S607
|
|
15
|
-
shutil.copy(
|
|
16
|
-
cwd / "target/release/libruststartracker.so", cwd / "ruststartracker/libruststartracker.so"
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if __name__ == "__main__":
|
|
21
|
-
rust_build()
|