diff --git a/PhysicsAnalysis/Algorithms/AnalysisAlgorithmsConfig/python/ConfigAccumulator.py b/PhysicsAnalysis/Algorithms/AnalysisAlgorithmsConfig/python/ConfigAccumulator.py index fbd9b9b9510033b46404b0f47e3e9785296a3ac9..3c123e6147cabb1b5db032aa8a3fea61ebbfe809 100644 --- a/PhysicsAnalysis/Algorithms/AnalysisAlgorithmsConfig/python/ConfigAccumulator.py +++ b/PhysicsAnalysis/Algorithms/AnalysisAlgorithmsConfig/python/ConfigAccumulator.py @@ -1,5 +1,8 @@ # Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +import AnaAlgorithm.DualUseConfig as DualUseConfig + + def mapUserName (name) : """map an internal name to a name for systematics data handles @@ -19,127 +22,29 @@ class ContainerConfig : self.name = name self.sourceName = sourceName self.index = 0 + self.maxIndex = None self.viewIndex = 1 self.selection = {} self.selection[''] = [] self.selectionBits = {} self.selectionBits[''] = [] - - def indexName (self, index) : - """the name of the (temporary) container at the processing - step `index`""" - - if index == 0 : - if not self.sourceName : - raise Exception ("no source name defined for " + self.name) + def currentName (self) : + if self.index == 0 : return self.sourceName - if index == self.index : - return mapUserName (self.name) - return mapUserName(self.name + "_STEP" + str(index)) - - - - -class ContainerReadRef : - """a read-only reference to a container""" - - def __init__ (self, config, readIndex) : - self._config = config - self._readIndex = readIndex - - def sourceContainer (self): - """get the original container for the container""" - if not self._config.sourceName: - raise Exception ('no source container for ' + self.config.name) - return self._config.sourceName - - def input (self) : - """get the name of the input container in the event store""" - return self._config.indexName (self._readIndex) - - def wantCopy (self) : - """whether a shallow copy should be configured with this reference""" - return False - - - - -class ContainerUpdateRef : - """a copy/update reference to a container (i.e. making a copy)""" - - def __init__ (self, config, readIndex, writeIndex) : - self._config = config - self._readIndex = readIndex - self._writeIndex = writeIndex - - def sourceContainer (self): - """get the original container for the container""" - if not self._config.sourceName: - raise Exception ('no source container for ' + self.config.name) - return self._config.sourceName - - def input (self) : - """get the name of the input container in the event store""" - return self._config.indexName (self._readIndex) - - def output (self) : - """get the name of the output container in the event store""" - return self._config.indexName (self._writeIndex) - - def wantCopy (self) : - """whether a shallow copy should be configured with this reference""" - return True - - - - -class ContainerWriteRef : - """a write reference to a container (creating a new container)""" - - def __init__ (self, config) : - self._config = config - - def output (self) : - """get the name of the output container in the event store""" - return self._config.indexName (1) - - - - -class ContainerViewRef : - """a view reference to a container (providing a view container based - on a selection""" + if self.maxIndex and self.index == self.maxIndex : + return mapUserName(self.name) + return mapUserName(self.name + "_STEP" + str(self.index)) - def __init__ (self, config, baseConfig, baseRef, selection) : - self._config = config - self._baseConfig = baseConfig - self._baseRef = baseRef - self._selection = selection - self._scheduledAlg = False - def sourceContainer (self): - """get the original container for the container""" - return self._baseRef.sourceContainer() - - def input (self) : - """get the name of the input container in the event store""" - - if not self._scheduledAlg : - viewIndex = self._config.viewIndex - self._config.viewIndex += 1 - inputContainer = self._baseRef.input() - outputContainer = mapUserName(self._config.name + "_VIEW" + str(viewIndex)) - self.outputContainer = outputContainer - from AnaAlgorithm.DualUseConfig import createAlgorithm - viewalg = createAlgorithm( 'CP::AsgViewFromSelectionAlg', self._config.name + 'View' + str (viewIndex) + 'Alg' ) - viewalg.selection = [ self._selection ] - viewalg.input = inputContainer - viewalg.output = outputContainer - self._baseConfig.addAlg (viewalg) - self._scheduledAlg = True - - return self.outputContainer + def nextPass (self) : + self.maxIndex = self.index + self.index = 0 + self.viewIndex = 1 + self.selection = {} + self.selection[''] = [] + self.selectionBits = {} + self.selectionBits[''] = [] @@ -168,104 +73,111 @@ class ConfigAccumulator : self._dataType = dataType self._algSeq = algSeq self._containerConfig = {} + self._pass = 0 + self._algorithms = {} + self._currentAlg = None + def dataType (self) : """the data type we run on (data, mc, afii)""" return self._dataType - def addAlg (self, alg) : - """add an algorithm to the sequence being created""" - self._algSeq += alg - - def addPublicTool (self, tool) : - """add a public tool to the sequence being created""" - try: - # Try to access the ToolSvc, to see whethet we're in Athena mode: - from AthenaCommon.AppMgr import ToolSvc # noqa: F401 - except ImportError: - # We're not, so let's remember this as a "normal" algorithm: - self._algSeq += tool - - - def readOrUpdateRef (self, containerName, sourceName) : - """get a reference object to decorate the given container with - an option to update it - - The idea is that for the first algorithm in the sequence we - usually want to make a shallow copy, and usually do that by - taking advantage of copy-handles that can optionally copy. So - for every algorithm that could be the first in a sequence we - use this kind of reference which will either return a - read-reference or an update reference based on the context in - which it is used. - - Callers should check the wantCopy() member function on the - reference to see whether a copy should be configured. - """ - if containerName not in self._containerConfig : - if not sourceName : - raise Exception ("no source container for: " + containerName) - self._containerConfig[containerName] = ContainerConfig (containerName, sourceName) - config = self._containerConfig[containerName] - config.index += 1 - return ContainerUpdateRef (config, config.index-1, config.index) + + def createAlgorithm (self, type, name) : + """create a new algorithm and register it as the current algorithm""" + if self._pass == 0 : + if name in self._algorithms : + raise Exception ('duplicate algorithms: ' + name) + alg = DualUseConfig.createAlgorithm (type, name) + self._algSeq += alg + self._algorithms[name] = alg + self._currentAlg = alg + return alg else : - config = self._containerConfig[containerName] - return ContainerReadRef (config, config.index) + if name not in self._algorithms : + raise Exception ('unknown algorithm requested: ' + name) + self._currentAlg = self._algorithms[name] + return self._algorithms[name] + + + def createPublicTool (self, type, name) : + '''create a new public tool and register it as the "current algorithm"''' + if self._pass == 0 : + if name in self._algorithms : + raise Exception ('duplicate public tool: ' + name) + tool = DualUseConfig.createPublicTool (type, name) + try: + # Try to access the ToolSvc, to see whethet we're in Athena mode: + from AthenaCommon.AppMgr import ToolSvc # noqa: F401 + except ImportError: + # We're not, so let's remember this as a "normal" algorithm: + self._algSeq += tool + self._algorithms[name] = tool + self._currentAlg = tool + return tool + else : + if name not in self._algorithms : + raise Exception ('unknown public tool requested: ' + name) + self._currentAlg = self._algorithms[name] + return self._algorithms[name] + + + def addPrivateTool (self, type, name) : + """add a private tool to the current algorithm""" + if self._pass == 0 : + DualUseConfig.addPrivateTool (self._currentAlg, type, name) + + def readName (self, containerName, sourceName=None) : + """get the name of the "current copy" of the given container - def updateRef (self, containerName, sourceName) : - """get a reference object to update/copy the given container""" + As extra copies get created during processing this will track + the correct name of the current copy. Optionally one can pass + in the name of the container before the first copy. + """ if containerName not in self._containerConfig : if not sourceName : raise Exception ("no source container for: " + containerName) self._containerConfig[containerName] = ContainerConfig (containerName, sourceName) - config = self._containerConfig[containerName] - config.index += 1 - return ContainerUpdateRef (config, config.index-1, config.index) + return self._containerConfig[containerName].currentName() - def writeRef (self, containerName) : - """get a reference object to write/create the given container""" - if containerName in self._containerConfig : - raise Exception ("trying to create already existing container: " + containerName) - self._containerConfig[containerName] = ContainerConfig (containerName, None) - config = self._containerConfig[containerName] - config.index = 1 - return ContainerWriteRef (config) + def copyName (self, containerName) : + """register that a copy of the container will be made and return + its name""" + if containerName not in self._containerConfig : + raise Exception ("unknown container: " + containerName) + self._containerConfig[containerName].index += 1 + return self._containerConfig[containerName].currentName() - def readRef (self, containerName) : - """get a reference object to read the given container""" - if containerName not in self._containerConfig : - self._containerConfig[containerName] = ContainerConfig (containerName, containerName) - config = self._containerConfig[containerName] - return ContainerReadRef (config, config.index) + def wantCopy (self, containerName) : + """ask whether we want/need a copy of the container + This usually only happens if no copy of the container has been + made yet and the copy is needed to allow modifications, etc. + """ + if containerName not in self._containerConfig : + raise Exception ("unknown container: " + containerName) + return self._containerConfig[containerName].index == 0 - def viewRef (self, containerName) : - """get a reference object to read the given container with the given selection - The idea here is that this allows the user to specify a given view - as e.g. MyElectrons.tight and the reference object will then return - the name of a view container in the event store that has the - selection applied. This brings the handling of algorithms with a - view-based preselection in line with other algorithms. + def nextPass (self) : + """switch to the next configuration pass - WARNING: Unlike the other references this may/will schedule an - algorithm when queried (to create the view), so care must be - taken to query the container name at the right time.""" - split = containerName.split ('.') - if len(split) == 1: - return self.readRef (containerName) - if len(split) != 2: - raise Exception ('invalid name for a view input: ' + containerName) - baseRef = self.readRef(split[0]) - config = self._containerConfig[split[0]] - return ContainerViewRef (config, self, baseRef, split[1]) + Configuration happens in two steps, with all the blocks processed + twice. This switches from the first to the second pass. + """ + if self._pass != 0 : + raise Exception ("already performed final pass") + for name in self._containerConfig : + self._containerConfig[name].nextPass () + self._pass = 1 + self._currentAlg = None def getSelection (self, containerName, selectionName) : + """get the selection string for the given selection on the given container""" if containerName not in self._containerConfig : diff --git a/PhysicsAnalysis/Algorithms/AnalysisAlgorithmsConfig/python/ConfigSequence.py b/PhysicsAnalysis/Algorithms/AnalysisAlgorithmsConfig/python/ConfigSequence.py index 595760202c0825e9630d1997f88ca86de67a5e98..d0c789a598f3109d30efe9539ff5bf7ff54f8e1b 100644 --- a/PhysicsAnalysis/Algorithms/AnalysisAlgorithmsConfig/python/ConfigSequence.py +++ b/PhysicsAnalysis/Algorithms/AnalysisAlgorithmsConfig/python/ConfigSequence.py @@ -24,17 +24,6 @@ class ConfigSequence: self._blocks.append (block) - def collectReferences (self, config) : - """call collectReferences() on all blocks - - This registers references to the containers being processed in - the individual blocks, allowing them to match up along the - sequence when creating the algorithms. - """ - for block in self._blocks: - block.collectReferences (config) - - def makeAlgs (self, config) : """call makeAlgs() on all blocks @@ -52,5 +41,6 @@ class ConfigSequence: contain all the blocks that will be configured, as it will perform all configuration steps at once. """ - self.collectReferences (config) + self.makeAlgs (config) + config.nextPass () self.makeAlgs (config) diff --git a/PhysicsAnalysis/Algorithms/MuonAnalysisAlgorithms/python/MuonAnalysisConfig.py b/PhysicsAnalysis/Algorithms/MuonAnalysisAlgorithms/python/MuonAnalysisConfig.py index 3d76142dcfb87c9a1c1957321605f8eb13d7380b..502ac0acc0b4fccc1f187f102efae9aa5bb730c4 100644 --- a/PhysicsAnalysis/Algorithms/MuonAnalysisAlgorithms/python/MuonAnalysisConfig.py +++ b/PhysicsAnalysis/Algorithms/MuonAnalysisAlgorithms/python/MuonAnalysisConfig.py @@ -1,7 +1,6 @@ # Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration # AnaAlgorithm import(s): -from AnaAlgorithm.DualUseConfig import createAlgorithm, addPrivateTool from AnalysisAlgorithmsConfig.ConfigBlock import ConfigBlock import ROOT @@ -15,59 +14,51 @@ class MuonCalibrationConfig (ConfigBlock): self.postfix = postfix self.ptSelectionOutput = False - def collectReferences (self, config) : - self._muonRef1 = config.readOrUpdateRef (self.containerName, "Muons") - self._muonRef2 = config.updateRef (self.containerName, "Muons") - def makeAlgs (self, config) : # Set up the eta-cut on all muons prior to everything else - alg = createAlgorithm( 'CP::AsgSelectionAlg', + alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'MuonEtaCutAlg' + self.postfix ) - addPrivateTool( alg, 'selectionTool', 'CP::AsgPtEtaSelectionTool' ) + config.addPrivateTool( 'selectionTool', 'CP::AsgPtEtaSelectionTool' ) alg.selectionTool.maxEta = 2.5 alg.selectionDecoration = 'selectEta' + self.postfix + ',as_bits' - alg.particles = self._muonRef1.input() - if self._muonRef1.wantCopy() : - alg.particlesOut = self._muonRef1.output() + alg.particles = config.readName (self.containerName, "Muons") + if config.wantCopy (self.containerName) : + alg.particlesOut = config.copyName (self.containerName) alg.preselection = config.getSelection (self.containerName, '') config.addSelection (self.containerName, '', alg.selectionDecoration, 2) config.addSelection (self.containerName, 'output', alg.selectionDecoration, 2) - config.addAlg (alg) # Set up the track selection algorithm: - alg = createAlgorithm( 'CP::AsgLeptonTrackSelectionAlg', + alg = config.createAlgorithm( 'CP::AsgLeptonTrackSelectionAlg', 'MuonTrackSelectionAlg' + self.postfix ) alg.selectionDecoration = 'trackSelection' + self.postfix + ',as_bits' alg.maxD0Significance = 3 alg.maxDeltaZ0SinTheta = 0.5 - alg.particles = self._muonRef2.input() + alg.particles = config.readName (self.containerName) alg.preselection = config.getSelection (self.containerName, '') config.addSelection (self.containerName, '', alg.selectionDecoration, 3) config.addSelection (self.containerName, 'output', alg.selectionDecoration, 3) - config.addAlg (alg) # Set up the muon calibration and smearing algorithm: - alg = createAlgorithm( 'CP::MuonCalibrationAndSmearingAlg', + alg = config.createAlgorithm( 'CP::MuonCalibrationAndSmearingAlg', 'MuonCalibrationAndSmearingAlg' + self.postfix ) - addPrivateTool( alg, 'calibrationAndSmearingTool', + config.addPrivateTool( 'calibrationAndSmearingTool', 'CP::MuonCalibrationPeriodTool' ) alg.calibrationAndSmearingTool.calibrationMode = 2 # choose ID+MS with no sagitta bias - alg.muons = self._muonRef2.input() - alg.muonsOut = self._muonRef2.output() + alg.muons = config.readName (self.containerName) + alg.muonsOut = config.copyName (self.containerName) alg.preselection = config.getSelection (self.containerName, '') - config.addAlg (alg) # Set up the the pt selection - alg = createAlgorithm( 'CP::AsgSelectionAlg', 'MuonPtCutAlg' + self.postfix ) + alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'MuonPtCutAlg' + self.postfix ) alg.selectionDecoration = 'selectPt' + self.postfix + ',as_bits' - addPrivateTool( alg, 'selectionTool', 'CP::AsgPtEtaSelectionTool' ) - alg.particles = self._muonRef2.output() + config.addPrivateTool( 'selectionTool', 'CP::AsgPtEtaSelectionTool' ) + alg.particles = config.readName (self.containerName) alg.selectionTool.minPt = 3e3 alg.preselection = config.getSelection (self.containerName, '') config.addSelection (self.containerName, '', alg.selectionDecoration, 2) if self.ptSelectionOutput : config.addSelection (self.containerName, 'output', alg.selectionDecoration, 2) - config.addAlg (alg) @@ -85,9 +76,6 @@ class MuonWorkingPointConfig (ConfigBlock) : self.isolation = isolation self.qualitySelectionOutput = False - def collectReferences (self, config) : - self._muonRef1 = config.readRef (self.containerName) - def makeAlgs (self, config) : if self.quality == 'Tight' : @@ -116,45 +104,42 @@ class MuonWorkingPointConfig (ConfigBlock) : '\", allowed values are Iso, NonIso') # Setup the muon quality selection - alg = createAlgorithm( 'CP::MuonSelectionAlgV2', + alg = config.createAlgorithm( 'CP::MuonSelectionAlgV2', 'MuonSelectionAlg' + postfix ) - addPrivateTool( alg, 'selectionTool', 'CP::MuonSelectionTool' ) + config.addPrivateTool( 'selectionTool', 'CP::MuonSelectionTool' ) alg.selectionTool.MuQuality = quality alg.selectionDecoration = 'good_muon' + postfix + ',as_bits' alg.badMuonVetoDecoration = 'is_bad' + postfix + ',as_char' - alg.muons = self._muonRef1.input() + alg.muons = config.readName (self.containerName) alg.preselection = config.getSelection (self.containerName, self.selectionName) config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration, 4) if self.qualitySelectionOutput: config.addSelection (self.containerName, 'output', alg.selectionDecoration, 4) - config.addAlg (alg) # Set up the isolation calculation algorithm: if self.isolation != 'NonIso' : - alg = createAlgorithm( 'CP::MuonIsolationAlg', + alg = config.createAlgorithm( 'CP::MuonIsolationAlg', 'MuonIsolationAlg' + postfix ) - addPrivateTool( alg, 'isolationTool', 'CP::IsolationSelectionTool' ) + config.addPrivateTool( 'isolationTool', 'CP::IsolationSelectionTool' ) alg.isolationDecoration = 'isolated_muon' + postfix + ',as_bits' - alg.muons = self._muonRef1.input() + alg.muons = config.readName (self.containerName) alg.preselection = config.getSelection (self.containerName, self.selectionName) config.addSelection (self.containerName, self.selectionName, alg.isolationDecoration, 1) if self.qualitySelectionOutput: config.addSelection (self.containerName, 'output', alg.isolationDecoration, 1) - config.addAlg (alg) # Set up the efficiency scale factor calculation algorithm: if config.dataType() != 'data': - alg = createAlgorithm( 'CP::MuonEfficiencyScaleFactorAlg', + alg = config.createAlgorithm( 'CP::MuonEfficiencyScaleFactorAlg', 'MuonEfficiencyScaleFactorAlg' + postfix ) - addPrivateTool( alg, 'efficiencyScaleFactorTool', + config.addPrivateTool( 'efficiencyScaleFactorTool', 'CP::MuonEfficiencyScaleFactors' ) alg.scaleFactorDecoration = 'muon_effSF' + postfix + "_%SYS%" alg.outOfValidity = 2 #silent alg.outOfValidityDeco = 'bad_eff' + postfix alg.efficiencyScaleFactorTool.WorkingPoint = self.quality - alg.muons = self._muonRef1.input() + alg.muons = config.readName (self.containerName) alg.preselection = config.getSelection (self.containerName, self.selectionName) - config.addAlg (alg) diff --git a/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/DiTauAnalysisConfig.py b/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/DiTauAnalysisConfig.py index eb39e7fd5d2c59b210f14c5c306cdcf2cd8538f5..93a5b282ce59081e8fcfa80cf798166f775174b8 100644 --- a/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/DiTauAnalysisConfig.py +++ b/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/DiTauAnalysisConfig.py @@ -2,7 +2,6 @@ # AnaAlgorithm import(s): from AnalysisAlgorithmsConfig.ConfigBlock import ConfigBlock -from AnaAlgorithm.DualUseConfig import createAlgorithm, addPrivateTool class DiTauCalibrationConfig (ConfigBlock): @@ -14,9 +13,6 @@ class DiTauCalibrationConfig (ConfigBlock): self.postfix = postfix self.rerunTruthMatching = True - def collectReferences (self, config) : - self._tauRef1 = config.updateRef (self.containerName, "DiTauJets") - def makeAlgs (self, config) : @@ -25,23 +21,21 @@ class DiTauCalibrationConfig (ConfigBlock): postfix = '_' + postfix # Set up the tau 4-momentum smearing algorithm: - alg = createAlgorithm( 'CP::DiTauSmearingAlg', 'DiTauSmearingAlg' + postfix ) - addPrivateTool( alg, 'smearingTool', 'TauAnalysisTools::DiTauSmearingTool' ) - alg.taus = self._tauRef1.input() - alg.tausOut = self._tauRef1.output() + alg = config.createAlgorithm( 'CP::DiTauSmearingAlg', 'DiTauSmearingAlg' + postfix ) + config.addPrivateTool( 'smearingTool', 'TauAnalysisTools::DiTauSmearingTool' ) + alg.taus = config.readName (self.containerName, "DiTauJets") + alg.tausOut = config.copyName (self.containerName) alg.preselection = config.getSelection (self.containerName, '') - config.addAlg (alg) # Set up the tau truth matching algorithm: if self.rerunTruthMatching and config.dataType() != 'data': - alg = createAlgorithm( 'CP::DiTauTruthMatchingAlg', + alg = config.createAlgorithm( 'CP::DiTauTruthMatchingAlg', 'DiTauTruthMatchingAlg' + postfix ) - addPrivateTool( alg, 'matchingTool', + config.addPrivateTool( 'matchingTool', 'TauAnalysisTools::DiTauTruthMatchingTool' ) alg.matchingTool.WriteTruthTaus = 1 - alg.taus = self._tauRef1.input() + alg.taus = self.readName (self.containerName) alg.preselection = config.getSelection (self.containerName, '') - config.addAlg (alg) @@ -60,10 +54,6 @@ class DiTauWorkingPointConfig (ConfigBlock) : self.quality = quality self.legacyRecommendations = False - def collectReferences (self, config) : - if config.dataType() != 'data': - self._tauRef1 = config.readRef (self.containerName) - def makeAlgs (self, config) : @@ -87,17 +77,16 @@ class DiTauWorkingPointConfig (ConfigBlock) : # Set up the algorithm calculating the efficiency scale factors for the # taus: if config.dataType() != 'data': - alg = createAlgorithm( 'CP::DiTauEfficiencyCorrectionsAlg', + alg = config.createAlgorithm( 'CP::DiTauEfficiencyCorrectionsAlg', 'DiTauEfficiencyCorrectionsAlg' + postfix ) - addPrivateTool( alg, 'efficiencyCorrectionsTool', + config.addPrivateTool( 'efficiencyCorrectionsTool', 'TauAnalysisTools::DiTauEfficiencyCorrectionsTool' ) alg.efficiencyCorrectionsTool.IDLevel = IDLevel alg.scaleFactorDecoration = 'tau_effSF' + postfix # alg.outOfValidity = 2 #silent # alg.outOfValidityDeco = "bad_eff" - alg.taus = self._tauRef1.input() + alg.taus = config.readName (self.containerName) alg.preselection = config.getSelection (self.containerName, self.selectionName) - config.addAlg (alg) diff --git a/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/TauAnalysisConfig.py b/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/TauAnalysisConfig.py index 10425f6e04b212b7188a5bd9cfb5241a5090bbf1..00a515e601d925be00f52cf64dfbe5c496e2d80c 100644 --- a/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/TauAnalysisConfig.py +++ b/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/TauAnalysisConfig.py @@ -2,8 +2,6 @@ # AnaAlgorithm import(s): from AnalysisAlgorithmsConfig.ConfigBlock import ConfigBlock -from AnaAlgorithm.DualUseConfig import createAlgorithm, addPrivateTool, \ - createPublicTool class TauCalibrationConfig (ConfigBlock): @@ -15,9 +13,6 @@ class TauCalibrationConfig (ConfigBlock): self.postfix = postfix self.rerunTruthMatching = True - def collectReferences (self, config) : - self._tauRef1 = config.updateRef (self.containerName, "TauJets") - def makeAlgs (self, config) : @@ -27,22 +22,20 @@ class TauCalibrationConfig (ConfigBlock): # Set up the tau truth matching algorithm: if self.rerunTruthMatching and config.dataType() != 'data': - alg = createAlgorithm( 'CP::TauTruthMatchingAlg', - 'TauTruthMatchingAlg' + postfix ) - addPrivateTool( alg, 'matchingTool', - 'TauAnalysisTools::TauTruthMatchingTool' ) + alg = config.createAlgorithm( 'CP::TauTruthMatchingAlg', + 'TauTruthMatchingAlg' + postfix ) + config.addPrivateTool( 'matchingTool', + 'TauAnalysisTools::TauTruthMatchingTool' ) alg.matchingTool.WriteTruthTaus = 1 - alg.taus = self._tauRef1.input() + alg.taus = config.readName (self.containerName, 'TauJets') alg.preselection = config.getSelection (self.containerName, '') - config.addAlg (alg) # Set up the tau 4-momentum smearing algorithm: - alg = createAlgorithm( 'CP::TauSmearingAlg', 'TauSmearingAlg' + postfix ) - addPrivateTool( alg, 'smearingTool', 'TauAnalysisTools::TauSmearingTool' ) - alg.taus = self._tauRef1.input() - alg.tausOut = self._tauRef1.output() + alg = config.createAlgorithm( 'CP::TauSmearingAlg', 'TauSmearingAlg' + postfix ) + config.addPrivateTool( 'smearingTool', 'TauAnalysisTools::TauSmearingTool' ) + alg.taus = config.readName (self.containerName, 'TauJets') + alg.tausOut = config.copyName (self.containerName) alg.preselection = config.getSelection (self.containerName, '') - config.addAlg (alg) @@ -61,9 +54,6 @@ class TauWorkingPointConfig (ConfigBlock) : self.quality = quality self.legacyRecommendations = False - def collectReferences (self, config) : - self._tauRef1 = config.readRef (self.containerName) - def makeAlgs (self, config) : @@ -82,38 +72,35 @@ class TauWorkingPointConfig (ConfigBlock) : inputfile = nameFormat.format(self.quality.lower()) # Setup the tau selection tool - selectionTool = createPublicTool( 'TauAnalysisTools::TauSelectionTool', - 'TauSelectionTool' + postfix) + selectionTool = config.createPublicTool( 'TauAnalysisTools::TauSelectionTool', + 'TauSelectionTool' + postfix) selectionTool.ConfigPath = inputfile - config.addPublicTool( selectionTool ) # Set up the algorithm selecting taus: - alg = createAlgorithm( 'CP::AsgSelectionAlg', 'TauSelectionAlg' + postfix ) - addPrivateTool( alg, 'selectionTool', 'TauAnalysisTools::TauSelectionTool' ) + alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'TauSelectionAlg' + postfix ) + config.addPrivateTool( 'selectionTool', 'TauAnalysisTools::TauSelectionTool' ) alg.selectionTool.ConfigPath = inputfile alg.selectionDecoration = 'selected_tau' + postfix + ',as_bits' - alg.particles = self._tauRef1.input() + alg.particles = config.readName (self.containerName) alg.preselection = config.getSelection (self.containerName, self.selectionName) config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration, 6) config.addSelection (self.containerName, 'output', alg.selectionDecoration, 6) - config.addAlg (alg) # Set up the algorithm calculating the efficiency scale factors for the # taus: if config.dataType() != 'data': - alg = createAlgorithm( 'CP::TauEfficiencyCorrectionsAlg', + alg = config.createAlgorithm( 'CP::TauEfficiencyCorrectionsAlg', 'TauEfficiencyCorrectionsAlg' + postfix ) - addPrivateTool( alg, 'efficiencyCorrectionsTool', + config.addPrivateTool( 'efficiencyCorrectionsTool', 'TauAnalysisTools::TauEfficiencyCorrectionsTool' ) alg.efficiencyCorrectionsTool.TauSelectionTool = '%s/%s' % \ ( selectionTool.getType(), selectionTool.getName() ) alg.scaleFactorDecoration = 'tau_effSF' + postfix + '_%SYS%' alg.outOfValidity = 2 #silent alg.outOfValidityDeco = 'bad_eff' + postfix - alg.taus = self._tauRef1.input() + alg.taus = config.readName (self.containerName) alg.preselection = config.getSelection (self.containerName, self.selectionName) - config.addAlg (alg)