diff --git a/SAS/TMSS/backend/services/scheduling/test/t_dynamic_scheduling.py b/SAS/TMSS/backend/services/scheduling/test/t_dynamic_scheduling.py index eae4dc9c97d568831e7e49df7ff542d26bb14f1f..9767b76eb5923e4524c5a93ca4f565720a7c4f28 100755 --- a/SAS/TMSS/backend/services/scheduling/test/t_dynamic_scheduling.py +++ b/SAS/TMSS/backend/services/scheduling/test/t_dynamic_scheduling.py @@ -3175,6 +3175,129 @@ class TestDynamicScheduling(BaseDynamicSchedulingTestCase): self.assertFalse("FR606" in su_blueprint.unschedulable_reason) self.assertTrue("IE613" in su_blueprint.unschedulable_reason) + def test_bugfix_TMSS_2823_coarse_fine_grid(self): + '''Test the correct evaluation at both the coarse and fine grid for this tightly-constrained unit. + See https://support.astron.nl/jira/browse/TMSS-2823. + This test uses a specification from https://tmss.lofar.eu/api/scheduling_unit_blueprint/3703/specifications_doc_with_just_the_parameters + ''' + project = models.Project.objects.create(**Project_test_data(name=str(uuid.uuid4()), project_state=models.ProjectState.objects.get(value=models.ProjectState.Choices.ACTIVE.value))) + cycle = models.Cycle.objects.create(**Cycle_test_data(name=str(uuid.uuid4()), start=datetime(2020, 1, 1), stop=datetime(2030, 1, 1))) + project.cycles.set([cycle]) + project.save() + + scheduling_set = models.SchedulingSet.objects.create(**SchedulingSet_test_data(project=project)) + strategy_template = models.SchedulingUnitObservingStrategyTemplate.get_latest(name="IM LBA Survey - 3 Beams") + + spec = { + "scheduling_constraints_doc": { + "daily": { + "avoid_twilight": True, + "require_day": False, + "require_night": True + }, + "location": "center", + "scheduler": "dynamic", + "sky": { + "min_distance": { + "jupiter": 0.2617993877991494, + "moon": 0.5235987755982988, + "sun": 0.5235987755982988 + }, + "min_elevation": { + "calibrator": 0.5235987755982988, + "target": 0.6108652381980153 + }, + "reference_pointing": { + "enabled": False, + "pointing": { + "angle1": 0, + "angle2": 0, + "direction_type": "J2000", + "target": "_target_name_" + } + }, + "transit_offset": { + "from": -8100, + "to": -7500 + } + }, + "time": { + "between": [], + "not_between": [], + # "at": "2024-02-02T02:27:12Z" + } + }, + "tasks": { + "Combined Observation": { + "short_description": "O4.1_field-1_field-3_field-7", + "specifications_doc": { + "QA": { + "file_conversion": { + "enabled": False + }, + "plots": { + "enabled": False + } + }, + "calibrator": { + "pointing": { + "angle1": 3.714676749469887, + "angle2": 0.9111089934308438, + "direction_type": "J2000", + "target": "3c295" + } + }, + "duration": 7200, + "station_configuration": { + "SAPs": [ + { + "digital_pointing": { + "angle1": 3.319577840049671, + "angle2": 0.25591239223217255, + "direction_type": "J2000", + "target": "field-1" + } + }, + { + "digital_pointing": { + "angle1": 3.2392385892511197, + "angle2": 0.21168225832813228, + "direction_type": "J2000", + "target": "field-3" + } + }, + { + "digital_pointing": { + "angle1": 3.291280816887087, + "angle2": 0.12433376525357202, + "direction_type": "J2000", + "target": "field-7" + } + } + ], + "station_groups": [ + { + "max_nr_missing": 0, + "stations": [ + "CS002" + ] + } + ] + } + } + } + } + } + + su_draft = create_scheduling_unit_draft_from_observing_strategy_template(strategy_template, scheduling_set=scheduling_set, specifications_doc_overrides=spec) + su_blueprint = create_scheduling_unit_blueprint_and_tasks_and_subtasks_from_scheduling_unit_draft(su_draft) + + # let the scheduler search for this unit in a known schedulable window. + # it should find this unit (and thus, in scheduler.do_dynamic_schedule it should get scheduled) + best_next_schedulable_unit = self.scheduler.find_best_next_schedulable_unit([su_blueprint], datetime(2024, 2, 16), datetime(2024, 2, 17)) + self.assertIsNotNone(best_next_schedulable_unit) + self.assertEqual(su_blueprint.id, best_next_schedulable_unit.id) + def test_scheduling_blocks_outside_observation_window_TMSS_2298_bugfix(self): '''When scheduling two units, one a bit after the other, the first units erroneously blocks the second outside its observation window.