def test_invert(init_times, durations): """Test `invert` method.""" end_times = init_times + durations init_intervals = [] for i, init_time in enumerate(init_times): init_intervals.append(TimeInterval(init_times[i], end_times[i])) intervals = TimeIntervalList( init_intervals, start_valid=init_times[0] - TimeDelta(1.0, format="jd"), end_valid=end_times[-1] + TimeDelta(1.0, format="jd"), ) inverted_intervals = intervals.invert() truth_txt = ("[ 2020-04-10T00:00:00.000 2020-04-11T00:00:00.000 ]\n" "[ 2020-04-11T00:10:00.000 2020-04-12T00:00:00.000 ]\n" "[ 2020-04-12T00:20:00.000 2020-04-13T00:00:00.000 ]\n" "[ 2020-04-13T00:30:00.000 2020-04-14T00:30:00.000 ]\n") truth_validity = "[ 2020-04-10T00:00:00.000 2020-04-14T00:30:00.000 ]" assert truth_txt == str(inverted_intervals) assert truth_validity == str(inverted_intervals.validity_interval())
def test_is_intersecting(init_times, durations): """Test `is_intersecting` method.""" init_intervals = [] for i, init_time in enumerate(init_times): init_intervals.append(TimeInterval(init_times[i], durations[i])) interval = TimeIntervalList(init_intervals).get_interval(0) assert interval.is_intersecting(before) is False assert interval.is_intersecting(within) is True assert interval.is_intersecting(intersect) is True assert interval.is_intersecting(exact) is True assert interval.is_intersecting(after) is False
def test_is_in_interval(init_times, durations): """Test `is_in_interval` method.""" init_intervals = [] for i, init_time in enumerate(init_times): init_intervals.append(TimeInterval(init_times[i], durations[i])) interval = TimeIntervalList(init_intervals).get_interval(0) t_before = Time("2020-04-09T00:00:00", scale="utc") t_eqinit = Time("2020-04-11T00:00:00", scale="utc") t_within = Time("2020-04-11T00:05:00", scale="utc") t_eqend = Time("2020-04-11T00:10:00", scale="utc") t_after = Time("2020-04-11T12:00:00", scale="utc") assert interval.is_in_interval(t_before) is False assert interval.is_in_interval(t_eqinit) is True assert interval.is_in_interval(t_within) is True assert interval.is_in_interval(t_eqend) is True assert interval.is_in_interval(t_after) is False
def test_interval_list_init_with_end_times(init_times, durations): """Test initialisation with explicit end times.""" end_times = init_times + durations init_intervals = [] for i, init_time in enumerate(init_times): init_intervals.append(TimeInterval(init_times[i], end_times[i])) intervals = TimeIntervalList(init_intervals, start_valid=init_times[0], end_valid=end_times[-1]) truth_txt = ("[ 2020-04-11T00:00:00.000 2020-04-11T00:10:00.000 ]\n" "[ 2020-04-12T00:00:00.000 2020-04-12T00:20:00.000 ]\n" "[ 2020-04-13T00:00:00.000 2020-04-13T00:30:00.000 ]\n") truth_validity = "[ 2020-04-11T00:00:00.000 2020-04-13T00:30:00.000 ]" assert truth_txt == str(intervals) assert truth_validity == str(intervals.validity_interval())
def test_interval_list_intersection(init_times, durations): """Test interval intersection.""" init_intervals = [] for i, init_time in enumerate(init_times): init_intervals.append(TimeInterval(init_times[i], durations[i])) intervals = TimeIntervalList(init_intervals) interval_full_intersect = TimeInterval(Time("2020-04-13T00:00:00.000"), 5 * u.min) interval_part_intersect = TimeInterval(Time("2020-04-10T23:50:00.000"), 60 * u.min) interval_no_intersect = TimeInterval(Time("2020-04-11T12:00:00.000"), 5 * u.min) # *** Test TimeIntervalList vs. TimeInterval intersection *** assert intervals.is_intersecting(interval_full_intersect) is True assert "[ 2020-04-13T00:00:00.000 2020-04-13T00:05:00.000 ]" == str( intervals.intersect(interval_full_intersect) ) assert intervals.is_intersecting(interval_part_intersect) is True assert "[ 2020-04-11T00:00:00.000 2020-04-11T00:10:00.000 ]" == str( intervals.intersect(interval_part_intersect) ) assert intervals.is_intersecting(interval_no_intersect) is False assert intervals.intersect(interval_no_intersect) is None # *** Test TimeIntervalList vs. TimeIntervalList intersection *** test_intervals = TimeIntervalList( [interval_full_intersect, interval_part_intersect, interval_no_intersect] ) truth_txt = ( "[ 2020-04-11T00:00:00.000 2020-04-11T00:10:00.000 ]\n" "[ 2020-04-13T00:00:00.000 2020-04-13T00:05:00.000 ]\n" ) assert truth_txt == str(intervals.intersect_list(test_intervals))
def test_interval_list_init_with_durations(init_times, durations): """Test initialisation with durations.""" init_intervals = [] for i, init_time in enumerate(init_times): init_intervals.append(TimeInterval(init_times[i], durations[i])) intervals = TimeIntervalList(init_intervals) truth_txt = ("[ 2020-04-11T00:00:00.000 2020-04-11T00:10:00.000 ]\n" "[ 2020-04-12T00:00:00.000 2020-04-12T00:20:00.000 ]\n" "[ 2020-04-13T00:00:00.000 2020-04-13T00:30:00.000 ]\n") assert truth_txt == str(intervals)
def test_interval_list_union(init_times, durations): """Test interval union.""" init_intervals = [] for i, init_time in enumerate(init_times): init_intervals.append(TimeInterval(init_times[i], durations[i])) intervals = TimeIntervalList( init_intervals, start_valid=Time("2020-04-11T00:00:00.000"), end_valid=Time("2020-04-14T00:00:00.000"), ) interval_part_intersect = TimeInterval(Time("2020-04-10T23:50:00.000"), 60 * u.min) interval_no_intersect = TimeInterval(Time("2020-04-11T12:00:00.000"), 5 * u.min) interval_full_intersect = TimeInterval(Time("2020-04-13T00:00:00.000"), 5 * u.min) interval_outside = TimeInterval(Time("2020-04-13T23:50:00.000"), 15 * u.min) # *** Test TimeIntervalList vs. TimeInterval intersection *** assert "[ 2020-04-13T00:00:00.000 2020-04-13T00:30:00.000 ]" == str( intervals.union(interval_full_intersect) ) assert "[ 2020-04-10T23:50:00.000 2020-04-11T00:50:00.000 ]" == str( intervals.union(interval_part_intersect) ) assert intervals.union(interval_no_intersect) is None # *** Test TimeIntervalList vs. TimeIntervalList intersection *** test_intervals = TimeIntervalList( [ interval_full_intersect, interval_part_intersect, interval_no_intersect, interval_outside, ] ) # print(intervals.union_list(test_intervals)) truth_txt = ( "[ 2020-04-11T00:00:00.000 2020-04-11T00:50:00.000 ]\n" "[ 2020-04-11T12:00:00.000 2020-04-11T12:05:00.000 ]\n" "[ 2020-04-12T00:00:00.000 2020-04-12T00:20:00.000 ]\n" "[ 2020-04-13T00:00:00.000 2020-04-13T00:30:00.000 ]\n" "[ 2020-04-13T23:50:00.000 2020-04-14T00:00:00.000 ]\n" ) assert truth_txt == str(intervals.union_list(test_intervals))
def test_union(init_times, durations): """Test `union` method.""" init_intervals = [] for i, init_time in enumerate(init_times): init_intervals.append(TimeInterval(init_times[i], durations[i])) interval = TimeIntervalList(init_intervals).get_interval(0) assert interval.union(before) is None assert interval.union(within).is_equal(interval) assert interval.union(intersect).is_equal( TimeInterval(intersect.start, interval.end)) assert interval.union(exact).is_equal(interval) assert interval.union(after) is None
def _find_intervals(self, time_list, neg_to_pos_is_start): """ Finds the start / end intervals within the time list. Parameters ---------- time_list : Time List of time instances neg_to_pos_is_start : bool If `True` value turning from negative to positive marks a *start* event, otherwise marks an *end* event Returns ------- intervals : TimeIntervalList Time intervals marked with start and end events """ init_time = time_list[0] end_time = time_list[-1] # *** Find start / end events (do not extrapolate to find roots) *** # No roots mean no events during this time start_end_events = self._interpolator.roots(extrapolate=False) intervals = [] if start_end_events.size != 0: # there should be some roots within the search range to check for intervals # classify start / end events and fill the timetable events = self._classify_start_end_events( init_time, start_end_events, neg_to_pos_is_start ) # Put events into intervals event_start = init_time for event in events: # ignore events outside the search interval if self.search_interval.is_in_interval(event["time"]): if event["type"] == "start": event_start = event["time"] else: intervals.append(TimeInterval(event_start, event["time"])) # check for the last event - force end time if it is out of search bounds if events[-1]["type"] == "end": if self.search_interval.is_in_interval(events[-1]["time"]): intervals.append(TimeInterval(event_start, events[-1]["time"])) else: intervals.append( TimeInterval(event_start, self.search_interval.end) ) else: intervals.append(TimeInterval(event_start, self.search_interval.end)) # If interval list is empty by this stage, either the complete duration is # is a valid interval with no event (e.g. a continuously visible satellite) # or the complete duration is an invalid interval with no event (e.g. a # satellite continuously outside visibility) if not intervals: mid_time = 0.5 * (self.search_interval.end - self.search_interval.start) value = self._interpolator(mid_time.to_value(u.day)) if neg_to_pos_is_start: if value > 0: # event already started intervals.append( TimeInterval( self.search_interval.start, self.search_interval.end ) ) else: if value < 0: # event already started intervals.append( TimeInterval( self.search_interval.start, self.search_interval.end ) ) # generate the list of time intervals return TimeIntervalList(intervals, start_valid=init_time, end_valid=end_time)