Skip to content
Snippets Groups Projects
Commit d80517be authored by Tadej Novak's avatar Tadej Novak
Browse files

Merge branch 'MultiTriggerChain' into 'main'

Add support for multiTriggerChainsPerYear in TriggerAnalysisBlock

See merge request atlas/athena!70292
parents c43a3c36 52cfd53e
No related branches found
No related tags found
No related merge requests found
......@@ -19,6 +19,12 @@ class TriggerAnalysisBlock (ConfigBlock):
"to enforce an OR of triggers without looking up the individual "
"triggers. Used for both trigger selection and SFs. "
"The default is {} (empty dictionary).")
self.addOption ('multiTriggerChainsPerYear', {}, type=None,
info="a dictionary with key (string) a trigger set name and value a "
"triggerChainsPerYear dictionary, following the previous convention. "
"Relevant for analyses using different triggers in different categories, "
"where the trigger global scale factors shouldn't be combined. "
"The default is {} (empty dictionary).")
self.addOption ('triggerChainsForSelection', [], type=None,
info="a list of trigger chains (list of strings) to be used for "
"trigger selection. Only set it if you need a different setup "
......@@ -77,16 +83,25 @@ class TriggerAnalysisBlock (ConfigBlock):
def makeAlgs (self, config) :
if (self.multiTriggerChainsPerYear and self.triggerChainsPerYear and
self.triggerChainsPerYear is not self.multiTriggerChainsPerYear.get('')):
raise Exception('multiTriggerChainsPerYear and triggerChainsPerYear cannot be configured at the same time!')
if self.triggerChainsPerYear and not self.multiTriggerChainsPerYear:
self.multiTriggerChainsPerYear = {'': self.triggerChainsPerYear}
# if we are only given the trigger dictionary, we fill the selection list automatically
if self.triggerChainsPerYear and not self.triggerChainsForSelection:
triggers = set()
for chain_list in self.triggerChainsPerYear.values():
for chain in chain_list:
if '||' in chain:
chains = chain.split('||')
triggers.update(map(str.strip, chains))
else:
triggers.add(chain.strip())
for trigger_chains in self.multiTriggerChainsPerYear.values():
for chain_list in self.triggerChainsPerYear.values():
for chain in chain_list:
if '||' in chain:
chains = chain.split('||')
triggers.update(map(str.strip, chains))
else:
triggers.add(chain.strip())
self.triggerChainsForSelection = list(triggers)
# Create the decision algorithm, keeping track of the decision tool for later
......
......@@ -23,6 +23,12 @@ class TriggerAnalysisSFBlock (ConfigBlock):
"to enforce an OR of triggers without looking up the individual "
"triggers. Used for both trigger selection and SFs. "
"The default is {} (empty dictionary).")
self.addOption ('multiTriggerChainsPerYear', {}, type=None,
info="a dictionary with key (string) a trigger set name and value a "
"triggerChainsPerYear dictionary, following the previous convention. "
"Relevant for analyses using different triggers in different categories, "
"where the trigger global scale factors shouldn't be combined. "
"The default is {} (empty dictionary).")
self.addOption ('noFilter', False, type=bool,
info="do not apply an event filter. The default is False, i.e. "
"remove events not passing trigger selection and matching.")
......@@ -88,7 +94,8 @@ class TriggerAnalysisSFBlock (ConfigBlock):
return matchingTool
def makeTriggerGlobalEffCorrAlg(self, config, matchingTool, noSF):
def makeTriggerGlobalEffCorrAlg(self, config, matchingTool, noSF,
triggerSuffix=''):
alg = config.createAlgorithm( 'CP::TrigGlobalEfficiencyAlg', 'TrigGlobalSFAlg' )
if config.geometry() == LHCPeriod.Run3:
......@@ -119,9 +126,9 @@ class TriggerAnalysisSFBlock (ConfigBlock):
alg.matchingTool = '%s/%s' % ( matchingTool.getType(), matchingTool.getName() )
alg.isRun3Geo = config.geometry() == LHCPeriod.Run3
alg.scaleFactorDecoration = 'globalTriggerEffSF_%SYS%'
alg.matchingDecoration = 'globalTriggerMatch_%SYS%'
alg.eventDecisionOutputDecoration = 'globalTriggerMatch_dontsave_%SYS%'
alg.scaleFactorDecoration = 'globalTriggerEffSF'+triggerSuffix+'_%SYS%'
alg.matchingDecoration = 'globalTriggerMatch'+triggerSuffix+'_%SYS%'
alg.eventDecisionOutputDecoration = 'globalTriggerMatch'+triggerSuffix+'_dontsave_%SYS%'
alg.doMatchingOnly = config.dataType() is DataType.Data or noSF
alg.noFilter = self.noFilter
alg.electronID = self.electronID
......@@ -138,8 +145,8 @@ class TriggerAnalysisSFBlock (ConfigBlock):
raise ValueError ('TriggerAnalysisConfig: at least one object collection must be provided! (electrons, muons, photons)' )
if config.dataType() != DataType.Data and not alg.doMatchingOnly:
config.addOutputVar ('EventInfo', alg.scaleFactorDecoration, 'globalTriggerEffSF')
config.addOutputVar ('EventInfo', alg.matchingDecoration, 'globalTriggerMatch', noSys=True)
config.addOutputVar ('EventInfo', alg.scaleFactorDecoration, 'globalTriggerEffSF'+triggerSuffix)
config.addOutputVar ('EventInfo', alg.matchingDecoration, 'globalTriggerMatch'+triggerSuffix, noSys=False)
return
......@@ -152,7 +159,9 @@ class TriggerAnalysisSFBlock (ConfigBlock):
matchingTool = self.makeTriggerMatchingTool(config, decisionTool)
# Calculate multi-lepton (electron/muon/photon) trigger efficiencies and SFs
if self.triggerChainsPerYear and not self.noGlobalTriggerEff:
self.makeTriggerGlobalEffCorrAlg(config, matchingTool, self.noEffSF)
if self.multiTriggerChainsPerYear and not self.noGlobalTriggerEff:
for suffix, trigger_chains in self.multiTriggerChainsPerYear:
self.triggerChainsPerYear = trigger_chains
self.makeTriggerGlobalEffCorrAlg(config, matchingTool, self.noEffSF, suffix)
return
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment