ATLAS Offline Software
GetLBsToIgnore.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
2 
3 from __future__ import print_function
4 
5 import sys, re
6 import xmlrpc.client
7 from PyCool import cool
8 from CoolConvUtilities.AtlCoolLib import indirectOpen
9 from DQDefects import DefectsDB
10 
11 try:
12  serverfile=open("/afs/cern.ch/user/l/larmon/public/atlasdqmpass.txt")
13  password=serverfile.readline().strip()
14  serverfile.close()
15 except Exception as e:
16  print ("Failed to read xmlrpc server connection details from AFS location")
17  print (e)
18  sys.exit(-1)
19 
20 
21 def getLBsToIgnore(runnum,burstsFromCosmic=True,bulkProcessing=False, dropNonReady=True):
22 
23  badLBs=set()
24 
25  # 1. Get LB range for this run and LBs without "ATLAS-READY"
26  nReadyLBs=0
27  nNotReadyLBs=0
28  tdaqdb=indirectOpen('COOLONL_TDAQ/CONDBR2')
29  if (tdaqdb is None):
30  print ("ERROR: Can't access COOLONL_TDAQ/CONDBR2")
31  sys.exit(-1)
32 
33  fmode=tdaqdb.getFolder("/TDAQ/RunCtrl/DataTakingMode")
34 
35  since=(runnum<<32)+1
36  until=((1+runnum)<<32)-1
37  maxLb=0
38  minLb=1
39  itr=fmode.browseObjects(since,until,cool.ChannelSelection.all())
40  while itr.goToNext():
41  obj=itr.currentRef()
42  pl=obj.payload()
43  isReady=pl["ReadyForPhysics"]
44  lb1=max(since,obj.since()) & 0xFFFFFFFF
45  ts2=obj.until()
46  if ts2<until: #ignore the IOV beyond the end of the run
47  lb2=ts2 & 0xFFFFFFFF
48  if lb2>maxLb:
49  maxLb=lb2
50  if not isReady:
51  if dropNonReady:
52  print ("Ignoring LumiBlocks %i - %i not ATLAS READY" % (lb1,lb2))
53  badLBs.update(range(lb1,lb2))
54  nNotReadyLBs+=(lb2-lb1)
55  else:
56  nReadyLBs+=(lb2-lb1)
57  pass
58  pass
59  pass
60  pass
61  itr.close()
62  tdaqdb.closeDatabase()
63 
64  print ("Run %i goes up to LB %i" % (runnum,maxLb))
65 
66  #2. Get problematic LBs
67  #2.1 Look for collisions in empty bunches - Fetch from DQ Web Server
68  source = 'tier0'
69  stream = 'physics_CosmicCalo'
70 
71  serverstring="https://%s@atlasdqm.cern.ch" % password
72  server = xmlrpc.client.ServerProxy(serverstring)
73  multicall = xmlrpc.client.MultiCall(server)
74 
75  # Look for the highest(latest) processing version of CosmicCalo by retrieving amitag
76  run_spec = {'source': source, 'high_run': runnum, 'low_run': runnum}
77  multicall.get_procpass_amitag_mapping(run_spec)
78  results = multicall()
79  if len(results[0])==0:
80  print ("Nothing found about run",runnum,"on DQM server")
81  proc = 0
82  try:
83  list = results[0][str(runnum)]
84  for item in list:
85  if ("f" in item[2] and bulkProcessing and "CosmicCalo" in item[1] and item[0]>proc):
86  proc = 2
87  if ("x" in item[2] and (not bulkProcessing) and "CosmicCalo" in item[1] and item[0]>proc):
88  print (item)
89  proc = 1
90  pass
91  pass
92  except Exception as e:
93  print ("ERROR: can't retrieve the AMI Tag")
94  print (e)
95 
96  if (proc == 0):
97  print ("I haven't found any processing version for CosmicCalo. Assume express processing")
98  proc=1
99 
100 
101  try:
102  multicall = xmlrpc.client.MultiCall(server)
103  run_spec = {'source': source, 'high_run': runnum, 'stream': stream, 'proc_ver': proc, 'low_run': runnum}
104  multicall.get_timestamp(run_spec)
105  results=multicall()
106  timestamp=results[0][str(runnum)]
107  from time import asctime,localtime
108  print ("DQM server timestamp:", asctime(localtime(timestamp)))
109  print ("Now: ",asctime())
110  except Exception as e:
111  print ("ERROR: can't get timestamp from DQM server")
112  print (e)
113 
114 
115  multicall = xmlrpc.client.MultiCall(server)
116  run_spec = {'source': source, 'high_run': runnum, 'stream': stream, 'proc_ver': proc, 'low_run': runnum}
117  multicall.get_dqmf_all_results(run_spec,'LAr/LAR_GLOBAL/Collisions-Bkg/LArCollTimeLumiBlockTimeCut')
118  results = multicall()
119  RE = re.compile(r'\‍((?P<lb>\S+)\.0*\‍)')
120 
121  try:
122  list = results[0][str(runnum)]
123  for item in list:
124  if 'NBins' in item:
125  continue
126  m = RE.search(item).groupdict()
127  lb=int(m['lb'])
128  ncollisions=int(results[0][str(runnum)][item])
129  if ncollisions > 50:
130  badLBs.add(lb)
131  print ("LumiBlock %i ignored because it is empty bunches are polluted with collisions" % lb)
132  pass
133  pass
134  except Exception as e:
135  print ("ERROR: can't get LArCollTimeLumiBlockTimeCut from DQM server")
136  print (e)
137 
138  if (burstsFromCosmic):# CosmicCalo stream : from the DQ web
139  histoName = {'EMBC':'BarrelC','EMBA':'BarrelA','EMECC':'EMECC','EMECA':'EMECA'}
140  for iPart in histoName.keys():
141  multicall = xmlrpc.client.MultiCall(server)
142  #multicall.get_dqmf_all_results(run_spec,'LAr/%s/Noise/Partition/NoisyEvent_TimeVeto_%s'%(iPart,histoName[iPart]))
143  multicall.get_dqmf_all_results(run_spec,'/LAr/%s/Occupancy-Noise/Noise_Burst/NoisyEvent_TimeVeto_%s'%(iPart,iPart))
144 
145  results = multicall()
146  try:
147  resultlist = results[0][str(runnum)]
148  #print ("Got %i items for NoisyEvent_TimeVeto_%s" % (len(list),histoName[iPart]))
149  for item in resultlist:
150  if 'NBins' in item:
151 
152  continue
153  m = RE.search(item).groupdict()
154  lb=int(m['lb'])
155  yieldbursts=float(results[0][str(runnum)][item])
156  if yieldbursts > 0:
157  badLBs.add(lb)
158  print ("LumiBlock %i ignored because it contains bursts in CosmicCalo stream in %s" % (lb,iPart))
159  pass
160  pass
161  except Exception as e:
162  print ("ERROR: can't get NoisyEvent from DQM server")
163  print (e)
164 
165 
166  del multicall
167  del server
168 
169  #3.2 Get defects from Defects DB
170  db = DefectsDB()
171  lar_defects = [d for d in (db.defect_names | db.virtual_defect_names) if d.startswith("LAR")]
172  defects = db.retrieve((runnum, minLb), (runnum, maxLb), lar_defects)
173  for defect in defects:
174  part=defect.channel.split("_")[1]
175  #3.2.1 Check for HV trip
176  if "HVTRIP" in defect.channel and defect.present:
177  for lb in range(defect.since.lumi,defect.until.lumi):
178  badLBs.add(lb)
179  print ("LumiBlock %i ignored because of a HV trip in partition %s" % (lb,part))
180  pass
181  pass
182  #3.2.2 Check for Noise Bursts from the defects
183  if (not burstsFromCosmic):
184  if not bulkProcessing:
185  if "NOISEBURST" in defect.channel and defect.present:
186  for lb in range(defect.since.lumi,defect.until.lumi):
187  badLBs.add(lb)
188  print ("LumiBlock %i ignored because of a noise burst in partition %s" % (lb,part))
189  pass
190  pass
191  else: #not bulk processing
192  if "SEVNOISEBURST" in defect.channel and defect.present:
193  for lb in range(defect.since.lumi,defect.until.lumi):
194  badLBs.add(lb)
195  print ("LumiBlock %i ignored because of a severe noise burst in partition %s" % (lb,part))
196  pass
197  pass
198 
199  del db #Close Defects DB
200 
201  nBadLBs=len(badLBs)
202  if dropNonReady:
203  nBadLBs=nBadLBs-nNotReadyLBs
204 
205  print ("Found %i not-ready LBs, %i atlas-ready LBs and %i bad LBs" % (nNotReadyLBs,nReadyLBs,nBadLBs))
206 
207  return badLBs
208 
209 
210 
211 
212 
213 if __name__ == "__main__":
214  import getopt
215  if len(sys.argv) == 1 :
216  print ()
217  print ("usage: python %s <options> <runnumber> "%(sys.argv[0]))
218  print ()
219  sys.exit(1)
220 
221  burstsFromCosmic=True
222  bulkProcessing=False
223  dropNonReady=True
224 
225  outputFN=None
226 
227  opts,args=getopt.getopt(sys.argv[1:],"brco:",[])
228  for o,a in opts:
229  if (o=='-c'):
230  burstsFromCosmics=False
231  if (o=='-b'):
232  bulkProcessing=True
233  if (o=='-r'):
234  dropNonReady=False
235  if (o=='-o'):
236  outputFN=a
237 
238  if len(args)<0:
239  print ("No run number found")
240  sys.exit(-1)
241 
242  if len(args)>1:
243  print ("Too many arguments")
244  sys.exit(-1)
245 
246  run=int(args[0])
247 
248  if (bulkProcessing):
249  print ("Searching for bad lumi blocks in run %d for bulk processing"%run)
250  else:
251  print ("Searching for bad lumi blocks in run %d for express processing"%run)
252 
253  if (dropNonReady):
254  print ("LB not marked as AtlasReady will be considered bad")
255  else:
256  print ("LB not marked as AtlasReady will be considered good")
257 
258 
259 
260  badLBset=getLBsToIgnore(run,burstsFromCosmic,bulkProcessing, dropNonReady)
261 
262  badLBsorted=sorted(badLBset)
263  print ("LBs to ignore:",badLBsorted)
264 
265  if outputFN is not None:
266  out=open(outputFN,"w")
267  out.write(', '.join([ str(i) for i in badLBsorted ]))
268  out.write("\n")
269  out.close()
270 
271 
272 # badLBset2=getLBsToIgnore(run)
273 # print ("LBs to ignore:",sorted(badLBset))
max
#define max(a, b)
Definition: cfImp.cxx:41
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
GetLBsToIgnore.getLBsToIgnore
def getLBsToIgnore(runnum, burstsFromCosmic=True, bulkProcessing=False, dropNonReady=True)
Definition: GetLBsToIgnore.py:21
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename T::value_type > sorted(T begin, T end)
Helper function to create a sorted vector from an unsorted one.
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:224
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
Trk::open
@ open
Definition: BinningType.h:40
str
Definition: BTagTrackIpAccessor.cxx:11
python.AtlCoolLib.indirectOpen
def indirectOpen(coolstr, readOnly=True, debug=False)
Definition: AtlCoolLib.py:130
readCCLHist.float
float
Definition: readCCLHist.py:83