Skip to content

The caltib Python API

The library provides a clean, unified interface to query both discrete traditional engines and continuous astronomical models. Because of the strict mathematical decoupling under the hood, the top-level API remains identical whether you are evaluating a 15th-century integer framework or an L6 JPL numerical ephemeris.


1. Initialization & The Engine Factory

The get_calendar() factory is the gateway to the library. It dynamically instantiates the requested CalendarEngine, utilizing lazy loading to ensure high-end dependencies (like jplephem) are only imported if explicitly requested.

import caltib
from caltib.engines.specs import LOC_MONTREAL, LOC_LHASA

# Instantiate a traditional engine (defaults to approximate historical coordinates)
phugpa_engine = caltib.get_calendar("phugpa")

# Instantiate a reform engine with localized geographical dependency injection
# This dynamically overrides the thresholds used for spherical sunrise
l3_montreal = caltib.get_calendar("l3", location=LOC_MONTREAL)

2. Core Day Queries

The most common operation is fetching the complete calendrical state for a specific Gregorian date. You can use the top-level day_info() function for quick lookups, or call it directly on an instantiated engine.

from datetime import date

# 1. Top-level quick query
info = caltib.day_info(date(2026, 2, 21), engine="mongol")

# 2. Engine-level query (faster for bulk operations)
info = l3_montreal.day_info(date(2026, 2, 21))

print(f"Tibetan Year: {info.tibetan.year}")
print(f"Tithi (Lunar Day): {info.tibetan.tithi}")
print(f"Is Leap Month?: {info.tibetan.is_leap_month}")

The DayInfo & TibetanDate Data Models

The day_info method returns a comprehensive DayInfo dataclass containing both the input Gregorian parameters and the resulting Tibetan mapping.

  • DayInfo.gregorian: A standard Python datetime.date object.
  • DayInfo.jdn: The Julian Day Number (integer) representing local noon.
  • DayInfo.tibetan: A TibetanDate dataclass containing:
    • year: The Tibetan year number.
    • month: The Tibetan month number (1–12).
    • is_leap_month: Boolean. True if this is an intercalary month.
    • tithi: The lunar day number (1–30).
    • is_leap_day: Boolean. True if this specific tithi is duplicated (the second occurrence).
    • is_skipped: Boolean. Identifies if the preceding mathematical tithi was skipped in the civil calendar.

3. Calendar Arithmetic & Conversions

The API provides robust tools for navigating the calendar chronologically, handling the complex boundaries of leap months and missing days.

  • caltib.new_year_day(Y: int, engine: str) -> date: Resolves the Gregorian start date of the Tibetan New Year (Losar / Tsagaan Sar) for the given Tibetan year \(Y\).
  • caltib.month_bounds(Y: int, M: int, is_leap: bool = False, engine: str) -> MonthBounds: Returns the exact starting and ending JDN and Gregorian dates of a specific lunar month, mapping the continuous coordinate \(x\) to the civil grid.
  • caltib.to_gregorian(t_date: TibetanDate, engine: str, policy: str = "all") -> list[date]: Inverts a Tibetan date back into Gregorian. Because Tibetan civil days can be duplicated, this returns a list.
    • policy="all": Returns all Gregorian dates matching the Tibetan date (returns 2 dates if duplicated, 0 if skipped).
    • policy="first": Returns only the first occurrence of a duplicated day.
    • policy="second": Returns only the second occurrence.

4. High-Performance Bulk Processing

When generating millennia-spanning charts in the Diagnostics Lab, repeatedly calling the top-level caltib.day_info(..., engine="...") introduces factory overhead. For maximum performance, instantiate the CalendarEngine once and use its internal generators.

# Instantiate engine once
engine = caltib.get_calendar("l4")

# Fetch civil calendar mappings for an entire lunation efficiently
# lunation_index (n) maps directly to the absolute coordinate x = 30n + d
month_map = engine.build_civil_month(lunation_index=12345)

for civil_jdn, tithi in month_map.items():
    # Process the discrete grid...
    pass

Exhaustive API Reference

Below is the automatically generated technical reference for all public classes and functions in the caltib library, extracted directly from the Python source code.

Top-Level API & Configuration

caltib.api

civil_month_n
civil_month_n(n: int, *, engine: str = 'phugpa') -> List[Dict[str, Any]]

Diagnostic: list civil day records for a specific lunation n.

day_info
day_info(d: date, *, engine: str = 'phugpa', attributes: Sequence[str] = (), debug: bool = False) -> DayInfo
days_in_month
days_in_month(Y: int, M: int, *, is_leap_month: bool = False, engine: str = 'phugpa')
debug_lunation_n
debug_lunation_n(n: int, *, engine: str = 'phugpa', debug: bool = False) -> Dict[str, Any]

Formerly called 'month_from_n'. Returns internal math labels for absolute n.

debug_month_labels
debug_month_labels(Y: int, M: int, *, engine: str = 'phugpa', debug: bool = False) -> Dict[str, Any]

Formerly called 'month_info'. Returns internal math labels.

end_jd_dn
end_jd_dn(d: int, n: int, *, engine: str = 'phugpa') -> int

Returns absolute Julian Day Number via continuous x.

engine_info
engine_info(engine: str) -> Dict[str, Any]
explain
explain(d: date, *, engine: str = 'phugpa') -> Dict[str, Any]
first_day_of_month
first_day_of_month(Y: int, M: int, *, is_leap_month: bool = False, engine: str = 'phugpa') -> date
get_calendar
get_calendar(name: str, *, location: Optional[LocationSpec] = None) -> CalendarEngine
intercalation_index
intercalation_index(Y: int, M: int, *, engine: str = 'phugpa') -> int
last_day_of_month
last_day_of_month(Y: int, M: int, *, is_leap_month: bool = False, engine: str = 'phugpa') -> date
list_engines
list_engines() -> List[str]
make_engine
make_engine(spec: CalendarSpec) -> CalendarEngine
month_bounds
month_bounds(Y: int, M: int, *, is_leap_month: bool = False, engine: str = 'phugpa', debug: bool = False, as_date: bool = True) -> dict
month_from_n
month_from_n(n: int, *, engine: str = 'phugpa', debug: bool = False) -> Dict[str, Any]
month_info
month_info(Y: int, M: int, *, is_leap_month: bool = False, engine: str = 'phugpa') -> MonthInfo

Returns a fully populated MonthInfo dataclass, including all days and alignments.

new_year_day
new_year_day(Y: int, *, engine: str = 'phugpa', as_date: bool = True) -> Any

Returns the Gregorian date for Losar/Tsagaan Sar. If as_date is True, returns a pure datetime.date object. Otherwise, returns a dictionary with physical diagnostic data.

