diff --git a/SAS/TMSS/src/tmss/tmssapp/adapters/parset.py b/SAS/TMSS/src/tmss/tmssapp/adapters/parset.py index 94af483cc8fd31248f4fff9f4dc357d6a07175f8..18068fe8ee4976828ebe15c820127f0c54bb2518 100644 --- a/SAS/TMSS/src/tmss/tmssapp/adapters/parset.py +++ b/SAS/TMSS/src/tmss/tmssapp/adapters/parset.py @@ -20,21 +20,70 @@ from lofar.sas.tmss.tmss.tmssapp.models.scheduling import Subtask from lofar.parameterset import parameterset from lofar.common.datetimeutils import formatDatetime +from lofar.common.json_utils import add_defaults_to_json_object_for_schema def convert_to_parset(subtask: Subtask) -> parameterset: - print(subtask.specifications_doc) + # make sure the spec is complete (including all non-filled in properties with default) + spec = add_defaults_to_json_object_for_schema(subtask.specifications_doc, subtask.specifications_template.schema) parset = dict() # parameterset has no proper assignment operators, so take detour via dict... + parset["Observation.ObsID"] = subtask.pk + parset["Observation.momID"] = -1 # Needed by MACScheduler + parset["Observation.otdbID"] = -1 # Needed by MACScheduler; should/can this be the same as subtask.pk? + parset["Observation.processType"] = subtask.specifications_template.type.value.capitalize() + parset["Observation.processSubtype"] = subtask.specifications_template.type.value.capitalize() # TODO: where to derive the processSubtype from? parset["Observation.startTime"] = formatDatetime(subtask.start_time) parset["Observation.stopTime"] = formatDatetime(subtask.stop_time) - parset["Observation.antennaSet"] = subtask.specifications_doc["stations"]["antenna_set"] - parset["Observation.VirtualInstrument.stationList"] = subtask.specifications_doc["stations"]["station_list"] - parset["Observation.bandFilter"] = subtask.specifications_doc["stations"]["filter"] - parset["Observation.sampleClock"] = 200 - parset["Observation.nrBitsPerSample"] = 8 + parset["Observation.VirtualInstrument.stationList"] = spec["stations"]["station_list"] + parset["Observation.antennaSet"] = spec["stations"]["antenna_set"] + parset["Observation.bandFilter"] = spec["stations"]["filter"] + parset["Observation.sampleClock"] = 200 # why is this not part of the schema? for example as a required setting with a single allowed value. + parset["Observation.nrBitsPerSample"] = 8 # why is this not part of the schema? for example as a required setting with a single allowed value. + + digi_beams = spec['stations']['digital_pointings'] + parset["Observation.nrBeams"] = len(digi_beams) + for beam_nr, digi_beam in enumerate(digi_beams): + beam_prefix = "Observation.Beam[%d]." % beam_nr + parset[beam_prefix+"directionType"] = digi_beam['pointing']['direction_type'] + parset[beam_prefix+"angle1"] = digi_beam['pointing']['angle1'] + parset[beam_prefix+"angle2"] = digi_beam['pointing']['angle2'] + parset[beam_prefix+"target"] = digi_beam['name'] + parset[beam_prefix+"subbandList"] = digi_beam['subbands'] + + phase_centers = spec['COBALT']['correlator']['phase_centers'] + if phase_centers: + # for now, cobalt can handle only one phase_center + # assume the first is the one + phase_center = phase_centers[0] + parset[beam_prefix+"Correlator.phaseCenterOverride"] = phase_center['index'] == beam_nr + parset[beam_prefix+"Correlator.directionType"] = phase_center['pointing']['direction_type'] + parset[beam_prefix+"Correlator.angle1"] = phase_center['pointing']['angle1'] + parset[beam_prefix+"Correlator.angle2"] = phase_center['pointing']['angle2'] + + analog_beam = spec['stations']['analog_pointing'] + parset["Observation.nrAnaBeams"] = 1 + beam_prefix = "Observation.AnaBeam[0]." + parset[beam_prefix+"directionType"] = analog_beam['direction_type'] + parset[beam_prefix+"angle1"] = analog_beam['angle1'] + parset[beam_prefix+"angle2"] = analog_beam['angle2'] + + parset["Cobalt.realTime"] = True + parset["Cobalt.blockSize"] = spec['COBALT']['blocksize'] + parset["Cobalt.correctBandPass"] = spec['COBALT']['bandpass_correction'] + parset["Cobalt.delayCompensation"] = spec['COBALT']['delay_compensation'] + + parset["Cobalt.Correlator.nrChannelsPerSubband"] = spec['COBALT']['correlator']['channels_per_subband'] + parset["Cobalt.Correlator.nrBlocksPerIntegration"] = spec['COBALT']['correlator']['blocks_per_integration'] + parset["Cobalt.Correlator.nrIntegrationsPerBlock"] = spec['COBALT']['correlator']['integrations_per_block'] + + parset["Observation.DataProducts.Output_Correlated.enabled"] = True + + # TODO: locations of dataproducts + parset["Observation.DataProducts.Output_Correlated.filenames"] = [] + parset["Observation.DataProducts.Output_Correlated.locations"] = [] + parset["Observation.Cluster.ProcessingCluster.clusterName"] = subtask.cluster or "CEP4" # convert dict to real parameterset, and return it parset = parameterset(parset) - print(parset) return parset diff --git a/SAS/TMSS/test/t_parset_adapter.py b/SAS/TMSS/test/t_parset_adapter.py index c4aad2d1fa54aa717e2b53834cc3f9ed96933c9b..39b9f01f1871e991e5185fbf4a78e47b91f17ca5 100755 --- a/SAS/TMSS/test/t_parset_adapter.py +++ b/SAS/TMSS/test/t_parset_adapter.py @@ -46,6 +46,8 @@ class ParsetAdapterTest(unittest.TestCase): def test_01(self): subtask_template = models.SubtaskTemplate.objects.get(name='obscontrol schema') specifications_doc = get_default_json_object_for_schema(subtask_template.schema) + for dp in specifications_doc['stations']['digital_pointings']: + dp['subbands'] = list(range(8)) subtask_data = Subtask_test_data(subtask_template, specifications_doc) subtask = models.Subtask.objects.create(**subtask_data)