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 77 of file TriggerAnalysisSFConfig.py.

Constructor & Destructor Documentation

◆ __init__()

def python.TriggerAnalysisSFConfig.TriggerAnalysisSFBlock.__init__ (   self)

Definition at line 79 of file TriggerAnalysisSFConfig.py.

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

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 226 of file TriggerAnalysisSFConfig.py.

226  def createTrigMatching(
227  self,
228  config: ConfigAccumulator,
229  matchingTool,
230  particles,
231  trig_string: str = "",
232  trig_chains: set = None,
233  trig_chains_dummy: set = None,
234  ) -> None:
235  if not particles or (not trig_chains and not trig_chains_dummy):
236  return
237 
238  if not any(trig_string in trig for trig in trig_chains) \
239  and not any(trig_string in trig for trig in trig_chains_dummy):
240  return
241 
242  alg = config.createAlgorithm("CP::TrigMatchingAlg", f"TrigMatchingAlg_{trig_string}{self.postfix}")
243  alg.matchingTool = f"{matchingTool.getType()}/{matchingTool.getName()}"
244  alg.matchingDecoration = f"trigMatched{self.postfix}"
245  alg.trigSingleMatchingList = [trig for trig in trig_chains if trig_string in trig]
246  alg.trigSingleMatchingListDummy = [trig for trig in trig_chains_dummy if trig_string in trig]
247  alg.particles, alg.particleSelection = config.readNameAndSelection(particles)
248 
249  for trig in list(alg.trigSingleMatchingList) + list(alg.trigSingleMatchingListDummy):
250  trig = trig.replace(".", "p").replace("-", "_").replace(" ", "")
251  if trig_string in trig:
252  config.addOutputVar(particles.split(".")[0], f"trigMatched_{self.postfix}{trig}", f"trigMatched_{self.postfix}{trig}", noSys=True)
253 

◆ makeAlgs()

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

Definition at line 284 of file TriggerAnalysisSFConfig.py.

284  def makeAlgs(self, config: ConfigAccumulator) -> None:
285  if (
286  self.multiTriggerChainsPerYear and
287  self.triggerChainsPerYear and
288  self.triggerChainsPerYear not in self.multiTriggerChainsPerYear.values()
289  ):
290  raise Exception('multiTriggerChainsPerYear and triggerChainsPerYear cannot be configured at the same time!')
291 
292  if self.triggerChainsPerYear and not self.multiTriggerChainsPerYear:
293  self.multiTriggerChainsPerYear = {'': self.triggerChainsPerYear}
294 
295  # Create the decision algorithm, keeping track of the decision tool for later
296  decisionTool = TriggerAnalysisBlock.makeTriggerDecisionTool(config)
297 
298  # Now pass it to the matching algorithm, keeping track of the matching tool for later
299  matchingTool = TriggerAnalysisBlock.makeTriggerMatchingTool(config, decisionTool)
300 
301  # Calculate multi-lepton (electron/muon/photon) trigger efficiencies and SFs
302  if self.multiTriggerChainsPerYear and not self.noGlobalTriggerEff:
303  for suffix, trigger_chains in self.multiTriggerChainsPerYear.items():
304  self.triggerChainsPerYear = trigger_chains
305  self.makeTriggerGlobalEffCorrAlg(config, matchingTool, self.noEffSF, suffix)
306 
307  # Save trigger matching information (currently only single leg trigger are supported)
308  if self.triggerMatchingChainsPerYear:
309  self.makeTrigMatchingAlg(config, matchingTool)
310 
311  return

◆ makeTriggerGlobalEffCorrAlg()

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

Definition at line 147 of file TriggerAnalysisSFConfig.py.

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

◆ makeTrigMatchingAlg()

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

Definition at line 254 of file TriggerAnalysisSFConfig.py.

254  def makeTrigMatchingAlg(
255  self,
256  config: ConfigAccumulator,
257  matchingTool,
258  ) -> None:
259  years = get_input_years(config)
260 
261  triggerMatchingChains = set()
262  triggerMatchingChainsDummy = set()
263  for year in years:
264  for trig in get_year_data(self.triggerMatchingChainsPerYear, year):
265  trig = trig.replace(' || ', '_OR_')
266  triggerMatchingChains.update(trig.split('_OR_'))
267  if self.includeAllYearsPerRun:
268  triggerMatchingChainsAll = set()
269  for year in self.triggerMatchingChainsPerYear:
270  if not is_year_in_current_period(config, year):
271  continue
272  for trig in get_year_data(self.triggerMatchingChainsPerYear, year):
273  trig = trig.replace(' || ', '_OR_')
274  triggerMatchingChainsAll.update(trig.split('_OR_'))
275  triggerMatchingChainsDummy = triggerMatchingChainsAll - triggerMatchingChains
276 
277  self.createTrigMatching(config, matchingTool, self.electrons, 'HLT_e', triggerMatchingChains, triggerMatchingChainsDummy)
278  self.createTrigMatching(config, matchingTool, self.muons, 'HLT_mu', triggerMatchingChains, triggerMatchingChainsDummy)
279  self.createTrigMatching(config, matchingTool, self.photons, 'HLT_g', triggerMatchingChains, triggerMatchingChainsDummy)
280  self.createTrigMatching(config, matchingTool, self.taus, 'HLT_tau', triggerMatchingChains, triggerMatchingChainsDummy)
281 
282  return
283 

Member Data Documentation

◆ multiTriggerChainsPerYear

python.TriggerAnalysisSFConfig.TriggerAnalysisSFBlock.multiTriggerChainsPerYear

Definition at line 293 of file TriggerAnalysisSFConfig.py.

◆ triggerChainsPerYear

python.TriggerAnalysisSFConfig.TriggerAnalysisSFBlock.triggerChainsPerYear

Definition at line 304 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:310
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