caput.time

Routines for calculation and of solar and sidereal times.

This module can:

  • Convert between Python datetime, UNIX times (as floats), and Skyfield time objects.

  • Determine the number of leap seconds in an interval (thanks Skyfield!)

  • Calculate the Earth Rotation Angle (the successor to Sidereal Time)

  • Determine various local time standards (Local Stellar Angle and Day)

  • Generate a nice wrapper for Skyfield to ease the loading of required data.

Time Utilities

Time conversion routine which are location independent.

Local Time Utilities

Routines which are location specific are grouped into the location aware class Observer.

This class can be used to calculate Local Stellar Angle (LSA), and the Local Stellar Day (LSD). LSA is an equivalent to the Local Sidereal Time based around the Earth Rotation Angle instead of the Greenwich Sidereal Time. This is defined as:

\[\mathrm{LSA} = \theta + \lambda\]

where \(\theta\) is the Earth Rotation Angle, and \(\lambda\) is the longitude. Local Stellar Day counts the stellar days (i.e. the number of cycles of LSA) that have occured since a given start epoch. This means that the fractional part is simply the LSA rescaled., with the integer part the number of stellar days elapsed since that epoch. This requires the specification of the start epoch, which is determined from a given UNIX time, the code simply picks the first time \(\mathrm{LSA} = 0\) after this time.

Note that the quantities LSA and LSD are not really used elsewhere. However, the concept of a Stellar Day as a length of time is well established (IERS constants), and the Stellar Angle is an older term for the Earth Rotation Angle (NFA Glossary).

Skyfield Interface

This module provides an interface to Skyfield which stores the required datasets (timescale data and an ephemeris) in a fixed location. The location is determined by the following (in order):

  • As the wrapper is initialised by passing in a path=<path> option.

  • By setting the environment variable CAPUT_SKYFIELD_PATH

  • If neither of the above is set, the data is place in <path to caput>/caput/data/

Constants

SIDEREAL_S

Number of SI seconds in a sidereal second [s/sidereal s].

STELLAR_S

Approximate number of SI seconds in a stellar second (i.e. 1/86400 of a stellar day) [s/stellar s].

Why not Sidereal Time?

Sidereal time is a long established and well known quantity that is very similar to the Earth Rotation Angle (and the derived quantities, LSA and LSD). The reason we don’t use that is that Sidereal Time is essentially the Earth’s rotation measured with respect to the vernal equinox, but this quantity moves significantly with respect to the fixed frame due to precession of the Earth’s pole.

The Earth Rotation Angle is measured with respect to the Celestial Intermediate Origin (CIO), which essentially moves the minimal amount as the Earth precesses to remain on the celestial equator. For experiments like CHIME which map the sky as a function of the Earth’s rotation, this gives the minimal coordinate shifts when combining maps made on different days.

See USNO Circular 179 for more details about the CIO based coordinates.

Accuracy

Conversions between time standards (as opposed to representations of UTC) in this module are mostly handled by Skyfield, which has a comprehensive and modern handling of the various effects. This includes leap seconds, which PyEphem mostly ignored, just pretending that UTC and UT1 were equivalent.

Skyfield uses Julian Dates for its internal representations. For a double precision floating point (np.float64), the effective precision on calculations is around 30 us. A technical note discussing this further is available here. Most conversions should be accurate to around this accuracy 0.1 ms. However, the era_to_unix routine (and related routines), are accurate to only around 5 ms at the moment as they ignore the difference in time between the Sidereal day, and a complete cycle of ERA.

class caput.time.Observer(lon=0.0, lat=0.0, alt=0.0, lsd_start=None, sf_wrapper=None)[source]

Bases: object

Time calculations for a local observer.

Parameters
  • longitude (float) – Longitude of observer in degrees.

  • latitude (float) – Latitude of observer in degrees.

  • altitude (float, optional) – Altitude of observer in metres.

  • lsd_start (float or datetime, optional) – The zeroth LSD. If not set use the J2000 epoch start.

  • sf_wrapper – (optional) Skyfield wrapper

longitude

Longitude of observer in degrees.

Type

float

latitude

Latitude of observer in degrees.

Type

float

altitude

Altitude of observer in metres.