next_month
next_month(Y: int, M: int, *, is_leap_month: bool = False, engine: str = 'phugpa', debug: bool = False) -> dict
prev_month
prev_month(Y: int, M: int, *, is_leap_month: bool = False, engine: str = 'phugpa', debug: bool = False) -> dict
register_engine
register_engine(name: str, engine: CalendarEngine, *, overwrite: bool = False) -> None
set_registry
set_registry(reg: EngineRegistry) -> None
to_gregorian
to_gregorian(t: TibetanDate, *, engine: Optional[str] = None, policy: str = 'all') -> List[date]
true_date_dn
true_date_dn(d: int, n: int, *, engine: str = 'phugpa')

Returns absolute true_date (Days since J2000.0) via continuous x.

year_info
year_info(Y: int, *, engine: str = 'phugpa') -> YearInfo

Returns a fully populated YearInfo dataclass, including all active months and days.

caltib.engines.factory

caltib.engines.factory

Transforms pure data specifications into live, executable Engine objects.

build_calendar_engine
build_calendar_engine(spec: CalendarSpec) -> CalendarEngine

Transforms a pure data CalendarSpec into a live CalendarEngine.

make_engine
make_engine(spec: CalendarSpec) -> CalendarEngine

The universal entry point.

caltib.engines.specs

arith_day
arith_day(*, location: LocationSpec, m0_abs: Fraction | None = None, m0_loc: Fraction | None = None, s0: Fraction, s1: Fraction = S1_TIB, U: int = 11312, V: int = 11135, dawn_time: Fraction = Fraction(1, 4)) -> ArithmeticDayParams

Auto-computes delta_star phase shifts natively for either absolute or local m0.

arith_month
arith_month(*, Y0: Optional[int] = None, M0: Optional[int] = None, beta_star: Optional[int] = None, tau: Optional[int] = None, P: int = P_TIB, Q: int = Q_TIB, m0: Fraction, m1: Fraction = M1_TIB, s0: Fraction = Fraction(0, 1), sgang1_deg: Fraction = Fraction(307, 1)) -> ArithmeticMonthParams
fp_day
fp_day(*, epoch_k: int, location: LocationSpec = LOC_LHASA, solar_table: Tuple[Tuple[float, ...], ...] = (), lunar_table: Tuple[Tuple[float, ...], ...] = (), iterations: int = 3, delta_t: FloatDeltaTDef = DT_FLOAT_DEF, sunrise: FloatSunriseDef = DAWN_FLOAT_DEF, sine_poly_coeffs: Tuple[float, ...] = SINE_POLY_5_COEFFS, C_sun: float = 0.0, C_elong: float = 0.0, include_drift: bool = False) -> FloatDayParams

Builds pure-data FloatDayParams using exact J2000.0 astronomical constants.

rational_day
rational_day(*, funds: dict[str, FundArg], location: LocationSpec = LOC_LHASA, solar_table: Tuple[Tuple[Any, ...], ...] = (), lunar_table: Tuple[Tuple[Any, ...], ...] = (), iterations: int = 1, delta_t: DeltaTDef = DT_CONSTANT_DEF, sunrise: SunriseDef = DAWN_600AM_DEF, moon_tab_quarter: Tuple[int, ...] = MOON_TAB_QUARTER, sun_tab_quarter: Tuple[int, ...] = SUN_TAB_QUARTER, invB_prec: Optional[Fraction] = None, C_sun: Fraction = Fraction(0, 1), C_elong: Fraction = Fraction(0, 1), include_drift: bool = False) -> RationalDayParams
rational_month
rational_month(*, funds: dict[str, FundArg], solar_table: Tuple[Tuple[Any, ...], ...] = (), lunar_table: Tuple[Tuple[Any, ...], ...] = (), iterations: int = 1, moon_tab_quarter: Tuple[int, ...] = MOON_TAB_QUARTER, sun_tab_quarter: Tuple[int, ...] = SUN_TAB_QUARTER, sgang1_deg: Fraction = Fraction(307, 1), leap_labeling: str = 'first_is_leap', skipped_naming: str = 'second', invB_prec: Optional[Fraction] = None, C_sun: Fraction = Fraction(0, 1), C_elong: Fraction = Fraction(0, 1), include_drift: bool = False) -> RationalMonthParams
trad_day
trad_day(*, m0: Fraction, s0: Fraction, a0: Fraction, m1: Fraction = M1_TIB, s1: Fraction = S1_TIB, a1: Fraction = A1_STD, a2: Fraction = A2_STD, location: LocationSpec = LOC_TIBET_APPROX) -> TraditionalDayParams
trad_planets
trad_planets(*, m0: Fraction, s0: Fraction, pd0: dict[str, int], p_rates=P_RATES, birth_signs=BIRTH_SIGNS, manda_tables=TAB_MANDA, sighra_tables=TAB_SIGHRA) -> TraditionalPlanetsParams

Builds the traditional planetary engine configuration for a given epoch.

Core Data Models

caltib.core.types

CalendarSpec dataclass

Pure data payload for constructing a full modular calendar.

day_params instance-attribute
day_params: Any
id instance-attribute
id: EngineId
leap_labeling instance-attribute
leap_labeling: str
meta instance-attribute
meta: dict
month_params instance-attribute
month_params: Any
planets_params class-attribute instance-attribute
planets_params: Any = None
with_location
with_location(new_loc: 'LocationSpec') -> 'CalendarSpec'

Creates a new spec securely recalibrated for the target location.

DayInfo dataclass

Rich UI container for a specific civil day.

civil_attributes class-attribute instance-attribute
civil_attributes: Optional[Dict[str, Any]] = None
civil_date instance-attribute
civil_date: date
debug class-attribute instance-attribute
debug: Optional[Dict[str, Any]] = None
engine instance-attribute
engine: EngineId
festival_tags class-attribute instance-attribute
festival_tags: Tuple[str, ...] = ()
lunar_attributes class-attribute instance-attribute
lunar_attributes: Optional[Dict[str, Any]] = None
planets class-attribute instance-attribute
planets: Optional[Dict[str, Any]] = None
status instance-attribute
status: Literal['normal', 'duplicated']
tibetan instance-attribute
tibetan: TibetanDate
EngineId dataclass
family instance-attribute
family: Literal['trad', 'reform', 'custom']
name instance-attribute
name: str
version instance-attribute
version: str
EngineSpec dataclass

Top-level wrapper for all engine specifications.

