ATLAS Offline Software
Public Member Functions | Public Attributes | List of all members
python.TriggerAnalysisSFConfig.TriggerAnalysisSFBlock Class Reference
Inheritance diagram for python.TriggerAnalysisSFConfig.TriggerAnalysisSFBlock:
Collaboration diagram for python.TriggerAnalysisSFConfig.TriggerAnalysisSFBlock:

Public Member Functions

def __init__ (self)
 
None makeTriggerGlobalEffCorrAlg (self, ConfigAccumulator config, matchingTool, bool noSF, str triggerSuffix='')
 
None createTrigMatching (self, ConfigAccumulator config, matchingTool, particles, str trig_string="", set trig_chains=None, set trig_chains_dummy=None)
 
None makeTrigMatchingAlg (self, ConfigAccumulator config, matchingTool)
 
None makeAlgs (self, ConfigAccumulator config)
 

Public Attributes

 multiTriggerChainsPerYear
 
 triggerChainsPerYear
 

Detailed Description

the ConfigBlock for trigger analysis

Definition at line 64 of file TriggerAnalysisSFConfig.py.

Constructor & Destructor Documentation

◆ __init__()

def python.TriggerAnalysisSFConfig.TriggerAnalysisSFBlock.__init__ (   self)

Definition at line 66 of file TriggerAnalysisSFConfig.py.

66  def __init__(self):
67  super(TriggerAnalysisSFBlock, self).__init__()
68  self.addDependency('Electrons', required=False)
69  self.addDependency('Photons', required=False)
70  self.addDependency('Muons', required=False)
71  self.addDependency('Taus', required=False)
72  self.addDependency('OverlapRemoval', required=False)
73 
74  self.addOption ('triggerChainsPerYear', {}, type=None,
75  info="a dictionary with key (string) the year and value (list of "
76  "strings) the trigger chains. You can also use || within a string "
77  "to enforce an OR of triggers without looking up the individual "
78  "triggers. Used for both trigger selection and SFs. "
79  "The default is {} (empty dictionary).")
80  self.addOption ('multiTriggerChainsPerYear', {}, type=None,
81  info="a dictionary with key (string) a trigger set name and value a "
82  "triggerChainsPerYear dictionary, following the previous convention. "
83  "Relevant for analyses using different triggers in different categories, "
84  "where the trigger global scale factors shouldn't be combined. "
85  "The default is {} (empty dictionary).")
86  self.addOption ('noFilter', False, type=bool,
87  info="do not apply an event filter. The default is False, i.e. "
88  "remove events not passing trigger selection and matching.")
89  self.addOption ('electronID', '', type=str,
90  info="the electron ID WP (string) to use.")
91  self.addOption ('electronIsol', '', type=str,
92  info="the electron isolation WP (string) to use.")
93  self.addOption ('photonIsol', '', type=str,
94  info="the photon isolation WP (string) to use.")
95  self.addOption ('muonID', '', type=str,
96  info="the muon quality WP (string) to use.")
97  self.addOption ('electrons', '', type=str,
98  info="the input electron container, with a possible selection, in "
99  "the format container or container.selection.")
100  self.addOption ('muons', '', type=str,
101  info="the input muon container, with a possible selection, in the "
102  "format container or container.selection.")
103  self.addOption ('photons', '', type=str,
104  info="the input photon container, with a possible selection, in "
105  "the format container or container.selection.")
106  self.addOption ('taus', '', type=str,
107  info="the input tau container, with a possible selection, in "
108  "the format container or container.selection.")
109  self.addOption ('numberOfToys', 0, type=int,
110  info="Number of toy experiments to run to estimate the trigger efficiencies, "
111  "instead of using explicit formulas. The default is 0 (not using toys).")
112  self.addOption ('noEffSF', False, type=bool,
113  info="disables the calculation of efficiencies and scale factors. "
114  "Experimental! only useful to test a new WP for which scale "
115  "factors are not available. Still performs the global trigger "
116  "matching (same behaviour as on data). The default is False.",
117  expertMode=True)
118  self.addOption ('noGlobalTriggerEff', False, type=bool,
119  info="disables the global trigger efficiency tool (including "
120  "matching), which is only suited for electron/muon/photon "
121  "trigger legs. The default is False.")
122  self.addOption ('separateChainMatching', False, type=bool,
123  info="Store the matching status for each trigger separately")
124  self.addOption ('triggerMatchingChainsPerYear', {}, type=None,
125  info="a dictionary with key (string) the year and value (list of "
126  "strings) the trigger chains. The default is {} (empty dictionary).")
127  self.addOption("includeAllYearsPerRun", False, type=bool,
128  info="if True, trigger matching will include all configured years "
129  "in the LHC run in all jobs. The default is False.")
130  self.addOption ('postfix', '', type=str,
131  info="a unique identifier for the trigger matching decorations. Only "
132  "useful when defining multiple setups. The default is '' (empty string).")
133 

