def statusCutsToRange(dbconn, foldername, since, until, tag, statusreq): """Return a RangeList giving the good IOV range corresponding to the specified set of daetector status cuts, using the given DB and folder""" range = RangeList(since, until) reqs = DetStatusReq() reqs.setFromString(statusreq) folder = dbconn.getFolder(foldername) # loop over all requested status cuts for (ichan, req) in reqs.getDict().items(): itr = folder.browseObjects(since, until, cool.ChannelSelection(ichan), tag) lastiov = since while itr.goToNext(): obj = itr.currentRef() status = obj.payload()['Code'] if (lastiov < obj.since()): # veto gaps where no status data was provided - assume bad range.vetoRange(lastiov, obj.since()) if (status < req): range.vetoRange(obj.since(), obj.until()) lastiov = obj.until() # veto final gap (if any) range.vetoRange(lastiov, until) itr.close() return range
def calcFromList(self, triggername, lblist): """ Calculate the integrated luminosity for a list of LBs, returning a list of (run,lb,lumiResult,evts) object tuples (note, this is the only difference in functionality between coolLumiCalc and coolLumiResultsGetter) """ lumiResults = [] # setup the triggerlevel triggerlevel = self.triggerLevel(triggername) if triggerlevel != 1: raise Exception("Please use a L1 trigger for this tool.") totalL = 0 totaltime = 0. totalacc = 3 * [0] totalgoodblock = 0 totalbadblock = 0 # get counters, prescales LB timest folders folderLBCOUNTL1 = self.cooldb.getFolder('/TRIGGER/LUMI/LVL1COUNTERS') folderL1PRESCALE = self.cooldb.getFolder('/TRIGGER/LVL1/Prescales') folderL1LB = self.cooldb.getFolder('/TRIGGER/LUMI/LBLB') # loop over LBList for lbinfo in lblist: # get the trigger configuration for this run runstat, chainnums, hltprescale = self._getChains( lbinfo.run, triggername, triggerlevel) if (self.loglevel > 1): print("L1 chain number", chainnums[0]) if (runstat): since, until = lbinfo.IOVRange() # check for detector status requirements if (self.detstatus != ""): if (self.loglevel > 0): print( lbinfo, ": Applying detector status cuts: %s" % self.detstatus) gooddetstatus = statusCutsToRange( self.detstatusdb, '/GLOBAL/DETSTATUS/LBSUMM', since, until, self.detstatustag, self.detstatus) else: gooddetstatus = RangeList(since, until) if (self.loglevel > 1): print( "LumiB L1-Acc L1-pre LiveTime MeanInts IntL/ub-1") # get and cache the LVL1 prescales for this run; note these can have >1 LB intervals l1precache = IOVCache() itr = folderL1PRESCALE.browseObjects( since, until - 1, cool.ChannelSelection(chainnums[0])) while (itr.goToNext()): obj = itr.currentRef() l1precache.add(obj.since(), obj.until(), obj.payload()['Lvl1Prescale']) itr.close() # get and cache the lumiosity estimates for this run; note these can have >1 LB intervals lumicache = self.getLumiMuCache(since, until) # loop through the LBs for this range # looping is driven by the LVL1COUNTERS folder which has 1 LB IOVs. # Should be matched by LBLB which is also 1 LB IOVs. nblocks = 0 l1countitr = folderLBCOUNTL1.browseObjects( since, until - 1, cool.ChannelSelection(chainnums[0])) l1lbiter = folderL1LB.browseObjects( since, until - 1, cool.ChannelSelection( 0)) #just one channel in this folder. while l1countitr.goToNext(): # access LVL1 information l1countobj = l1countitr.currentRef() lb = l1countobj.since() & 0xFFFFFFFF l1lbiter.goToNext() lblbobj = l1lbiter.currentRef() if (lblbobj.since() != l1countobj.since()): raise Exception( "L1 counter/lumiblock synchronisation error. Cannot get length of Lumiblocks!" ) l1payload = l1countobj.payload() lblbpayload = lblbobj.payload() l1acc = l1payload['L1Accept'] l1dt = (lblbpayload['EndTime'] - lblbpayload['StartTime']) * 1.0e-09 l1tstart = lblbpayload['StartTime'] # calculate livefraction from LVL1 (events accepted after mask and busy veto)/(events accepted by prescale) # this will be a poor estimate when prescales are large. if (l1payload['AfterPrescale'] > 0): livefrac = float(l1payload['L1Accept']) / float( l1payload['AfterPrescale']) else: livefrac = 1. pass l2acc = 0 l3acc = 0 if (len( gooddetstatus.getAllowedRanges( l1countobj.since(), l1countobj.until())) > 0): # calculate intL for block # lumi is being given in units of 10^33 cm^-2s^-1 # equivalent to 1 nb^-1s^-1 # instantaneous and time increment lumi try: (lumi, evtsbx) = lumicache.find(l1countobj.since()) except TypeError: if (self.lumimethod != 'EXTERNAL'): print("WARNING: No payload in", self.lumifoldername, "for run", lbinfo.run, "[", lb, "]!") lumi = 0 evtsbx = 0 pass l1prescale = l1precache.find(l1countobj.since()) if (lumi is not None and l1prescale is not None): # multiply by livetime in seconds to get # intL in nb^-1 # intlumi = nlumi * L1acc / (L1accAP * P ) livetime = livefrac * l1dt if self.useprescale: intlumi = (lumi * livetime) / (1.0 * l1prescale) if not (intlumi >= 0): print( "WARNING:", lbinfo.run, "[", lb, "]: bad lumi, prescale or livetime found:(IL,LV):", lumi, livetime) else: intlumi = (lumi * livetime) if not (intlumi >= 0): print( "WARNING:", lbinfo.run, "[", lb, "]: bad lumi or livetime found:(IL,LV)", lumi, livetime) if (self.loglevel > 1): print("%5i %7i %8i %8.2f %8.7f %10.1f" % (lb, l1acc, l1prescale, livetime, evtsbx, intlumi)) elif (lumi is not None): intlumi = (lumi * livetime) if (self.loglevel > 1): print( "%5i %7i %8i %8s %8.7f %10.if <missing prescale>" % (lb, l1acc, "??", livetime, evtsbx, intlumi)) if not (intlumi >= 0): print("WARNING:", lbinfo.run, "[", lb, "]: bad lumi or livetime found:(IL,LV)", lumi, livetime) else: intlumi = 0 if (self.loglevel > 1): print( "%5i %7i %8i %8s %8s %10s <missing prescale>" % (lb, l1acc, "??", livetime, "??", "??")) lumiResults.append( (lbinfo.run, int(lb), lumiResult(intlumi, l1acc, 0, 0, livetime, 1, 0), evtsbx, l1tstart)) # accumulate statistics totalacc[0] += l1acc totaltime += livetime totalL += intlumi totalgoodblock += 1 else: #this was a bad run detstatus totalbadblock += 1 pass pass l1countitr.close() else: print("WARNING: Trigger not defined for run", lbinfo.run) pass if (self.loglevel > 0): print( "Running total after %24s:" % lbinfo, " %7i events; %8.2f seconds; %10.1f (nb^-1)" % (totalacc[0], totaltime, totalL)) pass #end of loop over iovs return lumiResults
def runsFromSEOR(self, run1=0, run2=(1 << 31) - 1): """Query /TDAQ/RunCtrl/LB_Params to get details of runs in runrange Use both SOR_Params and EOR_Params to catch runs which ended badly. Return a map of runs to RunParams objects""" # get detector status information if needed iov1 = run1 << 32 iov2 = (run2 + 1) << 32 if (iov2 > cool.ValidityKeyMax): iov2 = cool.ValidityKeyMax if (self.detstatus != ""): if (self.loglevel > 0): print("Applying detector status cuts: %s" % self.detstatus) gooddetstatus = statusCutsToRange(self.coolstatusdb, '/GLOBAL/DETSTATUS/LBSUMM', iov1, iov2, self.detstatustag, self.detstatus) else: gooddetstatus = RangeList(iov1, iov2) runlist = {} folderSOR_Params = self.cooldb.getFolder(self.coolpath + '/SOR_Params') itr = folderSOR_Params.browseObjects((run1 << 32), (run2 << 32), cool.ChannelSelection.all()) while itr.goToNext(): obj = itr.currentRef() payload = obj.payload() run = payload['RunNumber'] # correction for inverted RecEnabled logic here if (self.checkSelection( not payload['RecordingEnabled'], payload['DetectorMask'], payload['RunType'], payload['FilenameTag']) and len( gooddetstatus.getAllowedRanges(run << 32, (run + 1) << 32)) > 0): runlist[run] = RunParams( run, payload['SORTime'], payload['RunType'], payload['DAQConfiguration'], payload['DetectorMask'], payload['FilenameTag'], payload['RecordingEnabled'], payload['DataSource']) itr.close() if (self.loglevel > 0): print("SOR_Params has data for %i runs" % len(runlist)) # now query EOR_Params and fill in missing info neor = 0 folderEOR_Params = self.cooldb.getFolder(self.coolpath + '/EOR_Params') itr = folderEOR_Params.browseObjects((run1 << 32), (run2 << 32), cool.ChannelSelection.all()) while itr.goToNext(): obj = itr.currentRef() payload = obj.payload() run = payload['RunNumber'] #maxlb=(obj.until() & 0xFFFFFFF)-1 #if (maxlb==0 or maxlb==0xFFFFFFFF): maxlb=None maxlb = None # note that run may not be found if filtered from SOR list by # selection if (run in runlist.keys()): runlist[run].addEORInfo(payload['EORTime'], payload['TotalTime'], payload['CleanStop'], maxlb) runlist[run].updateEORInfo(payload['DAQConfiguration']) neor += 1 if (self.loglevel > 0): print("EOR_Params has data for %i runs" % neor) itr.close() # now query FinalSFOStats and fill in event counts nsfo = 0 folderSFOStat = self.cooldb.getFolder(self.coolpath + '/FinalSFOStat') itr = folderSFOStat.browseObjects((run1 << 32), (run2 << 32), cool.ChannelSelection.all()) while itr.goToNext(): obj = itr.currentRef() payload = obj.payload() run = obj.since() >> 32 if (run in runlist.keys()): runlist[run].addSFOStat(payload['PartitionName'], payload['ReceivedEvents'], payload['StoredEvents']) nsfo += 1 itr.close() if (self.loglevel > 0): print("FinalSFOStat has data for %i runs" % nsfo) # now query EventCounters and fill in trigger counts/partition name nevc = 0 folderEvtCount = self.cooldb.getFolder(self.coolpath + '/EventCounters') itr = folderEvtCount.browseObjects((run1 << 32), (run2 << 32), cool.ChannelSelection.all()) while itr.goToNext(): obj = itr.currentRef() payload = obj.payload() run = obj.since() >> 32 if (run in runlist.keys()): runlist[run].addEventCounters(payload['PartitionName'], payload['L1Events'], payload['L2Events'], payload['EFEvents'], payload['RecordedEvents']) nevc += 1 itr.close() if (self.loglevel > 0): print("EventCounters has data for %i runs" % nevc) return runlist
def calcFromList(self, triggername, lblist): """ Calculate the integrated luminosity for a list of LBs, returning a lumiResult object""" # setup the triggerlevel triggerlevel = self.triggerLevel(triggername) if triggerlevel is None: return None totalL = 0 totaltime = 0. totalacc = 3 * [0] totalgoodblock = 0 totalbadblock = 0 # get counters folders folderLBCOUNTL1 = self.cooldb.getFolder('/TRIGGER/LUMI/LVL1COUNTERS') folderLBCOUNTHLT = self.cooldb.getFolder('/TRIGGER/LUMI/HLTCOUNTERS') folderL1PRESCALE = self.cooldb.getFolder('/TRIGGER/LVL1/Prescales') for lbinfo in lblist: if (self.loglevel > 0): print "Beginning calculation for", lbinfo # get the trigger configuration for this run runstat, chainnums, hltprescale = self._getChains( lbinfo.run, triggername, triggerlevel) if (self.loglevel > 1): print "L1/2/3 chain numbers", chainnums[0], chainnums[ 1], chainnums[2] if (runstat): since, until = lbinfo.IOVRange() # check for detector status requirements if (self.detstatus != ""): if (self.loglevel > 0): print "Applying detector status cuts: %s" % self.detstatus gooddetstatus = statusCutsToRange( self.detstatusdb, '/GLOBAL/DETSTATUS/LBSUMM', since, until, self.detstatustag, self.detstatus) else: gooddetstatus = RangeList(since, until) if (self.loglevel > 0): print "LumiB L1-Acc L2-Acc L3-Acc L1-pre L2-pre L3-pre LiveTime IntL/nb-1" # get and cache the LVL1 prescales for this run l1precache = IOVCache() itr = folderL1PRESCALE.browseObjects( since, until - 1, cool.ChannelSelection(chainnums[0])) while (itr.goToNext()): obj = itr.currentRef() l1precache.add(obj.since(), obj.until(), obj.payload()['Lvl1Prescale']) itr.close() # get and cache the luminosity estimates for this run # note these can have >1 LB intervals lumicache = self.getLumiCache(since, until) # loop through the LBs for this range # looping is driven by the LVL1COUNTERS folder which has # one entry for EACH lumiblock # assume that HLTCOUNTERS also have one entry for EACH block nblocks = 0 l1countitr = folderLBCOUNTL1.browseObjects( since, until - 1, cool.ChannelSelection(chainnums[0])) if (triggerlevel > 1): l2countitr = folderLBCOUNTHLT.browseObjects( since, until - 1, cool.ChannelSelection(chainnums[1])) if (triggerlevel > 2): l3countitr = folderLBCOUNTHLT.browseObjects( since, until - 1, cool.ChannelSelection(chainnums[2])) while l1countitr.goToNext(): # access LVL1 information l1countobj = l1countitr.currentRef() lb = l1countobj.since() & 0xFFFFFFFF l1payload = l1countobj.payload() l1acc = l1payload['L1Accept'] # calculate livefraction from LVL1 ratios # this needs to be improved to avoid rounding errors if (l1payload['AfterPrescale'] > 0): livefrac = float(l1payload['L1Accept']) / float( l1payload['AfterPrescale']) else: livefrac = 1. # access LVL2 information if needed if (triggerlevel > 1): l2countitr.goToNext() l2countobj = l2countitr.currentRef() if (l2countobj.since() != l1countobj.since()): raise "L2/L1 counter synchronisation error" l2payload = l2countobj.payload() l2acc = l2payload['HLTAccept'] else: l2acc = 0 # access LVL3 information if needed if (triggerlevel > 2): l3countitr.goToNext() l3countobj = l3countitr.currentRef() if (l3countobj.since() != l1countobj.since()): raise "L3/L1 counter synchronisation error" l3payload = l3countobj.payload() l3acc = l3payload['HLTAccept'] else: l3acc = 0 if (len( gooddetstatus.getAllowedRanges( l1countobj.since(), l1countobj.until())) > 0): # calculate intL for block # lumi is being given in units of 10^33 cm^-2s^-1 # equivalent to 1 nb^-1s^-1 # instantaneous and time increment lumi (lumi, deltat) = lumicache.find(l1countobj.since()) l1prescale = l1precache.find(l1countobj.since()) if (lumi is not None and l1prescale is not None): # multiply by livetime in seconds to get # intL in nb^-1 livetime = livefrac * deltat intlumi = (lumi * livetime) / float( l1prescale * hltprescale[0] * hltprescale[1]) 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) else: intlumi = 0 print "%5i %7i %7i %7i <missing prescale or lumi>" % ( lb, l1acc, l2acc, l3acc) # accumulate statistics totalacc[0] += l1acc totalacc[1] += l2acc totalacc[2] += l3acc totaltime += livetime totalL += intlumi totalgoodblock += 1 else: totalbadblock += 1 l1countitr.close() else: print "Trigger not defined for run", lbinfo.run if (self.loglevel > 0): print "Rng-T %7i %7i %7i %8.2f %10.1f" % ( totalacc[0], totalacc[1], totalacc[2], totaltime, totalL) return lumiResult(totalL, totalacc[0], totalacc[1], totalacc[2], totaltime, totalgoodblock, totalbadblock)