id instance-attribute
id: EngineId
kind instance-attribute
kind: Literal['traditional', 'rational', 'float', 'ephemeris']
payload instance-attribute
payload: CalendarSpec
LocationSpec dataclass
elev_m class-attribute instance-attribute
elev_m: Optional[Fraction] = None
lat_turn class-attribute instance-attribute
lat_turn: Optional[Fraction] = None
lon_turn instance-attribute
lon_turn: Fraction
name instance-attribute
name: str
MonthInfo dataclass

Rich UI container for a lunar month.

attributes class-attribute instance-attribute
attributes: Optional[Dict[str, Any]] = None
days class-attribute instance-attribute
days: List[DayInfo] = field(default_factory=list)
gregorian_end instance-attribute
gregorian_end: Optional[date]
gregorian_start instance-attribute
gregorian_start: Optional[date]
status class-attribute instance-attribute
status: Literal['normal', 'duplicated', 'skipped'] = 'normal'
tibetan instance-attribute
tibetan: TibetanMonth
SunriseState

Bases: Enum

TibetanDate dataclass

Pure mathematical coordinate of a Tibetan day.

engine instance-attribute
engine: EngineId
is_leap_month instance-attribute
is_leap_month: bool
linear_day class-attribute instance-attribute
linear_day: int = 0
lunar_day property
lunar_day: int
month instance-attribute
month: int
occ class-attribute instance-attribute
occ: int = 1
previous_tithi_skipped class-attribute instance-attribute
previous_tithi_skipped: bool = False
tithi instance-attribute
tithi: int
year instance-attribute
year: int
TibetanMonth dataclass

Pure mathematical coordinate of a Tibetan month.

engine instance-attribute
engine: EngineId
is_leap_month instance-attribute
is_leap_month: bool
linear_month class-attribute instance-attribute
linear_month: int = 0
month instance-attribute
month: int
occ class-attribute instance-attribute
occ: int = 1
previous_month_skipped class-attribute instance-attribute
previous_month_skipped: bool = False
year instance-attribute
year: int
TibetanYear dataclass

Pure mathematical coordinate of a Tibetan year.

engine instance-attribute
engine: EngineId
rabjung_cycle property
rabjung_cycle: int
rabjung_year property
rabjung_year: int
year instance-attribute
year: int
YearInfo dataclass

Rich UI container for a Tibetan year.

attributes class-attribute instance-attribute
attributes: Optional[Dict[str, Any]] = None
gregorian_end class-attribute instance-attribute
gregorian_end: Optional[date] = None
gregorian_start class-attribute instance-attribute
gregorian_start: Optional[date] = None
months class-attribute instance-attribute
months: List[MonthInfo] = field(default_factory=list)
tibetan instance-attribute
tibetan: TibetanYear

caltib.core.time

a0_from_trad
a0_from_trad(ril_int: int, ril_fractions: tuple[int, ...], radices: tuple[int, ...] = (126,)) -> Fraction

Calculates lunar anomaly (turns) from traditional ril (Anomaly in 28 lunar mansions).

a1_from_trad
a1_from_trad(ril_int: int, ril_fractions: tuple[int, ...], radices: tuple[int, ...] = (126,)) -> Fraction

Converts Anomaly advance (in 28 mansions) to fractional turns.

advance_sun_to_epoch
advance_sun_to_epoch(s0_j2000: Fraction, m0: Fraction, m1: Fraction, P: int, Q: int) -> Fraction

Advances the J2000 Mean Sun to the epoch m0. Returns the true Mean Sun at the epoch (s_epoch).

deduce_epoch_constants
deduce_epoch_constants(s_epoch: Fraction, sgang1_deg: Fraction, P: int, Q: int) -> tuple[int, int, int]

Deduces the normalized internal epoch constants from the P/Q grid: - the month label carried by lunation n=0, - the internal phase beta_int for trigger set {0,...,ell-1}, - tau_int = 0. These are not necessarily the published epoch constants (Y0, M0, beta_star, tau).

from_jdn
from_jdn(jdn: int) -> date

Fliegel-Van Flandern inverse of to_jdn (Gregorian).

from_mixed_radix
from_mixed_radix(integer_part: int, fractions: tuple[int, ...], radices: tuple[int, ...]) -> Fraction

Evaluates traditional mixed radix notation: a0; a1, ..., an (b1, ..., bn) Matches the inductive definition: a0 + a1/b1 + a2/(b1*b2) + ...

k_from_epoch_jd
k_from_epoch_jd(m0: float | Fraction) -> int

Derives the absolute Meeus lunation index k from an epoch's Mean New Moon JD.

m0_from_k
m0_from_k(k: int) -> Fraction

Derives the exact epoch Mean New Moon JD (m0) from a Meeus lunation index k. Evaluated purely in fractions to preserve determinism in rational engines.

m0_from_trad
m0_from_trad(jd: int, gza_fractions: tuple[int, ...], radices: tuple[int, ...] = (60, 60, 6, 707)) -> Fraction

Calculates absolute Julian Day m0 from traditional gza' (Mean Weekday). The integer part of gza is implicitly handled by the base epoch JD.

m1_from_trad
m1_from_trad(gza_int: int, gza_fractions: tuple[int, ...], radices: tuple[int, ...] = (60, 60, 6, 707)) -> Fraction

Converts Mean Weekday advance (modulo 7) to absolute Synodic Month (days).

s0_from_trad
s0_from_trad(nyi_int: int, nyi_fractions: tuple[int, ...], radices: tuple[int, ...] = (60, 60, 6, 67)) -> Fraction

Calculates mean sun (turns) from traditional nyi (Mean Sun in 27 lunar mansions).

s1_from_trad
s1_from_trad(nyi_int: int, nyi_fractions: tuple[int, ...], radices: tuple[int, ...] = (60, 60, 6, 67)) -> Fraction

Converts Mean Sun advance (in 27 mansions) to fractional turns.

to_jdn
to_jdn(d: date) -> int

Convert Gregorian date to Julian Day Number (JDN).

y0_from_epoch_jd
y0_from_epoch_jd(m0: float | Fraction) -> int

Infers the human calendar year (Y0) from an epoch's Julian Date. Because Tibetan epochs (m0) always fall in the Spring (Months 1-3), we can safely map the JD to the Gregorian/Julian year without edge-case rollover. Evaluated purely in fractions to preserve absolute determinism.

year_decimal_approx
year_decimal_approx(d: date) -> float

Approximate decimal year as float: year + doy/span.

year_decimal_fraction
year_decimal_fraction(d: date) -> Fraction

Decimal year as Fraction: year + doy/span.

Base Engine Architectures

caltib.engines.interfaces

caltib.engines.interfaces

Defines the strict architectural boundaries between discrete arithmetic (Month), continuous kinematics (Day), and the orchestrator (Calendar).

Standard Reference Frame: Unless otherwise specified, all physical time variables (t) in the DayEngine represent Days since J2000.0 TT (Terrestrial Time), where J2000.0 = JD 2451545.0.

NumT module-attribute
NumT = Union[int, float, Fraction]
AttributeEngineProtocol

Bases: Protocol

Calculates astrological attributes. Returns a flexible dictionary of indices/values defined by the specific tradition.

get_civil_day_attributes
get_civil_day_attributes(jdn: int) -> Dict[str, Any]
get_lunar_day_attributes
get_lunar_day_attributes(tib_year: int, month_no: int, tithi: int) -> Dict[str, Any]
get_month_attributes
get_month_attributes(tib_year: int, month_no: int) -> Dict[str, Any]
get_year_attributes
get_year_attributes(tib_year: int) -> Dict[str, Any]
CalendarEngineProtocol

Bases: Protocol

The orchestrator. Binds Month, Day, and Attribute engines together.

attr instance-attribute
attr: AttributeEngineProtocol | None
day instance-attribute
day: DayEngineProtocol
leap_labeling instance-attribute
leap_labeling: str
month instance-attribute
month: MonthEngineProtocol
planets instance-attribute
planets: PlanetsEngineProtocol | None
from_jdn
from_jdn(jdn: int) -> Dict[str, Any]
to_jdn
to_jdn(year: int, month: int, is_leap: bool, day: int) -> int
DayEngineProtocol

Bases: Protocol

Strictly handles kinematics. Maps the absolute tithi index (x) to physical time (Days since J2000.0 TT) and solar/lunar longitudes.

The absolute kinematic coordinate is defined as: x = 30 * n + d

epoch_k property
epoch_k: int

The absolute Meeus lunation index of the engine's epoch.

location property
location: LocationSpec

The geographic anchor for civil day boundaries.

civil_jdn
civil_jdn(x: NumT) -> int

Returns the absolute, discrete Julian Day Number on which tithi x ends. Must be computed securely to prevent float precision boundary snapping.

eval_sunrise_lmt
eval_sunrise_lmt(t2000_tt: NumT) -> Tuple[Fraction, SunriseState]

Evaluates the exact LMT fraction of sunrise for the solar coordinates at the given continuous physical time (J2000 TT).

get_x_from_t2000
get_x_from_t2000(t2000: NumT) -> int

Inverse kinematic lookup. Returns the active absolute tithi index (x) that covers the given physical time (Days since J2000.0).

local_civil_date
local_civil_date(x: NumT) -> NumT

Civil-aligned time. Shifted such that floor(local_civil_date + J2000) accurately bounds the human day (e.g., local dawn).

mean_date
mean_date(x: NumT) -> NumT

Returns the mean physical time (Days since J2000.0) for absolute tithi x.

mean_sun
mean_sun(x: NumT) -> NumT

Returns the mean solar longitude (turns) at absolute tithi x.

true_date
true_date(x: NumT) -> NumT

Returns the true physical time (Days since J2000.0) for absolute tithi x.

true_sun
true_sun(x: NumT) -> NumT

Returns the true solar longitude (turns) at absolute tithi x.

MonthEngineProtocol

Bases: Protocol

Handles discrete arithmetic. Maps absolute lunation indices (n) to human calendar labels (Year, Month, Leap status) and vice versa.

epoch_k property
epoch_k: int

The absolute Meeus lunation index of the engine's epoch.

sgang_base property
sgang_base: NumT

The principal solar term (longitude anchor) for the epoch.

first_lunation
first_lunation(year: int) -> int

Returns the absolute lunation index of the first lunation in the given year.

get_l_from_t2000
get_l_from_t2000(t2000: NumT) -> NumT

Inverse kinematic lookup: true elongation (in turns) at physical time t.

get_lunations
get_lunations(tib_year: int, month_no: int) -> List[int]

Returns the absolute lunation indices for a given Year and Month number. Returns: [] -> If the astronomical month was skipped. [n] -> Standard single month. [n, n+1] -> If the month is leaped (contains a main and intercalary month).

get_month_info
get_month_info(n: int) -> Dict[str, Any]

Expected keys: 'year': int 'month': int 'leap_state': int (0=regular, 1=first of two, 2=second of two) 'linear_month': int

mean_date
mean_date(l: NumT) -> NumT

Physical time t when Mean Elongation equals l turns.

mean_sun
mean_sun(l: NumT) -> NumT

Mean solar longitude (turns) at the moment true_date(l).

true_date
true_date(l: NumT) -> NumT

Physical time t when True Elongation equals l turns.

true_sun
true_sun(l: NumT) -> NumT

True solar longitude (turns) at the moment true_date(l).

PlanetsEngineProtocol

Bases: Protocol

Calculates planetary kinematics. Maps absolute physical time (JD) to geocentric longitudes (in turns) for the visible planets, Sun, and Rahu.

epoch_k property
epoch_k: int

The absolute Meeus lunation index deduced from the engine's m0.

longitudes
longitudes(jd: NumT) -> Dict[str, Dict[str, NumT]]

Convenience method to return all bodies at once. Format: {"mars": {"mean": 0.5, "true": 0.51}, ...}

mean_longitude
mean_longitude(planet: str, jd: NumT) -> NumT

Returns the mean longitude of the requested body.

true_longitude
true_longitude(planet: str, jd: NumT) -> NumT

Returns the true geocentric longitude of the requested body.

caltib.engines.calendar

caltib.engines.calendar

The Orchestrator. Binds the discrete MonthEngine and continuous DayEngine together, handling epoch synchronization and civil Julian Day boundaries.

CalendarEngine

Translates full human dates to local Julian Day Numbers (JDN) and vice versa, hiding all internal continuous time (t2000) and coordinate (x) shifts.

attr instance-attribute
attr = attr
day instance-attribute
day = day
delta_k instance-attribute
delta_k = epoch_k - epoch_k
id instance-attribute
id = id
leap_labeling instance-attribute
leap_labeling = getattr(spec, 'leap_labeling', 'first_is_leap')
month instance-attribute
month = month
planets instance-attribute
planets = planets
sgang_base property
sgang_base: Fraction

Returns the continuous zodiac offset [0, 1) turns for the first Sgang.

spec instance-attribute
spec = spec
trad property
trad

Convenience accessor for traditional almanac methods, if available.

build_civil_month
build_civil_month(n_d: int) -> dict

Diagnostic wrapper: Builds a month array using pure continuous bounds.

day_info
day_info(d: Any, *, debug: bool = False) -> DayInfo
eval_sunrise_lmt
eval_sunrise_lmt(t2000_tt: NumT) -> Tuple[Fraction, SunriseState]
from_jdn
from_jdn(jdn: int) -> dict

