diff --git a/MAPS/merge_maps.py b/MAPS/merge_maps.py index 95f1c062296d21c53c1157298ee3c4639dbe6d1f..3bb9cd72e693a03e2a07fb8e42f3a42cca0630b1 100644 --- a/MAPS/merge_maps.py +++ b/MAPS/merge_maps.py @@ -2,34 +2,91 @@ 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.slots = [] + 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.num = -1 - # These go in front of SLOT number. - self.KWs1 = { - 'ROC': -1, - } - # These go after the SLOT number. - self.KWs2 = { - 'REFCHAN': -1, - 'REFINDEX': -1 - } - # These are ignored. - self.SkipKWs = set([ - 'MASK', - 'NSUBADD', - 'BSUB', - ]) - self.entries = [] + self.ID = -1 + self.comment = '' + self.KWs = {kw: -1 for kw in slotKWs} + self.channels = [] + + def __str__(self): + string = 'SLOT={0.ID}'.format(self) + if self.comment != '': + string += ' ! {0.comment}'.format(self) + 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 (sys.argv[1] == '-h' or len(sys.argv) != 3): + print('Call as:') + print(' merge_maps.py merge_list.txt outfile.map') + sys.exit() listName = sys.argv[1] @@ -44,21 +101,18 @@ with open(listName, 'r') as fi: ] -# Header information. -KWs = [] -IDs = [] -signals = [] +header = { + "KWs": [], + "IDs": [], + "signals": [], +} -# Detector information. -detectors = [] +detectors = [Detector()] for fileName in fileNames: - detector = Detector() - slot = Slot() - # Track detector IDs in current file. - IDsCurrent = [] + currentIDs = [] with open(fileName, 'r') as fi: for line in fi: @@ -66,6 +120,8 @@ for fileName in fileNames: if line.isspace(): continue + line = line.strip() + # Check if comment line. if line.startswith('!'): # Check if header line. @@ -73,25 +129,23 @@ for fileName in fileNames: i = line.find('_ID=') if i == -1: continue - else: - KW = line[1:i].strip() - ID = line[i+4:].split()[0].strip() - signal = ','.join(line[i+4:].split()[1:]) - - if KW in KWs: - print('Detector keyword `{}` already present!'.format(KW)) - sys.exit(1) - if ID in IDs: - print('Detector ID `{}` already present!'.format(ID)) - sys.exit(1) - KWs.append(KW) - IDs.append(ID) - IDsCurrent.append(ID) - signals.append(signal) - continue - - line = line.strip() + KW = line[1:i].strip() + ID = line[i+4:].split()[0].strip() + signal = ','.join(line[i+4:].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('!') @@ -100,93 +154,102 @@ for fileName in fileNames: 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() - value = line[i+1:] + ID = line[i+1:] - if command in slot.KWs1.keys(): - slot.KWs1[command] = value - elif command in slot.KWs2.keys(): - slot.KWs2[command] = value - elif command in slot.SkipKWs: - continue + 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 == 'DETECTOR': - if detector.ID > 0: - detectors.append(detector) - detector = Detector() - if value not in IDsCurrent: - print('Detector ID `{}` not found!'.format(value)) - sys.exit() - detector.ID = value + 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 slot.num > 0: - detector.slots.append(slot) - slot = Slot() - slot.num = value + 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(',') - values = ','.join(['{:>4}'.format(val) for val in values]) - slot.entries.append('{} ! {}'.format(values, comment)) - - detectors.append(detector) + detectors[-1].rocs[-1].slots[-1].channels.append( + Channel(*values, comment=comment) + ) - -# Check if each detector has at least one slot and ROC defined. -for ID, KW in sorted(zip(IDs, KWs)): +# 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 len(detector.slots) == 0: - print('Detector with ID {} has no slots!'.format(ID)) - sys.exit(1) - if detector.slots[0].KWs1['ROC'] == -1: - print('No crate defined for detector with ID {}!'.format(ID)) + 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 with ID {}!'.format(ID)) + print('No entry for detector {}!'.format(ID)) +# Write merged map file. with open(mergedName, 'w') as fo: # Write header. - for ID, KW, signal in sorted(zip(IDs, KWs, signals)): + for ID, KW, signals in sorted(zip( + header['IDs'], header['KWs'], header['signals'] + )): IDString = '{}_ID={}'.format(KW, ID) fo.write('! {:15} :: {}\n'.format(IDString, signal)) - # Write detectors sorted by their ID. - for ID, KW in sorted(zip(IDs, KWs)): + # 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{}\n'.format(detector)) - fo.write('\n\n') - fo.write('DETECTOR={0.ID} ! {1}\n'.format(detector, KW)) - - for slot in detector.slots: - fo.write('\n') - - for key, value in sorted(slot.KWs1.items()): - if value > 0: - fo.write('{}={}\n'.format(key, value)) + for roc in detector.rocs: + fo.write('\n{}\n'.format(roc)) - fo.write('SLOT={0.num}\n'.format(slot)) + for slot in roc.slots: + fo.write('\n{}\n'.format(slot)) - for key, value in sorted(slot.KWs2.items()): - if value > 0: - fo.write('{}={}\n'.format(key, value)) + for channel in slot.channels: + fo.write('{}\n'.format(channel)) - for entry in slot.entries: - fo.write('{}\n'.format(entry)) - break +print('\nDone.')