diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py b/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py index e67b2972a11ed4617e724ebde3ddb2e26d8b6042..4fe567030157c268a2fd63275fc23f6fbe8b6ff4 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py @@ -1050,7 +1050,7 @@ def schedule_observation_subtask(observation_subtask: Subtask): directory=directory, dataformat=Dataformat.objects.get(value="MeasurementSet"), datatype=Datatype.objects.get(value="visibilities"), - producer=subtask_output, + producer=subtask_output, # Select correct output for target or calibrator. Depending on pointing name? specifications_doc={"sap": [str(sap_nr)]}, specifications_template=dataproduct_specifications_template, feedback_doc=get_default_json_object_for_schema(dataproduct_feedback_template.schema), diff --git a/SAS/TMSS/backend/test/t_scheduling.py b/SAS/TMSS/backend/test/t_scheduling.py index 115d918a25e975ef8539ff09d63bc67f8bc13fda..877248bf200226035620a0c00eea3e9146772a40 100755 --- a/SAS/TMSS/backend/test/t_scheduling.py +++ b/SAS/TMSS/backend/test/t_scheduling.py @@ -447,6 +447,60 @@ class SubtaskInputOutputTest(unittest.TestCase): self.assertEqual(set(pipe_in1.dataproducts.all()), {dp1_1, dp1_3}) self.assertEqual(set(pipe_in2.dataproducts.all()), {dp2_2}) + @mock.patch("lofar.sas.tmss.tmss.tmssapp.subtasks.assign_or_unassign_resources") + def test_combined_target_calibrator_subtask_connects_dataproducts_to_correct_output(self, assign_resources_mock): + """ + Create a subtask that combines a target and parallel calibrator observation. + Schedule the subtask and assert that dataproducts are assigned to both outputs. + """ + + # setup tasks + cal_task_template = models.TaskTemplate.objects.get(name="calibrator observation") + cal_task_spec = get_default_json_object_for_schema(cal_task_template.schema) + + cal_task_draft = models.TaskDraft.objects.create(**TaskDraft_test_data(specifications_template=cal_task_template, specifications_doc=cal_task_spec)) + cal_task_blueprint = models.TaskBlueprint.objects.create(**TaskBlueprint_test_data(task_draft=cal_task_draft)) + + target_task_template = models.TaskTemplate.objects.get(name="target observation") + target_task_spec = get_default_json_object_for_schema(target_task_template.schema) + target_task_draft = models.TaskDraft.objects.create(**TaskDraft_test_data(specifications_template=target_task_template, specifications_doc=target_task_spec)) + target_task_blueprint = models.TaskBlueprint.objects.create(**TaskBlueprint_test_data(task_draft=target_task_draft)) + + models.TaskSchedulingRelationBlueprint.objects.create(first=cal_task_blueprint, second=target_task_blueprint, + placement=models.SchedulingRelationPlacement.objects.get(value='parallel')) + + # specify two beams with known number of subbands + target_task_blueprint.specifications_doc['SAPs'] = [{'name': 'target1', 'target': '', 'subbands': [0, 1], + 'digital_pointing': {'angle1': 0.1, 'angle2': 0.1, 'angle3': 0.1, + 'direction_type': 'J2000'}}, + {'name': 'target2', 'target': '', 'subbands': [2, 3, 4], + 'digital_pointing': {'angle1': 0.1, 'angle2': 0.1, 'angle3': 0.1, + 'direction_type': 'J2000'}} + ] + + # create subtask + create_observation_control_subtask_from_task_blueprint(target_task_blueprint) + subtask = create_observation_control_subtask_from_task_blueprint(cal_task_blueprint) + subtask.start_time = datetime.utcnow() + subtask.stop_time = datetime.utcnow() + subtask.save() + + # assert no dataproducts are connected before scheduling + target_output = subtask.outputs.filter(task_blueprint=target_task_blueprint).first() + cal_output = subtask.outputs.filter(task_blueprint=cal_task_blueprint).first() + self.assertEqual(target_output.dataproducts.count(), 0) + self.assertEqual(cal_output.dataproducts.count(), 0) + + # schedule, and assert subtask state + self.assertEqual('defined', subtask.state.value) + schedule_observation_subtask(subtask) + self.assertEqual('scheduled', subtask.state.value) + + # assert dataproducts are connected to both outputs after scheduling + # task and calibrator tasks should each have associated one dataproduct per subband of the target task + self.assertEqual(target_output.dataproducts.count(), 5) + self.assertEqual(cal_output.dataproducts.count(), 5) + class SAPTest(unittest.TestCase): """