Update docs for v0.7.0: types, operators, test count, performance framing

- types.mdx: "seven" → "seven base types + one SQL composite",
  add observer_window section with field table and usage example
- operators-gist.mdx: "three operators" → "four operators", reframe
  SP-GiST performance as scalability feature (honest about seqscan
  being faster at 14k catalog size, index helps at 100k+)
- installation.mdx: "14 test suites" → "15 test suites", list all
  suites including od_fit, spgist_tle, vallado_518
- design-principles.mdx: clarify observer_window is SQL composite
  (variable-length, query-time only), base types still STORAGE=plain
- pass-prediction.mdx: lead with operator value (80-90% elimination),
  SP-GiST index framed as optional for large catalogs
This commit is contained in:
Ryan Malloy 2026-02-17 21:51:26 -07:00
parent 845aeee3a5
commit 5e5588fddb
5 changed files with 46 additions and 7 deletions

View File

@ -104,7 +104,7 @@ For v0.1.0/v0.2.0 functions, there are no file-scope variables, no static locals
### Fixed-size types
All seven pg_orrery types use `STORAGE = plain` and fixed `INTERNALLENGTH`. No TOAST, no detoasting, no variable-length headers. The `tle` type is exactly 112 bytes. Direct pointer access via `PG_GETARG_POINTER(n)` --- no copies, no allocations on read.
All seven pg_orrery base types use `STORAGE = plain` and fixed `INTERNALLENGTH`. No TOAST, no detoasting, no variable-length headers. The `tle` type is exactly 112 bytes. Direct pointer access via `PG_GETARG_POINTER(n)` --- no copies, no allocations on read. The eighth type, `observer_window`, is a SQL composite used only as a query-time parameter --- it is never stored in table columns.
### Deterministic memory

View File

@ -97,13 +97,13 @@ import { Tabs, TabItem, Steps, Aside } from "@astrojs/starlight/components";
## Running the test suite
If building from source, the regression tests verify all functions across 14 test suites:
If building from source, the regression tests verify all functions across 15 test suites:
```bash
make installcheck PG_CONFIG=/usr/bin/pg_config
```
This runs the tests listed in the `REGRESS` variable: TLE parsing, SGP4 propagation, coordinate transforms, pass prediction, GiST indexing, convenience functions, star observation, Keplerian propagation, planet observation, moon observation, Lambert transfers, and DE ephemeris.
This runs the tests listed in the `REGRESS` variable: TLE parsing, SGP4 propagation, coordinate transforms, pass prediction, GiST indexing, convenience functions, star observation, Keplerian propagation, planet observation, moon observation, Lambert transfers, DE ephemeris, orbit determination, SP-GiST visibility index, and the 518 Vallado test vectors.
## Upgrading

View File

@ -6,7 +6,7 @@ sidebar:
import { Steps, Aside, Tabs, TabItem } from "@astrojs/starlight/components";
Satellite pass prediction answers a deceptively simple question: "which satellites will fly over me tonight?" The brute-force approach -- propagating every object in a 30,000-satellite catalog with SGP4 at 10-second intervals over a 24-hour window -- requires billions of floating-point operations. pg_orrery solves this with an SP-GiST index on the `tle` type that prunes by orbital geometry before any propagation runs, reducing the candidate set to a handful of objects that could plausibly be visible.
Satellite pass prediction answers a deceptively simple question: "which satellites will fly over me tonight?" The brute-force approach -- propagating every object in a 30,000-satellite catalog with SGP4 at 10-second intervals over a 24-hour window -- requires billions of floating-point operations. pg_orrery solves this with the `&?` visibility cone operator, which applies three geometric filters (altitude, inclination, RAAN) to eliminate 80-90% of candidates without any SGP4 propagation. An optional SP-GiST index provides tree-level pruning for large catalogs.
## How you do it today

View File

@ -6,7 +6,7 @@ sidebar:
import { Aside, Tabs, TabItem } from "@astrojs/starlight/components";
pg_orrery defines three operators on the `tle` type and two operator classes (GiST and SP-GiST) that enable indexed satellite queries over large catalogs. The GiST index accelerates conjunction screening (orbit-to-orbit overlap). The SP-GiST index accelerates pass prediction (observer-to-orbit visibility).
pg_orrery defines four operators on the `tle` type and two operator classes (GiST and SP-GiST) that enable indexed satellite queries over large catalogs. The GiST index accelerates conjunction screening (orbit-to-orbit overlap). The SP-GiST index accelerates pass prediction (observer-to-orbit visibility).
---
@ -288,7 +288,9 @@ During the index scan, inner nodes are pruned by altitude band (level 0) and inc
### Performance
The SP-GiST index is most effective for:
The `&?` operator eliminates 80-90% of a satellite catalog without SGP4 propagation --- this is the primary value, regardless of whether a sequential scan or index scan evaluates it. At typical catalog sizes (10-30k objects), the operator evaluates the full catalog in under 10 ms, and PostgreSQL's query planner may choose a sequential scan over the index.
The SP-GiST index becomes advantageous at larger catalog sizes (100k+ objects) where tree-level pruning avoids examining individual TLEs in entire subtrees. The index is most effective for:
- **Short query windows** (1-6 hours): The RAAN filter aggressively eliminates satellites whose orbital plane is not currently aligned with the observer
- **Mid-latitude observers** (30-60 degrees): The inclination filter eliminates equatorial and low-inclination satellites

View File

@ -6,7 +6,7 @@ sidebar:
import { Aside, Tabs, TabItem } from "@astrojs/starlight/components";
pg_orrery defines seven composite types that represent the core data structures of orbital mechanics. Each type has a fixed on-disk size, a text I/O format for readability, and accessor functions for extracting individual fields.
pg_orrery defines seven fixed-size base types and one SQL composite type that represent the core data structures of orbital mechanics. Each base type has a fixed on-disk size, a text I/O format for readability, and accessor functions for extracting individual fields.
## tle
@ -267,3 +267,40 @@ SELECT body_id,
FROM generate_series(1, 8) AS body_id,
planet_heliocentric(body_id, now()) AS h;
```
---
## observer_window
**Type:** SQL composite (variable-length)
A query-time parameter that defines a ground observer's visibility window. Unlike the seven base types above, `observer_window` is a SQL composite type --- it is not designed for table storage, but as an argument to the `&?` visibility cone operator.
### Fields
| Field | Type | Description |
|-------|------|-------------|
| `obs` | `observer` | Ground location (latitude, longitude, altitude) |
| `t_start` | `timestamptz` | Start of observation window |
| `t_end` | `timestamptz` | End of observation window |
| `min_el` | `float8` | Minimum elevation angle in degrees |
### Construction
Construct with `ROW(...)::observer_window` syntax:
```sql
-- Eagle, Idaho: 6-hour window, 10 deg minimum elevation
SELECT tle
FROM catalog
WHERE tle &? ROW(
observer('43.6977N 116.3535W 760m'),
'2024-01-01 01:00:00+00'::timestamptz,
'2024-01-01 07:00:00+00'::timestamptz,
10.0
)::observer_window;
```
<Aside type="tip">
See [Satellite Pass Prediction](/guides/pass-prediction/) for the full two-stage workflow using `&?` to filter candidates before SGP4 propagation with `predict_passes()`.
</Aside>