Member Function Documentation

◆ createTrigMatching()

None python.TriggerAnalysisSFConfig.TriggerAnalysisSFBlock.createTrigMatching (   self,
ConfigAccumulator  config,
  matchingTool,
  particles,
str   trig_string = "",
set   trig_chains = None,
set   trig_chains_dummy = None 
)

Definition at line 213 of file TriggerAnalysisSFConfig.py.

213  def createTrigMatching(
214  self,
215  config: ConfigAccumulator,
216  matchingTool,
217  particles,
218  trig_string: str = "",
219  trig_chains: set = None,
220  trig_chains_dummy: set = None,
221  ) -> None:
222  if not particles or (not trig_chains and not trig_chains_dummy):
223  return
224 
225  if not any(trig_string in trig for trig in trig_chains) \
226  and not any(trig_string in trig for trig in trig_chains_dummy):
227  return
228 
229  alg = config.createAlgorithm("CP::TrigMatchingAlg", f"TrigMatchingAlg_{trig_string}{self.postfix}")
230  alg.matchingTool = f"{matchingTool.getType()}/{matchingTool.getName()}"
231  alg.matchingDecoration = f"trigMatched{self.postfix}"
232  alg.trigSingleMatchingList = [trig for trig in trig_chains if trig_string in trig]
233  alg.trigSingleMatchingListDummy = [trig for trig in trig_chains_dummy if trig_string in trig]
234  alg.particles, alg.particleSelection = config.readNameAndSelection(particles)
235 
236  for trig in list(alg.trigSingleMatchingList) + list(alg.trigSingleMatchingListDummy):
237  trig = trig.replace(".", "p").replace("-", "_").replace(" ", "")
238  if trig_string in trig:
239  config.addOutputVar(particles.split(".")[0], f"trigMatched_{self.postfix}{trig}", f"trigMatched_{self.postfix}{trig}", noSys=True)
240 

◆ makeAlgs()

None python.TriggerAnalysisSFConfig.TriggerAnalysisSFBlock.makeAlgs (   self,
ConfigAccumulator  config 
)

Definition at line 271 of file TriggerAnalysisSFConfig.py.

271  def makeAlgs(self, config: ConfigAccumulator) -> None:
272  if (
273  self.multiTriggerChainsPerYear and
274  self.triggerChainsPerYear and
275  self.triggerChainsPerYear not in self.multiTriggerChainsPerYear.values()
276  ):
277  raise Exception('multiTriggerChainsPerYear and triggerChainsPerYear cannot be configured at the same time!')
278 
279  if self.triggerChainsPerYear and not self.multiTriggerChainsPerYear:
280  self.multiTriggerChainsPerYear = {'': self.triggerChainsPerYear}
281 
282  # Create the decision algorithm, keeping track of the decision tool for later
283  decisionTool = TriggerAnalysisBlock.makeTriggerDecisionTool(config)
284 
285  # Now pass it to the matching algorithm, keeping track of the matching tool for later
286  matchingTool = TriggerAnalysisBlock.makeTriggerMatchingTool(config, decisionTool)
287 
288  # Calculate multi-lepton (electron/muon/photon) trigger efficiencies and SFs
289  if self.multiTriggerChainsPerYear and not self.noGlobalTriggerEff:
290  for suffix, trigger_chains in self.multiTriggerChainsPerYear.items():
291  self.triggerChainsPerYear = trigger_chains
292  self.makeTriggerGlobalEffCorrAlg(config, matchingTool, self.noEffSF, suffix)
293 
294  # Save trigger matching information (currently only single leg trigger are supported)
295  if self.triggerMatchingChainsPerYear:
296  self.makeTrigMatchingAlg(config, matchingTool)
297 
298  return

◆ makeTriggerGlobalEffCorrAlg()

None python.TriggerAnalysisSFConfig.TriggerAnalysisSFBlock.makeTriggerGlobalEffCorrAlg (   self,
ConfigAccumulator  config,
  matchingTool,
bool  noSF,
str   triggerSuffix = '' 
)

Definition at line 134 of file TriggerAnalysisSFConfig.py.

