From df1b74bf192b12591d5eccb03cf3ec90e1d308c9 Mon Sep 17 00:00:00 2001 From: Sergio Date: Wed, 16 Oct 2024 12:11:50 -0300 Subject: [PATCH] SCHED-744: Add new time losses values --- scheduler/core/eventsqueue/nightchanges.py | 1 + .../core/statscalculator/statscalculator.py | 34 +++++++++++++------ scheduler/graphql_mid/types.py | 5 ++- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/scheduler/core/eventsqueue/nightchanges.py b/scheduler/core/eventsqueue/nightchanges.py index 2d30124d..fd15222c 100644 --- a/scheduler/core/eventsqueue/nightchanges.py +++ b/scheduler/core/eventsqueue/nightchanges.py @@ -34,6 +34,7 @@ class NightlyTimeline: A collection of timeline entries per night and site. """ timeline: Dict[NightIndex, Dict[Site, List[TimelineEntry]]] = field(init=False, default_factory=dict) + time_losses: Dict[NightIndex, Dict[Site, Dict[str, float]]] = field(init=False, default_factory=dict) _datetime_formatter: ClassVar[str] = field(init=False, default='%Y-%m-%d %H:%M') def add(self, diff --git a/scheduler/core/statscalculator/statscalculator.py b/scheduler/core/statscalculator/statscalculator.py index cebb7d84..039b50e8 100644 --- a/scheduler/core/statscalculator/statscalculator.py +++ b/scheduler/core/statscalculator/statscalculator.py @@ -49,44 +49,56 @@ def calculate_timeline_stats(timeline: NightlyTimeline, scores_per_program: Dict[ProgramID, float] = {} programs = {} for night_idx in nights: + timeline.time_losses.setdefault(night_idx, {}) for site in sites: - time_losses = {StatCalculator._FAULT_KEY: 0, - StatCalculator._WEATHER_KEY: 0, - StatCalculator._UNSCHEDULE_KEY: 0} + + timeline_time_losses = {StatCalculator._FAULT_KEY: 0, + StatCalculator._WEATHER_KEY: 0} + timeline.time_losses[night_idx].setdefault(site, {}) # Gather unsolved interruptions during the night. interruptions = [] for entry in timeline.timeline[night_idx][site]: if isinstance(entry.event, InterruptionEvent): interruptions.append(entry.event) elif isinstance(entry.event, InterruptionResolutionEvent): - interruptions.pop() + interruptions.pop() # remove reported interruption and register the time loss + if isinstance(entry.event, FaultResolutionEvent): + timeline_time_losses[StatCalculator._FAULT_KEY] += int(entry.event.time_loss.total_seconds()/60) + elif isinstance(entry.event, WeatherClosureResolutionEvent): + timeline_time_losses[StatCalculator._WEATHER_KEY] += int(entry.event.time_loss.total_seconds()/60) + # Unsolved interruptions for the night for e in interruptions: + print('event never finished:', e.description) if isinstance(e, FaultEvent): time_loss = timeline.timeline[night_idx][site][-1].event.time - e.time - time_losses[StatCalculator._FAULT_KEY] += time_loss.total_seconds() / 60 + timeline_time_losses[StatCalculator._FAULT_KEY] += int(time_loss.total_seconds() / 60) elif isinstance(e, WeatherClosureEvent): time_loss = timeline.timeline[night_idx][site][-1].event.time - e.time - time_losses[StatCalculator._WEATHER_KEY] += time_loss.total_seconds() / 60 + timeline_time_losses[StatCalculator._WEATHER_KEY] += int(time_loss.total_seconds() / 60) + timeline.time_losses[night_idx][site] = timeline_time_losses for entry in timeline.timeline[night_idx][site]: + time_losses = {StatCalculator._FAULT_KEY: 0, + StatCalculator._WEATHER_KEY: 0, + StatCalculator._UNSCHEDULE_KEY: 0} + # Morning twilight generates no plan. if entry.plan_generated is None: continue plan = entry.plan_generated # Update last plan - if isinstance(entry.event, InterruptionResolutionEvent): - if isinstance(entry.event, FaultResolutionEvent): - time_losses[StatCalculator._FAULT_KEY] += int(entry.event.time_loss.total_seconds()/60) - elif isinstance(entry.event, WeatherClosureResolutionEvent): - time_losses[StatCalculator._WEATHER_KEY] += int(entry.event.time_loss.total_seconds()/60) + if 'Morning' in entry.event.description: + time_losses[StatCalculator._FAULT_KEY] = timeline_time_losses[StatCalculator._FAULT_KEY] + time_losses[StatCalculator._WEATHER_KEY] = timeline_time_losses[StatCalculator._WEATHER_KEY] time_losses[StatCalculator._UNSCHEDULE_KEY] = (plan.time_left() - time_losses[StatCalculator._FAULT_KEY] - time_losses[StatCalculator._WEATHER_KEY]) + n_toos = 0 plan_score = 0 plan_conditions = [] diff --git a/scheduler/graphql_mid/types.py b/scheduler/graphql_mid/types.py index c6f49bb6..4be8b546 100644 --- a/scheduler/graphql_mid/types.py +++ b/scheduler/graphql_mid/types.py @@ -151,6 +151,7 @@ class TimelineEntriesBySite: time_entries: List[STimelineEntry] eve_twilight: datetime morn_twilight: datetime + time_losses: JSON @strawberry.type @@ -172,6 +173,7 @@ def from_computed_timelines(timeline: NightlyTimeline) -> 'SNightTimelines': s_entries = [] eve_twi = timeline.timeline[n_idx][site][0].event.time morn_twi = timeline.timeline[n_idx][site][-1].event.time + time_losses = timeline.time_losses[n_idx][site] for entry in timeline.timeline[n_idx][site]: if entry.plan_generated is None: continue @@ -182,7 +184,8 @@ def from_computed_timelines(timeline: NightlyTimeline) -> 'SNightTimelines': te = TimelineEntriesBySite(site=site, time_entries=s_entries, eve_twilight=eve_twi, - morn_twilight=morn_twi) + morn_twilight=morn_twi, + time_losses=time_losses) s_timeline_entries.append(te) sn = SNightInTimeline(night_index=n_idx, time_entries_by_site=s_timeline_entries) timelines.append(sn)