Maps a Gregorian JDN to a Tibetan Date using pure monotonic search over exact discrete boundaries.

get_planet_longitudes
get_planet_longitudes(jd: NumT) -> Dict[str, Dict[str, NumT]] | None

Directly evaluates planetary longitudes for a given Julian Date (Local JD for traditional calendars) or continuous physical time. Useful for debugging or isolated kinematic testing.

info
info() -> Dict[str, Any]
month_info
month_info(year: int, month: int, is_leap: bool = False) -> MonthInfo

Generates a fully populated MonthInfo object using month-engine lunation lookup.

to_gregorian
to_gregorian(t: 'TibetanDate', *, policy: str = 'all') -> list[date]

Maps a TibetanDate back to Gregorian dates using pure continuous analytical mapping.

to_jdn
to_jdn(year: int, month: int, is_leap: bool, day: int) -> int

Translates a full human calendar date into a local Julian Day Number.

with_location
with_location(new_loc: 'LocationSpec') -> 'CalendarEngine'

Returns a completely new CalendarEngine instance, perfectly recalibrated for the requested geographic location.

year_info
year_info(year: int) -> YearInfo

Generates a complete YearInfo object by iterating continuously through the exact mathematical lunations (n) that exist in the year.

Internal Solvers & Physics Models

caltib.engines.trad_day

caltib.engines.trad_day

Traditional discrete-table kinematic engine. Maps absolute tithis (x) to true physical time (t2000) using historical affine equations and piecewise linear periodic tables.

TraditionalDayEngine

Bases: DayEngineProtocol

Evaluates historical calendar kinematics. Fully implements DayEngineProtocol.

epoch_k property
epoch_k: int
location property
location: LocationSpec

Satisfies the new location-aware protocol.

moon_table instance-attribute
moon_table = QuarterWaveTable(quarter=moon_tab_quarter)
p instance-attribute
p = p
phase_moon instance-attribute
phase_moon = PhaseDN(a0, a1, a2)
phase_sun_anomaly instance-attribute
phase_sun_anomaly = PhaseDN(r0, r1, r2)
series instance-attribute
series = AffineTabSeriesDN(base_c0=m0, base_cn=m1, base_cd=m2, terms=(TabTermDN(amp=Fraction(1, 60), phase=phase_moon, table_eval_turn=eval_turn), TabTermDN(amp=Fraction(-1, 60), phase=phase_sun_anomaly, table_eval_turn=eval_turn)))
sun_series instance-attribute
sun_series = AffineTabSeriesDN(base_c0=s0, base_cn=s1, base_cd=s2, terms=(TabTermDN(amp=Fraction(-1, 720), phase=phase_sun_anomaly, table_eval_turn=eval_turn),))
sun_table instance-attribute
sun_table = QuarterWaveTable(quarter=sun_tab_quarter)
civil_jdn
civil_jdn(x: NumT) -> int

Returns the absolute discrete JDN using pure rational integer arithmetic. Completely bypasses FPU and math.floor.

eval_sunrise_lmt
eval_sunrise_lmt(t2000_tt: NumT) -> Tuple[Fraction, SunriseState]

Debug/Validation Wrapper: Traditional/Arithmetic models use a constant equinoctial dawn, completely ignoring seasonal daylight variance.

get_x_from_t2000
get_x_from_t2000(t2000: float) -> int

Inverse kinematic lookup. Returns the active absolute tithi index (x) that covers the given physical time (Days since J2000.0).

local_civil_date
local_civil_date(x: NumT) -> Fraction

For traditional engines, the affine true_date is already civil-aligned.

mean_date
mean_date(x: NumT) -> Fraction
mean_elong_tt
mean_elong_tt(t2000: NumT) -> Fraction

Rough mean elongation in unwrapped turns at time t2000.

mean_moon_tt
mean_moon_tt(t2000: NumT) -> Fraction

Rough mean moon in turns at time t2000 (Elongation + Sun).

mean_sun
mean_sun(x: NumT) -> Fraction
mean_sun_tt
mean_sun_tt(t2000: NumT) -> Fraction

Rough mean sun in turns at time t2000.

true_date
true_date(x: NumT) -> Fraction
true_elong_tt
true_elong_tt(t2000: NumT) -> Fraction

Rough true elongation in unwrapped turns at time t2000.

true_moon_tt
true_moon_tt(t2000: NumT) -> Fraction

Rough true moon in turns at time t2000 (Elongation + Sun).

true_sun
true_sun(x: NumT) -> Fraction
true_sun_tt
true_sun_tt(t2000: NumT) -> Fraction

Rough true sun in turns at time t2000.

TraditionalDayParams dataclass
a0 instance-attribute
a0: Fraction
a1 instance-attribute
a1: Fraction
a2 instance-attribute
a2: Fraction
epoch_k instance-attribute
epoch_k: int
location instance-attribute
location: LocationSpec
m0 instance-attribute
m0: Fraction
m1 instance-attribute
m1: Fraction
m2 instance-attribute
m2: Fraction
moon_tab_quarter instance-attribute
moon_tab_quarter: Tuple[int, ...]
r0 class-attribute instance-attribute
r0: Optional[Fraction] = None
r1 class-attribute instance-attribute
r1: Optional[Fraction] = None
r2 class-attribute instance-attribute
r2: Optional[Fraction] = None
s0 instance-attribute
s0: Fraction
s1 instance-attribute
s1: Fraction
s2 instance-attribute
s2: Fraction
sun_tab_quarter instance-attribute
sun_tab_quarter: Tuple[int, ...]
with_location
with_location(location: LocationSpec) -> TraditionalDayParams

Traditional engines do not use geographical coordinates for math, but we accept the location to satisfy the DayEngineProtocol and allow for theoretical reformed calendars.

frac_turn
frac_turn(val: Fraction) -> Fraction

Wraps a fractional turn to [0, 1).

caltib.engines.rational_day

caltib.engines.rational_day

High-precision rational day engine. Maps absolute tithis (x) to physical time (t2000) using continuous fractional affine series and the Picard fixed-point iteration.

RationalDayEngine

Bases: DayEngineProtocol

Evaluates high-precision calendar kinematics via Picard iteration. Fully implements DayEngineProtocol.

delta_t instance-attribute
delta_t = ConstantDeltaT(value)
elong_series instance-attribute
elong_series = AffineTabSeriesT(A=A_elong, B=B_elong, C=C_elong, terms=active_lunar + active_elong_solar)
epoch_k property
epoch_k: int
location property
location: LocationSpec

