Files
astronomy/demo/python/constellation.py
Don Cross 871c26abde Enforce strict type checking in all Python demo programs.
Use mypy to check all Python demo programs.
Updated the demos to pass type checking.
There were a couple of small mistakes found, so this was worth the effort.
2023-10-03 11:49:04 -04:00

83 lines
3.2 KiB
Python
Executable File

#!/usr/bin/env python3
#
# constellation.py - Don Cross - 2021-04-30 Fri
#
# Searches for the moon moving into different constellations.
# This is an example of doing a search for the time of transition
# of a body from one constellation to another.
#
import sys
from astronomy import Time, Body, Constellation, ConstellationInfo, GeoVector, EquatorFromVector
from typing import Tuple
#------------------------------------------------------------------------------
def BodyConstellation(body: Body, time: Time) -> ConstellationInfo:
vec = GeoVector(body, time, False)
equ = EquatorFromVector(vec)
return Constellation(equ.ra, equ.dec)
#------------------------------------------------------------------------------
def FindConstellationChange(body: Body, c1: ConstellationInfo, t1: Time, t2: Time) -> Tuple[Time, ConstellationInfo]:
# Do a binary search to find what time between t1 and t2
# is the boundary between being in constellation c1 and some other
# constellation. Return the tuple (tx, cx), where tx is the
# transition time, and cx is the constellation we are moving into.
tolerance = 0.1 / (24.0 * 3600.0) # one tenth of a second
while True:
dt = t2.ut - t1.ut
tx = t1.AddDays(dt/2)
cx = BodyConstellation(body, tx)
if cx.symbol == c1.symbol:
t1 = tx
else:
if dt < tolerance:
# Always end the search inside the new constellation.
return (tx, cx)
t2 = tx
#------------------------------------------------------------------------------
def FindConstellationChanges(body: Body, startTime: Time, stopTime: Time, dayIncrement: float) -> int:
t1 = startTime
c1 = BodyConstellation(body, t1)
while t1 < stopTime:
t2 = t1.AddDays(dayIncrement)
c2 = BodyConstellation(body, t2)
if c1.symbol != c2.symbol:
# The body moved from one constellation to another during this time step.
# Narrow in on the exact moment by doing a binary search.
tx, cx = FindConstellationChange(body, c1, t1, t2)
print('{} : {} leaves {} and enters {}.'.format(tx, body.name, c1.name, cx.name))
c1 = cx
t1 = tx
else:
# No constellation change in this time step. Try again on the next time step.
c1 = c2
t1 = t2
return 0
#------------------------------------------------------------------------------
if __name__ == '__main__':
if len(sys.argv) == 1:
startTime = Time.Now()
elif len(sys.argv) == 2:
startTime = Time.Parse(sys.argv[1])
else:
print('USAGE: {} [yyyy-mm-ddThh:mm:ssZ]'.format(sys.argv[0]))
sys.exit(1)
stopTime = startTime.AddDays(30.0)
# There are 12 zodiac constellations, and the moon takes
# about 27.3 days in its sidereal period. Therefore, there
# are roughly 2.2 days per constellation. We will sample
# the Moon's constellation once every 0.1 days to reduce
# the chance of missing a brief transition through a small
# part of a constellation.
dayIncrement = 0.1
rc = FindConstellationChanges(Body.Moon, startTime, stopTime, dayIncrement)
sys.exit(rc)