from lofarobsxml.observationspecificationbase import ObservationSpecificationBase
from lofarobsxml.momformats import mom_duration, mom_timestamp, mom_frequency_range
from lofarobsxml.momformats import mom_antenna_name_from_mac_name
from lofarobsxml.targetsource import TargetSource
from lofarobsxml.utilities import validate_enumeration, indent
from math import ceil
import ephem
class Observation(ObservationSpecificationBase):
def __init__(self, antenna_set, frequency_range, start_date, duration_seconds,
stations, clock_mhz, beam_list, backend, name = None, bit_mode=16,
allow_tbb=True, allow_aartfaac=True, initial_status='opened'):
"""
*antenna_set* : One of 'LBA_INNER', 'LBA_OUTER', 'LBA_SPARSE_ODD',
'LBA_SPARSE_EVEN', 'HBA_ZERO', 'HBA_ONE',
'HBA_DUAL', or 'HBA_JOINED'
*frequency_range* : One of 'LBA_LOW' (10-90/70 MHz), 'LBA_HIGH' (30-90/70 MHz),
'HBA_LOW' (110-190 MHz), 'HBA_MID' (170-230 MHz), or
'HBA_HIGH' (210-250 MHz)
*start_date* : UTC time of the beginning of the observation as a tuple
with format (year, month, day, hour, minute, second)
*duration_seconds* : Observation duration in seconds
*stations* : List of stations, e.g. ['CS001', 'RS205', 'DE601']. An
easy way to generate such a list is through the
utilities.station_list() function.
*clock_mhz* : An integer value of 200 or 160.
*beam_list* : A list of Beam objects, which contain source/subband
specifications. Provide at least one beam.
*backend* : BackendProcessing instance with correlator settings
*name* : Name of the observation. Defaults to name of first target plus antenna set.
*bit_mode* : number of bits per sample. Either 4, 8, or 16.
*initial_status* : status when first imported into MoM. Either 'opened' or 'approved'
allow_tbb : bool
If True, allow piggy-back observing with Transient Buffer Boards [TBB].
Default: True.
allow_aartfaac : bool
If True, allow piggy-back observing with AARTFAAC.
Default: True.
"""
super(Observation, self).__init__(name = name, parent = None, children = None,
initial_status=initial_status)
self.antenna_set = antenna_set
self.frequency_range = frequency_range
self.duration_seconds = duration_seconds
self.stations = stations
self.clock_mhz = int(clock_mhz)
self.start_date = start_date
self.bit_mode = bit_mode
self.allow_aartfaac = allow_aartfaac
self.allow_tbb = allow_tbb
self.backend = backend
for beam in beam_list:
self.append_child(beam)
self.validate()
pass
def validate(self):
valid_antenna_sets = ['LBA_INNER', 'LBA_OUTER',
'LBA_SPARSE_ODD', 'LBA_SPARSE_EVEN',
'HBA_ZERO', 'HBA_ONE',
'HBA_DUAL', 'HBA_JOINED',
'HBA_DUAL_INNER']
valid_frequency_ranges = ['LBA_LOW', 'LBA_HIGH', 'HBA_LOW', 'HBA_MID', 'HBA_HIGH']
valid_clocks = [160, 200]
valid_bit_modes = [4, 8, 16]
validate_enumeration('Observation antenna set', self.antenna_set, valid_antenna_sets)
validate_enumeration('Observation frequency range', self.frequency_range, valid_frequency_ranges)
validate_enumeration('Observation clock frequency', self.clock_mhz, valid_clocks)
validate_enumeration('Observation observation bit mode', self.bit_mode, valid_bit_modes)
if type(self.start_date) != type(tuple([])) or len(self.start_date) != 6:
raise ValueError('Observation start_date must be a tuple of length 6; you provided %s'%(self.start_date,))
pass
def xml_prefix(self, project_name):
obs_name = self.children[0].target_source.name+' '+self.antenna_set
if self.name:
obs_name = self.name
now = ephem.Observer().date
start_date = self.start_date
end_date = ephem.Date(ephem.Date(self.start_date) + ephem.second*(self.duration_seconds)).tuple()
rounded_start_date = start_date[:-1]+(int(round(start_date[-1])),)
rounded_end_date = end_date[:-1]+(int(round(end_date[-1])),)
now = now.tuple()[:-1] + (int(round(now.tuple()[-1])),)
observation_str = '''<lofar:observation>
<name>'''+obs_name+'''</name>
<description>'''+obs_name+'''</description>
<topology>'''+self.label()+'''</topology>
<currentStatus>
<mom2:'''+self.initial_status+'''Status/>
</currentStatus>
<lofar:observationAttributes>
<name>'''+obs_name+'''</name>
<projectName>'''+project_name+'''</projectName>
<instrument>'''+self.backend.instrument_name()+'''</instrument>
<defaultTemplate>'''+self.backend.default_template+'''</defaultTemplate>
<tbbPiggybackAllowed>'''+str(self.allow_tbb).lower()+'''</tbbPiggybackAllowed>
<aartfaacPiggybackAllowed>'''+str(self.allow_aartfaac).lower()+'''</aartfaacPiggybackAllowed>
<userSpecification>
<antenna>'''+mom_antenna_name_from_mac_name(self.antenna_set)+'''</antenna>
<clock mode=\"'''+str(self.clock_mhz)+''' MHz\"/>
<instrumentFilter>'''+mom_frequency_range(self.frequency_range, self.clock_mhz)+'''</instrumentFilter>
'''+indent(self.backend.xml(), 6)+''' <stationSet>Custom</stationSet>
<stations>
'''+'\n '.join(['<station name=\"'+n+'\" />' for n in self.stations])+'''
</stations>
<timeFrame>UT</timeFrame>
<startTime>'''+mom_timestamp(*rounded_start_date)+'''</startTime>
<endTime>'''+mom_timestamp(*rounded_end_date)+'''</endTime>
<duration>'''+mom_duration(seconds = self.duration_seconds)+'''</duration>
<numberOfBitsPerSample>'''+str(self.bit_mode)+'''</numberOfBitsPerSample>
</userSpecification>
<systemSpecification/>
</lofar:observationAttributes>'''
return observation_str
def xml_suffix(self, project_name = None):
observation_str = '\n</lofar:observation>'
return observation_str
[docs]def xml(items, project='2015LOFAROBS_new', description=None):
"""
Format a list of *items* as an XML string that can be
uploaded to a MoM project with name *project*.
"""
return """<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<lofar:project xmlns:lofar=\"http://www.astron.nl/MoM2-Lofar\"
xmlns:mom2=\"http://www.astron.nl/MoM2\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.astron.nl/MoM2-Lofar http://lofar.astron.nl:8080/mom3/schemas/LofarMoM2.xsd http://www.astron.nl/MoM2 http://lofar.astron.nl:8080/mom3/schemas/MoM2.xsd \">
<version>1.16</version>
<name>"""+project+"""</name>
<description>"""+ (description or project) +"""</description>
<children>
<item>\n"""+' </item>\n <item>'.join([indent(item.xml(project), 8)
for child_id, item in enumerate(items)])+"""
</item>
</children>
</lofar:project>
"""