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