ATLAS Offline Software
Loading...
Searching...
No Matches
RatesTrigger.py
Go to the documentation of this file.
2# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3#
4
5'''
6@file RatesTrigger.py
7@brief Accumulator class to buffer data for a single trigger and export this to JSON or CSV
8'''
9
10import math
11from enum import Enum
12from AthenaCommon.Logging import logging
13log = logging.getLogger('RatesTrigger')
14
15class RatesBins(Enum):
16 ACTIVE_RAW_BIN = 1
17 ACTIVE_WEIGHTED_BIN = 2
18 PASS_RAW_BIN = 3
19 PASS_WEIGHTED_OR_BIN = 4
20 PASS_WEIGHTED_AND_BIN = 5
21 EXPRESS_BIN = 6
22 UNIQUE_BIN = 7
23
25 def __init__(self, name, metadata, data, masterGroup, suffix):
26 self.name = name
27 self.chainName = self.name.removesuffix(suffix)
28 # Total weighted events passing the trigger
29 self.passWeighted = data.GetBinContent(RatesBins.PASS_WEIGHTED_OR_BIN.value)
30 self.passWeightedErr = data.GetBinError(RatesBins.PASS_WEIGHTED_OR_BIN.value)
31
32 # Total un-weighted events passing the trigger
33 self.passRaw = data.GetBinContent(RatesBins.PASS_RAW_BIN.value)
34
35 # Total weighted events passing the trigger, using the express prescale
36 self.passExpressWeighted = data.GetBinContent(RatesBins.EXPRESS_BIN.value)
37 self.passExpressWeightedErr = data.GetBinError(RatesBins.EXPRESS_BIN.value)
38
39 # Total weighted events passing a full hypothetical menu which *excluded* this trigger
40 self.passUniqueWeighted = data.GetBinContent(RatesBins.UNIQUE_BIN.value)
41 self.passUniqueWeightedErr = data.GetBinError(RatesBins.UNIQUE_BIN.value)
42
43 # Total weighted events passing the full menu (full L1 for L1 chains, full HLT for HLT chains)
44 self.passMasterWeighted = masterGroup.GetBinContent(RatesBins.PASS_WEIGHTED_OR_BIN.value)
45
46 # Total un-weighted number of events in which the trigger was active (always active if L1)
47 self.activeRaw = data.GetBinContent(RatesBins.ACTIVE_RAW_BIN.value)
48
49 # Total weighted number of events in which the trigger was active
50 self.activeWeighted = data.GetBinContent(RatesBins.ACTIVE_WEIGHTED_BIN.value)
51 self.activeWeightedErr = data.GetBinError(RatesBins.ACTIVE_WEIGHTED_BIN.value)
52
53 # Wall-time in seconds. No error on this.
54 self.rateDenominator = metadata['normalisation'+suffix]
55 if not self.rateDenominator:
56 log.error("Normalisation factor not found in the input ntuple! Check if it's not corrupted")
57 raise ValueError
58
59 # Trigger's rate is total weighted passing events normalised to wall-time
62
63 # Trigger's efficiency is the fraction of active events which are passed. Error propagated.
64 self.efficiency = self.passWeighted / self.activeWeighted if self.activeWeighted > 0.0 else 0.0
66 if self.passWeighted != 0 and self.activeWeighted != 0:
67 fracErr = math.sqrt( math.pow(self.passWeightedErr/self.passWeighted,2) + math.pow(self.activeWeightedErr/self.activeWeighted,2) )
68 self.efficiencyErr = self.efficiency * fracErr
69
70 # Rate using express prescales
73
74 # Some menu-derived metadata
75 prescales = metadata['prescales']
76
77 lowers = metadata['lowers']
78 express = metadata['express']
79
80 self.prescale = prescales.get(self.chainName,1)
81 self.lower = lowers.get(self.chainName)
82 self.expressPrescale = express.get(self.chainName)
83
84 # Unique rate requires the subtraction of the (all minus this trigger) total from the (all triggers) total
85 # The error is taken as a fractional error on the main rate calc
86 # Disabled items should have unique rate = 0
87 if self.prescale != "Multiple" and float(self.prescale) <= 0:
88 self.rateUnique = 0
89 self.rateUniqueErr = 0
90 else:
92 self.rateUniqueErr = 0
93 if self.passWeighted != 0:
94 self.rateUniqueErr = (self.passWeightedErr / self.passWeighted) * self.rateUnique
95
96 # The total rate of all triggers
98
99 # What fraction of the total rate is unique to this trigger
100 self.uniqueFraction = 0 if self.masterRate == 0 else self.rateUnique / self.masterRate
101
102
103 def export(self, exportDict):
104 myDict = {}
105 myDict['express_stream'] = self.rateExpress
106 myDict['chain_prescale'] = self.prescale
107 myDict['lower_chain_name'] = self.lower
108 myDict['evts_passed'] = self.passRaw
109 myDict['evts_passed_weighted'] = self.passWeighted
110 myDict['efficiency'] = self.efficiency
111 myDict['efficiency_err'] = self.efficiencyErr
112 myDict['rate'] = self.rate
113 myDict['rate_err'] = self.rateErr
114 myDict['unique_fraction'] = self.uniqueFraction
115 myDict['unique_rate'] = self.rateUnique
116 exportDict[self.name] = myDict
__init__(self, name, metadata, data, masterGroup, suffix)