Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 12 additions & 39 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,12 @@ SSAPy - Space Situational Awareness for Python
orbital modeling and analysis tool for orbits spanning from low-Earth orbit
into the cislunar regime.

SSAPy retains the core coordinate, observer-geometry, and propagation routines.
For higher-level utilities, convenience workflows, plotting tools, workflow
wrappers around coordinate conversions, Lambertian magnitude / brightness
calculations, and related extensions, see the companion project
`SSAPy-Toolkit <https://github.com/llnl/SSAPy-Toolkit>`__.
SSAPy provides physics-based orbital modeling and analysis for space-domain
applications.

Optional packaged datasets are available with ``llnl-ssapy[data]``. Install
``llnl-ssapy[all-data]`` to install every split ``ssatk-data-*`` distribution.
Ephemerides, gravity models, and textures install automatically from the
``ssa-data-*`` packages; ``pip install "llnl-ssapy[all-data]"`` adds the
propulsion and benchmark data sets.

SSAPy includes:

Expand Down Expand Up @@ -65,37 +63,13 @@ SSAPy includes:
including GCRF, IERS, GCRS Cartesian, TEME Cartesian, RA/Dec, NTW,
zenith/azimuth, apparent positions, and orthogonal tangent plane coordinates

SSAPy-Toolkit
-------------

SSAPy provides the core propagation and modeling engine. Many
higher-level, analysis-ready capabilities built on top of it live in the
companion project
`SSAPy-Toolkit <https://github.com/LLNL/SSAPy-Toolkit>`__ (sometimes abbreviated
*SSATK*), including:

- Higher-level utilities and convenience workflows that wrap common SSAPy tasks
- Plotting tools for orbit and analysis visualization
- Workflow-level wrappers around SSAPy's coordinate and observer-geometry
routines
- Lambertian magnitude / brightness calculations
- Additional related extensions

If your work centers on plotting, dashboards, convenience utilities, or
higher-level workflows, SSAPy-Toolkit is often the best place to start — and the
natural home for contributions of that kind.

Installation
------------

For installation details, see the
`Installing SSAPy <https://software.llnl.gov/SSAPy/installation.html>`_
section of the documentation.

If you are looking for higher-level utilities or plotting-oriented workflows,
you may also want to install or explore
`SSAPy-Toolkit <https://github.com/llnl/SSAPy-Toolkit>`__.

Strict dependencies
-------------------

Expand All @@ -113,9 +87,9 @@ The following Python packages are installed automatically when you install SSAPy
- `ipython_genutils <https://pypi.org/project/ipython-genutils/>`_
- `jplephem <https://pypi.org/project/jplephem/>`_
- `tqdm <https://pypi.org/project/tqdm/>`_

Earth/Moon mesh helpers and other visualization tools are maintained in
`SSAPy-Toolkit <https://github.com/llnl/SSAPy-Toolkit>`__.
- `ssa-data-core <https://pypi.org/project/ssa-data-core/>`_,
``ssa-data-gravity``, ``ssa-data-lunar``, and ``ssa-data-lunar-gravity``
(packaged data)

Documentation
-------------
Expand Down Expand Up @@ -143,17 +117,16 @@ Contributing to SSAPy is straightforward. Please open a
targeting the ``main`` branch of the
`SSAPy repository <https://github.com/LLNL/SSAPy>`_.

For work that primarily concerns plotting, dashboards, convenience utilities,
or higher-level workflows, please also consider whether the contribution belongs
in the companion repository
`SSAPy-Toolkit <https://github.com/llnl/SSAPy-Toolkit>`__.

Your PR must pass SSAPy's required CI checks. For local testing guidance,
documentation builds, and Git workflow tips, see the
`Contribution Guide <https://software.llnl.gov/SSAPy/contribution_guide.html>`_.

SSAPy's ``main`` branch contains the latest development work.

For six-degree-of-freedom (6-DOF) propagation, visualization, and mission-level
workflows, see the
`Space Situational Awareness Toolkit (SSATK) <https://github.com/LLNL/ssatk>`__.

Releases
--------

