From 6a45c914ac7c85a0ccc63387d7c2ea82c9a517a0 Mon Sep 17 00:00:00 2001 From: Senrokai Date: Wed, 30 Sep 2026 19:42:37 +0200 Subject: [PATCH] Say a derived radius came from the star's type where no colour went into its temperature The card said every derived radius came "from colour and brightness". Since 206e88a a star with no colour the table reads is placed at its type's row, and a giant's temperature is always its type's (giantSurface): on the published catalogue that is 844 stars with no colour at all, GJ 3655 (M8) among them, and 10 702 giants with one, all labelled "from colour". temperatureFromColour, beside effectiveTemperatureK, says which path the temperature took, and the card now reads "from its type and brightness" where it was the type, and "from its temperature and brightness" for the archive hosts whose colour was itself read off st_teff. Guarded mutants, each caught by "says a radius was derived, and from what" alone (1 of 831 failed): - the basis always "colour" - giants not excluded in temperatureFromColour - colorFromTemperature ignored Co-Authored-By: Claude Opus 5.5 (1M context) --- .../galaxy-system/star-readouts.spec.ts | 8 +++++++- .../features/galaxy-system/star-readouts.ts | 20 ++++++++++++++++--- src/app/shared/astro/stellar.ts | 11 +++++++++- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/app/features/galaxy-system/star-readouts.spec.ts b/src/app/features/galaxy-system/star-readouts.spec.ts index ddcf87f..e514e77 100644 --- a/src/app/features/galaxy-system/star-readouts.spec.ts +++ b/src/app/features/galaxy-system/star-readouts.spec.ts @@ -88,7 +88,13 @@ describe('starReadouts', () => { derived: true }); expect(value(starReadouts(PLACED_BY_GAIA, { radiusSolar: 0.141, radiusDerived: false, temperatureK: 2900, luminositySolar: null, luminosityDerived: true }), 'Radius')).toBe('0.141 solar radii'); - expect(value(starReadouts(HYG_STAR, { radiusSolar: 584.3, radiusDerived: true, temperatureK: 3590, luminositySolar: null, luminosityDerived: true }), 'Radius')).toBe('~580 solar radii, from colour and brightness'); + // A giant's temperature is its type's whatever its colour, and so is a dwarf's with no colour. + const betelgeuse = { ...HYG_STAR, name: 'Betelgeuse', spectralType: 'M1-M2Ia-Iab', colorIndex: 1.85 }; + expect(value(starReadouts(betelgeuse, { radiusSolar: 584.3, radiusDerived: true, temperatureK: 3590, luminositySolar: null, luminosityDerived: true }), 'Radius')).toBe('~580 solar radii, from its type and brightness'); + const gj3655 = { ...HYG_STAR, name: 'GJ 3655', spectralType: 'M8', colorIndex: null, colorSystem: undefined }; + expect(value(starReadouts(gj3655, { radiusSolar: 0.106, radiusDerived: true, temperatureK: 2570, luminositySolar: null, luminosityDerived: true }), 'Radius')).toBe('~0.11 solar radii, from its type and brightness'); + const kepler445 = { ...HYG_STAR, spectralType: 'M4', colorIndex: 1.66, colorFromTemperature: true, source: 'exoplanet-archive' }; + expect(value(starReadouts(kepler445, { radiusSolar: 0.21, radiusDerived: true, temperatureK: 3157, luminositySolar: null, luminosityDerived: true }), 'Radius')).toBe('~0.21 solar radii, from its temperature and brightness'); expect(value(starReadouts(HYG_STAR, { radiusSolar: 1, radiusDerived: false, temperatureK: 5772, luminositySolar: null, luminosityDerived: true }), 'Radius')).toBe('1.00 solar radii'); expect(starReadouts(HYG_STAR, { radiusSolar: null, radiusDerived: true, temperatureK: null, luminositySolar: null, luminosityDerived: true }).some((readout) => readout.label === 'Radius')).toBe(false); }); diff --git a/src/app/features/galaxy-system/star-readouts.ts b/src/app/features/galaxy-system/star-readouts.ts index ddd638a..93ba09e 100644 --- a/src/app/features/galaxy-system/star-readouts.ts +++ b/src/app/features/galaxy-system/star-readouts.ts @@ -1,4 +1,5 @@ import { spectralClassification } from '../../shared/astro/spectral'; +import { temperatureFromColour } from '../../shared/astro/stellar'; import { formatDistance, formatLuminosity } from '../../shared/format/quantity'; import { StarRecord, SUN_STAR_ID } from '../../shared/models/star.model'; import { StarSurface } from '../body-detail/body-view-model'; @@ -58,17 +59,30 @@ export function starReadouts(star: StarRecord, surface?: StarSurface): HudReadou ...(surface?.luminositySolar ? [{ label: 'Luminosity', value: formatLuminosity(surface.luminositySolar), ...(surface.luminosityDerived ? { derived: true } : {}) }] : []), - ...(surface?.radiusSolar ? [radiusReadout(surface.radiusSolar, surface.radiusDerived)] : []), + ...(surface?.radiusSolar ? [radiusReadout(surface.radiusSolar, surface.radiusDerived, radiusBasis(star))] : []), { label: 'Source', value: catalogue === 'HYG' && star.distanceFromGaia ? 'HYG, Gaia DR3 distance' : catalogue } ]; } +/** + * What a derived radius is worked out from besides the brightness: the temperature the star's + * colour gives, or its type's — a giant's always, and a dwarf's with no colour the table reads. + * 11 546 radii read "from colour" whose temperature no colour went into: 10 702 giants with one, and + * 844 stars with none, GJ 3655 (M8) among them. + */ +function radiusBasis(star: StarRecord): string { + if (star.colorFromTemperature) { + return 'its temperature'; + } + return temperatureFromColour(star) ? 'colour' : 'its type'; +} + /** Two figures for a derived radius, three for a published one: 0.105 is not what colour gives. */ -function radiusReadout(radiusSolar: number, derived: boolean): HudReadout { +function radiusReadout(radiusSolar: number, derived: boolean, basis: string): HudReadout { const digits = derived ? 2 : 3; const figure = radiusSolar.toLocaleString('en-GB', { minimumSignificantDigits: digits, maximumSignificantDigits: digits }); return derived - ? { label: 'Radius', value: `~${figure} solar radii, from colour and brightness`, derived: true } + ? { label: 'Radius', value: `~${figure} solar radii, from ${basis} and brightness`, derived: true } : { label: 'Radius', value: `${figure} solar radii` }; } diff --git a/src/app/shared/astro/stellar.ts b/src/app/shared/astro/stellar.ts index 1f7383b..dcc5707 100644 --- a/src/app/shared/astro/stellar.ts +++ b/src/app/shared/astro/stellar.ts @@ -151,7 +151,7 @@ export function luminositySolar(star: StellarPhotometry): number | null { * off-table colour is more often a bad one than an extreme star — HD 49748, G5 V, at B−V −0.32 — * and the type is read instead. */ -function sequenceAtColour(star: StellarPhotometry): DwarfSequencePoint | null { +function sequenceAtColour(star: Pick): DwarfSequencePoint | null { if (star.colorIndex == null) { return null; } @@ -175,6 +175,15 @@ export function effectiveTemperatureK(star: StellarPhotometry): number | null { return giantSurface(star.spectralType)?.temperatureK ?? (sequenceAtColour(star) ?? dwarfSequenceAtType(star.spectralType))?.temperatureK ?? null; } +/** + * Whether {@link effectiveTemperatureK} reads the star off its colour rather than off its type: not + * for a giant, nor for a star with no colour the table reads, which since 206e88a is 821 dwarfs + * placed at their type's row. The card said their radii came "from colour and brightness". + */ +export function temperatureFromColour(star: Pick): boolean { + return giantSurface(star.spectralType) === null && sequenceAtColour(star) !== null; +} + /** * What a giant's type says of its surface: its effective temperature, and the bolometric * correction the dwarf sequence has at that temperature — both off the type, so that the two a