diff --git a/SAS/TMSS/services/scheduling/lib/constraints/template_constraints_v1.py b/SAS/TMSS/services/scheduling/lib/constraints/template_constraints_v1.py index b9b7bfe1a72bfe00c5a42f21318289e66a3ef418..b570f271378a5cac46828fd1764f681bd078b857 100644 --- a/SAS/TMSS/services/scheduling/lib/constraints/template_constraints_v1.py +++ b/SAS/TMSS/services/scheduling/lib/constraints/template_constraints_v1.py @@ -139,19 +139,6 @@ def can_run_anywhere_within_timewindow_with_daily_constraints(scheduling_unit: m def can_run_within_timewindow_with_time_constraints(scheduling_unit: models.SchedulingUnitBlueprint, lower_bound: datetime, upper_bound: datetime) -> bool: - """ - Checks whether it is possible to run the scheduling unit /somewhere/ in the given time window, considering the duration of the involved observation. - :return: True if there is at least one possibility to place the scheduling unit in a way that all time constraints are met over the runtime of the observation, else False. - """ - # todo: use moving window lower_bound to lower_bound + obs duration, return true once window returned true - return can_run_anywhere_within_timewindow_with_time_constraints(scheduling_unit, lower_bound, upper_bound) - - -def can_run_anywhere_within_timewindow_with_time_constraints(scheduling_unit: models.SchedulingUnitBlueprint, lower_bound: datetime, upper_bound: datetime) -> bool: - """ - Checks whether it is possible to place the scheduling unit arbitrarily in the given time window, i.e. the time constraints must be met over the full time window. - :return: True if all time constraints are met over the entire time window, else False. - """ '''evaluate the time contraint(s)''' constraints = scheduling_unit.draft.scheduling_constraints_doc # TODO: TMSS-244 (and more?), evaluate the constraints in constraints['time'] @@ -175,6 +162,19 @@ def can_run_anywhere_within_timewindow_with_time_constraints(scheduling_unit: mo def can_run_within_timewindow_with_sky_constraints(scheduling_unit: models.SchedulingUnitBlueprint, lower_bound: datetime, upper_bound: datetime) -> bool: + """ + Checks whether it is possible to run the scheduling unit /somewhere/ in the given time window, considering the duration of the involved observation. + :return: True if there is at least one possibility to place the scheduling unit in a way that all sky constraints are met over the runtime of the observation, else False. + """ + # todo: use moving window lower_bound to lower_bound + obs duration, return true once window returned true + return can_run_anywhere_within_timewindow_with_sky_constraints(scheduling_unit, lower_bound, upper_bound) + + +def can_run_anywhere_within_timewindow_with_sky_constraints(scheduling_unit: models.SchedulingUnitBlueprint, lower_bound: datetime, upper_bound: datetime) -> bool: + """ + Checks whether it is possible to place the scheduling unit arbitrarily in the given time window, i.e. the sky constraints must be met over the full time window. + :return: True if all sky constraints are met over the entire time window, else False. + """ '''evaluate the time contraint(s)''' logger.info('### can_run_within_timewindow_with_sky_constraints called with lower_bound=%s upper_bound=%s '% (lower_bound, upper_bound)) constraints = scheduling_unit.draft.scheduling_constraints_doc diff --git a/SAS/TMSS/services/scheduling/test/t_dynamic_scheduling.py b/SAS/TMSS/services/scheduling/test/t_dynamic_scheduling.py index 1a391f7b125cff80f7e9581b3359999b30558f8c..54ee94f8b4fd8898bcd508bce97d2b1341611e41 100755 --- a/SAS/TMSS/services/scheduling/test/t_dynamic_scheduling.py +++ b/SAS/TMSS/services/scheduling/test/t_dynamic_scheduling.py @@ -62,8 +62,10 @@ from lofar.sas.tmss.tmss.tmssapp.subtasks import unschedule_subtask from lofar.common.postgres import PostgresDatabaseConnection # the module under test +import lofar.sas.tmss.services.scheduling.constraints.template_constraints_v1 as tc1 from lofar.sas.tmss.services.scheduling.dynamic_scheduling import * + @unittest.skip('Disabled until scheduler can deal with failing constraints. (Currently causes infinite loop.)') class TestDynamicScheduling(unittest.TestCase): ''' @@ -386,7 +388,7 @@ class TestDailyConstraints(unittest.TestCase): returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp) self.assertEqual(returned_time, self.sunrise_data['CS001']['day'][1]['start']) - def test_can_run_within_timewindow_with_daytime_constraint_returns_true(self): + def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_daytime_constraint_returns_true(self): self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky']['min_distance'] = {} # remove sky constraint self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True self.scheduling_unit_blueprint.save() @@ -394,9 +396,9 @@ class TestDailyConstraints(unittest.TestCase): self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night lower_bound = datetime(2020, 1, 1, 10, 0, 0) upper_bound = datetime(2020, 1, 1, 15, 0, 0) - self.assertTrue(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound)) + self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound)) - def test_can_run_within_timewindow_with_daytime_constraint_returns_false_when_not_daytime(self): + def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_daytime_constraint_returns_false_when_not_daytime(self): self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky']['min_distance'] = {} # remove sky constraint self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True self.scheduling_unit_blueprint.save() @@ -404,9 +406,9 @@ class TestDailyConstraints(unittest.TestCase): self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night lower_bound = datetime(2020, 1, 1, 20, 0, 0) upper_bound = datetime(2020, 1, 1, 23, 0, 0) - self.assertFalse(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound)) + self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound)) - def test_can_run_within_timewindow_with_daytime_constraint_returns_false_when_partially_not_daytime(self): + def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_daytime_constraint_returns_false_when_partially_not_daytime(self): self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky']['min_distance'] = {} # remove sky constraint self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True self.scheduling_unit_blueprint.save() @@ -414,12 +416,12 @@ class TestDailyConstraints(unittest.TestCase): self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night lower_bound = datetime(2020, 1, 1, 10, 0, 0) upper_bound = datetime(2020, 1, 1, 18, 0, 0) - self.assertFalse(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound)) + self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound)) self.sunrise_mock.return_value = self.sunrise_data_early_night_late_night lower_bound = datetime(2020, 1, 1, 8, 0, 0) upper_bound = datetime(2020, 1, 1, 10, 0, 0) - self.assertFalse(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound)) + self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound)) # require_night @@ -463,7 +465,7 @@ class TestDailyConstraints(unittest.TestCase): returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp) self.assertEqual(returned_time, self.sunrise_data_early_night['CS001']['night'][1]['start']) - def test_can_run_within_timewindow_with_nighttime_constraint_returns_true(self): + def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_nighttime_constraint_returns_true(self): self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky']['min_distance'] = {} # remove sky constraint self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_night'] = True self.scheduling_unit_blueprint.save() @@ -472,21 +474,21 @@ class TestDailyConstraints(unittest.TestCase): self.sunrise_mock.return_value = self.sunrise_data_early_night_early_night lower_bound = datetime(2020, 1, 1, 1, 0, 0) upper_bound = datetime(2020, 1, 1, 3, 0, 0) - self.assertTrue(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound)) + self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound)) # late night self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night lower_bound = datetime(2020, 1, 1, 20, 0, 0) upper_bound = datetime(2020, 1, 1, 23, 0, 0) - self.assertTrue(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound)) + self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound)) # night-night next day self.sunrise_mock.return_value = self.sunrise_data_late_night_early_night_next_day lower_bound = datetime(2020, 1, 1, 23, 0, 0) upper_bound = datetime(2020, 1, 2, 3, 0, 0) - self.assertTrue(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound)) + self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound)) - def test_can_run_within_timewindow_with_nighttime_constraint_returns_false_when_not_nighttime(self): + def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_nighttime_constraint_returns_false_when_not_nighttime(self): self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky']['min_distance'] = {} # remove sky constraint self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_night'] = True self.scheduling_unit_blueprint.save() @@ -494,9 +496,9 @@ class TestDailyConstraints(unittest.TestCase): self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night lower_bound = datetime(2020, 1, 1, 10, 0, 0) upper_bound = datetime(2020, 1, 1, 14, 0, 0) - self.assertFalse(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound)) + self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound)) - def test_can_run_within_timewindow_with_nighttime_constraint_returns_false_when_partially_not_nighttime(self): + def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_nighttime_constraint_returns_false_when_partially_not_nighttime(self): self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky']['min_distance'] = {} # remove sky constraint self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_night'] = True self.scheduling_unit_blueprint.save() @@ -505,37 +507,37 @@ class TestDailyConstraints(unittest.TestCase): self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night_next_day lower_bound = datetime(2020, 1, 1, 23, 0, 0) upper_bound = datetime(2020, 1, 2, 10, 0, 0) - self.assertFalse(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound)) + self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound)) # day-night next day self.sunrise_mock.return_value = self.sunrise_data_late_night_early_night_next_day lower_bound = datetime(2020, 1, 1, 14, 0, 0) upper_bound = datetime(2020, 1, 2, 3, 0, 0) - self.assertFalse(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound)) + self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound)) # day-night same day self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night lower_bound = datetime(2020, 1, 1, 14, 0, 0) upper_bound = datetime(2020, 1, 1, 20, 0, 0) - self.assertFalse(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound)) + self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound)) # night-day same day self.sunrise_mock.return_value = self.sunrise_data_early_night_late_night lower_bound = datetime(2020, 1, 1, 3, 0, 0) upper_bound = datetime(2020, 1, 1, 10, 0, 0) - self.assertFalse(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound)) + self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound)) # day-night-day self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night_next_day lower_bound = datetime(2020, 1, 1, 14, 0, 0) upper_bound = datetime(2020, 1, 2, 10, 0, 0) - self.assertFalse(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound)) + self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound)) # night-day-night self.sunrise_mock.return_value = self.sunrise_data_early_night_late_night lower_bound = datetime(2020, 1, 1, 3, 0, 0) upper_bound = datetime(2020, 1, 1, 23, 0, 0) - self.assertFalse(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound)) + self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound)) # avoid_twilight @@ -610,7 +612,7 @@ class TestDailyConstraints(unittest.TestCase): returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp) self.assertEqual(returned_time, self.sunrise_data['CS001']['day'][0]['start']) - def test_can_run_within_timewindow_with_twilight_constraint_returns_true(self): + def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_twilight_constraint_returns_true(self): self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky'][ 'min_distance'] = {} # remove sky constraint self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True @@ -619,9 +621,9 @@ class TestDailyConstraints(unittest.TestCase): self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night lower_bound = datetime(2020, 1, 1, 10, 0, 0) upper_bound = datetime(2020, 1, 1, 15, 0, 0) - self.assertTrue(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound)) + self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound)) - def test_can_run_within_timewindow_with_twilight_constraint_returns_false_when_in_twilight(self): + def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_twilight_constraint_returns_false_when_in_twilight(self): self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky'][ 'min_distance'] = {} # remove sky constraint self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True @@ -630,9 +632,9 @@ class TestDailyConstraints(unittest.TestCase): self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night lower_bound = datetime(2020, 1, 1, 20, 0, 0) upper_bound = datetime(2020, 1, 1, 23, 0, 0) - self.assertFalse(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound)) + self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound)) - def test_can_run_within_timewindow_with_twilight_constraint_returns_false_when_partially_in_twilight(self): + def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_twilight_constraint_returns_false_when_partially_in_twilight(self): self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky'][ 'min_distance'] = {} # remove sky constraint self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True @@ -641,12 +643,12 @@ class TestDailyConstraints(unittest.TestCase): self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night lower_bound = datetime(2020, 1, 1, 10, 0, 0) upper_bound = datetime(2020, 1, 1, 18, 0, 0) - self.assertFalse(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound)) + self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound)) self.sunrise_mock.return_value = self.sunrise_data_early_night_late_night lower_bound = datetime(2020, 1, 1, 8, 0, 0) upper_bound = datetime(2020, 1, 1, 10, 0, 0) - self.assertFalse(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound)) + self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound)) class TestSkyConstraints(unittest.TestCase): @@ -676,18 +678,18 @@ class TestSkyConstraints(unittest.TestCase): # min_distance - def test_can_run_within_timewindow_with_min_distance_constraint_returns_true_when_met(self): + def test_can_run_anywhere_within_timewindow_with_sky_constraints_with_min_distance_constraint_returns_true_when_met(self): self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky']['min_distance'] = {'sun': 0.1, 'moon': 0.1, 'jupiter': 0.1} self.scheduling_unit_blueprint.save() timestamp = datetime(2020, 1, 1, 10, 0, 0) - returned_value = can_run_within_timewindow(self.scheduling_unit_blueprint, timestamp, timestamp + timedelta(seconds=self.obs_duration)) + returned_value = tc1.can_run_anywhere_within_timewindow_with_sky_constraints(self.scheduling_unit_blueprint, timestamp, timestamp + timedelta(seconds=self.obs_duration)) self.assertTrue(returned_value) - def test_can_run_within_timewindow_with_min_distance_constraint_returns_false_when_not_met(self): + def test_can_run_anywhere_within_timewindow_with_sky_constraints_with_min_distance_constraint_returns_false_when_not_met(self): self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky']['min_distance'] = {'sun': 0.2, 'moon': 0.2, 'jupiter': 0.2} self.scheduling_unit_blueprint.save() timestamp = datetime(2020, 1, 1, 10, 0, 0) - returned_value = can_run_within_timewindow(self.scheduling_unit_blueprint, timestamp, timestamp + timedelta(seconds=self.obs_duration)) + returned_value = tc1.can_run_anywhere_within_timewindow_with_sky_constraints(self.scheduling_unit_blueprint, timestamp, timestamp + timedelta(seconds=self.obs_duration)) self.assertFalse(returned_value)