def addPhysValAODContent(algseq, doJets, doTopoCluster): ''' Schedule the addition of collections needed for validation of primary xAODs: AntiKt4TruthJets and LC/EMOriginTopoClusters ''' logger.info( '****************** Adding content for AOD PhysVal *****************') # Check some flags for steering from RecExConfig.AutoConfiguration import IsInInputFile requiresTruthJets = IsInInputFile( 'xAOD::TruthParticleContainer', 'TruthParticles') and not IsInInputFile('xAOD::JetContainer', 'AntiKt4TruthJets') requiresLCOriginTC = not IsInInputFile('xAOD::CaloClusterContainer', 'LCOriginTopoClusters') requiresEMOriginTC = not IsInInputFile('xAOD::CaloClusterContainer', 'EMOriginTopoClusters') jettools_PhysVal = [] # Truth jets if doJets and requiresTruthJets: jettools_PhysVal += addAntiKt4TruthJets(algseq) # Origin-corrected topoclusters if doTopoCluster and (requiresLCOriginTC or requiresEMOriginTC): jettools_PhysVal += addOriginCorrectedClusters(algseq, requiresLCOriginTC, requiresEMOriginTC) from AthenaCommon import CfgMgr # Only add the algorithm if there is a need for it if jettools_PhysVal: from JetRec.JetRecStandard import jtm jtm += CfgMgr.JetToolRunner( "jetrun_PhysVal", EventShapeTools=[], Tools=jettools_PhysVal, Timer=0 # No timing information ) from JetRec.JetRecConf import JetAlgorithm algseq += CfgMgr.JetAlgorithm("jetalgPhysVal", Tools=[jtm.jetrun_PhysVal]) logger.info( '****************** Done *****************')
def getCollectionNameIfInFile(coll_type, coll_name): from RecExConfig.AutoConfiguration import IsInInputFile if not IsInInputFile(coll_type, coll_name): printfunc('DEBUG getRecTrackParticleNameIfInFile set %s' % coll_name) return coll_name else: return ""
def getTrackDecorators(**kwargs): ''' Get track particle decorators needed for the InDetPhysValMonitoring tool If the collection name TrackParticleContainerName is specified and differs from the default, the name of the algorithms will be extended by the collection name. ''' # only valid kwarg : TrackParticleContainerName from RecExConfig.AutoConfiguration import IsInInputFile if not IsInInputFile('Trk::TrackCollection', 'CombinedInDetTracks'): return [getParameterErrDecoratorAlg(**kwargs)] else: return [ getInDetPhysHitDecoratorAlg(**kwargs), getParameterErrDecoratorAlg(**kwargs) ]
def addCHSPFlowObjects(): # Only act if the collection does not already exist from RecExConfig.AutoConfiguration import IsInInputFile if not IsInInputFile("xAOD::PFOContainer", "CHSParticleFlowObjects"): # Check that an alg doing this has not already been inserted from AthenaCommon.AlgSequence import AlgSequence job = AlgSequence() from JetRec.JetRecStandard import jtm if not hasattr(job, "jetalgCHSPFlow") and not hasattr( jtm, "jetconstitCHSPFlow"): from JetRec.JetRecConf import JetToolRunner jtm += JetToolRunner("jetconstitCHSPFlow", EventShapeTools=[], Tools=[jtm.JetConstitSeq_PFlowCHS]) # Add this tool runner to the JetAlgorithm instance "jetalg" # which runs all preparatory tools # This was added by JetCommon job.jetalg.Tools.append(jtm.jetconstitCHSPFlow) extjetlog.info("Added CHS PFlow sequence to \'jetalg\'") extjetlog.info(job.jetalg.Tools)
def __init__(self, **kwargs): super(InDetPhysValMonitoringTool.InDetPhysValMonitoringTool,self)\ .__init__(**_args( kwargs, name = self.__class__.__name__)) # special parameters of the default InDetPhysValMonitoringTool self.useTrackSelection = False self.EnableLumi = False # create the HistogramDefinitionSvc # at the moment there can only be one HistogramDefinitionSvc from InDetPhysValMonitoring.HistogramDefinitionSvc import HistogramDefinitionSvc #self.HistogramDefinitionSvc = serviceFactory(HistogramDefinitionSvc.HistogramDefinitionSvc) from InDetPhysValMonitoring.InDetPhysValJobProperties import isMC, InDetPhysValFlags if isMC(): self.TruthParticleContainerName = "TruthParticles" if InDetPhysValFlags.doValidateTracksInJets(): self.jetContainerName = 'AntiKt4TruthJets' self.FillTrackInJetPlots = True from InDetPhysValMonitoring.addTruthJets import addTruthJetsIfNotExising addTruthJetsIfNotExising(self.jetContainerName) else: self.jetContainerName = '' self.FillTrackInJetPlots = False else: # disable truth monitoring for data self.TruthParticleContainerName = '' # the jet container is actually meant to be a truth jet container self.jetContainerName = '' # hack to remove example phyval monitor from RecExConfig.AutoConfiguration import IsInInputFile if not IsInInputFile('xAOD::JetContainer', 'AntiKt4EMTopoJets'): from RecExConfig.RecFlags import rec rec.UserExecs += [ 'from InDetPhysValMonitoring.InDetPhysValMonitoringTool import removePhysValExample;removePhysValExample();' ]
def addJetRecoToAlgSequence(job=None, useTruth=None, eventShapeTools=None, separateJetAlgs=None, debug=None): myname = "JetAlgorithm: " # We need this to modify the global variable. global jetalg # Import message level flags. from GaudiKernel.Constants import DEBUG # Import the jet reconstruction control flags. from JetRec.JetRecFlags import jetFlags # Import the standard jet tool manager. from JetRec.JetRecStandardToolManager import jtm # Set sequence and flags as needed. if job == None: from AthenaCommon.AlgSequence import AlgSequence job = AlgSequence() if useTruth == None: useTruth = jetFlags.useTruth() if eventShapeTools == None: eventShapeTools = jetFlags.eventShapeTools() if eventShapeTools == None: eventShapeTools = [] if separateJetAlgs == None: separateJetAlgs = jetFlags.separateJetAlgs() # Event shape tools. evstools = [] evsDict = { "emtopo": ("EMTopoEventShape", jtm.emget), "lctopo": ("LCTopoEventShape", jtm.lcget), "empflow": ("EMPFlowEventShape", jtm.empflowget), "emcpflow": ("EMCPFlowEventShape", jtm.emcpflowget), "lcpflow": ("LCPFlowEventShape", jtm.lcpflowget), } if jetFlags.useTracks(): evsDict["emtopo"] = ("EMTopoOriginEventShape", jtm.emoriginget) evsDict["lctopo"] = ("LCTopoOriginEventShape", jtm.lcoriginget) jetlog.info(myname + "Event shape tools: " + str(eventShapeTools)) from RecExConfig.AutoConfiguration import IsInInputFile for evskey in eventShapeTools: from EventShapeTools.EventDensityConfig import configEventDensityTool if evskey in evsDict: (toolname, getter) = evsDict[evskey] if toolname in jtm.tools: jetlog.info(myname + "Skipping duplicate event shape: " + toolname) else: jetlog.info(myname + "Adding event shape " + evskey) if not IsInInputFile("xAOD::EventShape", "Kt4" + toolname): jtm += configEventDensityTool(toolname, getter, 0.4) evstools += [jtm.tools[toolname]] else: jetlog.info(myname + "Invalid event shape key: " + evskey) raise Exception # Add the tool runner. It runs the jetrec tools. rtools = [] # Add the truth tools. if useTruth: from JetRec.JetFlavorAlgs import scheduleCopyTruthParticles rtools += scheduleCopyTruthParticles() # build truth jet input : rtools += [jtm.truthpartcopy, jtm.truthpartcopywz] ## if jetFlags.useCells(): ## rtools += [jtm.missingcells] commented out : incompatible with trigger : ATR-9696 if jetFlags.useTracks: rtools += [ jtm.tracksel, jtm.tvassoc, jtm.trackselloose_trackjets, ] # Add the algorithm. It runs the jetrec tools. from JetRec.JetRecConf import JetAlgorithm ctools = [] if jetFlags.useTracks: if not IsInInputFile("xAOD::CaloClusterContainer", "LCOriginTopoClusters"): ctools += [jtm.JetConstitSeq_LCOrigin] if not IsInInputFile("xAOD::CaloClusterContainer", "EMOriginTopoClusters"): ctools += [jtm.JetConstitSeq_EMOrigin] from JetRec.JetRecConf import JetToolRunner runners = [] if len(ctools) > 0: jtm += JetToolRunner("jetconstit", EventShapeTools=[], Tools=ctools, Timer=jetFlags.timeJetToolRunner()) jtm.jetconstit runners = [jtm.jetconstit] if jetFlags.separateJetAlgs(): jtm += JetToolRunner("jetrun", EventShapeTools=evstools, Tools=rtools, Timer=jetFlags.timeJetToolRunner()) runners += [jetrun] job += JetAlgorithm("jetalg") jetalg = job.jetalg jetalg.Tools = runners for t in jtm.jetrecs: jalg = JetAlgorithm("jetalg" + t.name()) jalg.Tools = [t] job += jalg else: from JetRec.JetRecConf import JetToolRunner jtm += JetToolRunner("jetrun", EventShapeTools=evstools, Tools=rtools + jtm.jetrecs, Timer=jetFlags.timeJetToolRunner()) runners += [jtm.jetrun] job += JetAlgorithm("jetalg") jetalg = job.jetalg jetalg.Tools = runners if jetFlags.debug > 0: jtm.setOutputLevel(jtm.jetrun, DEBUG) jetalg.OutputLevel = DEBUG if jetFlags.debug > 1: for tool in jtm.jetrecs: jtm.setOutputLevel(tool, DEBUG) if jetFlags.debug > 2: for tool in jtm.finders: jtm.setOutputLevel(tool, DEBUG) if jetFlags.debug > 3: jtm.setOutputLevel(jtm.jetBuilderWithArea, DEBUG) jtm.setOutputLevel(jtm.jetBuilderWithoutArea, DEBUG)
except Exception: logRecExCommon_DetFlags.warning("could not set DetFlags.dcs") pass from RecExConfig.RecFlags import rec if not rec.readESD() and not rec.readAOD() and not rec.doWriteRDO(): DetFlags.makeRIO.all_setOn() else: DetFlags.makeRIO.all_setOff() #calo cells are there on ESD if rec.readESD(): DetFlags.readRIOPool.Calo_setOn() # savannah 73686 from RecExConfig.AutoConfiguration import IsInInputFile from InDetRecExample.InDetKeys import InDetKeys if IsInInputFile('InDet::PixelClusterContainer', InDetKeys.PixelClusters()): DetFlags.readRIOPool.pixel_setOn() if IsInInputFile('InDet::SCT_ClusterContainer', InDetKeys.SCT_Clusters()): DetFlags.readRIOPool.SCT_setOn() if IsInInputFile('InDet::TRT_DriftCircleContainer', InDetKeys.TRT_DriftCircles()): DetFlags.readRIOPool.TRT_setOn() if rec.doESD(): if IsInInputFile('PixelRDO_Container', InDetKeys.PixelRDOs()): DetFlags.makeRIO.pixel_setOn() if IsInInputFile('SCT_RDO_Container', InDetKeys.SCT_RDOs()): DetFlags.makeRIO.SCT_setOn() if IsInInputFile('TRT_RDO_Container', InDetKeys.TRT_RDOs()): DetFlags.makeRIO.TRT_setOn()
def addTruthJetsIfNotExising(truth_jets_name): ''' Add algorithm to create the truth jets collection unless the collection exists already, or a truth jet finder is already running ''' from RecExConfig.AutoConfiguration import IsInInputFile # the jet collection name does not exist in the input file # add a jet finder algorithm in front of the monitoring if the algorithm # does not yet exist. if not IsInInputFile('xAOD::JetContainer', truth_jets_name): try: from AthenaCommon.Logging import logging log = logging.getLogger('InDetPhysValMonitoring/addTruthJets.py') from PyUtils.MetaReaderPeeker import convert_itemList, metadata eventdata_itemsDic = convert_itemList(layout='dict') log.info( 'DEBUG addTruthJetsIfNotExising {} not in {} [file_type={}]'. format(truth_jets_name, eventdata_itemsDic, metadata['file_type'])) if truth_jets_name in eventdata_itemsDic: return except: pass # Access the algorithm sequence: from AthenaCommon.AlgSequence import AlgSequence, AthSequencer topSequence = AlgSequence() # extract the jet finder type and main parameter import re extract_alg = re.search('^([^0-9]+)([0-9]+)TruthJets', truth_jets_name) if extract_alg != None: alg_type = extract_alg.group(1) alg_param_str = extract_alg.group(2) else: alg_type = 'AntiKt' alg_param_str = 4 jet_finder_alg_name = "jetalg" + alg_type + alg_param_str + 'TruthJets' # add the jet finder unless it exists already in the alg sequence from InDetPhysValDecoration import findAlg, findMonMan alg_pos = findAlg([jet_finder_alg_name]) if alg_pos == None: from JetRec.JetRecStandard import jtm mon_man_index = findMonMan() # configure truth jet finding ? from JetRec.JetRecFlags import jetFlags jetFlags.useTruth = True jetFlags.useTracks = False jetFlags.truthFlavorTags = [ "BHadronsInitial", "BHadronsFinal", "BQuarksFinal", "CHadronsInitial", "CHadronsFinal", "CQuarksFinal", "TausFinal", "Partons", ] # tool to create truth jet finding inputs truth_part_copy_name = 'truthpartcopy' dir(jtm) create_truth_jet_input = None if not hasattr(jtm, truth_part_copy_name): from MCTruthClassifier.MCTruthClassifierConfig import firstSimCreatedBarcode from MCTruthClassifier.MCTruthClassifierConf import MCTruthClassifier truth_classifier_name = 'JetMCTruthClassifier' if not hasattr(jtm, truth_classifier_name): from AthenaCommon.AppMgr import ToolSvc if not hasattr(ToolSvc, truth_classifier_name): truthClassifier = MCTruthClassifier( name=truth_classifier_name, barcodeG4Shift=firstSimCreatedBarcode(), ParticleCaloExtensionTool="") else: truthClassifier = getattr(ToolSvc, truth_classifier_name) truthClassifier.barcodeG4Shift = firstSimCreatedBarcode( ) jtm += truthClassifier else: truthClassifier = getattr(jtm, truth_classifier_name) truthClassifier.barcodeG4Shift = firstSimCreatedBarcode() from ParticleJetTools.ParticleJetToolsConf import CopyTruthJetParticles create_truth_jet_input = CopyTruthJetParticles( truth_part_copy_name, OutputName="JetInputTruthParticles", MCTruthClassifier=truthClassifier) jtm += create_truth_jet_input else: create_truth_jet_input = getattr(jtm, truth_part_copy_name) jet_finder_tool = jtm.addJetFinder(truth_jets_name, alg_type, float(alg_param_str) / 10., "truth", ptmin=5000) jet_tools = [] from JetRec.JetFlavorAlgs import scheduleCopyTruthParticles jet_tools += scheduleCopyTruthParticles() jet_tools += [create_truth_jet_input] jet_tools += jtm.jetrecs # add the jet finder in front of the monitoring from JetRec.JetRecConf import JetAlgorithm from JetRec.JetRecConf import JetToolRunner jtm += JetToolRunner( "jetrun", Tools=jet_tools, EventShapeTools=[], # OutputLevel = 1, Timer=jetFlags.timeJetToolRunner()) # jet_finder_alg = JetAlgorithm(jet_finder_alg_name, jet_tools) jet_finder_alg = JetAlgorithm(jet_finder_alg_name) # jet_finder_alg.OutputLevel = 1 jet_finder_alg.Tools = [jtm.jetrun] if mon_man_index != None: topSequence.insert(mon_man_index, jet_finder_alg) else: topSequence += jet_finder_alg
topSequence) if doConversion: convertTrackParticles( getRecTrackParticleNameIfInFile(InDetKeys.TrackParticles()), InDetKeys.TrackParticlesTruth(), InDetKeys.xAODTrackParticleContainer(), topSequence) if (InDetFlags.doDBMstandalone() or InDetFlags.doDBM()) and doCreation: # or instead of InDetKeys.DBMTracksTruth() rather InDetKeys.DBMDetailedTracksTruth() ? createTrackParticles(InDetKeys.xAODDBMTrackParticleContainer(), InDetKeys.DBMTracksTruth(), InDetKeys.xAODDBMTrackParticleContainer(), topSequence) if not InDetFlags.doVertexFinding(): if (not InDetFlags.doDBMstandalone() and not IsInInputFile( 'xAOD::VertexContainer', InDetKeys.xAODVertexContainer()) and IsInInputFile('VxContainer', InDetKeys.PrimaryVertices())): if len(getRecVertexNameIfInFile(InDetKeys.PrimaryVertices())) > 0: from xAODTrackingCnv.xAODTrackingCnvConf import xAODMaker__VertexCnvAlg xAODVertexCnvAlg = xAODMaker__VertexCnvAlg("VertexCnvAlg") xAODVertexCnvAlg.xAODContainerName = InDetKeys.xAODVertexContainer( ) xAODVertexCnvAlg.AODContainerName = InDetKeys.PrimaryVertices() xAODVertexCnvAlg.TPContainerName = InDetKeys.xAODTrackParticleContainer( ) topSequence += xAODVertexCnvAlg if InDetFlags.doDBMstandalone() or InDetFlags.doDBM(): if (IsInInputFile('VxContainer', InDetKeys.PrimaryVertices())): from xAODTrackingCnv.xAODTrackingCnvConf import xAODMaker__VertexCnvAlg xAODVertexCnvAlgDBM = xAODMaker__VertexCnvAlg("VertexCnvAlgDBM")
def getInDetPhysValMonitoringTool(**kwargs): kwargs = setDefaults(kwargs, useTrackSelection=False, EnableLumi=False) # create the HistogramDefinitionSvc # at the moment there can only be one HistogramDefinitionSvc from InDetPhysValMonitoring.HistogramDefinitionSvc import getHistogramDefinitionSvc #self.HistogramDefinitionSvc = serviceFactory(getHistogramDefinitionSvc) from InDetPhysValMonitoring.InDetPhysValJobProperties import isMC, InDetPhysValFlags if isMC(): from InDetPhysValMonitoring.InDetPhysValDecoration import getInDetRttTruthSelectionTool kwargs = setDefaults(kwargs, TruthParticleContainerName="TruthParticles") if 'TruthSelectionTool' not in kwargs: kwargs = setDefaults( kwargs, TruthSelectionTool=getInDetRttTruthSelectionTool()) if InDetPhysValFlags.doValidateTracksInJets(): jets_name = 'AntiKt4LCTopoJets' kwargs = setDefaults(kwargs, JetContainerName=jets_name, FillTrackInJetPlots=True) from InDetPhysValMonitoring.addTruthJets import addTruthJetsIfNotExising addTruthJetsIfNotExising(jets_name) if InDetPhysValFlags.doValidateTracksInBJets(): kwargs = setDefaults(kwargs, FillTrackInBJetPlots=True) else: kwargs = setDefaults(kwargs, JetContainerName='', FillTrackInJetPlots=False) #adding the VeretxTruthMatchingTool from InDetTruthVertexValidation.InDetTruthVertexValidationConf import InDetVertexTruthMatchTool kwargs = setDefaults( kwargs, useVertexTruthMatchTool=True, VertexTruthMatchTool=toolFactory(InDetVertexTruthMatchTool)) #Options for Truth Strategy : Requires full pile-up truth containers for some if InDetPhysValFlags.setTruthStrategy( ) == 'All' or InDetPhysValFlags.setTruthStrategy() == 'PileUp': from RecExConfig.AutoConfiguration import IsInInputFile if IsInInputFile('xAOD::TruthPileupEventContainer', 'TruthPileupEvents'): kwargs = setDefaults( kwargs, PileupSwitch=InDetPhysValFlags.setTruthStrategy()) else: print( 'WARNING Truth Strategy for InDetPhysValMonitoring set to %s but TruthPileupEvents are missing in the input; resetting to HardScatter only' % (InDetPhysValFlags.setTruthStrategy())) elif InDetPhysValFlags.setTruthStrategy() != 'HardScatter': print( 'WARNING Truth Strategy for for InDetPhysValMonitoring set to invalid option %s; valid flags are ["HardScatter", "All", "PileUp"]' % (InDetPhysValFlags.setTruthStrategy())) else: # disable truth monitoring for data kwargs = setDefaults( kwargs, TruthParticleContainerName='', TruthVertexContainerName='', TruthEvents='', TruthPileupEvents='', TruthSelectionTool='', # the jet container is actually meant to be a truth jet container JetContainerName='', FillTrackInJetPlots=False, FillTrackInBJetPlots=False) # Control the number of output histograms if InDetPhysValFlags.doPhysValOutput(): kwargs = setDefaults(kwargs, SkillLevel=100) elif InDetPhysValFlags.doExpertOutput(): kwargs = setDefaults(kwargs, SkillLevel=200) # hack to remove example physval monitor from RecExConfig.AutoConfiguration import IsInInputFile if not IsInInputFile('xAOD::JetContainer', 'AntiKt4EMTopoJets'): add_remover = True from RecExConfig.RecFlags import rec try: for elm in rec.UserExecs: if elm.find('removePhysValExample') > 0: add_remover = False break except: pass if add_remover: rec.UserExecs += [ 'from InDetPhysValMonitoring.InDetPhysValMonitoringTool import removePhysValExample;removePhysValExample();' ] return InDetPhysValMonitoring.InDetPhysValMonitoringConf.InDetPhysValMonitoringTool( **kwargs)
def addStandardJets(jetalg, rsize, inputtype, ptmin=0., ptminFilter=0., mods="default", calibOpt="none", ghostArea=0.01, algseq=None, namesuffix="", outputGroup="CustomJets", customGetters=None, pretools=[], constmods=[], overwrite=False): jetnamebase = "{0}{1}{2}{3}".format(jetalg, int(rsize * 10), inputtype, namesuffix) jetname = jetnamebase + "Jets" algname = "jetalg" + jetnamebase OutputJets.setdefault(outputGroup, []).append(jetname) # return if the alg is already scheduled here : from RecExConfig.AutoConfiguration import IsInInputFile if algseq is None: dfjetlog.warning("No algsequence passed! Will not schedule " + algname) return elif IsInInputFile("xAOD::JetContainer", jetname) and not overwrite: dfjetlog.warning("Collection " + jetname + " is already in input AOD!") return elif algname in DFJetAlgs: if hasattr(algseq, algname): dfjetlog.warning("Algsequence " + algseq.name() + " already has an instance of " + algname) else: dfjetlog.info("Added " + algname + " to sequence " + algseq.name()) algseq += DFJetAlgs[algname] return DFJetAlgs[algname] from JetRec.JetRecStandard import jtm if not jetname in jtm.tools: # no container exist. simply build a new one. # Set default for the arguments to be passd to addJetFinder defaultmods = { "EMTopo": "emtopo_ungroomed", "LCTopo": "lctopo_ungroomed", "EMPFlow": "pflow_ungroomed", "EMCPFlow": "pflow_ungroomed", "Truth": "truth_ungroomed", "TruthWZ": "truth_ungroomed", "PV0Track": "track_ungroomed", } if mods == "default": mods = defaultmods[inputtype] if inputtype in defaultmods else [] finderArgs = dict(modifiersin=mods, consumers=[]) finderArgs['ptmin'] = ptmin finderArgs['ptminFilter'] = ptminFilter finderArgs['ghostArea'] = ghostArea finderArgs['modifiersin'] = mods finderArgs['calibOpt'] = calibOpt print("mods in:", finderArgs['modifiersin']) if overwrite: dfjetlog.info("Will overwrite AOD version of " + jetname) finderArgs['overwrite'] = True # map the input to the jtm code for PseudoJetGetter getterMap = dict(LCTopo='lctopo', EMTopo='emtopo', EMPFlow='empflow', EMCPFlow='emcpflow', Truth='truth', TruthWZ='truthwz', TruthDressedWZ='truthdressedwz', TruthCharged='truthcharged', PV0Track='pv0track') # create the finder for the temporary collection. if customGetters is None: inGetter = getterMap[inputtype] for getter in jtm.gettersMap[inGetter]: if not hasattr(algseq, getter.name()): algseq += getter else: inGetter = customGetters for getter in customGetters: if not hasattr(algseq, getter.name()): algseq += getter finderTool = jtm.addJetFinder( jetname, jetalg, rsize, inGetter, constmods=constmods, **finderArgs # pass the prepared arguments ) from JetRec.JetRecConf import JetAlgorithm alg = JetAlgorithm(algname, Tools=pretools + [finderTool]) dfjetlog.info("Added " + algname + " to sequence " + algseq.name()) algseq += alg DFJetAlgs[algname] = alg
def buildGenericGroomAlg(jetalg, rsize, inputtype, groomedName, jetToolBuilder, includePreTools=False, algseq=None, outputGroup="CustomJets", writeUngroomed=False, variableRMassScale=-1.0, variableRMinRadius=-1.0, constmods=[]): algname = "jetalg" + groomedName[:-4] from RecExConfig.AutoConfiguration import IsInInputFile if algseq is None: dfjetlog.info("No algsequence passed! Will not schedule " + algname) return elif IsInInputFile("xAOD::JetContainer", groomedName): dfjetlog.info("Collection " + groomedName + " is already in input AOD!") return from JetRec.JetRecUtils import buildJetContName constmodstr = "".join(constmods) inputname = inputtype + constmodstr label = inputtype + constmodstr ungroomedName = buildJetContName(jetalg, rsize, inputname, variableRMassScale, variableRMinRadius) ungroomedalgname = "jetalg" + ungroomedName[:-4] # Remove "Jets" from name # add these groomed jets to the output (use setdefault() to constuct the list if not existing yet) OutputJets.setdefault(outputGroup, []).append(groomedName) if writeUngroomed: OutputJets.setdefault(outputGroup, []).append(ungroomedName) dfjetlog.info("Write " + ungroomedName) from JetRec.JetRecConf import JetAlgorithm # return if the alg is already scheduled here : if hasattr(algseq, ungroomedalgname): finderalg = getattr(algseq, ungroomedalgname) dfjetlog.warning("Algsequence " + algseq.name() + " already has an instance of " + ungroomedalgname) elif ungroomedalgname in DFJetAlgs: dfjetlog.info("Added jet finder " + ungroomedalgname + " to sequence" + algseq.name()) finderalg = DFJetAlgs[ungroomedalgname] algseq += DFJetAlgs[ungroomedalgname] else: # 1. make sure we have pseudo-jet in our original container # this returns a list of the needed tools to do so. jetalgTools = reCreatePseudoJets(jetalg, rsize, inputtype, variableRMassScale, variableRMinRadius, algseq, constmods=constmods) if includePreTools and jetFlags.useTracks( ) and not "Truth" in inputtype: # enable track ghost association and JVF jetalgTools = [jtm.tracksel, jtm.tvassoc] + jetalgTools finderalg = JetAlgorithm(ungroomedalgname, Tools=jetalgTools) DFJetAlgs[ungroomedalgname] = finderalg dfjetlog.info("Added jet finder " + ungroomedalgname + " to sequence " + algseq.name()) algseq += finderalg # 2nd step run the trimming alg. We can re-use the original largeR jet since we reassociated the PseudoJet already. fatjet_groom = jetToolBuilder(groomedName, ungroomedName) print(finderalg.Tools) print(ungroomedName) fatjet_rectool = [ t for t in finderalg.Tools if t.name().endswith(ungroomedName) ][0] fatjet_groom.InputPseudoJets = fatjet_rectool.InputPseudoJets # recopy the InputPseudoJets so tools know how to map fastjet constituents with xAOD constituents dfjetlog.info("Added jet groomer " + algname + " to sequence " + algseq.name()) groomeralg = JetAlgorithm(algname, Tools=[fatjet_groom]) DFJetAlgs[algname] = groomeralg algseq += groomeralg return groomeralg
def reCreatePseudoJets(jetalg, rsize, inputtype, variableRMassScale=-1.0, variableRMinRadius=-1.0, algseq=None, constmods=[]): """Return a list of tools (possibly empty) to be run in a jetalg. These tools will make sure PseudoJets will be associated to the container specified by the input arguments. """ from JetRec.JetRecStandard import jtm from JetRec.JetRecUtils import buildJetContName constmodstr = "".join(constmods) inputname = inputtype + constmodstr label = inputtype + constmodstr jetContName = buildJetContName(jetalg, rsize, inputname, variableRMassScale, variableRMinRadius) # Set default for the arguments to be passd to addJetFinder finderArgs = dict( modifiersin=[], consumers=[], ghostArea=0.01, ptmin=40000, constmods=constmods, ) # We do things differently if the container already exists in the input from RecExConfig.AutoConfiguration import IsInInputFile if IsInInputFile("xAOD::JetContainer", jetContName): # yes ! # make sure we don't already have what we need tmpName = "tmp_" + jetContName if tmpName in jtm.tools: return [jtm.tools[tmpName]] # then we'll have to build a temporary container to re-create the pseudojet # and we recopy this pseudojets to the original collection. This done through # this tool : from JetRec.JetRecConf import JetPseudojetCopier jtm += JetPseudojetCopier("PJcopierTo" + jetContName, DestinationContainer=jetContName, JetPseudojetRetriever=jtm.jpjretriever) # prepare args for this case : finderArgs['consumers'] = [jtm.tools["PJcopierTo" + jetContName]] finderArgs['ptmin'] = 20000 else: # no preexisting container # make sure we don't already have what we need tmpName = jetContName if tmpName in jtm.tools: # return [] return [jtm.tools[tmpName]] # no container exist. simply build a new one. if inputtype == "LCTopo" or inputtype == "EMTopo" or inputtype == "EMPFlow" or inputtype == "EMCPFlow": defaultmods = { "EMTopo": "emtopo_ungroomed", "LCTopo": "lctopo_ungroomed", "EMPFlow": "pflow_ungroomed", "EMCPFlow": "pflow_ungroomed", "Truth": "truth_ungroomed", "TruthWZ": "truth_ungroomed", "PV0Track": "track_ungroomed" } finderArgs['modifiersin'] = defaultmods[inputtype] finderArgs['ptmin'] = 2000 finderArgs['ptminFilter'] = 50000 finderArgs['calibOpt'] = "none" elif inputtype == "PV0Track": finderArgs['modifiersin'] = None finderArgs['ptmin'] = 2000 finderArgs['ptminFilter'] = 40000 finderArgs['calibOpt'] = "none" #if not "PFlow" in inputtype: finderArgs.pop('modifiersin') # leave the default modifiers. if (variableRMassScale > 0): finderArgs['variableRMassScale'] = variableRMassScale finderArgs['variableRMinRadius'] = variableRMinRadius #finderArgs['ghostArea'] =0 ## Cannot afford ghost area calculation for variable-R jets (for now) # map the input to the jtm code for PseudoJetGetter getterMap = dict(LCTopo='lctopo', EMTopo='emtopo', EMPFlow='empflow', EMCPFlow='emcpflow', Truth='truth', TruthWZ='truthwz', TruthDressedWZ='truthdressedwz', TruthCharged='truthcharged', PV0Track='pv0track') # create the finder for the temporary collection. getters = getterMap[inputtype] for getter in jtm.gettersMap[getters]: if not hasattr(algseq, getter.name()): algseq += getter if len(constmods) > 0: finderArgs['modifiersin'] = [] from JetRecConfig import ConstModHelpers from JetRecConfig.JetDefinition import xAODType, JetConstit if inputtype == "EMTopo": constit = JetConstit(xAODType.CaloCluster, ["EM", "Origin"]) elif inputtype == "LCTopo": constit = JetConstit(xAODType.CaloCluster, ["LC", "Origin"]) elif inputtype == "EMPFlow": constit = JetConstit(xAODType.ParticleFlow) constit.modifiers += constmods constitalg = ConstModHelpers.getConstitModAlg(constit) if not hasattr(algseq, constitalg.name()): algseq += constitalg from JetRecConfig import JetRecConfig constitpjalg = JetRecConfig.getConstitPJGAlg(constit) if not hasattr(algseq, constitpjalg.name()): algseq += constitpjalg getterbase = inputtype.lower() getters = [constitpjalg] + list(jtm.gettersMap[getterbase])[1:] tmpFinderTool = jtm.addJetFinder( tmpName, jetalg, rsize, getters, **finderArgs # pass the prepared arguments ) return [tmpFinderTool]
def addJetRecoToAlgSequence(job=None, useTruth=None, eventShapeTools=None, separateJetAlgs=None, debug=None): myname = "JetAlgorithm: " # We need this to modify the global variable. global jetalg # Import message level flags. from GaudiKernel.Constants import DEBUG # Import the jet reconstruction control flags. from JetRec.JetRecFlags import jetFlags # Import the standard jet tool manager. from JetRec.JetRecStandard import jtm # Set sequence and flags as needed. if job == None: from AthenaCommon.AlgSequence import AlgSequence job = AlgSequence() if useTruth == None: useTruth = jetFlags.useTruth() if eventShapeTools == None: eventShapeTools = jetFlags.eventShapeTools() if eventShapeTools == None: eventShapeTools = [] if separateJetAlgs == None: separateJetAlgs = jetFlags.separateJetAlgs() # Event shape tools. evsDict = { "emtopo": ("EMTopoEventShape", jtm.emget), "lctopo": ("LCTopoEventShape", jtm.lcget), "empflow": ("EMPFlowEventShape", jtm.empflowget), } if jetFlags.useTracks(): if jetFlags.useVertices(): evsDict["emtopo"] = ("EMTopoOriginEventShape", jtm.emoriginget) evsDict["lctopo"] = ("LCTopoOriginEventShape", jtm.lcoriginget) else: evsDict["emtopo"] = ("EMTopoOriginEventShape", jtm.emget) evsDict["lctopo"] = ("LCTopoOriginEventShape", jtm.lcget) jetlog.info(myname + "Event shape tools: " + str(eventShapeTools)) from RecExConfig.AutoConfiguration import IsInInputFile for evskey in eventShapeTools: from EventShapeTools.EventDensityConfig import configEventDensityTool if evskey in evsDict: (toolname, getter) = evsDict[evskey] if toolname in jtm.tools: jetlog.info(myname + "Skipping duplicate event shape: " + toolname) else: jetlog.info(myname + "Adding event shape " + evskey) if not IsInInputFile("xAOD::EventShape", toolname): jtm += configEventDensityTool(toolname, getter.Label, 0.4) jtm.allEDTools += [jtm.tools[toolname]] else: jetlog.info(myname + "Invalid event shape key: " + evskey) raise Exception # Add the tool runner. It runs the jetrec tools. ctools = [] # Add the truth tools. if useTruth: from JetRec.JetFlavorAlgs import scheduleCopyTruthParticles ctools += scheduleCopyTruthParticles() # build truth jet input : ctools += [jtm.truthpartcopy, jtm.truthpartcopywz] ## if jetFlags.useCells(): ## ctools += [jtm.missingcells] commented out : incompatible with trigger : ATR-9696 if jetFlags.useTracks: ctools += [jtm.tracksel, jtm.trackselloose_trackjets] if jetFlags.useVertices: ctools += [jtm.tvassoc] # LCOriginTopoClusters and EMOriginTopoClusters are shallow copies # of CaloCalTopoClusters. This means that if CaloCalTopoClusters gets # thinned on output, the the two derived containers need to be thinned # in the same way, else they'll be corrupted in the output. # FIXME: this should be automatic somehow. postalgs = [] thinneg = False from RecExConfig.RecFlags import rec if rec.doWriteAOD() and not rec.readAOD(): from ParticleBuilderOptions.AODFlags import AODFlags if AODFlags.ThinNegativeEnergyCaloClusters: thinneg = True if jetFlags.useTracks and jetFlags.useVertices: if not IsInInputFile("xAOD::CaloClusterContainer", "LCOriginTopoClusters"): ctools += [jtm.JetConstitSeq_LCOrigin] if thinneg: from ThinningUtils.ThinningUtilsConf import ThinNegativeEnergyCaloClustersAlg postalgs.append( ThinNegativeEnergyCaloClustersAlg( 'ThinNegLCOriginTopoClusters', ThinNegativeEnergyCaloClusters=True, CaloClustersKey='LCOriginTopoClusters', StreamName='StreamAOD')) if not IsInInputFile("xAOD::CaloClusterContainer", "EMOriginTopoClusters"): ctools += [jtm.JetConstitSeq_EMOrigin] if thinneg: from ThinningUtils.ThinningUtilsConf import ThinNegativeEnergyCaloClustersAlg postalgs.append( ThinNegativeEnergyCaloClustersAlg( 'ThinNegEMOriginTopoClusters', ThinNegativeEnergyCaloClusters=True, CaloClustersKey='EMOriginTopoClusters', StreamName='StreamAOD')) if not IsInInputFile("xAOD::PFOContainer", "CHSParticleFlowObjects"): if not hasattr(job, "jetalgCHSPFlow"): ctools += [jtm.JetConstitSeq_PFlowCHS] if thinneg: from ThinningUtils.ThinningUtilsConf import ThinNegativeEnergyNeutralPFOsAlg CHSnPFOsThinAlg = ThinNegativeEnergyNeutralPFOsAlg( "ThinNegativeEnergyCHSNeutralPFOsAlg", NeutralPFOsKey="CHSNeutralParticleFlowObjects", ThinNegativeEnergyNeutralPFOs=True, StreamName='StreamAOD') postalgs.append(CHSnPFOsThinAlg) from JetRec.JetRecConf import JetToolRunner from JetRec.JetRecConf import JetAlgorithm runners = [] if len(ctools) > 0: jtm += JetToolRunner("jetconstit", EventShapeTools=[], Tools=ctools, Timer=jetFlags.timeJetToolRunner()) job += JetAlgorithm("jetalgConstituents", Tools=[jtm.jetconstit]) # Add all the PseudoJetAlgorithms now # To avoid massive refactoring and to preserve familiarity, # kept calling things "getters", but these are already # PseudoJetAlgorithms as we eliminated the wrappers for getter in jtm.allGetters: job += getter # Then, add all event shape tools in separate algs for evstool in jtm.allEDTools: from EventShapeTools.EventShapeToolsConf import EventDensityAthAlg job += EventDensityAthAlg("edalg_" + evstool.OutputContainer, EventDensityTool=evstool) if separateJetAlgs: for t in jtm.jetrecs: jalg = JetAlgorithm("jetalg" + t.name(), Tools=[t]) job += jalg else: from JetRec.JetRecConf import JetToolRunner jtm += JetToolRunner("jetrun", EventShapeTools=[], Tools=rtools + jtm.jetrecs, Timer=jetFlags.timeJetToolRunner()) runners += [jtm.jetrun] job += JetAlgorithm("jetalg") jetalg = job.jetalg jetalg.Tools = runners if jetFlags.debug > 0: # jtm.setOutputLevel(jtm.jetrun, DEBUG) jetalg.OutputLevel = DEBUG if jetFlags.debug > 1: for tool in jtm.jetrecs: jtm.setOutputLevel(tool, DEBUG) if jetFlags.debug > 2: for tool in jtm.finders: jtm.setOutputLevel(tool, DEBUG) if jetFlags.debug > 3: jtm.setOutputLevel(jtm.jetBuilderWithArea, DEBUG) jtm.setOutputLevel(jtm.jetBuilderWithoutArea, DEBUG) for postalg in postalgs: job += postalg