Satisfies the new location-aware protocol.

p instance-attribute
p = p
solar_series instance-attribute
solar_series = AffineTabSeriesT(A=A_sun, B=B_sun, C=C_sun, terms=active_solar)
sunrise instance-attribute
sunrise = ConstantSunrise(day_fraction)
boundary_utc
boundary_utc(x: NumT) -> Fraction

Returns Days since J2000.0 UTC for absolute tithi x.

civil_jdn
civil_jdn(x: NumT) -> int

Returns the absolute discrete JDN using pure rational integer arithmetic. Completely bypasses FPU and math.floor.

eval_sunrise_lmt
eval_sunrise_lmt(t2000_tt: NumT) -> Tuple[Fraction, SunriseState]

Debug/Validation Wrapper: Evaluates the Local Mean Time (LMT) fraction of dawn for the solar coordinates at the given continuous physical time. (e.g., 0.25 = exactly 6:00 AM LMT). Returns a tuple: (LMT Fraction, sunrise_state).

get_x_from_t2000
get_x_from_t2000(t2000: float) -> int

Inverse kinematic lookup. Returns the active absolute tithi index (x) that covers the given physical time (Days since J2000.0).

local_civil_date
local_civil_date(x: NumT) -> Fraction
mean_date
mean_date(x: NumT) -> Fraction

Returns the mean physical time (Days since J2000.0 TT) for absolute tithi x. Inverts the linear mean elongation system: E_mean(t) = A + B*t = x/30

mean_elong_tt
mean_elong_tt(t2000: NumT) -> Fraction
mean_moon_tt
mean_moon_tt(t2000: NumT) -> Fraction
mean_sun
mean_sun(x: NumT) -> Fraction

Mean solar longitude (turns) at the physical moment of tithi x.

mean_sun_tt
mean_sun_tt(t2000: NumT) -> Fraction
true_date
true_date(x: NumT) -> Fraction

Returns the true physical time (Days since J2000.0 TT) for absolute tithi x. Uses Picard iteration to solve: E_true(t) = x/30.

true_elong_tt
true_elong_tt(t2000: NumT) -> Fraction
true_moon_tt
true_moon_tt(t2000: NumT) -> Fraction
true_sun
true_sun(x: NumT) -> Fraction

True solar longitude (turns) at the physical moment of tithi x.

true_sun_tt
true_sun_tt(t2000: NumT) -> Fraction
RationalDayParams dataclass
A_elong instance-attribute
A_elong: Fraction
A_sun instance-attribute
A_sun: Fraction
B_elong instance-attribute
B_elong: Fraction
B_sun instance-attribute
B_sun: Fraction
C_elong instance-attribute
C_elong: Fraction
C_sun instance-attribute
C_sun: Fraction
delta_t instance-attribute
delta_t: DeltaTDef
epoch_k instance-attribute
epoch_k: int
invB_elong_prec class-attribute instance-attribute
invB_elong_prec: Optional[Fraction] = None
iterations instance-attribute
iterations: int
location instance-attribute
location: LocationSpec
lunar_terms instance-attribute
lunar_terms: Tuple[TermDef, ...]
moon_tab_quarter instance-attribute
moon_tab_quarter: Tuple[int, ...]
solar_terms instance-attribute
solar_terms: Tuple[TermDef, ...]
sun_tab_quarter instance-attribute
sun_tab_quarter: Tuple[int, ...]
sunrise instance-attribute
sunrise: SunriseDef
with_location
with_location(new_loc: LocationSpec) -> RationalDayParams

Rebuilds the parameters for a new location.

frac_turn
frac_turn(x: Fraction) -> Fraction

Wraps a fractional turn to [0, 1).

caltib.engines.fp_day

caltib.engines.fp_day

High-performance floating-point day engine. Strictly deterministic, FMA-free execution relying purely on J2000.0 hex-floats.

FloatDayEngine

Bases: DayEngineProtocol

delta_t instance-attribute
delta_t = FloatDeltaT(a=a, b=b, c=c, y0=y0)
elong_series instance-attribute
elong_series = FloatFourierSeries(A=A_elong, B=B_elong, C=C_elong, static_terms=elong_static, dynamic_terms=elong_dynamic, poly=sine_poly)
epoch_k property
epoch_k: int
epoch_offset_x property
epoch_offset_x: int
location property
location: LocationSpec
p instance-attribute
p = p
solar_series instance-attribute
solar_series = FloatFourierSeries(A=A_sun, B=B_sun, C=C_sun, static_terms=solar_static, dynamic_terms=solar_dynamic, poly=sine_poly)
sunrise instance-attribute
sunrise = FloatSunrise(h0_turn=h0_turn, eps_turn=eps_turn, sine_poly=QuarterWavePolynomial(coeffs=sine_poly_coeffs), atan_poly=ArctanPolynomial(coeffs=atan_poly_coeffs), day_fraction=day_fraction)
boundary_utc
boundary_utc(x: NumT) -> float
civil_jdn
civil_jdn(x: NumT) -> int
eval_sunrise_lmt
eval_sunrise_lmt(t2000_tt: NumT) -> Tuple[float, SunriseState]
get_x_from_t2000
get_x_from_t2000(t2000: float) -> int

Inverse lookup mapping physical time back to the active tithi index.

local_civil_date
local_civil_date(x: NumT) -> float
mean_date
mean_date(x: NumT) -> float

Solves E(t) = (x + offset) / 30 for the base quadratic.

mean_elong_tt
mean_elong_tt(t2000: NumT) -> float
mean_moon_tt
mean_moon_tt(t2000: NumT) -> float
mean_sun
mean_sun(x: NumT) -> float
mean_sun_tt
mean_sun_tt(t2000: NumT) -> float
true_date
true_date(x: NumT) -> float

Solves E_true(t) = (x + offset) / 30 via Picard Iteration.

true_elong_tt
true_elong_tt(t2000: NumT) -> float
true_moon_tt
true_moon_tt(t2000: NumT) -> float
true_sun
true_sun(x: NumT) -> float
true_sun_tt
true_sun_tt(t2000: NumT) -> float
FloatDayParams dataclass
A_elong instance-attribute
A_elong: float
A_sun instance-attribute
A_sun: float
B_elong instance-attribute
B_elong: float
B_sun instance-attribute
B_sun: float
C_elong instance-attribute
C_elong: float
C_sun instance-attribute
C_sun: float
delta_t instance-attribute
delta_t: FloatDeltaTDef
elong_dynamic instance-attribute
elong_dynamic: Tuple[FloatTermDef, ...]
elong_static instance-attribute
elong_static: Tuple[FloatTermDef, ...]
epoch_k instance-attribute
epoch_k: int
iterations instance-attribute
iterations: int
location instance-attribute
location: LocationSpec
sine_poly_coeffs instance-attribute
sine_poly_coeffs: Tuple[float, ...]
solar_dynamic instance-attribute
solar_dynamic: Tuple[FloatTermDef, ...]
solar_static instance-attribute
solar_static: Tuple[FloatTermDef, ...]
sunrise instance-attribute
sunrise: FloatSunriseDef
with_location
with_location(new_loc: LocationSpec) -> FloatDayParams

