Time Intervals and Time Interval Lists¶
Introduction¶
Time intervals are critical to define the start and end of certain events such as start and end of communications with a groundstation, entering and exiting the eclipse or start and end of a thruster firing. This is particularly useful when two intervals (or sets of intervals) can be evaluated through operations such as union and intersection. This enables us to answer questions such as “What are the time intervals where thruster firings occur during communications?” (an intersection operation between ‘intervals of thruster firings’ and ‘communications interval lists’) or “When can I see a satellite at night?” (an intersection operation between intervals of ‘satellite above horizon’, ‘sun below horizon’ and ‘satellite not in eclipse’).
The timeinterval
module provides the basic time interval functionality with the TimeInterval
class i.e., a time interval with a start and end time/date, using the high precision astropy.time.Time
classes under the hood to represent time and portion.interval.Interval
class to manage and manipulate the time intervals.
A TimeInterval
can interact with other intervals through TimeInterval.union()
and TimeInterval.intersect()
methods. They can change their size through TimeInterval.expand()
and they can check whether they contain (TimeInterval.contains()
) or intersect with (TimeInterval.is_intersecting()
) another time interval.
A list of such time intervals constitute TimeIntervalList
class. A list also has a start and end of validity. This usually marks the start and end of an analysis. For example, a communications list that is valid for one day and containing no time intervals would mean that there are no communication opportunities for that day. The list can simply be inverted (TimeIntervalList.invert()
) to get a list of ‘no communication duration’, which would then show a list with a single TimeInterval
that spans the entire duration of validity.
Using the Basic TimeInterval
Class¶
A TimeInterval
class can be simply initialised with a start time and either with an end time (astropy.time.Time
) or with a duration (astropy.time.TimeDelta
). These start and end times can be retrieved by the properties TimeInterval.start()
and TimeInterval.end()
.
from astropy.time import Time, TimeDelta
from satmad.utils.timeinterval import TimeInterval
interval_with_end_time = TimeInterval(
Time("2020-04-11T00:00:00.000", scale="utc"),
Time("2020-04-11T00:10:00.000", scale="utc"),
)
interval_with_duration = TimeInterval(
Time("2020-04-11T00:00:00", scale="utc"),
TimeDelta(60.0, format='sec'),
)
The resulting time intervals can be quickly shown as:
>>> str(interval_with_end_time)
'[ 2020-04-11T00:00:00.000 2020-04-11T00:10:00.000 ]\n'
>>> str(interval_with_duration)
'[ 2020-04-11T00:00:00.000 2020-04-11T00:01:00.000 ]\n'
The end time of the interval should be later than the start time. Otherwise, a
ValueError
will be raised.
The TimeInterval
class can answer some questions:
TimeInterval.is_in_interval()
: Is a given time within this interval?TimeInterval.is_equal()
: Is a given interval equal to this interval?TimeInterval.is_intersecting()
: Does a given interval have an intersection with this interval?TimeInterval.contains()
: Does a given interval contain this interval?TimeInterval.duration()
: What is the duration of this interval?
Some examples are given below:
>>> interval_with_end_time.is_in_interval(Time("2020-04-11T00:05:00.000", scale="utc"))
True
>>> interval_with_end_time.is_equal(TimeInterval(Time("2020-04-09T00:00:00", scale="utc"), TimeDelta(600.0, format="sec")))
True
>>> interval_with_end_time.is_intersecting(TimeInterval(Time("2020-04-11T00:05:00", scale="utc"), TimeDelta(600.0, format="sec")))
True
>>> interval_with_end_time.contains(TimeInterval(Time("2020-04-11T00:05:00", scale="utc"), TimeDelta(60.0, format="sec")))
True
>>> interval_with_end_time.duration().sec
599.9999999999931
The intervals can be expanded or shrunk through the TimeInterval.expand()
method and defining positive or negative astropy.time.TimeDelta
values to modify the start and end times of the interval.
>>> str(interval_with_end_time)
'[ 2020-04-11T00:00:00.000 2020-04-11T00:10:00.000 ]\n'
>>> expanded = interval_with_end_time.expand(start_delta=TimeDelta(60.0, format="sec"), end_delta=TimeDelta(-120.0, format="sec"))
>>> str(expanded)
'[ 2020-04-10T23:59:00.000 2020-04-11T00:08:00.000 ]\n'
Time intervals can be subjected to an intersection (a new TimeInterval
that is the intersection of two intervals) or union (a new TimeInterval
that is the union of two intervals) operator. These operators are possible only when these two intervals have some intersection - otherwise the result will be a None
.
>>> str(interval_with_end_time.union(expanded))
'[ 2020-04-10T23:59:00.000 2020-04-11T00:10:00.000 ]\n'
>>> str(interval_with_end_time.intersect(expanded))
'[ 2020-04-11T00:00:00.000 2020-04-11T00:08:00.000 ]\n'
List of time intervals: The TimeIntervalList
Class¶
The TimeIntervalList
usually will not be generated explicitly by a user, except, for example, as an external constraint such as the durations when a groundstation is not available. Usually such lists are results of certain analyses such as eclipse intervals for a location on ground or different attitude profiles for a satellite.
The TimeIntervalList
class stores the TimeInterval
objects as well as another TimeInterval
to represent the bounds of the validity of this list. If this validity interval is not defined explicitly, then it is assumed to start with the beginning of the first TimeInterval
and end with the end of the final TimeInterval
.
Operations such as TimeIntervalList.intersection()
and TimeIntervalList.union()
are also possible for two TimeIntervalList
objects. As a TimeIntervalList
is defined for a certain validity interval, the union or intersection of two TimeIntervalList
objects will yield another TimeIntervalList
that is only valid for the intersection of validity of these two intervals.
Any interval within the list can be queried through TimeIntervalList.get_interval()
method. Similarly, the TimeInterval
that keeps the interval of validity can be queried through TimeIntervalList.valid_interval()
property.
The TimeIntervalList
will yield a new, inverted (or complementing) version of itself through the TimeIntervalList.invert()
method. For example, for a single interval of [t0, t1]
in a validity interval [T0,T1]
, the inverted interval list would be [T0,t0]
and [t1,T1]
. If there are no intervals, the inverse becomes the entire validity interval.
Reference/API¶
Time interval module.
TimeInterval class stores time intervals and TimeIntervalList class stores lists of TimeInterval objects.
-
class
satmad.utils.timeinterval.
TimeInterval
(start_time, end_time, replicate=False, start_inclusive=True, end_inclusive=True)¶ Represent and manipulate a single time interval.
This is a thin wrapper around the
portion.interval.Interval
class from portion package (for the Atomic intervals), using Astropy Time classes under the hood.-
property
as_time
¶ Gets the start and end intervals contained a single Time object.
-
contains
(interval)¶ Checks whether the requested interval is contained within this (self) interval.
- Parameters
interval (TimeInterval) – Time interval to be checked
- Returns
True if check interval is contained within this interval, False otherwise
- Return type
-
property
duration
¶ Computes the duration of the interval.
- Returns
duration – Duration of the interval (always positive)
- Return type
TimeDelta
-
property
end
¶ Returns the end time of the interval.
-
expand
(start_delta=0, end_delta=0, replicate=False, start_inclusive=True, end_inclusive=True)¶ Expands (or shrinks) the interval.
Generates a new, expanded (or shrunk) TimeInterval, where:
new interval start: interval_start - start_delta
new interval end: interval_end + end_delta
Negative start and/or end times are possible (to shrink the interval), though values ending in a negative interval will throw a ValueError. This method can be used to modify the ends of the interval (open or closed) as well.
- Parameters
start_delta (TimeDelta) – The delta time to expand the start of the interval (or to shrink, with negative values)
end_delta (TimeDelta) – The delta time to expand the end of the interval (or to shrink, with negative values)
replicate (bool) – True to replicate (deep copy) the Time or TimeDelta objects, False to use a shallow copy to save memory
start_inclusive (bool) – True if the start of the new interval is inclusive (closed), False if exclusive (open)
end_inclusive (bool) – True if the start of the new interval is inclusive (closed), False if exclusive (open)
- Returns
A new TimeInterval that is the result of the requested change
- Return type
- Raises
ValueError – Raised if the requested expansion results in a negative duration interval
-
intersect
(interval)¶ Intersection operator for a time interval and this time interval.
Returns a new interval that is the Intersection of two intervals, or None if there is no intersection.
- Parameters
interval (TimeInterval) – Time interval to be checked
- Returns
A new interval that is the Intersection of two intervals, or None if there is no intersection
- Return type
-
is_equal
(interval)¶ Checks whether two intervals are (almost) equal in value.
If the two start or end values are as close as _EPS_TIME, then they are assumed to be equal in value.
- Parameters
interval (TimeInterval) – Time interval to be checked
- Returns
True if interval start and end are (almost) equal, False otherwise
- Return type
-
is_in_interval
(time)¶ Checks whether the requested time is within the time interval.
- Parameters
time (Time) – Time to be checked
- Returns
True if time is within the reference interval, False otherwise
- Return type
-
is_intersecting
(interval)¶ Checks whether the requested interval intersects (or is contained within) the reference interval.
- Parameters
interval (TimeInterval) – Time interval to be checked
- Returns
True if check interval intersects with the reference interval, False otherwise
- Return type
-
property
p_interval
¶ Returns the underlying Interval object.
Warning
Most users will not need to access this object. Intended for developer use only.
-
property
start
¶ Returns the start time of the interval.
-
union
(interval)¶ Union operator for a time interval and this time interval.
Returns a new interval that is the Union of two intervals, or None if there is no intersection.
- Parameters
interval (TimeInterval) – Time interval to be checked
- Returns
A new interval that is the Union of two intervals, or None if there is no intersection
- Return type
-
property
-
class
satmad.utils.timeinterval.
TimeIntervalList
(intervals, start_valid=None, end_valid=None, replicate=False)¶ Represent and manipulate time intervals.
This is a thin wrapper around the
portion.interval.Interval
class, using Astropy Time classes under the hood.start_valid and end_valid values are used to mark the start and end of this list of time intervals. If they are not specified, the beginning and end points of the list of TimeInterval instances are used.
- Parameters
intervals (list[TimeInterval] or None) – List of intervals
start_valid (Time or TimeInterval) – Time at which the validity of this TimeInterval starts (only the first instance contained in the Time object is used). If specified as TimeInterval, it is copied into this and end_valid is ignored (the only case where None is acceptable).
end_valid (Time, TimeDelta or None) – Time or duration at which the validity of this TimeInterval ends (only the first instance contained in the Time object is used). None is acceptable only when start_valid is defined as a TimeInterval
replicate (bool) – True to replicate (deep copy) the Time or TimeDelta objects, False to use a shallow copy to save memory
- Raises
ValueError – Raised if init_times and end_times objects sizes mismatch.
-
get_interval
(index)¶ Gets the time interval for the given index.
- Parameters
index (int) – requested index
- Returns
TimeInterval corresponding to the index
- Return type
- Raises
IndexError – Requested index is out of bounds
-
intersect
(interval)¶ Intersection operator for a time interval and this time interval list.
Returns a new interval that is the Intersection of the interval and the time interval list, or None if there is no intersection.
- Parameters
interval (TimeInterval) – Time interval to be checked
- Returns
A new interval that is the Intersection of the interval and the time interval list, or None if there is no intersection.
- Return type
-
intersect_list
(interval_list)¶ Intersection operator for a time interval list and this time interval list.
Returns a new interval list that is the Intersection of interval_list and this time interval list, or None if there is no intersection even in the validity intervals.
- Parameters
interval_list (TimeIntervalList) – Time interval list to be checked
- Returns
A new interval list that is the Intersection of interval_list and this time interval list, or None if there is no intersection even in the validity intervals.
- Return type
-
property
intervals
¶ Gets the time intervals within this TimeIntervalList.
-
invert
(replicate=False)¶ Creates an inverted (or complement) copy of this time interval list, while keeping the same validity range.
For example, for a single interval of [t0, t1] in a validity interval [T0,T1], the inverted interval list would be [T0,t0] and [t1,T1]. If there are no intervals, the inverse becomes the entire validity interval.
- Parameters
replicate (bool) – True to replicate (deep copy) the Time or TimeDelta objects, False to use a shallow copy to save memory
- Returns
A new TimeIntervalList that has the same validity range but the individual
intervals are inverted.
-
is_in_interval
(time)¶ Checks whether the requested time is within the time interval list.
- Parameters
time (Time) – Time to be checked
- Returns
True if time is within the interval list, False otherwise. Also returns False if requested time is outside validity interval.
- Return type
-
is_intersecting
(interval)¶ Checks whether the requested interval intersects (or is contained within) the interval list.
- Parameters
interval (TimeInterval) – Time interval to be checked
- Returns
True if check interval intersects with the interval list, False otherwise
- Return type
-
union
(interval)¶ Union operator for a time interval and this time interval list.
Returns a new interval that is the Union of the interval and the time interval list, or None if there is no intersection.
- Parameters
interval (TimeInterval) – Time interval to be checked
- Returns
A new interval that is the Union of the interval and the time interval list, or None if there is no intersection.
- Return type
-
union_list
(interval_list)¶ Union operator for a time interval list and this time interval list.
Returns a new interval list that is the Union of interval_list and this time interval list, or None if there is no intersection even in the validity intervals.
- Parameters
interval_list (TimeIntervalList) – Time interval list to be checked
- Returns
A new interval list that is the Union of interval_list and this time interval list, or None if there is no intersection.
- Return type
-
property
valid_interval
¶ Gets the time interval of validity for the TimeIntervalList.