Expand Down
4 changes: 3 additions & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ def linkcode_resolve(domain, info):
return "https://github.com/LLNL/SSAPy/tree/main/%s.py" % filename

autosummary_generate = True
autosummary_imported_members = True
# Document objects implemented by SSAPy rather than imported implementation
# helpers (for example ``functools.lru_cache``).
autosummary_imported_members = False
numpydoc_show_class_members = False
sphinx_tabs_valid_builders = ['linkcheck']
source_suffix = ['.rst', '.md']
Expand Down
4 changes: 1 addition & 3 deletions docs/source/examples.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
SSAPy by Example
================

The examples below use base SSAPy APIs that are part of the current package.
Higher-level plotting workflows and apparent-magnitude calculations are
maintained in `SSAPy-Toolkit <https://github.com/LLNL/SSAPy-Toolkit>`_.
The examples below demonstrate the core SSAPy APIs.

Define an epoch and a simple geosynchronous orbit:

Expand Down
9 changes: 7 additions & 2 deletions docs/source/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,13 @@ As the package has been published on `PyPI <https://pypi.org/project/llnl-ssapy/

pip install llnl-ssapy

SSAPy's data (ephemerides, gravity models, textures) is installed with it
from the split ``ssatk-data-*`` packages; no Git LFS is needed.
SSAPy's data (ephemerides, gravity models, and textures) ships in the
``ssa-data-*`` packages, which install automatically with SSAPy; no Git LFS
is needed. The ``all-data`` extra adds the propulsion and benchmark data sets:

.. code-block:: console

pip install "llnl-ssapy[all-data]"

Planetary ephemerides
^^^^^^^^^^^^^^^^^^^^^
Expand Down
29 changes: 18 additions & 11 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "llnl-ssapy"
version = "1.1.11"
version = "1.1.12"
authors = [
{ name = "LLNL SSAPy Software Team", email = "yeagerastro@gmail.com" },
]
Expand Down Expand Up @@ -28,23 +28,30 @@ dependencies = [
"ipython_genutils",
"jplephem",
"tqdm",
# Ephemerides, gravity models, and textures. Required so that a plain
# `pip install llnl-ssapy` can propagate; pins match ssatk's.
"ssa-data-core==0.0.1",
"ssa-data-gravity==0.0.1",
"ssa-data-lunar==0.0.1",
"ssa-data-lunar-gravity==0.0.1",
]

[project.optional-dependencies]
# Kept so `llnl-ssapy[data]` still resolves; the same packages are required.
data = [
"ssatk-data-core==0.0.1",
"ssatk-data-gravity==0.0.1",
"ssatk-data-lunar==0.0.1",
"ssatk-data-lunar-gravity==0.0.1",
"ssa-data-core==0.0.1",
"ssa-data-gravity==0.0.1",
"ssa-data-lunar==0.0.1",
"ssa-data-lunar-gravity==0.0.1",
]

all-data = [
"ssatk-data-core==0.0.1",
"ssatk-data-gravity==0.0.1",
"ssatk-data-lunar==0.0.1",
"ssatk-data-lunar-gravity==0.0.1",
"ssatk-data-propulsion==0.0.1",
"ssatk-data-benchmarks==0.0.1",
"ssa-data-core==0.0.1",
"ssa-data-gravity==0.0.1",
"ssa-data-lunar==0.0.1",
"ssa-data-lunar-gravity==0.0.1",
"ssa-data-propulsion==0.0.1",
"ssa-data-benchmarks==0.0.1",
]

dev = [
Expand Down
8 changes: 4 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ ipython_genutils
pytest-cov
pytest-xdist
flake8
ssatk-data-core==0.0.1
ssatk-data-gravity==0.0.1
ssatk-data-lunar==0.0.1
ssatk-data-lunar-gravity==0.0.1
ssa-data-core==0.0.1
ssa-data-gravity==0.0.1
ssa-data-lunar==0.0.1
ssa-data-lunar-gravity==0.0.1
27 changes: 16 additions & 11 deletions skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ installed from PyPI or cloned from GitHub.
- Import package: `ssapy`
- GitHub repository: `https://github.com/LLNL/SSAPy`
- Documentation: `https://software.llnl.gov/SSAPy/` or `https://LLNL.github.io/SSAPy/`
- Companion toolkit: `ssapy-toolkit`, imported as `ssapy_toolkit`
- Companion data packages: `ssatk-data-*`, imported through their `ssapy_data_*` namespaces
- Data packages: `ssa-data-*` distributions, imported as `ssa_data_*`
(single list in `ssapy/_data_packages.py`)
- Related toolkit: `ssatk` (`https://github.com/LLNL/ssatk`), installed and imported as `ssatk`
- Minimum Python version: Python 3.10

