ATLAS Offline Software
DetStatusLib.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
2 
3 # DetStatusLib.py
4 # python functions/classes to help management of detector status information
5 # Richard Hawkings, 5/2/07
6 
7 from __future__ import print_function
8 
9 def folderName(runLumi=True):
10  if (runLumi):
11  return '/GLOBAL/DETSTATUS/LBSUMM'
12  else:
13  return '/GLOBAL/DETSTATUS/TISUMM'
14 
15 def colour(code):
16  if (code==-1):
17  return "BLACK"
18  rcode=code % 4
19  if (rcode==1):
20  return "RED"
21  elif (rcode==2):
22  return "YELLOW"
23  elif (rcode==3):
24  return "GREEN"
25  return "UNKNOWN"
26 
27 def colourVal(sval):
28  "Translate traffic light string (numerical literal or letter) to number"
29  status=0
30  try:
31  uplight=sval.upper()
32  if uplight in ["R","RED"]:
33  status=1
34  elif uplight in ["Y","YELLOW"]:
35  status=2
36  elif uplight in ["G","GREEN"]:
37  status=3
38  elif uplight in ["U","UNKNOWN"]:
39  status=0
40  elif uplight in ["B","BLACK"]:
41  status=-1
42  else:
43  status=int(sval)
44  except Exception:
45  status=None
46  return status
47 
48 
50  def __init__(self):
51  # current list of status flags
52  # has to match definition in DetStatusSvc.cxx
53 
54  self.namedict={'PIXB':101,'PIX0':102,'PIXEA':104,'PIXEC':105,
55  'SCTB':111,'SCTEA':114,'SCTEC':115,
56  'TRTB':121,'TRTEA':124,'TRTEC':125,'TRTTR':126,
57  'IDGL':130,
58  'IDAL':140,
59  'IDBS':150,
60  'IDPF':160,'IDVX':161,
61  'IDBCM':170,
62  'EMBA':202,'EMBC':203,'EMECA':204,'EMECC':205,
63  'HECA':214,'HECC':215,'FCALA':224,'FCALC':225,
64  'TIGB':230,
65  'TILBA':232,'TILBC':233,'TIEBA':234,'TIEBC':235,
66  'MBTSA':244,'MBTSC':245,
67  'CALBA':251,'CALEA':254,'CALEC':255,
68  'MDTBA':302,'MDTBC':303,'MDTEA':304,'MDTEC':305,
69  'RPCBA':312,'RPCBC':313,
70  'TGCEA':324,'TGCEC':325,
71  'CSCEA':334,'CSCEC':335,
72  'LCD':350,'LCDA':353,'LCDC':354,
73  'ALFA':360,'ZDC':370,
74  'L1CAL':401,'L1MUB':402,'L1MUE':403,'L1CTP':404,
75  'TRCAL':411,
76  'TRDF':420,
77  'TRBJT':421,'TRBPH':422,'TRCOS':423,'TRELE':424,
78  'TRGAM':425,'TRJET':426,'TRMET':427,'TRMBI':428,
79  'TRMUO':429,'TRTAU':430,'TRIDT':431,
80  'LUMI':450,'LUMIONL':451,
81  'RUNCLT':460,
82  'RCOPS':461,
83  'ATLGL':480,'ATLSOL':481,'ATLTOR':482,
84  'EIDB':501,'EIDCR':502,'EIDE':503,
85  'PIDB':505,'PIDCR':506,'PIDE':507,
86  'EIDF':508,'EIDSOFT':509,
87  'MSTACO':510,'MMUIDCB':511,'MMUIDVX':512,
88  'MMUGIRL':513,'MMUBOY':514,'MMUIDSA':515,
89  'MMUTAG':516,'MMTIMO':517,'MCMUTAG':518,
90  'MCALLHR':519,
91  'JETB':521,'JETEA':524,'JETEC':525,
92  'JETFA':526,'JETFC':527,
93  'MET':530,'METCALO':531,'METMUON':532,
94  'BTGLIFE':541,'BTGSOFTE':544,'BTGSOFTM':545,
95  'TAUB':551,'TAUCR':552,'TAUE':553}
96 
97  # initialise reverse map from channel numbers to names
98  self.numdict={}
99  for (name,num) in self.namedict.items():
100  self.numdict[num]=name
101 
102  def name(self,num):
103  return self.numdict[num]
104 
105  def num(self,name):
106  "Return the numeric channel identifier which exactly matches name"
107  return self.namedict[name]
108 
109  def nums(self,name):
110  "Return a list of all numeric channel identifiers which match name"
111  result=[]
112  for (iname,inum) in self.namedict.items():
113  if (name==iname[:len(name)]):
114  result+=[inum]
115  return result
116 
117  def allNames(self):
118  a=self.namedict.keys()
119  a.sort()
120  return a
121 
122  def allNums(self):
123  a=self.namedict.values()
124  a.sort()
125  return a
126 
128  "Class to hold a list of detector status requirements"
129 
130  def __init__(self):
131  "Initialise to empty set of requirements"
132  # requirements are stored as dict[status_channelID]=minimum value
133  self.req={}
134  # access to name/number translation
136 
137  def setFromString(self,reqstring):
138  """Set requirements from a space-separated string with flag req pairs
139  e.g. 'SCTB 3 EMEC G' (numbers or letters for status)"""
140  self.req={}
141  namelist=self.names.allNames()
142  tokens=str(reqstring).split()
143  ix=0
144  while (ix+1<len(tokens)):
145  flagname=tokens[ix]
146  val=colourVal(tokens[ix+1])
147  if (val is not None):
148  used=False
149  # check if the name matches any flags
150  for name in namelist:
151  if (flagname==name[0:len(flagname)]):
152  self.req[self.names.num(name)]=val
153  used=True
154  if (not used):
155  print ("Name %s does not match any status flag" % flagname)
156  else:
157  print ("Value %s does not define a status" % tokens[ix+1])
158  ix+=2
159 
160  def getDict(self):
161  "Return the dictionary holding the requirements (channel/value pairs)"
162  return self.req
163 
164  def __str__(self):
165  "Print representation of status requirements"
166  result=""
167  for (key,val) in self.req.items():
168  result+="%s %i " % (self.names.name(key),val)
169  return result
170 
171 class StatusObj:
172  "Transient representation of one detector status"
173  def __init__(self,start,stop,code,deadfrac,thrust,nconfig=-1,nworking=-1,comment=''):
174  self.start=start
175  self.stop=stop
176  self.code=code
177  self.deadfrac=deadfrac
178  self.thrust=thrust
179  self.nconfig=nconfig
180  self.nworking=nworking
181  self.comment=comment
182 
183  def updateStart(self,newStart):
184  self.start=newStart
185 
186  def updateStop(self,newStop):
187  self.stop=newStop
188 
190  "Transient representation of detector status list (code,deadfrac,thrust)"
191  def __init__(self):
192  "Initialise to empty sequence"
193  # sequence stores the detector status in time order
194  self._seq=[]
195 
196  def merge(self,mobj,override=False):
197  "Merge the given StatusObj into the list, ANDing (default) or override"
198  if (mobj.start>=mobj.stop):
199  return
200  # loop over the list, looking for places affected by the new obj
201  ix=0
202  oldstop=0
203  while (ix<len(self._seq)):
204  # first check for a gap between current and previous object
205  # where a new object has to be inserted
206  if (mobj.start<self._seq[ix].start and mobj.stop>oldstop):
207  # calculate extent of object to insert
208  nstart=max(oldstop,mobj.start)
209  nstop=min(self._seq[ix].start,mobj.stop)
210  # only insert if gap is of non-zero length
211  if (nstop>nstart):
212  # insert the new object at this position
213  self._seq.insert(ix,StatusObj(nstart,nstop,mobj.code,mobj.deadfrac,mobj.thrust,mobj.nconfig,mobj.nworking,mobj.comment))
214  ix+=1
215  # now check if object intersects current one
216  if (mobj.start<self._seq[ix].stop and mobj.stop>self._seq[ix].start):
217  # use mobj if override set or
218  # (new status is <= existing and new is not undefined) or
219  # old is undefined
220  if (override or
221  (mobj.code<=self._seq[ix].code and mobj.code!=0) or
222  (self._seq[ix].code==0)):
223  # record existing status for splitting
224  ecode=self._seq[ix].code
225  edeadfrac=self._seq[ix].deadfrac
226  ethrust=self._seq[ix].thrust
227  enconfig=self._seq[ix].nconfig
228  enworking=self._seq[ix].nworking
229  ecomment=self._seq[ix].comment
230  estart=self._seq[ix].start
231  estop=self._seq[ix].stop
232  # position where status will be updated
233  iy=ix
234  if (mobj.start>estart):
235  # need to split at front
236  self._seq.insert(ix,StatusObj(estart,mobj.start,ecode,edeadfrac,ethrust,enconfig,enworking,ecomment))
237  ix+=1
238  iy+=1
239  if (mobj.stop<estop):
240  # need to split at end
241  self._seq.insert(ix+1,StatusObj(mobj.stop,estop,ecode,edeadfrac,ethrust,enconfig,enworking,ecomment))
242  ix+=1
243  # now update entry at iy with new status
244  self._seq[iy]=StatusObj(max(mobj.start,estart),min(mobj.stop,estop),mobj.code,mobj.deadfrac,mobj.thrust,mobj.nconfig,mobj.nworking,mobj.comment)
245  # move on to next object
246  oldstop=self._seq[ix].stop
247  ix+=1
248  # check if merged object extends over end of current list
249  # may not have processed the whole list in the loop
250  if (len(self._seq)>0):
251  oldstop=self._seq[-1].stop
252  if (mobj.stop>oldstop):
253  nstart=max(oldstop,mobj.start)
254  self._seq+=[StatusObj(nstart,mobj.stop,mobj.code,mobj.deadfrac,mobj.thrust,mobj.nconfig,mobj.nworking,mobj.comment)]
255 
256  def compress(self):
257  "Compress StatusList removing redundant entries with IoVs which can be combined"
258  ix=1
259  while (ix<len(self._seq)):
260  # check if payload of this entry is same as previous
261  # and start/stop times match without any gap
262  if (self._seq[ix].start==self._seq[ix-1].stop and
263  self._seq[ix].code==self._seq[ix-1].code and
264  self._seq[ix].deadfrac==self._seq[ix-1].deadfrac and
265  self._seq[ix].thrust==self._seq[ix-1].thrust and
266  self._seq[ix].nconfig==self._seq[ix-1].nconfig and
267  self._seq[ix].nworking==self._seq[ix-1].nworking and
268  self._seq[ix].comment==self._seq[ix-1].comment):
269  self._seq[ix].updateStart(self._seq[ix-1].start)
270  self._seq[ix-1:]=self._seq[ix:]
271  else:
272  ix+=1
273  return len(self._seq)
274 
275  def size(self):
276  "Return size of list"
277  return len(self._seq)
278 
279  def list(self):
280  "Return the list itself"
281  return self._seq
282 
283  def __str__(self):
284  "Print representation of StatusList"
285  rep=''
286  for i in self._seq:
287  rep+='[%i %i] : %i %6.3f %6.3f %s\n' % (i.start,i.stop,i.code,i.deadfrac,i.thrust,i.comment)
288  return rep
python.DetStatusLib.StatusObj.nworking
nworking
Definition: DetStatusLib.py:180
max
#define max(a, b)
Definition: cfImp.cxx:41
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
python.DetStatusLib.StatusList.merge
def merge(self, mobj, override=False)
Definition: DetStatusLib.py:196
python.DetStatusLib.StatusList.__str__
def __str__(self)
Definition: DetStatusLib.py:283
python.DetStatusLib.DetStatusReq.getDict
def getDict(self)
Definition: DetStatusLib.py:160
python.DetStatusLib.StatusObj.thrust
thrust
Definition: DetStatusLib.py:178
python.DetStatusLib.DetStatusReq.__init__
def __init__(self)
Definition: DetStatusLib.py:130
python.Bindings.values
values
Definition: Control/AthenaPython/python/Bindings.py:805
python.DetStatusLib.DetStatusNames.allNames
def allNames(self)
Definition: DetStatusLib.py:117
python.DetStatusLib.DetStatusReq
Definition: DetStatusLib.py:127
python.DetStatusLib.StatusObj.comment
comment
Definition: DetStatusLib.py:181
python.DetStatusLib.StatusList.__init__
def __init__(self)
Definition: DetStatusLib.py:191
python.DetStatusLib.StatusObj.stop
stop
Definition: DetStatusLib.py:175
python.DetStatusLib.StatusObj.start
start
Definition: DetStatusLib.py:174
python.DetStatusLib.StatusObj.deadfrac
deadfrac
Definition: DetStatusLib.py:177
python.DetStatusLib.folderName
def folderName(runLumi=True)
Definition: DetStatusLib.py:9
python.DetStatusLib.DetStatusNames.name
def name(self, num)
Definition: DetStatusLib.py:102
python.DetStatusLib.DetStatusNames
Definition: DetStatusLib.py:49
min
#define min(a, b)
Definition: cfImp.cxx:40
trigbs_pickEvents.num
num
Definition: trigbs_pickEvents.py:76
python.DetStatusLib.StatusList
Definition: DetStatusLib.py:189
python.DetStatusLib.DetStatusNames.namedict
namedict
Definition: DetStatusLib.py:54
python.DetStatusLib.DetStatusNames.__init__
def __init__(self)
Definition: DetStatusLib.py:50
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
python.DetStatusLib.colourVal
def colourVal(sval)
Definition: DetStatusLib.py:27
python.DetStatusLib.DetStatusNames.allNums
def allNums(self)
Definition: DetStatusLib.py:122
python.DetStatusLib.DetStatusReq.names
names
Definition: DetStatusLib.py:135
TrigJetMonitorAlgorithm.items
items
Definition: TrigJetMonitorAlgorithm.py:79
python.DetStatusLib.colour
def colour(code)
Definition: DetStatusLib.py:15
python.DetStatusLib.StatusObj
Definition: DetStatusLib.py:171
python.DetStatusLib.StatusObj.updateStart
def updateStart(self, newStart)
Definition: DetStatusLib.py:183
python.DetStatusLib.DetStatusReq.setFromString
def setFromString(self, reqstring)
Definition: DetStatusLib.py:137
python.DetStatusLib.StatusList.size
def size(self)
Definition: DetStatusLib.py:275
python.DetStatusLib.StatusObj.updateStop
def updateStop(self, newStop)
Definition: DetStatusLib.py:186
python.DetStatusLib.DetStatusNames.nums
def nums(self, name)
Definition: DetStatusLib.py:109
python.DetStatusLib.StatusList._seq
_seq
Definition: DetStatusLib.py:194
python.DetStatusLib.DetStatusNames.num
def num(self, name)
Definition: DetStatusLib.py:105
str
Definition: BTagTrackIpAccessor.cxx:11
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:798
python.DetStatusLib.DetStatusReq.req
req
Definition: DetStatusLib.py:133
python.DetStatusLib.DetStatusNames.numdict
numdict
Definition: DetStatusLib.py:98
python.DetStatusLib.StatusObj.__init__
def __init__(self, start, stop, code, deadfrac, thrust, nconfig=-1, nworking=-1, comment='')
Definition: DetStatusLib.py:173
python.DetStatusLib.StatusList.list
def list(self)
Definition: DetStatusLib.py:279
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
python.DetStatusLib.StatusObj.code
code
Definition: DetStatusLib.py:176
python.DetStatusLib.StatusList.compress
def compress(self)
Definition: DetStatusLib.py:256
python.DetStatusLib.DetStatusReq.__str__
def __str__(self)
Definition: DetStatusLib.py:164
python.DetStatusLib.StatusObj.nconfig
nconfig
Definition: DetStatusLib.py:179