Commit Graph
5 Commits
Author SHA1 Message Date
SenrokaiandClaude Opus 5.5 a81dd491ad Say which band each star was measured in, whose catalogue it is, and how sure its distance is
The readout named Hipparcos, Yale and Gliese while 378 775 of the 455 608 stars are described by
Gaia DR3, printed one "Magnitude" for G and V alike, and gave every distance to the parsec. The
band cannot be read off the star's source, which records whose position it has: 62 002 stars Gaia
places keep HYG's V and B-V, and the 575 hosts renamed after their planets are Gaia's, in G.

stars-meta.bin gains two byte columns, 14 to 16 bytes a star (6 378 512 to 7 289 728 bytes; gzip
-9 2 804 049 to 3 110 991). One holds the magnitude's band (V 76 555 stars, G 378 744, none 309,
whose magnitude is a stand-in), which colour the colour index is (B-V 75 203, BP-RP 376 703), and
whether the distance is Gaia's parallax. The other holds the distance's relative error as its
square root in 255ths: a step is 0.08 % of distance at 1 %, 0.35 % at 20 %, and 100 % is the top.
encode, decode, BYTES_PER_STAR_META and the build.ts round trip cover both; no workflow reads the
format.

Where the errors come from:
- Gaia rows keep the parallax_error their query already fetched: median 0.3 %, 90th percentile
  1.2 %, at most 20 %, the query's own cut.
- A HYG star at Gaia's distance takes the cross-match's parallax_over_error, and a star merged
  into a Gaia entry keeps that entry's error with its position.
- The 3 067 Hipparcos stars that keep their Hipparcos distance, Rigel, Deneb and Alnilam among
  them, take e_plx from van Leeuwen's 2007 reduction: a new cached query of
  public.hipparcos_newreduction on the ESA archive, whose 117 955 rows HYG's distances invert.
- The archive's stars take sy_disterr1/2 from pscomppars, in a query and cache file of their own
  so the composite rows already cached were not refetched.
- 439 distances have no published error: 357 Gliese rows and 82 archive hosts.

Of the errors, 392 786 are 1 % or less and are not printed; 61 156 print as "117 ± 12 pc" to the
distance's own digits; 1 196 between 20 and 100 %, and 30 past it, print as the range the
parallax gives, since a symmetric error in parallax is a lopsided one in distance.

The star card (measured on the dev server) now reads, for example:
- Rigel: 265 ± 23 pc, V 0.18, B-V -0.03, source HYG.
- Deneb: 433 ± 60 pc.
- Alnilam: "476 pc to 833 pc" (Hipparcos 1.65 ± 0.45 mas).
- Gaia DR3 5612323414549657984: 111 ± 2 pc, G 4.63, BP-RP -0.15, source Gaia DR3.
- Proxima Centauri: 1.30 pc, V 11.01, source "HYG, Gaia DR3 distance".
- TRAPPIST-1: G 15.62, BP-RP 4.90, source Gaia DR3.
- Kepler-186: V 15.14, source NASA Exoplanet Archive.
The neighbourhood's subtitle reads "Gaia DR3 378,775 · HYG 73,556 · NASA Exoplanet Archive
3,277", counted by the catalogue describing each star.

build.ts validateStars now fails a catalogue with more than 1 000 stars without a band (309
today) or without a distance error (439). Dropping G from the Gaia rows gave 379 040 without a
band, and dropping their parallax_error gave 441 216 without an error; both runs failed.

Decoding the catalogue in Node took a median 29 ms before and 24 ms after (nine runs each, within
noise). In the app, five cold boots gave a 654-786 ms long task after the data landed and the
HUD at 1.83-2.07 s.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-24 23:26:27 +02:00
SenrokaiandClaude Opus 5.5 74b93a0428 Fill in the Sun's faint neighbours from Gaia, and fold the Gliese entries they repeat
Gaia's G < 12 cut took a quarter of what lies within 10 pc: the red,
brown and white dwarfs most of the neighbourhood is made of, which the
map only had where Gliese happened to list them. Teegarden's Star was
missing, and with it its three planets' host.