## Install and Import
Expand Down Expand Up @@ -44,9 +45,9 @@ SSAPy is the base astrodynamics and orbit-determination engine. Prefer SSAPy
for core orbit models, propagators, accelerations, observers, TLE/SGP4 support,
coordinate transforms, sampling, and track association.

Use `ssapy-toolkit` for higher-level workflows, plotting dashboards, convenience
wrappers, brightness calculations, and reusable analysis utilities. New reusable
datasets should generally live in the appropriate split `ssatk-data-*` repository rather than this repository.
For 6-DOF propagation, visualization, and mission-level workflows, see
the Space Situational Awareness Toolkit (SSATK):
`https://github.com/LLNL/ssatk`.

SSAPy builds a compiled extension, `ssapy._ssapy`, through `scikit-build` and
`CMakeLists.txt`. If an import fails immediately after cloning, install the
Expand Down Expand Up @@ -115,9 +116,11 @@ r, v = rv(orbit, times, propagator=KeplerianPropagator())

## Data and Binary Rules

SSAPy's data (ephemerides, gravity models, textures) comes from the required
split `ssatk-data-*` packages; the repository no longer
stores data or uses Git LFS. Planetary ephemerides are handled by `ssapy.ephemeris`:
SSAPy's data (ephemerides, gravity models, and textures) installs automatically
from the required `ssa-data-core`, `-gravity`, `-lunar`, and `-lunar-gravity`
packages. Add the propulsion and benchmark data with
`python -m pip install 'llnl-ssapy[all-data]'`.
Planetary ephemerides are handled by `ssapy.ephemeris`:
DE440 (`de440s.bsp`, 1849-2150) by default and a 1900-2150 DE430 excerpt on
request. Epochs outside those spans download the full-span kernel from NAIF
(checksummed, cached, with a warning); `SSAPY_EPHEMERIS_DOWNLOAD=0` disables
Expand All @@ -129,8 +132,9 @@ orientation files internally; prefer those public loaders over hard-coded paths.

Avoid adding new large datasets, generated images, movies, notebooks with
embedded outputs, archives, local shared libraries, or binary payloads to this
repository. If new reusable data are needed, prefer adding them to the appropriate
split `ssatk-data-*` repository and consuming its released wheel.
repository. New reusable data belongs in the appropriate split data repository
(published as `ssa-data-*`); consume its released wheel and add its import name
to `ssapy/_data_packages.py`.

