"""EpochConverter module containing class EpochConverter.""" import numpy as np import matplotlib.units as units import matplotlib.dates as date_ticker __all__ = ['EpochConverter'] class EpochConverter(units.ConversionInterface): """: A matplotlib converter class. Provides matplotlib conversion functionality for Monte Epoch and Duration classes. """ # julian date reference for "Jan 1, 0001" minus 1 day because # matplotlib really wants "Jan 0, 0001" jdRef = 1721425.5 - 1 @staticmethod def axisinfo(unit, axis): """: Returns information on how to handle an axis that has Epoch data. = INPUT VARIABLES - unit The units to use for a axis with Epoch data. = RETURN VALUE - Returns a matplotlib AxisInfo data structure that contains minor/major formatters, major/minor locators, and default label information. """ majloc = date_ticker.AutoDateLocator() majfmt = date_ticker.AutoDateFormatter(majloc) return units.AxisInfo(majloc=majloc, majfmt=majfmt, label=unit) @staticmethod def float2epoch(value, unit): """: Convert a matplotlib floating-point date into an Epoch of the specified units. = INPUT VARIABLES - value The matplotlib floating-point date. - unit The unit system to use for the Epoch. = RETURN VALUE - Returns the value converted to an Epoch in the specified time system. """ # Delay-load due to circular dependencies. import matplotlib.testing.jpl_units as U secPastRef = value * 86400.0 * U.UnitDbl(1.0, 'sec') return U.Epoch(unit, secPastRef, EpochConverter.jdRef) @staticmethod def epoch2float(value, unit): """: Convert an Epoch value to a float suitable for plotting as a python datetime object. = INPUT VARIABLES - value An Epoch or list of Epochs that need to be converted. - unit The units to use for an axis with Epoch data. = RETURN VALUE - Returns the value parameter converted to floats. """ return value.julianDate(unit) - EpochConverter.jdRef @staticmethod def duration2float(value): """: Convert a Duration value to a float suitable for plotting as a python datetime object. = INPUT VARIABLES - value A Duration or list of Durations that need to be converted. = RETURN VALUE - Returns the value parameter converted to floats. """ return value.seconds() / 86400.0 @staticmethod def convert(value, unit, axis): """: Convert value using unit to a float. If value is a sequence, return the converted sequence. = INPUT VARIABLES - value The value or list of values that need to be converted. - unit The units to use for an axis with Epoch data. = RETURN VALUE - Returns the value parameter converted to floats. """ # Delay-load due to circular dependencies. import matplotlib.testing.jpl_units as U isNotEpoch = True isDuration = False if np.iterable(value) and not isinstance(value, str): if len(value) == 0: return [] else: return [EpochConverter.convert(x, unit, axis) for x in value] if isinstance(value, U.Epoch): isNotEpoch = False elif isinstance(value, U.Duration): isDuration = True if (isNotEpoch and not isDuration and units.ConversionInterface.is_numlike(value)): return value if unit is None: unit = EpochConverter.default_units(value, axis) if isDuration: return EpochConverter.duration2float(value) else: return EpochConverter.epoch2float(value, unit) @staticmethod def default_units(value, axis): """: Return the default unit for value, or None. = INPUT VARIABLES - value The value or list of values that need units. = RETURN VALUE - Returns the default units to use for value. """ frame = None if np.iterable(value) and not isinstance(value, str): return EpochConverter.default_units(value[0], axis) else: frame = value.frame() return frame