Creates a new params instance calibrated for a different location.

Experimental: L6 Engine

The following l6.engine module is under development.

caltib.engines.l6.engine

Optional ephemeris-backed L6 engine placeholder.

This module is only importable/usable if ephemeris extras are installed and configured.

build_l6_engine
build_l6_engine()

Analytical Astronomical Reference (Ground Truth)

caltib.reference.solar

SolarCoordinates dataclass

True and apparent solar coordinates (degrees).

L_app_deg instance-attribute
L_app_deg: float
L_true_deg instance-attribute
L_true_deg: float
SunriseApparent dataclass

Output for the Local Apparent Time of sunrise/sunset.

rise_app_hours instance-attribute
rise_app_hours: float
set_app_hours instance-attribute
set_app_hours: float
state class-attribute instance-attribute
state: SunriseState = NORMAL
SunriseCivil dataclass

Output for the uniform civil clock time (UTC) of sunrise/sunset.

rise_utc_hours instance-attribute
rise_utc_hours: float
set_utc_hours instance-attribute
set_utc_hours: float
state class-attribute instance-attribute
state: SunriseState = NORMAL
equation_of_time_minutes
equation_of_time_minutes(jd_tt: float, eps_model: Literal['iau2000', 'iau1980'] = 'iau2000') -> float

(C.13) Computes the Equation of Time (EOT) in minutes.

solar_declination_deg
solar_declination_deg(L_app_deg: float, eps_deg: float) -> float

(C.10) Solar declination from apparent longitude and obliquity.

solar_longitude
solar_longitude(jd_tt: float) -> SolarCoordinates

Computes true and apparent solar longitude for a given JD(TT) using truncated series expansions (accurate to ~0.01 deg).

sunrise_apparent_time
sunrise_apparent_time(jd_tt: float, lat_deg: float, h0_deg: float = -0.833, eps_model: Literal['iau2000', 'iau1980'] = 'iau2000') -> SunriseApparent

(C.11 & C.12) Computes sunrise and sunset in Local Apparent Solar Time (hours). Returns None if the sun does not rise or set (polar day/night).

sunrise_sunset_utc
sunrise_sunset_utc(jd_utc_noon: float, lat_deg: float, lon_deg_east: float, eps_model: Literal['iau2000', 'iau1980'] = 'iau2000', h0_deg: float = -0.833) -> SunriseCivil

(C.15) Iterative approach to compute accurate sunrise/sunset times in UTC hours. Expects jd_utc_noon to be the UTC JD of local noon (or 12:00 UTC for approximation).

caltib.reference.lunar

LunarCoordinates dataclass

True and apparent lunar coordinates (degrees).

B_true_deg instance-attribute
B_true_deg: float
L_app_deg instance-attribute
L_app_deg: float
L_true_deg instance-attribute
L_true_deg: float
R_true_au class-attribute instance-attribute
R_true_au: float = 0.0025695
lunar_position
lunar_position(jd_tt: float) -> LunarCoordinates

Computes lunar true/apparent longitude and true latitude for a given JD(TT).

caltib.reference.time_scales

T_from_jd_tt
T_from_jd_tt(jd_tt: float) -> float

T = (JD_TT - 2451545.0) / 36525 Julian centuries from J2000.0 in TT.

date_to_jdn
date_to_jdn(d: date) -> int

Gregorian date -> JDN (proleptic Gregorian). Time-zone/blind: purely civil date.

datetime_utc_to_jd
datetime_utc_to_jd(dt: datetime) -> float

datetime -> JD (UTC). Requires timezone-aware UTC datetime.

decimal_year_from_date
decimal_year_from_date(d: date) -> float

Convert a date to a decimal year, using day-of-year / year-length.

jd_to_datetime_utc
jd_to_datetime_utc(jd: float) -> datetime

JD (UTC) -> timezone-aware datetime in UTC.

jd_to_jdn
jd_to_jdn(jd: float) -> int

Convert Julian Date (JD, days from noon) to Julian Day Number (JDN, integer day starting at midnight).

Standard relation

JDN = floor(JD + 0.5)

jd_tt_from_T
jd_tt_from_T(T: float) -> float

JD_TT = 2451545.0 + 36525*T

jd_tt_to_jd_utc
jd_tt_to_jd_utc(jd_tt: float, *, ut1_utc_seconds: float = 0.0) -> float

Approximate inverse of jd_utc_to_jd_tt.

Solve

jd_tt = jd_utc + (ut1_utc + ΔT(y(jd_utc)))/86400

We do 2 fixed-point iterations (enough for sub-second consistency given ΔT varies slowly).

jd_utc_to_jd_tt
jd_utc_to_jd_tt(jd_utc: float, *, ut1_utc_seconds: float = 0.0) -> float

Convert JD(UTC) to JD(TT), using: TT = UT1 + ΔT UT1 = UTC + (UT1-UTC)

We take UT1-UTC from caller (default 0). For high-precision work, supply it from IERS.

ΔT is obtained from reference model delta_t_seconds(decimal_year).

jdn_to_date
jdn_to_date(jdn: int) -> date

JDN -> Gregorian date (proleptic Gregorian).

jdn_to_jd
jdn_to_jd(jdn: int) -> float

Convert Julian Day Number (JDN) to the JD at midnight UTC of that day. Since JD starts at noon, midnight is JDN - 0.5.

lmt_offset_hours
lmt_offset_hours(longitude_deg_east: float) -> float

Offset (hours) between UTC and Local Mean Time at given longitude. Positive east longitudes mean LMT ahead of UTC. 360° -> 24h => 1° -> 4 minutes.

lmt_to_utc
lmt_to_utc(dt_lmt: datetime, longitude_deg_east: float) -> datetime

Local Mean Time -> UTC at longitude (degrees east).

local_to_utc
local_to_utc(dt_local: datetime, tz_offset_hours: float) -> datetime

Local civil time -> UTC, given a fixed timezone offset (hours). Example: tz_offset_hours = -5 for EST (standard time).

utc_to_lmt
utc_to_lmt(dt_utc: datetime, longitude_deg_east: float) -> datetime

UTC -> Local Mean Time at longitude (degrees east).

