Timespan

class lsst.daf.butler.Timespan(begin: TimespanBound, end: TimespanBound, padInstantaneous: bool = True, _nsec: tuple[int, int] | None = None)

Bases: BaseModel

A half-open time interval with nanosecond precision.

Parameters:
beginastropy.time.Time, Timespan.EMPTY, or None

Minimum timestamp in the interval (inclusive). None indicates that the timespan has no lower bound. Timespan.EMPTY indicates that the timespan contains no times; if this is used as either bound, the other bound is ignored.

endastropy.time.Time, SpecialTimespanBound, or None

Maximum timestamp in the interval (exclusive). None indicates that the timespan has no upper bound. As with begin, Timespan.EMPTY creates an empty timespan.

padInstantaneousbool, optional

If True (default) and begin == end after discretization to integer nanoseconds, extend end by one nanosecond to yield a finite-duration timespan. If False, begin == end evaluates to the empty timespan.

_nsectuple of int, optional

Integer nanosecond representation, for internal use by Timespan and TimespanDatabaseRepresentation implementation only. If provided, all other arguments are are ignored.

Raises:
TypeError

Raised if begin or end has a type other than astropy.time.Time, and is not None or Timespan.EMPTY.

ValueError

Raised if begin or end exceeds the minimum or maximum times supported by this class.

Notes

Timespans are half-open intervals, i.e. [begin, end).

Any timespan with begin > end after nanosecond discretization (begin >= end if padInstantaneous is False), or with either bound set to Timespan.EMPTY, is transformed into the empty timespan, with both bounds set to Timespan.EMPTY. The empty timespan is equal to itself, and contained by all other timespans (including itself). It is also disjoint with all timespans (including itself), and hence does not overlap any timespan - this is the only case where contains does not imply overlaps.

Finite timespan bounds are represented internally as integer nanoseconds, and hence construction from astropy.time.Time (which has picosecond accuracy) can involve a loss of precision. This is of course deterministic, so any astropy.time.Time value is always mapped to the exact same timespan bound, but if padInstantaneous is True, timespans that are empty at full precision (begin > end, begin - end < 1ns) may be finite after discretization. In all other cases, the relationships between full-precision timespans should be preserved even if the values are not.

The astropy.time.Time bounds that can be obtained after construction from Timespan.begin and Timespan.end are also guaranteed to round-trip exactly when used to construct other Timespan instances.

Attributes Summary

EMPTY

begin

Minimum timestamp in the interval, inclusive.

end

Maximum timestamp in the interval, exclusive.

model_config

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

yaml_tag

Methods Summary

contains(other)

Test if the supplied timespan is within this one.

difference(other)

Return the one or two timespans that cover the interval(s).

fromInstant(time)

Construct a timespan that approximates an instant in time.

from_day_obs(day_obs[, offset])

Construct a timespan for a 24-hour period based on the day of observation.

from_yaml(loader, node)

Convert YAML node into _SpecialTimespanBound.

intersection(*args)

Return a new Timespan that is contained by all of the given ones.

isEmpty()

Test whether self is the empty timespan (bool).

makeEmpty()

Construct an empty timespan.

overlaps(other)

Test if the intersection of this Timespan with another is empty.

to_yaml(dumper, timespan)

Convert Timespan into YAML format.

Attributes Documentation

EMPTY: ClassVar[_SpecialTimespanBound] = 1
begin

Minimum timestamp in the interval, inclusive.

If this bound is finite, this is an astropy.time.Time instance. If the timespan is unbounded from below, this is None. If the timespan is empty, this is the special value Timespan.EMPTY.

end

Maximum timestamp in the interval, exclusive.

If this bound is finite, this is an astropy.time.Time instance. If the timespan is unbounded from above, this is None. If the timespan is empty, this is the special value Timespan.EMPTY.

model_config: ClassVar[ConfigDict] = {'json_schema_extra': {'description': 'A [begin, end) TAI timespan with bounds as integer nanoseconds since 1970-01-01 00:00:00.'}}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[dict[str, FieldInfo]] = {'nsec': FieldInfo(annotation=tuple[int, int], required=True, frozen=True)}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