A second query fetches the complement out to 50 pc: G >= 12 or no G,
parallax > 20 mas, with pmra/pmdec so the J2016 -> J2000 propagation
applies. The quality filter was chosen by counting. Parallax over error
> 5 keeps 39 751 of the 39 764 sources that pass the floor, but the Gaia
Catalogue of Nearby Stars (GCNS; Gaia Collaboration, Smart et al. 2021)
rejects 11 752 of them as spurious: median G 20.2, astrometric excess
noise 5.4 mas against 0.15 for the ones it keeps, 6 933 toward the
Galactic centre. So the query joins the GCNS main table (EDR3 astrometry
and source ids, which DR3 carries unchanged) and keeps 28 012 rows; the
error cut stays and costs no GCNS source, brown dwarfs included. The
query has its own row-count floor (28 012) and the row-limit cap, and is
ordered by (phot_g_mean_mag, source_id); a second ETL run reproduced
stars.bin, stars-meta.bin and stars-index.json byte for byte. Its ids
start at 1 050 000 000, clear of the main query's and under 2^30, which
V8 keeps unboxed: numbered from 2 000 000 000 they made the app's boot
task 230 ms longer (medians of five interleaved runs, 1.41 s against
1.18). validateStars now refuses an id outside 0 to 2^30.

The Gliese entries these stars duplicate were not folded: HYG carries
them with positions off by up to a minute of arc and photometric
distances, so they missed the 15" tolerance or failed the distance test.
Their proper motions, which Gliese measured well, give them away:
isSameStar now takes two entries moving within 20 % of each other as one
star up to 60" apart, whatever their distances, brightness still
permitting. Of the 602 Gliese-only rows left without a counterpart, 253
have such a Gaia entry; with every entry shifted a quarter degree, none
does. fetchStars passes HYG's motions only for rows without Hipparcos
astrometry: given them too, 15 Hipparcos stars took a co-moving
companion's Gaia entry and the cross-catalogue pairs under an arcsecond
went from 23 to 35. Of HYG's 1 200 stars fainter than V 12 within 25 pc,
1 024 now sit on a Gaia position (325 before); of the 176 left alone, 43
still have a Gaia entry 3-60" away (218 without the motion rule), some of
them real companions.

Measured on the rebuilt catalogue, against the GCNS (sources with
parallax > 100, 40 and 20 mas):
  within 10 pc  336 -> 372  (GCNS 312; the map adds 60 HYG-only stars)
  within 25 pc  3 652 -> 5 560  (GCNS 5 111)
  within 50 pc  13 702 -> 40 916  (GCNS 40 231)
452 331 stars (+27 214). Proxima, Barnard's Star, Wolf 359, Rigel, Deneb
and Alnilam are all present by name; Teegarden's Star is Gaia DR3
35227046884571776 at 3.83 pc and hosts its three planets. Luhman 16 is
not in Gaia DR3 with a parallax (5353626573555863424 has a two-parameter
solution) and stays absent. 94 more exoplanets find a host (2 071), none
changes host. TRAPPIST-1 is now drawn (Gaia DR3 2635476908753563008,
12.47 pc) but its planets are not yet matched to it.

Merge gate, ceilings unchanged: HYG rows without a Gaia counterpart
12 352 -> 11 554 (ceiling 15 000; 10 886 before the naked-eye stars),
cross-catalogue pairs under an arcsecond 23 -> 23 (ceiling 100). The
gate's comment now accounts for the survivors by magnitude.

gzip -9 sizes against the catalogue before both changes: stars.bin
4 711 922 -> 5 030 741 B, stars-meta.bin 2 576 213 -> 2 784 614 B,
stars-index.json 3 724 855 -> 4 003 584 B (+806 KB, 7.3 %). Boot on the
dev server, five interleaved cold runs: the task that indexes the
catalogue after the data lands, median 1 072 -> 1 182 ms; HUD shown,
median 2 622 -> 2 716 ms. This machine measured 0.82-1.30 s for the
same baseline task today, above audit #25's 627-843 ms. The drawn-star
budget is unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-24 20:35:21 +02:00
Claude efa9e4084a Draw the whole catalogue, and build the aggregation the rest would need
Two things, one verified and one that cannot be.

The render budget is now the whole catalogue: 68388 stars, one instanced
draw call, which is what a GPU should be asked to do. The budget itself
stays, because the catalogue is meant to grow past what any machine should
draw at once — Gaia alone could contribute a million — and at that point
the selection is what keeps the field legible rather than a grey wash. A
`?stars=` override handles the machines that cannot, including the
software rasterizer the end-to-end suite runs against, whose frame rate is
two orders of magnitude below a real GPU's and which was measuring the
rasterizer rather than the app.