Packaging should not include local compiled artifacts such as `_ssapy*.so` from
developer builds. Generated build outputs belong outside the repository or in
Expand Down Expand Up @@ -188,7 +192,8 @@ python -m twine check dist/*

## Common Pitfalls

- Do not add data files to this repository; add them to the appropriate split `ssatk-data-*` repository.
- Do not add data files or generated artifacts to this repository; add data to
the appropriate split data repository (published as `ssa-data-*`).
- Do not add Git LFS as a default solution for new data in this repository.
- Do not commit generated `_ssapy*.so`, `build/`, `dist/`, egg-info, docs build output, caches, or local environments.
- Do not rely on unbuilt in-tree imports for code paths that require `ssapy._ssapy`.
Expand Down
25 changes: 12 additions & 13 deletions ssapy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import os

__version__ = "1.1.11"
__version__ = "1.1.12"



def _datadir():
"""Best-effort directory for installed split SSATK data packages."""
try:
from importlib.resources import files
for package in ("ssapy_data_core", "ssapy_data_gravity", "ssapy_data_lunar", "ssapy_data_lunar_gravity"):
try:
return os.fspath(files(package) / "data")
except (ImportError, TypeError):
continue
except (ImportError, TypeError):
# Split data packages are optional at import time; find_file reports
# the missing package when a resource is requested.
return os.path.join(os.path.dirname(__file__), "data")
"""Data directory of the first installed ``ssa-data-*`` package."""
from importlib.resources import files
from ._data_packages import REQUIRED
for package in REQUIRED:
try:
return os.fspath(files(package) / "data")
except (ImportError, TypeError):
continue
# No data package is installed. Return a path (never None) so find_file
# raises FileNotFoundError with install instructions instead of TypeError.
return os.path.join(os.path.dirname(__file__), "data")


datadir = _datadir()
Expand Down
25 changes: 25 additions & 0 deletions ssapy/_data_packages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""The ``ssa-data-*`` distributions that ship SSAPy's data.

Each distribution ``ssa-data-<name>`` installs the import package
``ssa_data_<name>`` with its files below ``ssa_data_<name>/data``. This module
is the single list SSAPy searches.
"""

#: Required dependencies of SSAPy (ephemerides, gravity models, textures).
REQUIRED = (
"ssa_data_core",
"ssa_data_gravity",
"ssa_data_lunar",
"ssa_data_lunar_gravity",
)

#: Added by the ``all-data`` extra.
OPTIONAL = (
"ssa_data_propulsion",
"ssa_data_benchmarks",
)

ALL = REQUIRED + OPTIONAL

#: Command that installs every data package.
INSTALL_HINT = "pip install 'llnl-ssapy[all-data]'"
11 changes: 7 additions & 4 deletions ssapy/ephemeris.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Planetary ephemeris selection and long-span kernels.

SSAPy evaluates Sun, Moon and planet positions from JPL development
ephemerides (DE). The split SSATK data packages ship the supported kernels:
ephemerides (DE). The ``ssa-data-*`` packages ship the supported kernels:

========== ======================== =========================
Ephemeris Shipped kernel Coverage
Expand All @@ -18,7 +18,7 @@
For epochs outside the shipped kernel, SSAPy uses a longer kernel of the same
ephemeris (``de440.bsp`` or ``de430.bsp``, 1550-2650) and, for DE440 beyond
that, DE441 (-13200 to +17191). These are 120 MB to 1.65 GB, so they are not
shipped: SSAPy looks for them in the working directory and split data packages
shipped: SSAPy looks for them in the working directory, the ssa-data-* packages,
and the cache directory, and otherwise downloads them from NAIF, checks their
SHA-256, and caches them, warning with :class:`EphemerisDownloadWarning`
before each download. Set ``SSAPY_EPHEMERIS_DOWNLOAD=0`` to forbid downloads
Expand All @@ -42,6 +42,8 @@

import numpy as np

from ._data_packages import INSTALL_HINT as _DATA_INSTALL_HINT

__all__ = [
"EphemerisDownloadWarning",
"EphemerisRangeWarning",
Expand Down Expand Up @@ -72,7 +74,7 @@ class Kernel:
name: str
start_jd: float # TDB Julian dates covered by every segment SSAPy uses
end_jd: float
sha256: Optional[str] = None # None for kernels shipped in split data packages
sha256: Optional[str] = None # None for kernels shipped in ssa-data-* packages
nbytes: Optional[int] = None
solution: str = ""

Expand Down Expand Up @@ -194,7 +196,8 @@ def _path(kernel, reason):
return path
if kernel.sha256 is None:
raise EphemerisUnavailableError(
f"{kernel.name} is missing; install the appropriate ssatk-data-* package."
f"{kernel.name} is missing; install the ssa-data-* packages with: "
f"{_DATA_INSTALL_HINT}"
)
destination = os.path.join(cache_dir(), kernel.name)
manual = (f"Download {kernel.url} ({kernel.nbytes / 1e6:.0f} MB) into {cache_dir()} "
Expand Down
Loading
Loading