yaml_tag: ClassVar[str] = '!lsst.daf.butler.Timespan'

Methods Documentation

contains(other: Time | Timespan) bool

Test if the supplied timespan is within this one.

Tests whether the intersection of this timespan with another timespan or point is equal to the other one.

Parameters:
otherTimespan or astropy.time.Time

Timespan or instant in time to relate to self.

Returns:
overlapsbool

The result of the contains test.

Notes

If other is empty, True is always returned. In all other cases, self.contains(other) being True implies that self.overlaps(other) is also True.

Testing whether an instantaneous astropy.time.Time value is contained in a timespan is not equivalent to testing a timespan constructed via Timespan.fromInstant, because Timespan cannot exactly represent zero-duration intervals. In particular, [a, b) contains the time b, but not the timespan [b, b + 1ns) that would be returned by Timespan.fromInstant(b)`.

difference(other: Timespan) Generator[Timespan, None, None]

Return the one or two timespans that cover the interval(s).

The interval is defined as one that is in self but not other.

This is implemented as a generator because the result may be zero, one, or two Timespan objects, depending on the relationship between the operands.

Parameters:
otherTimespan

Timespan to subtract.

Yields:
resultTimespan

A Timespan that is contained by self but does not overlap other. Guaranteed not to be empty.

classmethod fromInstant(time: Time) Timespan

Construct a timespan that approximates an instant in time.

This is done by constructing a minimum-possible (1 ns) duration timespan.

This is equivalent to Timespan(time, time, padInstantaneous=True), but may be slightly more efficient.

Parameters:
timeastropy.time.Time

Time to use for the lower bound.

Returns:
instantTimespan

A [time, time + 1ns) timespan.

classmethod from_day_obs(day_obs: int, offset: int = 0) Timespan

Construct a timespan for a 24-hour period based on the day of observation.

Parameters:
day_obsint

The day of observation as an integer of the form YYYYMMDD. The year must be at least 1970 since these are converted to TAI.

offsetint, optional

Offset in seconds from TAI midnight to be applied.

Returns:
day_spanTimespan

A timespan corresponding to a full day of observing.

Notes

If the observing day is 20240229 and the offset is 12 hours the resulting time span will be 2024-02-29T12:00 to 2024-03-01T12:00.

classmethod from_yaml(loader: SafeLoader, node: MappingNode) Timespan | None

Convert YAML node into _SpecialTimespanBound.

Parameters:
loaderyaml.SafeLoader

Instance of YAML loader class.

nodeyaml.ScalarNode

YAML node.

Returns:
valueTimespan

Timespan instance, can be None.

intersection(*args: Timespan) Timespan

Return a new Timespan that is contained by all of the given ones.

Parameters:
*args

All positional arguments are Timespan instances.

Returns:
intersectionTimespan

The intersection timespan.

isEmpty() bool

Test whether self is the empty timespan (bool).

classmethod makeEmpty() Timespan

Construct an empty timespan.

Returns:
emptyTimespan

A timespan that is contained by all timespans (including itself) and overlaps no other timespans (including itself).

overlaps(other: Timespan | Time) bool

Test if the intersection of this Timespan with another is empty.

Parameters:
otherTimespan or astropy.time.Time

Timespan or time to relate to self. If a single time, this is a synonym for contains.

Returns:
overlapsbool

The result of the overlap test.

Notes

If either self or other is empty, the result is always False. In all other cases, self.contains(other) being True implies that self.overlaps(other) is also True.

classmethod to_yaml(dumper: Dumper, timespan: Timespan) Any

Convert Timespan into YAML format.

This produces a scalar node with a tag “!_SpecialTimespanBound” and value being a name of _SpecialTimespanBound enum.

Parameters:
dumperyaml.Dumper

YAML dumper instance.

timespanTimespan

Data to be converted.