Finding Events and Intervals in Discrete Time Data

Introduction

A common family of problems in satellite mission analysis involve finding events and intervals such as finding the communication times of a satellite with a groundstation, satellite eclipse entrance and exit times or finding the exact time a satellite crosses the Equator. They require the precise calculation of the time when a calculated value (or its derivative) crosses a certain threshold. Usually the data is not defined as a continuous and differentiable function, but only as a discrete data set corresponding to the variation of a value with respect to time.

To be able to solve this problem, the discrete_time_intervals module provides the DiscreteTimeEvents class. This class generates an interpolator for the data set and computes the roots to find the start / end events that mark intervals within this data set. Similarly, it computes the derivative of this interpolator and computes the roots again to find the max / min events within this data set.

Using the DiscreteTimeEvents Class

The DiscreteTimeEvents class is designed as a helper to interpret the values representing the behaviour of a parameter. A simple use case would be to “for a given ground location, compute the sunrise and sunset times as well as the time of the highest point of the Sun in the sky”. If the location has mountains around it, limiting the view of the Sun, a minimum elevation can also be defined. The altitude or elevation values of the Sun as seen from a ground location would be computed elsewhere and fed into this class.

Therefore, in this problem formulation, the value_list would be the Sun altitude values in degrees over several days and the time_list would be the times corresponding to these altitude values. crossing_value would be zero for horizon or perhaps 5, to illustrate the minimum altitude. Finally, as sunrise is defined as the altitude crossing from negative to positive, the neg_to_pos_is_start parameter would be set to True. If the night duration was sought, then this would be set to False, as night is defined as the time when the altitude of the Sun changes from positive to negative (except things are a bit more complicated than that, see here for more information on different types of twilight).

To retrieve the sunrise / sunset intervals, the start_end_intervals can be queried, yielding a list of intervals. Similarly, to find the times when the Sun is at the highest point, the max_min_table can be queried. Note that, by definition, only the max / min events inside the intervals are shown, and the remaining events are filtered. Therefore, the max / min table will only have the Sun highest points where it is above horizon and not the lowest points where it is well below the horizon and is technically midnight.

The class also supports events that has no definite start or end. For example, if the Sun was already up at the first element of the time_list, then the first interval starts at that time. Similarly, if the Sun has not set at the final element of the time_list, then the last interval is closed with this last element. If the Sun was up all through the time_list, then there will be a single interval from beginning to the end. Conversely, if the Sun was not up at all throughout the data points, then there will be no intervals.

Interpolation, Time Step and Accuracy

The interpolator scipy.interpolate.CubicSpline is used under the hood to interpolate the values. The accuracy of the start / end as well as max / min events is defined by the time step of the data, depending on the problem. For example, the sunrise / sunset problem above is very slowly varying and would not require a time step of 60 seconds. On the other hand, finding the communication times of a LEO satellite accurately would potentially require a stepsize of 20-40 seconds. Therefore, it is highly recommended checking the convergence with smaller time steps and decide on a time step for the specific problem and required level of accuracy.

Coarse data with large time steps can still yield reasonably accurate results if the slope around the “root” is steep (i.e., transition from negative to positive values happening very quickly and clearly). On the other hand, slowly varying events and coarse data do not play well, as it becomes extremely difficult to find the exact point where the maximum point occurs. For example, for an observer on the ground, the Sun moves very slowly around its highest point, with its derivative changing from positive to negative. With a coarse data set, it is very challenging for a numerical algorithm to find the exact time with a high accuracy.

Finally, best results can be had with continuous and smooth data. Heavy non-linearities require very small time steps and there is no guarantee that discontinuities will be handled well.

As with all numerical algorithms, you should “know thy problem”.

Reference/API

Discrete time events and intervals finding methods.

class satmad.utils.discrete_time_events.DiscreteTimeEvents(time_list, value_list, crossing_value=0, neg_to_pos_is_start=True)

Discrete time events and intervals finding and storage class.

An time event is described as a function value crossing a certain threshold in increasing (negative to positive) and decreasing (positive to negative) directions, defining a time interval.

The class initialises interpolators to find where the value_list crosses the crossing_value, which is essentially a root finding problem.

Parameters
  • time_list (Time) – List of time instances

  • value_list (ndarray or list) – List of values corresponding to time instances (should be of the same size as time_list)

  • crossing_value (float) – Crossing value for the value_list

  • neg_to_pos_is_start (bool) – If True value turning from negative to positive marks a start event, otherwise marks an end event

Raises

ValueErrortime_list and value_list are of different sizes

property search_interval

Search interval for the events.