134  def makeTriggerGlobalEffCorrAlg(
135  self,
136  config: ConfigAccumulator,
137  matchingTool,
138  noSF: bool,
139  triggerSuffix: str = ''
140  ) -> None:
141  alg = config.createAlgorithm( 'CP::TrigGlobalEfficiencyAlg', 'TrigGlobalSFAlg' + triggerSuffix + self.postfix)
142  if config.geometry() is LHCPeriod.Run3:
143  alg.triggers_2022 = [trig.replace("HLT_","").replace(" || ", "_OR_") for trig in get_year_data(self.triggerChainsPerYear, 2022)]
144  alg.triggers_2023 = [trig.replace("HLT_","").replace(" || ", "_OR_") for trig in get_year_data(self.triggerChainsPerYear, 2023)]
145  alg.triggers_2024 = [trig.replace("HLT_","").replace(" || ", "_OR_") for trig in get_year_data(self.triggerChainsPerYear, 2024)]
146  alg.triggers_2025 = [trig.replace("HLT_","").replace(" || ", "_OR_") for trig in get_year_data(self.triggerChainsPerYear, 2025)]
147  if is_mc_from(config, Campaign.MC23a) or is_data_from(config, 2022):
148  if not alg.triggers_2022:
149  raise ValueError('TriggerAnalysisConfig: you must provide a set of triggers for the year 2022!')
150  elif is_mc_from(config, Campaign.MC23d) or is_data_from(config, 2023):
151  if not alg.triggers_2023:
152  raise ValueError('TriggerAnalysisConfig: you must provide a set of triggers for the year 2023!')
153  else:
154  alg.triggers_2015 = [trig.replace("HLT_","").replace(" || ", "_OR_") for trig in get_year_data(self.triggerChainsPerYear, 2015)]
155  alg.triggers_2016 = [trig.replace("HLT_","").replace(" || ", "_OR_") for trig in get_year_data(self.triggerChainsPerYear, 2016)]
156  alg.triggers_2017 = [trig.replace("HLT_","").replace(" || ", "_OR_") for trig in get_year_data(self.triggerChainsPerYear, 2017)]
157  alg.triggers_2018 = [trig.replace("HLT_","").replace(" || ", "_OR_") for trig in get_year_data(self.triggerChainsPerYear, 2018)]
158  if is_mc_from(config, Campaign.MC20a):
159  if not (alg.triggers_2015 and alg.triggers_2016):
160  raise ValueError('TriggerAnalysisConfig: you must provide a set of triggers for the years 2015 and 2016!')
161  elif is_data_from(config, 2015):
162  if not alg.triggers_2015:
163  raise ValueError('TriggerAnalysisConfig: you must provide a set of triggers for the year 2015!')
164  elif is_data_from(config, 2016):
165  if not alg.triggers_2016:
166  raise ValueError('TriggerAnalysisConfig: you must provide a set of triggers for the year 2016!')
167  elif is_mc_from(config, Campaign.MC20d) or is_data_from(config, 2017):
168  if not alg.triggers_2017:
169  raise ValueError('TriggerAnalysisConfig: you must provide a set of triggers for the year 2017!')
170  elif is_mc_from(config, Campaign.MC20e) or is_data_from(config, 2018):
171  if not alg.triggers_2018:
172  raise ValueError('TriggerAnalysisConfig: you must provide a set of triggers for the year 2018!')
173 
174  triggerMatchingChains = set()
175  if self.separateChainMatching:
176  for year in get_input_years(config):
177  for trig in get_year_data(self.triggerChainsPerYear, year):
178  triggerMatchingChains.update(trig.replace(' || ', '_OR_').split('_OR_'))
179  alg.separateMatchingTriggers = list(triggerMatchingChains)
180  alg.separateMatchingDecorationSuffix = triggerSuffix + self.postfix
181 
182  alg.matchingTool = '%s/%s' % ( matchingTool.getType(), matchingTool.getName() )
183  alg.isRun3Geo = config.geometry() is LHCPeriod.Run3
184  alg.numberOfToys = self.numberOfToys
185  alg.scaleFactorDecoration = 'globalTriggerEffSF' + triggerSuffix + self.postfix + '_%SYS%'
186  alg.matchingDecoration = 'globalTriggerMatch' + triggerSuffix + self.postfix + '_%SYS%'
187  alg.eventDecisionOutputDecoration = 'globalTriggerMatch' + triggerSuffix + self.postfix + '_dontsave_%SYS%'
188  alg.doMatchingOnly = config.dataType() is DataType.Data or noSF
189  alg.noFilter = self.noFilter
190  alg.electronID = self.electronID
191  alg.electronIsol = self.electronIsol
192  alg.photonIsol = self.photonIsol
193  alg.muonID = self.muonID
194  if self.electrons:
195  alg.electrons, alg.electronSelection = config.readNameAndSelection(self.electrons)
196  if self.muons:
197  alg.muons, alg.muonSelection = config.readNameAndSelection(self.muons)
198  if self.photons:
199  alg.photons, alg.photonSelection = config.readNameAndSelection(self.photons)
200  if not (self.electrons or self.muons or self.photons):
201  raise ValueError('TriggerAnalysisConfig: at least one object collection must be provided! (electrons, muons, photons)' )
202 
203  if config.dataType() is not DataType.Data and not alg.doMatchingOnly:
204  config.addOutputVar('EventInfo', alg.scaleFactorDecoration, 'globalTriggerEffSF' + triggerSuffix + self.postfix)
205  config.addOutputVar('EventInfo', alg.matchingDecoration, 'globalTriggerMatch' + triggerSuffix + self.postfix, noSys=False)
206 
207  for trig in triggerMatchingChains:
208  var = f'triggerMatch_{trig.replace("-", "_").replace(".", "p")}{alg.separateMatchingDecorationSuffix}'
209  config.addOutputVar('EventInfo', f'{var}_%SYS%', var, noSys=False)
210 
211  return
212 