Type

float

lsd_start_day

UNIX time on the zeroth LSD. The actual zero point is the first time of LSA = 0.0 after the lsd_start_day.

Type

float

lsa

Calculate the Local Stellar Angle.

This is the angle between the current meridian and the CIO, i.e. the ERA + longitude.

Parameters

time (float) – Unix time.

Returns

lsa

Return type

float

lsa_to_unix[source]

Convert a Local Stellar Angle (LSA) on a given day to a UNIX time.

Parameters
  • lsa (scalar or np.ndarray) – Local Earth Rotation Angle degrees to convert.

  • time0 (scalar or np.ndarray) – An earlier time within 24 sidereal hours. For example, the start of the solar day of the observation.

Returns

time – Corresponding UNIX time.

Return type

scalar or np.ndarray

lsd

Calculate the Local Stellar Day (LSD) corresponding to the given time.

The Local Earth Rotation Day is the number of cycles of Earth Rotation Angle that have passed since the specified zero epoch (including fractional cycles).

Parameters

time (float or array of) – UNIX time

Returns

lsd

Return type

float or array of

lsd_to_unix[source]

Calculate the UNIX time corresponding to a given LSD.

Parameters

lsd (float or array of) –

Returns

time – UNIX time

Return type

float or array of

lsd_zero()[source]

Return the zero point of LSD as a UNIX time.

Returns

lsd_zero

Return type

float

lst

Calculate the apparent Local Sidereal Time for the given UNIX time.

Parameters

unix (float or array of) – UNIX time in floating point seconds since the epoch.

Returns

lst – The apparent LST in degrees.

Return type

float or array of

rise_set_times(source, t0, t1=None, step=None, diameter=0.0)[source]

Find all times a sources rises or sets in an interval.

Parameters
  • source (skyfield source) – The source we are calculating the rising and setting of.

  • t0 (float unix time, or datetime) – The start time to search for. Any type that be converted to a UNIX time by caput.

  • t1 (float unix time, or datetime, optional) – The end time of the search interval. If not set, this is 1 day after the start time t0.

  • step (float or None, optional) – The initial search step in days. This is used to find the approximate times of risings and settings, and should be set to something less than the spacing between events. If None is passed, an initial search step of 0.2 days, or else one fifth of the specified interval, is used, whichever is smaller.

  • diameter (float) – The size of the source in degrees. Use this to ensure the whole source is below the horizon. Also, if the local horizon is higher (i.e. mountains), this can be set to a negative value to account for this.

Returns

  • times (np.ndarray) – Source rise/set times as UNIX epoch times.

  • rising (np.ndarray) – Boolean array of whether the time corresponds to a rising (True) or setting (False).

rise_times(source, t0, t1=None, step=None, diameter=0.0)[source]

Find all times a sources rises in an interval.

Parameters
  • source (skyfield source) – The source we are calculating the rising of.

  • t0 (float unix time, or datetime) – The start time to search for. Any type that be converted to a UNIX time by caput.

  • t1 (float unix time, or datetime, optional) – The end time of the search interval. If not set, this is 1 day after the start time t0.

  • step (float or None, optional) – The initial search step in days. This is used to find the approximate times of rising, and should be set to something less than the spacing between events. If None is passed, an initial search step of 0.2 days, or else one fifth of the specified interval, is used, whichever is smaller.

  • diameter (float) – The size of the source in degrees. Use this to ensure the whole source is below the horizon. Also, if the local horizon is higher (i.e. mountains), this can be set to a negative value to account for this.

Returns

times – Source rise times as UNIX epoch times.

Return type

np.ndarray

set_times(source, t0, t1=None, step=None, diameter=0.0)[source]

Find all times a sources sets in an interval.

Parameters
  • source (skyfield source) – The source we are calculating the setting of.

  • t0 (float unix time, or datetime) – The start time to search for. Any type that be converted to a UNIX time by caput.

  • t1 (float unix time, or datetime, optional) – The end time of the search interval. If not set, this is 1 day after the start time t0.

  • step (float or None, optional) – The initial search step in days. This is used to find the approximate times of setting, and should be set to something less than the spacing between events. If None is passed, an initial search step of 0.2 days, or else one fifth of the specified interval, is used, whichever is smaller.

  • diameter (float) – The size of the source in degrees. Use this to ensure the whole source is below the horizon. Also, if the local horizon is higher (i.e. mountains), this can be set to a negative value to account for this.