The aggregation is the second thing, and none of it has run. Every ESA,
NOIRLab, SDSS and Euclid endpoint is unreachable from here — only GitHub
raw is, which is why HYG and OpenNGC are the current sources. So this is
infrastructure and a Gaia query written against the published DR3 schema,
not data.

What the framework encodes is that these surveys are not interchangeable.
The distinction is not size but whether a catalogue knows how far away its
objects are, because a 3D map cannot place a star it only has a direction
for. Gaia is the only one of the five that can add stars here, because it
is the only one that measures parallaxes. DECaPS2 has fifty times Gaia's
object count and photometry alone — not one of its 3.32 billion objects
can be placed in depth. Euclid's bulge is 8 kpc away, where a parallax is
microarcseconds; its contribution would be imagery. SDSS-V and SAGA are
keyed to stars something else already places, so they enrich rather than
extend. Those roles are recorded as data the ETL prints, not as prose that
can drift.

Overlapping catalogues are reconciled on direction rather than on 3D
proximity, which is the one non-obvious part. Two surveys agree on a
star's direction to within an arcsecond and disagree on its distance by
tens of per cent, so a star at 200 pc is 50 pc from itself between
catalogues while being unmistakably the same object. Matching in 3D would
need a tolerance so loose it swallowed real neighbours. The better
parallax wins where both reach; where only one does, the star stays.

Names become dense-with-holes with a source dictionary, because a survey
catalogue has no proper names — writing "Gaia DR3 4472832130942575872"
once per star would cost 25 MB per million to repeat what two adjacent
fields already say. An empty entry costs three bytes and is regenerated on
load. The Sun needed its own case in the merge: it sits at the origin, has
no direction to compare, and appears in every catalogue.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WaySiNst4HhDXBHnMy8p5G
2026-08-05 08:51:54 +00:00
Claude 4aca223027 Regenerate the star catalogue, fixing 2331 names and 875 colours
Two ETL bugs, both fixed at the source and then re-run against HYG. Star ids,
ordering and positions are all unchanged, so stars.bin is byte-identical and
every exoplanet cross-reference still resolves.

Names. HYG's `gl` column already carries its own catalogue prefix ("Gl 581",
"GJ 3512"), unlike the bare numbers in `hd` and `hip`, so prefixing it again
produced 2331 of 8750 stars named "Gl GJ 1076". That corrupted three surfaces at
once: search, the on-screen labels, and exoplanet host-star name matching, which
compares normalised names and could never match "glgj1076" to "gj1076".

Colours. `Number(row['ci']) || 0` cannot tell a blank cell from a real zero, and
0 is a real B-V colour index meaning a hot blue-white A-type star. All 875
affected stars turned out to be blanks — the catalogue contains no genuine zero
inside the distance cutoff — so several hundred red dwarfs were rendering
blue-white. colorIndex is now `number | null` rather than defaulted, because any
numeric default is indistinguishable from a measurement.

Consumers resolve the gap from the spectral type instead. That needs real
parsing: HYG's `spect` column runs to 134 distinct spellings among the affected
stars alone, including a bare lowercase "m" for 354 of them, plus "k-m" ranges,
"dM4" luminosity prefixes and "K:" uncertainty flags. 622 of the 875 recover a
class this way — 497 of them M-class — and the remaining 253, which carry no
classification at all, fall back to neutral white.

The parse is anchored at the start of the string rather than scanning it. A scan
is the obvious implementation and is quietly wrong: the ETL writes the literal
"Unknown" for unclassified stars, that contains a K, and every one of those 253
would have been classified as an orange K-type. A test covers it.

Also lifts parseOptionalNumber out of fetchExoplanets into lib/csv, where both
fetchers now use it, and gives magnitude a faint default instead of 0 — no
current star is affected, but 0 would mean "as bright as Vega" and render an
unphotometered star as one of the largest points on the map.

Tests: 145 passing, up from 116, including the first coverage of
StarFieldRenderer. Build, both typechecks and the Playwright suite are green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WaySiNst4HhDXBHnMy8p5G
2026-08-04 10:56:30 +00:00
Senrokai d7e8ea1d4d @
Add star-map Angular app, ETL pipeline, and caveman plugin

Angular 3D star map (galaxy/system/body views, Three.js rendering,
navigation store) plus the NASA ETL tooling that builds the star,
exoplanet and solar-system datasets, Playwright e2e suite, and the
cs:caveman Claude Code plugin (command, agent, skill).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@
2026-08-03 16:50:10 +02:00