◆ makeTrigMatchingAlg()

None python.TriggerAnalysisSFConfig.TriggerAnalysisSFBlock.makeTrigMatchingAlg (   self,
ConfigAccumulator  config,
  matchingTool 
)

Definition at line 241 of file TriggerAnalysisSFConfig.py.

241  def makeTrigMatchingAlg(
242  self,
243  config: ConfigAccumulator,
244  matchingTool,
245  ) -> None:
246  years = get_input_years(config)
247 
248  triggerMatchingChains = set()
249  triggerMatchingChainsDummy = set()
250  for year in years:
251  for trig in get_year_data(self.triggerMatchingChainsPerYear, year):
252  trig = trig.replace(' || ', '_OR_')
253  triggerMatchingChains.update(trig.split('_OR_'))
254  if self.includeAllYearsPerRun:
255  triggerMatchingChainsAll = set()
256  for year in self.triggerMatchingChainsPerYear:
257  if not is_year_in_current_period(config, year):
258  continue
259  for trig in get_year_data(self.triggerMatchingChainsPerYear, year):
260  trig = trig.replace(' || ', '_OR_')
261  triggerMatchingChainsAll.update(trig.split('_OR_'))
262  triggerMatchingChainsDummy = triggerMatchingChainsAll - triggerMatchingChains
263 
264  self.createTrigMatching(config, matchingTool, self.electrons, 'HLT_e', triggerMatchingChains, triggerMatchingChainsDummy)
265  self.createTrigMatching(config, matchingTool, self.muons, 'HLT_mu', triggerMatchingChains, triggerMatchingChainsDummy)
266  self.createTrigMatching(config, matchingTool, self.photons, 'HLT_g', triggerMatchingChains, triggerMatchingChainsDummy)
267  self.createTrigMatching(config, matchingTool, self.taus, 'HLT_tau', triggerMatchingChains, triggerMatchingChainsDummy)
268 
269  return
270 

Member Data Documentation

◆ multiTriggerChainsPerYear

python.TriggerAnalysisSFConfig.TriggerAnalysisSFBlock.multiTriggerChainsPerYear

Definition at line 280 of file TriggerAnalysisSFConfig.py.

◆ triggerChainsPerYear

python.TriggerAnalysisSFConfig.TriggerAnalysisSFBlock.triggerChainsPerYear

Definition at line 291 of file TriggerAnalysisSFConfig.py.


The documentation for this class was generated from the following file:
replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:307
python.processes.powheg.ZZj_MiNNLO.ZZj_MiNNLO.__init__
def __init__(self, base_directory, **kwargs)
Constructor: all process options are set here.
Definition: ZZj_MiNNLO.py:18
python.TriggerAnalysisSFConfig.is_mc_from
bool is_mc_from(ConfigAccumulator config, Union[Campaign, Iterable[Campaign]] campaign_list)
Definition: TriggerAnalysisSFConfig.py:11
python.Bindings.values
values
Definition: Control/AthenaPython/python/Bindings.py:808
python.TriggerAnalysisConfig.is_year_in_current_period
bool is_year_in_current_period(ConfigAccumulator config, int|str year)
Definition: TriggerAnalysisConfig.py:9
python.TriggerAnalysisSFConfig.get_year_data
list get_year_data(dict dictionary, int|str year)
Definition: TriggerAnalysisSFConfig.py:28
python.TriggerAnalysisSFConfig.is_data_from
bool is_data_from(config, Union[int, Iterable[int]] data_year_list)
Definition: TriggerAnalysisSFConfig.py:20
python.TriggerAnalysisSFConfig.get_input_years
list[int] get_input_years(ConfigAccumulator config)
Definition: TriggerAnalysisSFConfig.py:35
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
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:232
TrigJetMonitorAlgorithm.items
items
Definition: TrigJetMonitorAlgorithm.py:71
Trk::split
@ split
Definition: LayerMaterialProperties.h:38