utc_to_local
utc_to_local(dt_utc: datetime, tz_offset_hours: float) -> datetime

UTC -> local civil time, given a fixed timezone offset (hours).

caltib.reference.astro_args

FundamentalArgs dataclass

Fundamental arguments in turns and degrees.

D_deg property
D_deg: float
D_turn instance-attribute
D_turn: float
F_deg property
F_deg: float
F_turn instance-attribute
F_turn: float
Lp_deg property
Lp_deg: float
Lp_turn instance-attribute
Lp_turn: float
M_deg property
M_deg: float
M_turn instance-attribute
M_turn: float
Mp_deg property
Mp_deg: float
Mp_turn instance-attribute
Mp_turn: float
Omega_deg property
Omega_deg: float
Omega_turn instance-attribute
Omega_turn: float
SolarMean dataclass
L0_deg property
L0_deg: float
L0_turn instance-attribute
L0_turn: float
M_deg property
M_deg: float
M_turn instance-attribute
M_turn: float
T_centuries
T_centuries(jd_tt: float) -> float

Julian centuries from J2000.0 in TT.

anomalistic_month_days
anomalistic_month_days(T: float) -> float

Mean anomalistic month length in days.

Uses the ELP2000/Meeus polynomial for consistency with the fundamental argument M' (Moon's mean anomaly): 27.554549878 - 1.0092e-6 T - 3.48e-9 T^2

anomalistic_month_days_jd
anomalistic_month_days_jd(jd_tt: float) -> float
anomalistic_year_days
anomalistic_year_days(T: float) -> float

Mean anomalistic year length in days.

Uses the standard Laskar/Meeus polynomial for consistency with the fundamental argument M (Sun's mean anomaly): 365.259635864 + 3.04e-6 T + 1.52e-8 T^2

anomalistic_year_days_jd
anomalistic_year_days_jd(jd_tt: float) -> float
apply_matrix
apply_matrix(M: tuple[tuple[float, ...], ...], v: tuple[float, float, float]) -> tuple[float, float, float]

Applies a 3x3 matrix to a 3D vector.

arcsec_to_deg
arcsec_to_deg(arcsec: float) -> float
arcsec_to_rad
arcsec_to_rad(arcsec: float) -> float
arcsec_to_turn
arcsec_to_turn(arcsec: float) -> float
deg_to_turn
deg_to_turn(deg: float) -> float
eccentricity_factor
eccentricity_factor(T: float) -> float

Eccentricity factor E for the Earth's orbit. Used to scale analytical lunar perturbations that depend on the Sun's mean anomaly.

frac01
frac01(x: float) -> float

Return fractional part in [0,1).

fundamental_args
fundamental_args(T: float) -> FundamentalArgs

Fundamental arguments (mean elements) in turns, wrapped to [0,1).

Coefficients match the standard Meeus/ELP-style polynomials: L' = 218.3164477 + 481267.88123421 T - 0.0015786 T^2 + T^3/538841 - T^4/65194000 D = 297.8501921 + 445267.1114034 T - 0.0018819 T^2 + T^3/545868 - T^4/113065000 M = 357.5291092 + 35999.0502909 T - 0.0001536 T^2 + T^3/24490000 M' = 134.9633964 + 477198.8675055 T + 0.0087414 T^2 + T^3/69699 - T^4/14712000 F = 93.2720950 + 483202.0175233 T - 0.0036539 T^2 - T^3/3526000 + T^4/863310000

(The exact higher-order terms are usually negligible for your L1–L5 target, but included here since you asked for “more accurate” fundamentals.)

fundamental_args_jd
fundamental_args_jd(jd_tt: float) -> FundamentalArgs
jde_mean_new_moon
jde_mean_new_moon(k: float) -> float

Mean Julian Ephemeris Day (TT) of the k-th new moon relative to 2000.

Commonly cited Meeus mean-phase polynomial

JDE = 2451550.09766 + 29.530588861 k + 0.00015437 T^2 - 0.000000150 T^3 + 0.00000000073 T^4, T = k / 1236.85.

matrix_eq_j2000_to_ecl_date
matrix_eq_j2000_to_ecl_date(T: float) -> tuple[tuple[float, ...], ...]

Computes the rigorous 3x3 rotation matrix to transform a vector from the Equatorial J2000 frame (ICRF) to the Mean Ecliptic of Date.

mean_obliquity_deg
mean_obliquity_deg(T: float, model: Literal['iau2000', 'iau1980'] = 'iau2000') -> float

Mean obliquity of the ecliptic (degrees).

  • 'iau2000' (often cited IAU2000/2006 form): eps = 84381.406" - 46.836769"T - 0.0001831"T^2 + 0.00200340"T^3 - 0.000000576"T^4 - 0.0000000434"T^5
  • 'iau1980' (Lieske/IAU1980 cubic seen in your screenshot): eps = 23°26'21.448" - 46.8150"T - 0.00059"T^2 + 0.001813"T^3
mean_obliquity_deg_jd
mean_obliquity_deg_jd(jd_tt: float, model: Literal['iau2000', 'iau1980'] = 'iau2000') -> float
mean_obliquity_turn
mean_obliquity_turn(T: float, model: Literal['iau2000', 'iau1980'] = 'iau2000') -> float
solar_mean_elements
solar_mean_elements(T: float) -> SolarMean

Meeus-style geometric mean longitude L0 and mean anomaly M (degrees -> turns).

solar_mean_elements_jd
solar_mean_elements_jd(jd_tt: float) -> SolarMean
synodic_month_days
synodic_month_days(T: float) -> float

Mean synodic month length in days.

Uses the ELP2000/Meeus polynomial for strict consistency with the fundamental argument D (mean elongation): 29.5305888531 + 2.1621e-7 T - 3.64e-10 T^2

synodic_month_days_jd
synodic_month_days_jd(jd_tt: float) -> float
tropical_year_days
tropical_year_days(T: float) -> float

Mean tropical year length in ephemeris days (86400 SI seconds), Laskar-style.

Matches the commonly cited polynomial

365.2421896698 - 6.15359e-6 T - 7.29e-10 T^2 + 2.64e-10 T^3

with T in Julian centuries from J2000.0.

tropical_year_days_jd
tropical_year_days_jd(jd_tt: float) -> float
turn_to_deg
turn_to_deg(turn: float) -> float
wrap180
wrap180(deg: float) -> float

Wraps an angle in degrees to the range [-180.0, 180.0).

wrap_deg
wrap_deg(x_deg: float) -> float

Wrap degrees to [0,360).

wrap_turn
wrap_turn(x_turn: float) -> float

Wrap turns to [0,1).