From 8615a2548a8b20364b338685cef4cdac18c00f82 Mon Sep 17 00:00:00 2001 From: Don Cross Date: Thu, 27 Jun 2019 14:54:49 -0400 Subject: [PATCH] Huge performance boost to Python code: re-use e_tilt calculations. Calculate _e_tilt() no more than once per Time instance. Cache the value in the Time instance and re-use it. This reduced astro_check time from 5.0 minutes to 2.0 minutes. --- generate/template/astronomy.py | 13 +++++++++++-- source/python/astronomy.py | 13 +++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/generate/template/astronomy.py b/generate/template/astronomy.py index eb5d9e26..4f396e1f 100644 --- a/generate/template/astronomy.py +++ b/generate/template/astronomy.py @@ -168,6 +168,7 @@ class Time: def __init__(self, ut): self.ut = ut self.tt = _TerrestrialTime(ut) + self.etilt = None @staticmethod def Make(year, month, day, hour, minute, second): @@ -193,6 +194,14 @@ class Time: def Utc(self): return _EPOCH + datetime.timedelta(days=self.ut) + def _etilt(self): + # Calculates precession and nutation of the Earth's axis. + # The calculations are very expensive, so lazy-evaluate and cache + # the result inside this Time object. + if self.etilt is None: + self.etilt = _e_tilt(self) + return self.etilt + class Observer: def __init__(self, latitude, longitude, height=0): @@ -503,7 +512,7 @@ def _vector2radec(pos): def _nutation(time, direction, inpos): - tilt = _e_tilt(time) + tilt = time._etilt() oblm = tilt.mobl * _DEG2RAD oblt = tilt.tobl * _DEG2RAD psi = tilt.dpsi * _ASEC2RAD @@ -550,7 +559,7 @@ def _era(time): # Earth Rotation Angle def _sidereal_time(time): t = time.tt / 36525.0 - eqeq = 15.0 * _e_tilt(time).ee # Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) + eqeq = 15.0 * time._etilt().ee # Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) theta = _era(time) st = (eqeq + 0.014506 + (((( - 0.0000000368 * t diff --git a/source/python/astronomy.py b/source/python/astronomy.py index f9bf497a..4ccb2cd1 100644 --- a/source/python/astronomy.py +++ b/source/python/astronomy.py @@ -259,6 +259,7 @@ class Time: def __init__(self, ut): self.ut = ut self.tt = _TerrestrialTime(ut) + self.etilt = None @staticmethod def Make(year, month, day, hour, minute, second): @@ -284,6 +285,14 @@ class Time: def Utc(self): return _EPOCH + datetime.timedelta(days=self.ut) + def _etilt(self): + # Calculates precession and nutation of the Earth's axis. + # The calculations are very expensive, so lazy-evaluate and cache + # the result inside this Time object. + if self.etilt is None: + self.etilt = _e_tilt(self) + return self.etilt + class Observer: def __init__(self, latitude, longitude, height=0): @@ -594,7 +603,7 @@ def _vector2radec(pos): def _nutation(time, direction, inpos): - tilt = _e_tilt(time) + tilt = time._etilt() oblm = tilt.mobl * _DEG2RAD oblt = tilt.tobl * _DEG2RAD psi = tilt.dpsi * _ASEC2RAD @@ -641,7 +650,7 @@ def _era(time): # Earth Rotation Angle def _sidereal_time(time): t = time.tt / 36525.0 - eqeq = 15.0 * _e_tilt(time).ee # Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) + eqeq = 15.0 * time._etilt().ee # Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) theta = _era(time) st = (eqeq + 0.014506 + (((( - 0.0000000368 * t