Returns

times – Source rise times as UNIX epoch times.

Return type

np.ndarray

skyfield_obs()[source]

Create a Skyfield topos object for the current location.

Returns

obs

Return type

skyfield.toposlib.Topos

transit_RA[source]

Transiting RA for the observer at given Unix Time.

Because the RA is defined with respect to the specified epoch (J2000 by default), the elevation actually matters here. The elevation of the equator is used, which minimizes this effect.

Parameters

time (float or array of floats) – Time as specified by the Unix/POSIX time.

Returns

transit_RA – Transiting RA in degrees.

Return type

float or array of floats

Notes

It is not clear that this calculation includes nutation and stellar aberration. See the discussion on stackoverflow. Some testing does seem to indicate that these effects are accounted for.

This calculates the RA in the given epoch which by default is J2000, but it might be more appropriate to use an epoch that is closer to the observation time. The mismatch in the celestial poles is not insignificant (~5 arcmin from J2000 to J2016).

PyEphem uses all geocentric latitudes, which I don’t think affects this calculation.

transit_times(source, t0, t1=None, step=None, lower=False, return_dec=False)[source]

Find the transit times of the given source in an interval.

Parameters
  • source (skyfield source or float) – The source we are calculating the transit of. This can be any body skyfield can observe, such as a star (skyfield.api.Star), planet or moon (skyfield.vectorlib.VectorSum or skyfield.jpllib.ChebyshevPosition). Additionally if a float is passed, this is equivalent to a body with ICRS RA given by the float, and DEC=0.

  • t0 (float unix time, or datetime) – The start time to search for. Any type that can be converted to a UNIX time by caput.

  • t1 (float unix time, or datetime, optional) – The end time of the search interval. If not set, this is 1 day after the start time t0.

  • step (float or None, optional) – The initial search step in days. This is used to find the approximate times of transit, and should be set to something less than the spacing between events. If None is passed, an initial search step of 0.2 days, or else one fifth of the specified interval, is used, whichever is smaller.

  • lower (bool, optional) – By default this only returns the upper (regular) transit. This will cause lower transits to be returned instead.

  • return_dec (bool, optional) – If set, also return the declination of the source at transit.

Returns

  • times (np.ndarray) – UNIX times of transits.

  • dec (np.ndarray) – Only returned if return_dec is set. Declination of source at transit.

unix_to_lsa[source]

Calculate the Local Stellar Angle.

This is the angle between the current meridian and the CIO, i.e. the ERA + longitude.

Parameters

time (float) – Unix time.

Returns

lsa

Return type

float

unix_to_lsd[source]

Calculate the Local Stellar Day (LSD) corresponding to the given time.

The Local Earth Rotation Day is the number of cycles of Earth Rotation Angle that have passed since the specified zero epoch (including fractional cycles).

Parameters

time (float or array of) – UNIX time

Returns

lsd

Return type

float or array of

unix_to_lst[source]

Calculate the apparent Local Sidereal Time for the given UNIX time.

Parameters

unix (float or array of) – UNIX time in floating point seconds since the epoch.

Returns

lst – The apparent LST in degrees.

Return type

float or array of

class caput.time.SkyfieldWrapper(path=None, expire=None, ephemeris='de421.bsp')[source]

Bases: object

A wrapper to help with loading Skyfield and its data.

Parameters
  • path (string, optional) – Directory Skyfield should save data in. If not set data will be looked for in $CAPUT_SKYFIELD_PATH or in <path to caput>/caput/data.

  • expire (bool, optional) – Deprecated option. Skyfield no longer has a concept of expiring data. To get updated data you must force an explicit reload of it which can be done via SkyFieldWrapper.reload.

  • ephemeris (string, optional) – The JPL ephemeris to use. Defaults to ‘de421.bsp’.

property ephemeris

A Skyfield ephemeris object (skyfield.jpllib.SpiceKernel). Loaded at first call, and then cached.

property load

