9 from PyCool
import cool
11 from CoolConvUtilities.AtlCoolLib
import indirectOpen,RangeList
12 from DetectorStatus.DetStatusCoolLib
import statusCutsToRange
14 import LumiBlockComps.LumiQuery
as LumiQuery
17 """This class represents a range of lumiblocks within a single run"""
19 "Initialise to inclusive range lb1-lb2 in run run"
25 return 'Run %i LB [%i-%i]' % (self.
run,self.
lb1,self.
lb2)
28 "Return IOV since,until corresponding to this lumiblock range"
29 since=(self.
run << 32)+self.
lb1
30 until=(self.
run << 32)+self.
lb2+1
35 """An in-memory cache of items of data, each associated with an IOV
36 Methods provided to add more data (specified with IOV) and to lookup the
37 data for a particular time. Not optimised, suitable only for small amounts
44 def add(self,since,until,data):
56 """Class to hold luminosity calculation result"""
57 def __init__(self,intL,l1acc,l2acc,l3acc,livetime,ngood,nbadstat):
67 "addition of two lumiResults - accumulate totals"
71 """Luminosity calculator from COOL - main utility class"""
72 def __init__(self,cooldbconn,statusdbconn="",readoracle=False,loglevel=1,detStatus="",detStatusTag=""):
73 """Initialisation of luminosity calculator
74 Specify the COOL database string (e.g. COOLONL_TRIGGER/COMP200),
75 COOL detector status connection string (if needed),
76 whether to force Oracle (otherwise SQLite replicas might be used)
77 and the detector status requirements and tag (if any).
78 Status requirements given in the form 'SCTB G EMEC Y' etc
83 except Exception
as e:
95 except Exception
as e:
100 "Return a lumicache (pairs of inst lumi, deltaT) for given range"
102 folderLUMI=self.
cooldb.getFolder(
'/TRIGGER/LUMI/LBLEST')
103 itr=folderLUMI.browseObjects(since,until-1,cool.ChannelSelection(0))
104 while (itr.goToNext()):
108 payload=obj.payload()
109 instlumi=payload[
'OnlineLumiInst']
111 deltat=payload[
'OnlineLumiDel']/instlumi
114 lumicache.add(obj.since(),obj.until(),(instlumi,deltat))
119 """ Calculate the integrated luminosity for a list of LBs, returning
120 a lumiResult object"""
123 if triggerlevel
is None:
return None
130 folderLBCOUNTL1=self.
cooldb.getFolder(
'/TRIGGER/LUMI/LVL1COUNTERS')
131 folderLBCOUNTHLT=self.
cooldb.getFolder(
'/TRIGGER/LUMI/HLTCOUNTERS')
132 folderL1PRESCALE=self.
cooldb.getFolder(
'/TRIGGER/LVL1/Prescales')
134 for lbinfo
in lblist:
135 if (self.
loglevel>0):
print(
"Beginning calculation for",lbinfo)
137 runstat,chainnums,hltprescale=self.
_getChains(lbinfo.run,triggername,triggerlevel)
138 if (self.
loglevel>1):
print(
"L1/2/3 chain numbers",chainnums[0],chainnums[1],chainnums[2])
140 since,until=lbinfo.IOVRange()
147 gooddetstatus=RangeList(since,until)
149 if (self.
loglevel>0):
print(
"LumiB L1-Acc L2-Acc L3-Acc L1-pre L2-pre L3-pre LiveTime IntL/nb-1")
152 itr=folderL1PRESCALE.browseObjects(since,until-1,cool.ChannelSelection(chainnums[0]))
153 while (itr.goToNext()):
155 l1precache.add(obj.since(),obj.until(),obj.payload()[
'Lvl1Prescale'])
164 l1countitr=folderLBCOUNTL1.browseObjects(since,until-1,cool.ChannelSelection(chainnums[0]))
166 l2countitr=folderLBCOUNTHLT.browseObjects(since,until-1,cool.ChannelSelection(chainnums[1]))
168 l3countitr=folderLBCOUNTHLT.browseObjects(since,until-1,cool.ChannelSelection(chainnums[2]))
169 while l1countitr.goToNext():
171 l1countobj=l1countitr.currentRef()
172 lb=l1countobj.since() & 0xFFFFFFFF
173 l1payload=l1countobj.payload()
174 l1acc=l1payload[
'L1Accept']
177 if (l1payload[
'AfterPrescale']>0):
178 livefrac=
float(l1payload[
'L1Accept'])/
float(l1payload[
'AfterPrescale'])
183 l2countitr.goToNext()
184 l2countobj=l2countitr.currentRef()
185 if (l2countobj.since()!=l1countobj.since()):
186 raise RuntimeError(
"L2/L1 counter synchronisation error")
187 l2payload=l2countobj.payload()
188 l2acc=l2payload[
'HLTAccept']
193 l3countitr.goToNext()
194 l3countobj=l3countitr.currentRef()
195 if (l3countobj.since()!=l1countobj.since()):
196 raise RuntimeError(
"L3/L1 counter synchronisation error")
197 l3payload=l3countobj.payload()
198 l3acc=l3payload[
'HLTAccept']
201 if (len(gooddetstatus.getAllowedRanges(l1countobj.since(),l1countobj.until()))>0):
206 (lumi,deltat)=lumicache.find(l1countobj.since())
207 l1prescale=l1precache.find(l1countobj.since())
208 if (lumi
is not None and l1prescale
is not None):
211 livetime=livefrac*deltat
212 intlumi=(lumi*livetime)/
float(l1prescale*hltprescale[0]*hltprescale[1])
213 if (self.
loglevel>1):
print(
"%5i %7i %7i %7i %8i %8i %8i %8.2f %10.1f" % (lb,l1acc,l2acc,l3acc,l1prescale,hltprescale[0],hltprescale[1],livetime,intlumi))
216 print(
"%5i %7i %7i %7i <missing prescale or lumi>" %(lb,l1acc,l2acc,l3acc))
228 print(
"Trigger not defined for run",lbinfo.run)
229 if (self.
loglevel>0):
print(
"Rng-T %7i %7i %7i %8.2f %10.1f" % (totalacc[0],totalacc[1],totalacc[2],totaltime,totalL))
230 return lumiResult(totalL,totalacc[0],totalacc[1],totalacc[2],totaltime,totalgoodblock,totalbadblock)
233 """Extract the trigger level from the name (L1_x, L2_x or EF_x)
234 Return 1 for unknown levels (after printing warning)"""
235 if (trigname[:2]==
'L1'):
return 1
236 if (trigname[:2]==
'L2'):
return 2
237 if (trigname[:2]==
'EF'):
return 3
238 if (
not quiet):
print(
'WARNING: Trigger name',trigname,
'does not define trigger level, assume L1')
242 """Returns the trigger chain numbers for the specified trigger in this
243 run, which are used as the channel indexes for the LVL1/Prescale
244 and LUMI/LVL1COUNTERS and HLTCOUNTERS folders"""
245 if (self.
loglevel>1):
print(
"Get chain numbers for run",run,triggername,
"level",triggerlevel)
252 if (triggerlevel==3):
254 l3chain,l3prescale,lvl2name=self.
_getHLTChain(run,lvl3name,3)
258 l2chain,l2prescale,lvl1name=self.
_getHLTChain(run,lvl2name,2)
259 if (l2chain==-1): badrun=
True
260 elif (triggerlevel==2):
262 l2chain,l2prescale,lvl1name=self.
_getHLTChain(run,lvl2name,2)
263 if (l2chain==-1): badrun=
True
268 l1menu=self.
cooldb.getFolder(
"/TRIGGER/LVL1/Menu")
270 itr=l1menu.browseObjects(since,until-1,cool.ChannelSelection.all())
271 while itr.goToNext():
273 if (obj.payload()[
'ItemName']==lvl1name):
274 l1chain=obj.channelId()
277 print(
"LVL1 trigger %s not defined for run %i" % (lvl1name,run))
280 return (
not badrun,(l1chain,l2chain,l3chain),(l2prescale,l3prescale))
283 "access /TRIGGER/HLT/Menu folder to get chain counter for trigger name"
284 hltmenu=self.
cooldb.getFolder(
"/TRIGGER/HLT/Menu")
286 itr=hltmenu.browseObjects(since,until-1,cool.ChannelSelection.all())
290 levelid=[
'L2',
'EF'][level-2]
291 while itr.goToNext():
293 payload=obj.payload()
294 if (payload[
'ChainName']==name
and payload[
'TriggerLevel']==levelid):
295 chain=payload[
'ChainCounter']
296 if (level==3): chain+=10000
297 prescale=payload[
'Prescale']
298 lowername=payload[
'LowerChainName']
301 if (self.
loglevel>1):
print(
"Trigger",name,
"identifier chain",chain,
"prescale",prescale,
"lowername",lowername)
302 return (chain,prescale,lowername)
305 """Return a list of the available triggers for a particular run
306 Restrict to particular level level argument!=0"""
311 l1menu=self.
cooldb.getFolder(
"/TRIGGER/LVL1/Menu")
312 itr=l1menu.browseObjects(since,until-1,cool.ChannelSelection.all())
313 while itr.goToNext():
315 payload=obj.payload()
316 item=payload[
'ItemName']
317 if (item
not in [
'pass all',
'',
'-']):
318 tlist+=[payload[
'ItemName']]
322 hltmenu=self.
cooldb.getFolder(
"/TRIGGER/HLT/Menu")
323 itr=hltmenu.browseObjects(since,until-1,cool.ChannelSelection.all())
324 while itr.goToNext():
326 payload=obj.payload()
327 triglevel={
'L2':2,
'EF':3}[payload[
'TriggerLevel']]
328 if (triglevel==level
or level==0):
329 tlist+=[payload[
'ChainName']]
336 until=((run+1) << 32)
345 from ROOT
import gSystem
348 gSystem.Load(
'libGoodRunsListsLib')
349 from ROOT
import Root
354 goodrunslist = reader.GetMergedGoodRunsList()
355 goodrunslist.Summary(
True)
356 runs=goodrunslist.GetGoodRuns()
359 for i
in range(len(runs)):
361 for j
in range(len(run)):
363 rangelist+=[
RLBRange(run.GetRunNumber(),lumi_range.Begin(),lumi_range.End())]
367 """Extract list of LBs from a ROOT file using LumiQuery and return
368 as RLBRange objects"""
369 lblist=LumiQuery.ListFromFile(file)
374 if (start.run()==stop.run()):
375 rangelist+=[
RLBRange(start.run(),start.block(),stop.block())]
377 print(
"ERROR: Multirun RLBRange not supported:",start,stop)