/** * ayanamsa.ts — Sidereal zero-point models (Drik Siddhanta). * * Two families of ayanamsa live here, and the distinction matters: * * • **Star-defined ("true") ayanamsas** — the zero point is fixed by putting a * named star at an exact sidereal longitude. True Chitrapaksha is the * canonical case: Chitra (Spica, α Virginis) sits at exactly 180°00′00″. * These need no fitted constants at all. The ayanamsa is *derived* from the * star's computed position, so it is exact by construction at every date * and tracks the real sky (Drik / observational siddhanta). * * • **Epoch-defined ayanamsas** — the zero point is fixed by declaring a value * at a reference epoch (Lahiri, Raman, KP, Fagan/Bradley …). These need an * (epoch, value) anchor and are then propagated by precession. * * ── What changed and why ───────────────────────────────────────────────────── * The previous version modelled *every* ayanamsa as a J2000 constant plus the * scalar polynomial ψ_A = 5029.0966″T + 1.1120″T². Two problems: * * 1. Precession of the sidereal zero point is a rotation of the ecliptic * frame, not a scalar added to a longitude. The shortcut drifts. * 2. The J2000 constants were back-fitted so that one chart reproduced one * expected Moon longitude. Any error elsewhere in the engine (and there * was 7–41″ of it) got absorbed into those constants, then re-emitted at * every other date. * * Both families are now propagated with the exact IAU 2006 precession rotation * from `precession.ts`, and the true-star family carries no fitted constant. */ import { type Vec } from './precession.js'; /** * ICRS astrometry, matching the entries Swiss Ephemeris ships in `sefstars.txt` * so that star-defined ayanamsas agree with SE/JHora rather than drifting by * the ~1 mas/yr difference between Hipparcos reductions. */ export interface StarData { name: string; /** Right ascension at J2000, degrees (ICRS). */ ra: number; /** Declination at J2000, degrees (ICRS). */ dec: number; /** Proper motion in RA, μα·cos δ, mas/yr. */ pmRA: number; /** Proper motion in declination, mas/yr. */ pmDec: number; /** Parallax, mas. */ parallax: number; /** Radial velocity, km/s. */ radVel: number; } export declare const STARS: Record; /** * Longitude of a fixed star in the **mean ecliptic and equinox of date**, * in degrees. * * Applies space motion (proper motion + radial velocity) and, optionally, * annual parallax. Nutation is excluded by definition — ayanamsa is referred to * the mean equinox. Annual aberration is excluded by default: including it * would make the ayanamsa oscillate by ±20″ over each year, which is not how * panchanga ayanamsa is tabulated. * * @param star Catalogue entry * @param jdUT Julian Day, UT * @param observerAU Optional observer barycentric position (AU, ICRF) for parallax */ export declare function starLongitudeOfDate(star: StarData, jdUT: number, observerAU?: Vec): number; /** A star-defined ("true") ayanamsa: `star` sits at exactly `atLongitude`. */ interface StarModel { kind: 'star'; star: keyof typeof STARS; /** Sidereal longitude the star is pinned to, degrees. */ atLongitude: number; label: string; } /** An epoch-defined ayanamsa: `value` degrees at Julian Day `jd`. */ interface EpochModel { kind: 'epoch'; jd: number; value: number; label: string; /** Where the anchor came from — see AYANAMSA_MODELS for the provenance rules. */ source: 'definition' | 'jhora' | 'provisional'; } export type AyanamsaModel = StarModel | EpochModel; /** * Swiss Ephemeris `SE_SIDM_*` mode number → model. * * `source` records where each epoch anchor comes from: * * 'definition' — the published definition of the ayanamsa itself. * 'provisional' — best available anchor, not yet checked against JHora. Treat * these as approximate; they may be off by arcminutes. * * Star-defined entries need no anchor at all and are exact by construction — * prefer them. True Chitrapaksha (27) is the project default and is verified * against JHora to 0.015″; True Pushya (29) is verified to 0.03″. * * ── A caution, from experience ────────────────────────────────────────────── * An earlier revision carried a mode-1 anchor of 23.926408° at the 1998 chart, * described as a JHora reading showing that "JHora's Lahiri sits 4.78′ above the * ICRC definition". That was wrong. The figure came from a corrupted transcript * whose ayanamsa was 6′ too high and whose planets were correspondingly 6′ too * low — the signature of numbers generated from a bad ayanamsa rather than read * off a screen. Actual JHora output for that chart reads 23°49′35.07″, which is * True Chitrapaksha, and matches this engine to 0.015″. * * The lesson: an ayanamsa anchor is only as good as the provenance of the single * number behind it. Anchor to a published definition, or to a star; do not * anchor to a reading you cannot re-verify. */ export declare const AYANAMSA_MODELS: Record; /** Human-readable name for a mode, for logs and API responses. */ export declare function ayanamsaName(mode: number): string; /** * Longitude, in the mean ecliptic of date `jdTo`, of the vernal point that was * the equinox at `jdFrom`. This is the accumulated general precession between * the two epochs, computed as an exact frame rotation rather than a polynomial. * * Returned in (−180, 180] so that epochs before `jdFrom` give negative values. */ export declare function accumulatedPrecession(jdFrom: number, jdTo: number): number; /** * Ayanamsa in degrees for a given SE mode and Julian Day (UT). * * @param mode Swiss Ephemeris SE_SIDM_* code (27 = True Chitrapaksha) * @param jd Julian Day, UT */ export declare function getAyanamsa(mode: number, jd: number): number; /** * Mean longitude of the Moon's ascending node (Rahu), tropical degrees, * referred to the mean ecliptic of date. * * Meeus, *Astronomical Algorithms* eq. 47.7 — four terms rather than the * previous three, which drifted at the 0.001° level over the DE440s span. * * @param T Julian centuries (TT) from J2000.0 */ export declare function meanLunarNode(T: number): number; /** Convert a tropical longitude to sidereal by subtracting the ayanamsa. */ export declare function toSidereal(tropical: number, ayanamsa: number): number; export {};