A skyfield.iokit.Loader object to be used in the same way as skyfield.api.load, in case you want something other than timescale or ephemeris.

property path

The path to the Skyfield data.

reload()[source]

Reload the Skyfield data regardless of the expire setting.

property timescale

A skyfield.timelib.Timescale object. Loaded at first call, and then cached.

caput.time.datetime_to_timestr()[source]

Converts a datetime to “YYYYMMDDTHHMMSSZ” format.

Partial seconds are ignored.

Parameters

dt (datetime.datetime) –

Returns

time_str – Formated date and time.

Return type

string

caput.time.datetime_to_unix()[source]

Converts a datetime object to the unix time.

This is the inverse of datetime.datetime.utcfromtimestamp().

Parameters

dt (datetime.datetime) –

Returns

unix_time – Unix/POSIX time.

Return type

float

See also

unix_to_datetime(), datetime.datetime.utcfromtimestamp()

caput.time.ensure_unix()[source]

Convert the input time to Unix time format.

Parameters

time (float, string, datetime or skyfield.timelib.Time) – Input time, or array of times.

Returns

unix_time – Output time.

Return type

float, or array of

caput.time.era_to_unix()[source]

Calculate the UNIX time for a given Earth Rotation Angle.

The Earth Rotation Angle is the angle between the Celetial and Terrestrial Intermediate origins, and is a modern replacement for the Greenwich Sidereal Time.

This routine is accurate at about the 1 ms level.

Parameters
  • era (float or array of) – The Earth Rotation Angle in degrees.

  • time0 (scalar or np.ndarray) – An earlier time within 24 sidereal hours. For example, the start of the solar day of the observation.

Returns

unix_time – Unix/POSIX time.

Return type

float or array of.

caput.time.leap_seconds_between()[source]

Determine how many leap seconds occurred between two Unix times.

Parameters
  • time_a (float) – First Unix/POSIX time.

  • time_b (float) – Second Unix/POSIX time.

Returns

int – The number of leap seconds between time_a and time_b.

Return type

bool

caput.time.naive_datetime_to_utc()[source]

Add UTC timezone info to a naive datetime.

This only does anything if Skyfield is installed.

Parameters

dt (datetime) –

Returns

dt – New datetime with tzinfo added.

Return type

datetime

caput.time.skyfield_star_from_ra_dec(ra, dec, name='')[source]

Create a Skyfield star object from an ICRS position.

Parameters
  • ra (float) – The ICRS position in degrees.

  • dec (float) – The ICRS position in degrees.

  • name (str, optional) – The name of the body.

Returns

body – An object representing the body.

Return type

skyfield.starlib.Star

caput.time.skyfield_time_to_unix()[source]

Formats the Skyfield time into UNIX times.

Parameters

skyfield_time (skyfield.timelib.Time) – Skyfield time.

Returns

time – UNIX time.

Return type

float or array of

caput.time.time_of_day()[source]

Return the time since the start of the UTC day in seconds.

Parameters

time_date (float (UNIX time), or datetime) – Find the start time of the day that time is in.

Returns

time – Time since start of UTC day in seconds.

Return type

float

caput.time.timestr_to_datetime()[source]

Converts date “YYYYMMDDTHHMMSS*” to a datetime.

Parameters

time_str (string) – Formated date and time.

Returns

time_str

Return type

datetime.datetime

caput.time.unix_to_datetime()[source]

Converts unix time to a datetime object.

Equivalent to datetime.datetime.utcfromtimestamp().

Parameters

unix_time (float) – Unix/POSIX time.

Returns

dt

Return type

datetime.datetime

caput.time.unix_to_era()[source]

Calculate the Earth Rotation Angle for a given time.

The Earth Rotation Angle is the angle between the Celestial and Terrestrial Intermediate origins, and is a modern replacement for the Greenwich Sidereal Time.

Parameters

unix_time (float or array of.) – Unix/POSIX time.

Returns

era – The Earth Rotation Angle in degrees.

Return type

float or array of

caput.time.unix_to_skyfield_time()[source]

Formats the Unix time into a time that can be interpreted by Skyfield.

Parameters

unix_time (float or array of.) – Unix/POSIX time.

Returns

time

Return type

skyfield.timelib.Time