OrbX
OrbX is a Python toolkit for orbital capacity analysis. It clusters orbits based on geometrical similarity using Keplerian elements (excluding mean motion), generates representative synthetic orbits for each cluster, and computes a density score that helps quantify how tightly packed different orbital neighbourhoods are.
This project was developed as part of the following paper:
OrbX: A Framework for Orbital Capacity Management
Sam White, Samya Bagchi, Yasir Latif
12th Annual Space Traffic Management Conference, Austin TX, February 2026
Paper link
OrbX is designed for workflows such as:
- grouping similar resident space objects into orbital neighbourhoods/clusters
- identifying representative reference orbits for a cluster
- identifying the most geometrically isolated orbit within a neighbourhood
- calculating cluster density
Installation
pip install orbx
Requirements:
- Python
3.10+
Note: orekit is required for
density()andsynthetic_orbit(). Orekit is not pip installable, so install it via Conda if needed:conda install -c conda-forge orekit
Quick Start
import pandas as pd
from orbx import cluster, synthetic_orbit, density
df = pd.DataFrame(
{
"line1": [...],
"line2": [...],
}
)
# 1. Cluster orbits
labels = cluster(df)
df["label"] = labels
# 2. Remove noise (recommended, optional)
clustered_df = df[df["label"] != -1].copy()
# 3. Generate synthetic orbits
synthetic_df = synthetic_orbit(
clustered_df,
mode=["frechet", "max_separation"]
)
# 4. Score cluster density
density_df = density(clustered_df)
What OrbX Does
OrbX exposes three core functions:
cluster()
Clusters satellite orbits based on geometric similarity, using HDBSCAN and Keplerian elements extracted from two-line elements (TLEs).
synthetic_orbit()
Generates one or more synthetic orbits for each cluster. Two modes are supported:
"frechet"— computes a Fréchet mean orbit, which acts like a centroid in a non-Euclidean orbital metric space"max_separation"— finds an orbit inside the cluster region that maximises separation from existing members, highlighting available space within the neighbourhood
density()
Computes a density score for each labelled cluster by measuring dispersion around the cluster's Fréchet mean orbit. Useful for ranking or comparing how concentrated orbital neighbourhoods are within. The smaller the value, the higher the density.
Input Format
A minimum OrbX workflow may start with a DataFrame containing TLE rows:
import pandas as pd
df = pd.DataFrame(
{
"line1": [...],
"line2": [...],
}
)
After clustering, add the returned labels back onto the DataFrame in a label column before calling synthetic_orbit() or density().
API Reference
cluster(df, min_samples=3, min_cluster_size=2, verbose=False)
Groups similar TLEs into orbital neighbourhoods and returns one cluster label per input row.
Arguments:
| Argument | Type | Description |
|---|---|---|
df |
DataFrame |
Must contain line1 and line2 TLE columns. Each row is one object. |
min_samples |
int |
Controls clustering conservativeness. Higher values require stronger local support, which can increase noise points (-1). |
min_cluster_size |
int |
Minimum cluster size HDBSCAN will return. Higher values suppress small clusters and favour larger, more stable neighbourhoods. |
verbose |
bool |
If True, prints short clustering status lines. |
Tuning notes:
- Lower
min_samplesandmin_cluster_size→ more, smaller clusters - Higher
min_samplesandmin_cluster_size→ fewer clusters, more noise points - Both parameters default to the values used in the paper
Returns: NumPy array of integer cluster labels aligned to input row order. -1 = noise / unclustered.
synthetic_orbit(df, mode="max_separation", n_samples=5000, verbose=False, skip_errors=False)
Generates synthetic orbits for each cluster in a labelled DataFrame. Two modes are supported:
"frechet"— computes a Fréchet mean orbit, which represents a centroid in a non-Euclidean orbital metric space"max_separation"— finds an orbit inside the cluster that maximises separation from existing cluster members
Arguments:
| Argument | Type | Description |
|---|---|---|
df |
DataFrame |
Must contain line1, line2, and label columns. |
mode |
str or list |
"frechet", "max_separation", or ["frechet", "max_separation"] to run both. |
n_samples |
int |
Initial candidate samples for "max_separation" search. Higher values improve quality, but increase runtime. |
verbose |
bool |
If True, prints short per-label status and a final summary. |
skip_errors |
bool |
If False (default), raise on the first cluster/mode failure. If True, skip failures and warn. |
Returns: DataFrame of synthetic TLE rows with columns line1, line2, label, and synthetic_type.
density(df, label_column="label", verbose=False)
Computes a density score for each cluster by measuring the spread of member orbits around the cluster's Fréchet mean orbit.
Arguments:
| Argument | Type | Description |
|---|---|---|
df |
DataFrame |
Must contain line1, line2, and a cluster label column. TLEs are Schema-validated. |
label_column |
str |
Name of the column containing cluster IDs. Defaults to "label". |
verbose |
bool |
If True, shows a progress bar and per-label density scores. |
Returns: DataFrame with one row per cluster and columns label and density. The score is a variance-style dispersion around the Fréchet mean — interpret relative to other clusters in the same analysis. Smaller values mean a more tightly packed neighbourhood (higher density); larger values mean more dispersed.
Outputs
| Function | Returns |
|---|---|
cluster() |
NumPy array of integer cluster labels |
synthetic_orbit() |
DataFrame with line1, line2, label, synthetic_type |
density() |
DataFrame with label and density per cluster |
Demo
| Demo | Description |
|---|---|
| OrbX Cesium Demonstration | 3D Cesium visualisation composed of an orbital neighbourhood uniqueness model and an orbital cluster and synthetic orbit model |
References
| Ref | Resource | Link |
|---|---|---|
| [1] | scikit-learn HDBSCAN API |
https://scikit-learn.org/stable/modules/generated/sklearn.cluster.HDBSCAN.html |
| [2] | OrbX conference paper | https://github.com/importsam/OrbX/blob/main/OrbX__A_Framework_for_Orbital_Capacity_Characterization.pdf |
| [3] | Two-line element set (TLE) | https://en.wikipedia.org/wiki/Two-line_element_set |
Developed by Sam White, supervised by Yasir Latif and Samya Bagchi of Space Protocol.
Release files for orbx 1.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| orbx-1.0.2.tar.gz | 32.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| orbx-1.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 74.1 kB
Release files / orbx-1.0.2.tar.gz
| Download URL | orbx-1.0.2.tar.gz |
|---|---|
| Size | 32.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1d5182454982f8db19ecc10daa776c8beaa89733ee5c38881a006645564ebffd
|
|
BLAKE2b-256 checksum How to use checksums |
45b69967fe8cb01164f18a7d552dfbca24efd7bb6d4001b670fd7860a7fc157a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.2
|
Release files / orbx-1.0.2-py3-none-any.whl
| Download URL | orbx-1.0.2-py3-none-any.whl |
|---|---|
| Size | 41.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
afeecc563c71c343915c5ea65e5f493a34c6f4f2b051b5fcf3617f52004fcca8
|
|
BLAKE2b-256 checksum How to use checksums |
a2dc87d50f358be506cd67598e338e47d7fb59d53539c933f5a2fb6e1b5347c9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.2
|