Skip to content

Commit

Permalink
SCHED-453: Selection pickling no longer stores _program_scorer. (#305)
Browse files Browse the repository at this point in the history
  • Loading branch information
sraaphorst authored Aug 30, 2023
1 parent ef608b4 commit c8ecafa
Showing 1 changed file with 25 additions and 3 deletions.
28 changes: 25 additions & 3 deletions scheduler/core/calculations/selection.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Copyright (c) 2016-2022 Association of Universities for Research in Astronomy, Inc. (AURA)
# For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause

from dataclasses import dataclass
from dataclasses import dataclass, field
from datetime import timedelta
from typing import Callable, FrozenSet, Mapping, Optional

Expand All @@ -19,14 +19,30 @@ class Selection:
"""
The selection of information passed by the Selector to the Optimizer.
This includes the list of programs that are schedulable and the night event for the nights under consideration.
Note that the _program_scorer is a configured method to re-score a Program. It carries a lot of data with it,
and as a result, it is not pickled, so any unpickling of a Selection object will have:
_program_scorer = None.
"""
program_info: Mapping[ProgramID, ProgramInfo]
schedulable_groups: Mapping[UniqueGroupID, GroupData]
night_events: Mapping[Site, NightEvents]
night_indices: NightIndices
time_slot_length: timedelta
_program_scorer: Callable[[Program, Optional[FrozenSet[Site]], Optional[NightIndices], Optional[Ranker]],
Optional[ProgramCalculations]]

# Used to re-score programs.
_program_scorer: Optional[Callable[[Program, Optional[FrozenSet[Site]], Optional[NightIndices], Optional[Ranker]],
Optional[ProgramCalculations]]] = field(default=None)

def __reduce__(self):
"""
Pickle everything but the _program_scorer.
"""
return (self.__class__, (self.program_info,
self.schedulable_groups,
self.night_indices,
self.night_indices,
self.time_slot_length))

def score_program(self,
program: Program,
Expand All @@ -36,7 +52,13 @@ def score_program(self,
"""
Re-score a program. This calls Selector.score_program, which checks to make sure
that the night_indices are valid, so we don't need to include that logic here.
Note that this will raise a ValueError on unpickled instances of Selection since the
_program_scorer will be None.
"""
if self._program_scorer is None:
raise ValueError('Selection.score_program cannot be called as the selection has a value of None. '
'This could happen if the instance was unpickled.')

if night_indices is None:
night_indices = self.night_indices
return self._program_scorer(program, sites, night_indices, ranker)
Expand Down

0 comments on commit c8ecafa

Please sign in to comment.