ATLAS Offline Software
Loading...
Searching...
No Matches
MuonFixedIdUnpack.py
Go to the documentation of this file.
1# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
2
3import re
4import math
5
6class MdtIdError(Exception): pass
7
9 "Unpack numeric MuonId and convert to station Phi phi eta, and the reverse. Accept numeric id, online(hardware), or offline (software) name for initialization. Will throw TubeIdError exception if id format is not known. There are no methods to produce online format name strings, only offline."
10
11 #identifier - public
12 identifier=None
13
14 # regex common to string input formats
15 __stationRe = '(?P<station>[BE][IEMO][MESLRFG])'
16 __mlRe = '[-_]{0,1}(?P<ml>[12]){0,1}[-_]{0,1}(?P<ly>[1234]){0,1}[-_]{0,1}(?P<tb>[1-9][0-9]{0,2}){0,1}'
17
18 # regexps to match tube string possibilities
19 online_re = re.compile(__stationRe + '(?P<eta>[0-8][AC])(?P<phi>[0-1][0-9])' + __mlRe)
20 offline_re = re.compile(__stationRe + '_(?P<phi>[1-8])_(?P<eta>\\-*[0-8])_{0,1}' + __mlRe)
21 numeric_re = re.compile('[0-9]{7,9}')
22
23 # set unused fixed id bits to 1? The correct way is to set them. This flag is a convenience to software that may need
24 # to read from datasets where the bits were not set correctly
25 # BML5A01
26 # Example set: 01001101000000111
27 # Example unset: 01001101000000000
28 setUnusedBits = True
29
30 def __init__(self, iid=None, setUnusedBits=True):
31 self.setUnusedBits = setUnusedBits
32 if iid is None:
33 return
34 if (self.numeric_re.match(str(iid)) is not None):
35 self.identifier=int(iid)
36 else:
37 idmatch = self.offline_re.match(str(iid))
38 if (idmatch is not None):
39 # default to 1 for groups not participating in match (same as method defaults if last three arguments not provided)
40 idgroups = idmatch.groupdict(1)
41 self.InitByParam(idgroups['station'], idgroups['phi'], idgroups['eta'],idgroups['ml'],idgroups['ly'],idgroups['tb'])
42 else:
43 idmatch = self.online_re.match(str(iid))
44 if(idmatch is not None):
45 idgroups = idmatch.groupdict(1)
46 swid = self.mapToOffline(idgroups['station'],idgroups['phi'], idgroups['eta'],idgroups['ml'],idgroups['ly'],idgroups['tb'])
47 self.InitByParam(swid['station'],swid['phi'], swid['eta'], swid['ml'],swid['ly'],swid['tb'])
48 else:
49 raise MdtIdError("MDT id format does not match any known type")
50
51 #station name
53 if self.identifier:
54 return (self.identifier >> self.__kStationNameShift) & self.__kStationNameMask
55
56 def stationName(self):
57 if self.identifier:
58 return self.stationNameIndex() + self.__kStationNameMin
59
60
62 if self.identifier:
63 idx=self.stationName() - 1
64 if idx >= len(self.__kStationNameStrings):
65 return "XXX"
66 return self.__kStationNameStrings[ idx ]
67
68
69 #station Phi
70 def stationPhiIndex(self):
71 if self.identifier:
72 return (self.identifier >> self.__kStationPhiShift) & self.__kStationPhiMask
73
74 def stationPhi(self):
75 if self.identifier:
76 return self.stationPhiIndex() + self.__kStationPhiMin
77
78
79 #station Eta
80 def stationEtaIndex(self):
81 if self.identifier:
82 return (self.identifier >> self.__kStationEtaShift) & self.__kStationEtaMask
83
84 def stationEta(self):
85 if self.identifier:
86 return self.stationEtaIndex() + self.__kStationEtaMin
87
88
89 #multilayer
91 if self.identifier:
92 return (self.identifier >> self.__kMdtMultilayerShift) & self.__kMdtMultilayerMask
93
94 def mdtMultilayer(self):
95 if self.identifier:
96 return self.mdtMultilayerIndex() + self.__kMdtMultilayerMin
97
98
99 #TubeLayer
101 if self.identifier:
102 return (self.identifier >> self.__kMdtTubeLayerShift) & self.__kMdtTubeLayerMask
103
104 def mdtTubeLayer(self):
105 if self.identifier:
106 return self.mdtTubeLayerIndex() + self.__kMdtTubeLayerMin
107
108
109 #Tube
110 def mdtTubeIndex(self):
111 if self.identifier:
112 return (self.identifier >> self.__kMdtTubeShift) & self.__kMdtTubeMask
113
114 def mdtTube(self):
115 if self.identifier:
116 return self.mdtTubeIndex() + self.__kMdtTubeMin
117
118
119 # convert online station,phi,eta to offline equivalents
120 # returns dict of station,phi,eta,ml,ly,tb
121 def mapToOffline(self,station,phi,eta,ml=1, ly=1, tb=1):
122 swconv = {}
123
124 try:
125 swconv['station'] = self.__hardwareStationMaps[station]
126 except KeyError:
127 swconv['station'] = station
128
129 etasign = self.__hardwareSideMap[eta[1]]
130 swconv['phi'] = int(math.ceil(float(phi) / float(2)))
131
132 try:
133 swconv['eta'] = int(etasign + str(self.__hardwareEtaMaps[station][int(phi)][int(eta[0])]))
134 except KeyError:
135 swconv['eta'] = int(etasign + eta[0])
136
137 swconv['ml'] = int(ml)
138 swconv['ly'] = int(ly)
139 swconv['tb'] = int(tb)
140 return swconv
141
142 #init by parameters
143 def InitByParam(self, station, phi, eta, ml=1, ly=1, tb=1):
144 loc_station=station
145 if isinstance(station, str):
146 loc_station = self.__kStationNameStringsMap[station] + 1
147 loc_station -= self.__kStationNameMin
148 loc_station &= self.__kStationNameMask
149 loc_eta = (int(eta) - self.__kStationEtaMin) & self.__kStationEtaMask
150 loc_phi = (int(phi) - self.__kStationPhiMin) & self.__kStationPhiMask
151 loc_ml = (int(ml) - self.__kMdtMultilayerMin) & self.__kMdtMultilayerMask
152 loc_ly = (int(ly) - self.__kMdtTubeLayerMin) & self.__kMdtTubeLayerMask
153 loc_tb = (int(tb) - self.__kMdtTubeMin) & self.__kMdtTubeMask
154 self.identifier = (loc_station << self.__kStationNameShift) | (loc_eta << self.__kStationEtaShift) | (loc_phi << self.__kStationPhiShift) | (loc_ml << self.__kMdtMultilayerShift) | (loc_ly << self.__kMdtTubeLayerShift) | (loc_tb << self.__kMdtTubeShift)
155 if self.setUnusedBits:
156 self.identifier = self.identifier | self.__kUnusedBits
157
158
159
160 __kMdtMultilayerMask = 1
161 __kMdtMultilayerShift = 9
162 __kMdtMultilayerMin = 1
163
164 __kMdtTubeLayerMask = 3
165 __kMdtTubeLayerShift = 7
166 __kMdtTubeLayerMin = 1
167
168 __kMdtTubeMask = 127
169 __kMdtTubeShift = 0
170 __kMdtTubeMin = 1
171
172 __kStationNameMask = 63
173 __kStationNameShift = 24
174 __kStationNameMin = 1
175
176 __kStationEtaMask = 31
177 __kStationEtaShift = 19
178 __kStationEtaMin = -8
179
180 __kStationPhiMask = 63
181 __kStationPhiShift = 13
182 __kStationPhiMin = 1
183
184 __kUnusedBits = 7168
185
186 __kStationNameStrings = [ "BIL", "BIS", "BML", "BMS", "BOL", "BOS", "BEE", "BIR", "BMF", "BOF", "BOG", "BME", "BIM", "EIC", "EIL", "EEL", "EES", "EMC", "EML", "EMS", "EOC", "EOL", "EOS", "EIS", "T1F", "T1E", "T2F", "T2E", "T3F", "T3E", "T4F", "T4E", "CSS", "CSL", "BMG" ]
187
188 __kStationNameStringsMap = { "BIL" : 0,"BIS" : 1,"BML" : 2,"BMS" : 3,"BOL" : 4, "BOS" : 5,"BEE" : 6,"BIR" : 7,"BMF" : 8,"BOF" : 9,"BOG" : 10,"BME" : 11,"BIM" : 12,"EIC" : 13,"EIL" : 14,"EEL" : 15,"EES" : 16,"EMC" : 17,"EML" : 18,"EMS" : 19,"EOC" : 20,"EOL" : 21,"EOS" : 22,"EIS" : 23,"T1F" : 24,"T1E" : 25,"T2F" : 26,"T2E" : 27,"T3F" : 28,"T3E" : 29,"T4F" : 30,"T4E" : 31,"CSS" : 32,"CSL" : 33, "BMG" : 34 }
189
190 # following used for conversion from online to offline
191 # maps for 'non-standard' chambers
192
193 __hardwareStationMaps = { "BOE" : "BOL" }
194 __BOFMAP = {1:1, 3:2, 5:3, 7:4}
195 __BOGMAP = {0:0, 2:1, 4:2, 6:3, 8:4}
196 # keys in this map are the station names and phi values from hardware, values are key:value maps of non standard eta into software convention.
197 __hardwareEtaMaps = {
198 "EEL" : { 5 : { 2:1 } },
199 "BML" : { 13 : { 5:4, 6:5 } },
200 "BOE" : { 13: { 3:7 } },
201 "BME" : { 13 : { 4:1 } },
202 "BOF" : { 12 : __BOFMAP, 14 : __BOFMAP },
203 "BOG" : { 12 : __BOGMAP, 14 : __BOGMAP }
204 }
205 __hardwareSideMap = { "A": "", "C": "-"}
if(febId1==febId2)
__init__(self, iid=None, setUnusedBits=True)
mapToOffline(self, station, phi, eta, ml=1, ly=1, tb=1)
InitByParam(self, station, phi, eta, ml=1, ly=1, tb=1)
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition hcg.cxx:357