Forked from
jlab / hallc / exp / polhe3 / hallc_replay
598 commits behind the upstream repository.
-
Jure Bericic authoredJure Bericic authored
merge_maps.py 6.84 KiB
# -*- coding: utf-8 -*-
from __future__ import division, print_function
import copy
from pprint import pprint
import sys
slotKWs = [
'REFCHAN',
'REFINDEX',
]
skipKws = [
'MASK',
'NSUBADD',
'BSUB',
]
class Detector:
def __init__(self):
self.ID = -1
self.comment = ''
self.rocs = [Roc()]
def __str__(self):
string = 'DETECTOR={0.ID}'.format(self)
if self.comment != '':
string += ' ! {0.comment}'.format(self)
return string
class Roc:
def __init__(self):
self.ID = -1
self.comment = ''
self.slots = [Slot()]
def __str__(self):
string = 'ROC={0.ID}'.format(self)
if self.comment != '':
string += ' ! {0.comment}'.format(self)
return string
class Slot:
def __init__(self):
self.ID = -1
self.comment = ''
self.KWs = {}
self.channels = []
for kw in slotKWs:
self.KWs[kw] = -1
def __str__(self):
string = 'SLOT={0.ID}'.format(self)
if self.comment != '':
string += ' ! {0.comment}'.format(self)
string += '\n'
for k, v in self.KWs.items():
if v > -1:
string += '{}={}\n'.format(k, v)
return string
class Channel:
def __init__(self, ID, plane, bar, signal=-1, comment=''):
self.ID = ID
self.plane = plane
self.bar = bar
self.signal = signal
self.comment = comment
def __str__(self):
string = '{0.ID:>4},{0.plane:>4},{0.bar:>4}'.format(self)
if self.signal >= 0:
string += ',{0.signal:>4}'.format(self)
if self.comment:
string += ' ! {0.comment}'.format(self)
return string
if (len(sys.argv) != 3 or sys.argv[1] == '-h'):
print('Call as:')
print(' merge_maps.py merge_list.txt outfile.map')
sys.exit()
listName = sys.argv[1]
mergedName = sys.argv[2]
# Get map files to merge.
with open(listName, 'r') as fi:
fileNames = [
l.strip() for l in fi
if not l.isspace() and not l.startswith('#')
]
header = {
"KWs": [],
"IDs": [],
"signals": [],
}
detectors = []
for fileName in fileNames:
# Track detector IDs in current file.
currentIDs = []
detectors.append(Detector())
with open(fileName, 'r') as fi:
for line in fi:
# Skip empty lines.
if line.isspace():
continue
line = line.strip()
# Check if comment line.
if line.startswith('!'):
# Check if header line.
# eg: ! HCAL_ID=4 ADC
i = line.find('_ID=')
if i == -1:
continue
KW = line[1:i].strip()
ID = line[i+4:].split()[0].strip()
signal = ','.join(line[i+4:].replace('::', '').split()[1:])
if KW in header['KWs']:
print('Detector keyword `{}` already present!'.format(KW))
sys.exit(1)
if ID in header['IDs']:
print('Detector ID `{}` already present!'.format(ID))
sys.exit(1)
header['KWs'].append(KW)
header['IDs'].append(ID)
header['signals'].append(signal)
currentIDs.append(ID)
continue
# Get comments.
i = line.find('!')
if i > -1:
comment = line[i+1:].strip()
line = ''.join(line[:i].split())
else:
line = ''.join(line.split())
comment = ''
# Check if there is keyword.
i = line.find('=')
if i > -1:
command = line[:i].upper()
ID = line[i+1:]
if command == 'DETECTOR':
if detectors[-1].ID > 0:
detectors.append(Detector())
if ID not in currentIDs:
print('Detector ID `{}` not found!'.format(ID))
sys.exit(1)
detectors[-1].ID = ID
detectors[-1].comment = comment
elif command == 'ROC':
if detectors[-1].rocs[-1].ID > 0:
detectors[-1].rocs.append(Roc())
detectors[-1].rocs[-1].ID = ID
detectors[-1].rocs[-1].comment = comment
elif command == 'SLOT':
if detectors[-1].rocs[-1].slots[-1].ID > 0:
detectors[-1].rocs[-1].slots.append(Slot())
detectors[-1].rocs[-1].slots[-1].ID = ID
detectors[-1].rocs[-1].slots[-1].comment = comment
elif command in slotKWs:
detectors[-1].rocs[-1].slots[-1].KWs[command] = ID
elif command in skipKWs:
pass
else:
print('Unknown command `{}` in line:'.format(command))
print(line)
continue
# This must be channel line.
values = line.split(',')
detectors[-1].rocs[-1].slots[-1].channels.append(
Channel(*values, comment=comment)
)
# Check if each detector has defined at least one ROC and slot.
for ID, KW in sorted(zip(header['IDs'], header['KWs'])):
found = False
for detector in detectors:
if detector.ID == ID:
found = True
if detector.rocs[0].ID < 0:
print('No crate defined for detector {}!'.format(ID))
sys.exit(1)
for roc in detector.rocs:
if roc.slots[0].ID < 0:
print(
'No slot defined for crate {} in detector {}!'.format(
roc.ID, detector.ID
)
)
sys.exit(1)
if not found:
print('No entry for detector {}!'.format(ID))
# Write merged map file.
with open(mergedName, 'w') as fo:
# Write header.
for ID, KW, signals in sorted(zip(
header['IDs'], header['KWs'], header['signals']
)):
IDString = '{0}_ID={1}'.format(KW, ID)
fo.write('! {0:15} :: {1}\n'.format(IDString, signals))
# Write detector maps sorted by IDs.
for ID, KW in sorted(zip(
header['IDs'], header['KWs']
)):
for detector in detectors:
if detector.ID == ID:
fo.write('\n\n{0}\n'.format(detector))
for roc in detector.rocs:
fo.write('\n{0}\n'.format(roc))
for slot in roc.slots:
fo.write('\n{0}'.format(slot))
for channel in slot.channels:
fo.write('{0}\n'.format(channel))
print('\nDone.')