def _dvDownstreamReco(self, name): from Configurables import PatPV3D, PVOfflineTool, PVSeed3DTool, LSAdaptPVFitter _downVertices = PatPV3D(name + 'DownDV3DAlg') _downVertices.OutputVerticesName = 'Rec/' + name + 'DownDV3D/RecVertices' _downVertices.addTool(PVOfflineTool) _downVertices.PVOfflineTool.addTool(LSAdaptPVFitter()) _downVertices.PVOfflineTool.InputTracks = [ 'Rec/' + name + 'DownstreamTr/Tracks' ] _downVertices.PVOfflineTool.RequireVelo = False _downVertices.PVOfflineTool.PVsChi2Separation = 0 _downVertices.PVOfflineTool.PVsChi2SeparationLowMult = 0 _downVertices.PVOfflineTool.addTool(PVSeed3DTool()) _downVertices.PVOfflineTool.PVSeedingName = "PVSeed3DTool" _downVertices.PVOfflineTool.PVSeed3DTool.MinCloseTracks = 4 _downVertices.PVOfflineTool.PVSeed3DTool.TrackPairMaxDistance = 2 * mm _downVertices.PVOfflineTool.PVSeed3DTool.zMaxSpread = 20 * mm _downVertices.PVOfflineTool.addTool(LSAdaptPVFitter()) _downVertices.PVOfflineTool.PVFitterName = "LSAdaptPVFitter" _downVertices.PVOfflineTool.LSAdaptPVFitter.MinTracks = 4 _downVertices.PVOfflineTool.LSAdaptPVFitter.maxChi2 = 400.0 _downVertices.PVOfflineTool.LSAdaptPVFitter.maxDeltaZ = 0.0005 * mm _downVertices.PVOfflineTool.LSAdaptPVFitter.maxDeltaChi2NDoF = 0.002 _downVertices.PVOfflineTool.LSAdaptPVFitter.acceptTrack = 0.000000001 _downVertices.PVOfflineTool.LSAdaptPVFitter.trackMaxChi2 = 9 _downVertices.PVOfflineTool.LSAdaptPVFitter.trackMaxChi2Remove = 64 return PatPV3DWrapper(name + 'DownDV3D', _downVertices, 'Rec/' + name + 'DownDV3D/RecVertices', [self.DownstreamTracks])
def _create_pvalg(self): from Configurables import PatPV3D pvalg = PatPV3D('PatPV3DHltBeamGas') pvalg.OutputVerticesName = self.getProp("VertexContName") pvOfflineTool = self._configure_pvtool(pvalg) if self.getProp("FitTracks"): pvOfflineTool.InputTracks = [self.getProp("FittedTrackContName")] else: pvOfflineTool.InputTracks = [self.getProp("TrackContName")] return pvalg
def stage(self, stages, cuts): algs = [] from HltTracking.HltTrackNames import HltSharedTrackLoc tracksForVertexing = HltSharedTrackLoc["Velo"] ## Step 1 : apply Velo track selection (if required) filterCuts = cuts.get("FilterVelo") if filterCuts["Apply"]: from Configurables import SelectVeloTracksNotFromPV vWithIP = SelectVeloTracksNotFromPV( "Hlt2" + self.__prefix + self._name() + "NonPromptVelo", PVLocation=PV3D("Hlt2").output, MinIP=filterCuts["MinIP"], MinIPChi2=filterCuts["MinIPChi2"], RejectSplashEvents=filterCuts["RejectSplash"], RemoveBackwardTracks=filterCuts["RejectBackward"], MinNumTracks=filterCuts["MinNumTracks"], MaxNumInputTracks=filterCuts["MaxNumInput"], MaxNumOutputTracks=filterCuts["MaxNumOutput"]) vWithIP.Inputs = [tracksForVertexing] tracksForVertexing = "Hlt/Track/{0}{1}".format( self.__prefix, self._name()) vWithIP.Output = tracksForVertexing algs.append(vWithIP) ## Step 2 : run the vertex finding from Configurables import PVOfflineTool, PatPV3D, PVSeed3DTool, LSAdaptPV3DFitter vf = PVOfflineTool("Hlt2" + self.__prefix + self._name() + "VeloOfflineTool", InputTracks=[tracksForVertexing], PVSeedingName="PVSeed3DTool", PVFitterName="LSAdaptPV3DFitter", UseBeamSpotRCut=False) vf.addTool(PVSeed3DTool) vf.PVSeed3DTool.TrackPairMaxDistance = 0.2 * units.mm vf.PVSeed3DTool.zMaxSpread = 1.0 * units.mm vf.PVSeed3DTool.MinCloseTracks = 3 vf.addTool(LSAdaptPV3DFitter) vf.LSAdaptPV3DFitter.maxChi2 = 400. ## default value, to be tuned vf.LSAdaptPV3DFitter.MinTracks = 4 vx = PatPV3D("Hlt2" + self.__prefix + self._name() + "3DVelo", OutputVerticesName=self.outrv) vx.addTool(vf, name="PVOfflineTool") algs.append(vx) stages += self.dependencies(cuts) return algs
def _dvVeloReco(self, name): from Configurables import PatPV3D, PVOfflineTool, PVSeed3DTool, LSAdaptPV3DFitter _veloVertices = PatPV3D(name + 'DV3DAlg') _veloVertices.OutputVerticesName = 'Rec/' + name + 'DV3D/RecVertices' _veloVertices.addTool(PVOfflineTool) _veloVertices.PVOfflineTool.InputTracks = ["Rec/Track/Best"] _veloVertices.PVOfflineTool.PVsChi2Separation = 0 _veloVertices.PVOfflineTool.PVsChi2SeparationLowMult = 0 _veloVertices.PVOfflineTool.PVSeedingName = "PVSeed3DTool" _veloVertices.PVOfflineTool.addTool(PVSeed3DTool()) _veloVertices.PVOfflineTool.PVSeed3DTool.MinCloseTracks = 3 _veloVertices.PVOfflineTool.addTool(LSAdaptPV3DFitter()) _veloVertices.PVOfflineTool.PVFitterName = "LSAdaptPV3DFitter" _veloVertices.PVOfflineTool.LSAdaptPV3DFitter.maxIP2PV = 2 * mm _veloVertices.PVOfflineTool.LSAdaptPV3DFitter.MinTracks = 4 return PatPV3DWrapper(name + 'DV3D', _veloVertices, 'Rec/' + name + 'DV3D/RecVertices')
def __lumi_track_and_vertex_seq__(self): ''' returns a list of private lumi Velo tracking and vertexing algorithms ''' ### create the tracking alg from HltLine.HltDecodeRaw import DecodeVELO algsDecodeVelo = [i for i in DecodeVELO.members()] from Configurables import FastVeloTracking algTr = FastVeloTracking('FastVeloLumiHlt', OutputTracksName=self.containerNameLumiTracks, HitManagerName='FastVeloLumiHltHitManager') ### create the vertexing alg from Configurables import PatPV3D, PVOfflineTool, LSAdaptPV3DFitter algPV = PatPV3D('PV3DLumiHlt') algPV.addTool(PVOfflineTool, "PVOfflineTool") algPV.PVOfflineTool.addTool(LSAdaptPV3DFitter, "LSAdaptPV3DFitter") algPV.PVOfflineTool.PVFitterName = "LSAdaptPV3DFitter" algPV.PVOfflineTool.LSAdaptPV3DFitter.TrackErrorScaleFactor = 2. algPV.PVOfflineTool.InputTracks = [algTr.OutputTracksName] algPV.OutputVerticesName = self.containerNameLumiVertex #return a list with the 2 algorithms return algsDecodeVelo + [algTr, algPV]
def __init__(self, name, config): LineBuilder.__init__(self, name, config) ####################################################################### ### ### ### VELO BASED VERTEXING SEQUENCE ### ### ### ####################################################################### bestTracks = AutomaticData("Rec/Track/Best") withVeloTracksForVertexing = bestTracks if self.configurationParameter("FilterVelo")["Apply"]: from GaudiConfUtils.ConfigurableGenerators import SelectVeloTracksNotFromPV veloWithIP = SelectVeloTracksNotFromPV() self.validatedSetProps("FilterVelo", DisplVerticesLinesConf.veloWithIPCuts, veloWithIP) withVeloTracksForVertexing = Selection( "%sVeloFilteredTracks" % self.name(), RequiredSelections=[bestTracks], Algorithm=veloWithIP) # Displaced Vertex reconstruction with best tracks (dominated by those with a Velo segment) from Configurables import PatPV3D, PVOfflineTool, PVSeed3DTool, LSAdaptPV3DFitter, LSAdaptPVFitter withVeloVertexFinder = PVOfflineTool("%sWithVeloVertexFinder" % self.name(), PVsChi2Separation=0, PVsChi2SeparationLowMult=0, PVSeedingName="PVSeed3DTool", PVFitterName="LSAdaptPV3DFitter") withVeloVertexFinder.addTool(PVSeed3DTool) withVeloVertexFinder.PVSeed3DTool.MinCloseTracks = 3 withVeloVertexFinder.addTool(LSAdaptPV3DFitter) withVeloVertexFinder.LSAdaptPV3DFitter.maxIP2PV = 2.0 * units.mm withVeloVertexFinder.LSAdaptPV3DFitter.MinTracks = 4 withVeloVertexAlg = PatPV3D("%sWithVeloVertexAlg") withVeloVertexAlg.addTool(withVeloVertexFinder, name="PVOfflineTool") withVeloVertexing = SelectionPatPV3DWrapper( "%sWithVeloVertexing" % self.name(), withVeloVertexAlg, RequiredSelections=[withVeloTracksForVertexing]) # Make Particles out of the RecVertices from GaudiConfUtils.ConfigurableGenerators import LLParticlesFromRecVertices rv2pWithVelo = LLParticlesFromRecVertices(VerticesFromVeloOnly=False, WriteP2PVRelations=False, ForceP2PVBuild=False) self.validatedSetProps( "RV2PWithVelo", DisplVerticesLinesConf.recoCuts + DisplVerticesLinesConf.singleCuts, rv2pWithVelo) withVeloCandidates = Selection("%sWithVeloCandidates" % self.name(), RequiredSelections=[withVeloVertexing], Algorithm=rv2pWithVelo, InputDataSetter="RecVertexLocations") ####################################################################### ### ### ### DOWNSTREAM VERTEXING SEQUENCE ### ### ### ####################################################################### from GaudiConfUtils.ConfigurableGenerators import CopyDownstreamTracks downTracks = Selection("%sDownstreamTracks" % self.name(), RequiredSelections=[bestTracks], Algorithm=CopyDownstreamTracks()) # Displaced Vertex reconstruction from downstream tracks downVertexFinder = PVOfflineTool("%sDownVertexFinder" % self.name(), RequireVelo=False, PVsChi2Separation=0, PVsChi2SeparationLowMult=0, PVSeedingName="PVSeed3DTool", PVFitterName="LSAdaptPVFitter") downVertexFinder.addTool(PVSeed3DTool) downVertexFinder.PVSeed3DTool.TrackPairMaxDistance = 2.0 * units.mm downVertexFinder.PVSeed3DTool.zMaxSpread = 20.0 * units.mm downVertexFinder.PVSeed3DTool.MinCloseTracks = 4 downVertexFinder.addTool(LSAdaptPVFitter) downVertexFinder.LSAdaptPVFitter.MinTracks = 4 downVertexFinder.LSAdaptPVFitter.maxChi2 = 400.0 downVertexFinder.LSAdaptPVFitter.maxDeltaZ = 0.0005 * units.mm downVertexFinder.LSAdaptPVFitter.maxDeltaChi2NDoF = 0.002 downVertexFinder.LSAdaptPVFitter.acceptTrack = 0.000000001 downVertexFinder.LSAdaptPVFitter.trackMaxChi2 = 9 downVertexFinder.LSAdaptPVFitter.trackMaxChi2Remove = 64 downVertexAlg = PatPV3D("%sDownVertexAlg" % self.name()) downVertexAlg.addTool(downVertexFinder, name="PVOfflineTool") downVertexing = SelectionPatPV3DWrapper( "%sDownVertexing" % self.name(), downVertexAlg, RequiredSelections=[downTracks]) # Make Particles out of the RecVertices rv2pDown = LLParticlesFromRecVertices(VerticesFromVeloOnly=False, WriteP2PVRelations=False, ForceP2PVBuild=False #, OutputLevel = VERBOSE ) self.validatedSetProps( "RV2PDown", DisplVerticesLinesConf.recoCuts + DisplVerticesLinesConf.singleCuts, rv2pDown) downCandidates = Selection("%sDownCandidates" % self.name(), RequiredSelections=[downVertexing], Algorithm=rv2pDown, InputDataSetter="RecVertexLocations") ####################################################################### ### ### ### LINE DEFINITIONS ### ### ### ####################################################################### ##============================== Single ===================================## singleLineNames = [ p.split("Single")[1].split("Selection")[0] for p in self.configKeys() if p.startswith("Single") and p.endswith("Selection") ] for lAcroName in singleLineNames: lShortName = "Single%s" % lAcroName # SingleMedium lSelName = "%sSelection" % lShortName # SingleMediumSelection lLineName = "%s%s" % (self.name(), lShortName ) # DisplVerticesSingleMedium # Choose between Velo-based and downstream vertexing input candidates = withVeloCandidates code = None if "Down" in lAcroName: candidates = downCandidates code = self.getLLPSelection( self.validatedGetProps( lSelName, DisplVerticesLinesConf.singleCuts + DisplVerticesLinesConf.downCuts)) else: code = self.getLLPSelection( self.validatedGetProps(lSelName, DisplVerticesLinesConf.singleCuts)) lineFilter = FilterDesktop( DecayDescriptor=LLPLHCbName, Preambulo=DisplVerticesLinesConf.llpSelectionPreambulo, Code=code, WriteP2PVRelations=False, ForceP2PVBuild=False #, OutputLevel = VERBOSE ) lineSel = Selection("".join((self.name(), lSelName)), RequiredSelections=[candidates], Algorithm=lineFilter) line = StrippingLine( lLineName, prescale=self.validatedGetProps(lSelName, ["PreScale"])["PreScale"], selection=lineSel ## , FILTER = { "Preambulo" : [ "nVeloTracks = RECSUMMARY(13, 0)" ## , "nVeloClusters = RECSUMMARY(30, -1)" ## , "from LoKiCore.functions import *" ] ## , "Code" : "monitor( 1.*nVeloTracks/nVeloClusters , Gaudi.Histo1DDef('Number of Velo Tracks / Clusters', 0., 1., 100) , 'NumVeloTracksPerCluster' ) < 0.2" } ) if lShortName in self.configurationParameter("HLT"): line.HLT = self.configurationParameter("HLT")[lShortName] self.registerLine(line) ##============================== Double ===================================## doubleLineNames = [ p.split("Double")[1].split("Selection")[0] for p in self.configKeys() if p.startswith("Double") and p.endswith("Selection") ] for lAcroName in doubleLineNames: lShortName = "Double%s" % lAcroName lSelName = "%sSelection" % lShortName lLineName = "%s%s" % (self.name(), lShortName) combinationCut, motherCut = self.getResonanceSelection( self.validatedGetProps( lSelName, DisplVerticesLinesConf.doubleResonanceCuts)) lineFilter = CombineParticles( DecayDescriptor="H_10 -> %s %s" % (LLPLHCbName, LLPLHCbName), Preambulo=DisplVerticesLinesConf.llpSelectionPreambulo, DaughtersCuts={ LLPLHCbName: self.getLLPSelection( self.validatedGetProps( lSelName, DisplVerticesLinesConf.singleCuts)) }, CombinationCut=combinationCut, MotherCut=motherCut, WriteP2PVRelations=False, ForceP2PVBuild=False #, OutputLevel = VERBOSE ) lineSel = Selection("".join((self.name(), lSelName)), RequiredSelections=[withVeloCandidates], Algorithm=lineFilter) line = StrippingLine(lLineName, prescale=self.validatedGetProps( lSelName, ["PreScale"])["PreScale"], selection=lineSel) if lShortName in self.configurationParameter("HLT"): line.HLT = self.configurationParameter("HLT")[lShortName] self.registerLine(line) ##============================== HLT PS ===================================## hltPSLineNames = [ p.split("HLTPS")[0] for p in self.configKeys() if p.endswith("HLTPS") ] for lAcroName in hltPSLineNames: lShortName = "%sHLTPS" % lAcroName lLineName = "%s%s" % (self.name(), lShortName ) # DisplVerticesSingleMedium line = StrippingLine( lLineName, prescale=self.validatedGetProps(lShortName, ["PreScale"])["PreScale"] # these lines MUST have an HLT filter , HLT=self.validatedGetProps("HLT", [lShortName])[lShortName], selection=withVeloCandidates) self.registerLine(line) ##============================== OTHER ===================================## hltEffLineNames = [ p.split("HltEff")[1].split("Selection")[0] for p in self.configKeys() if p.startswith("HltEff") and p.endswith("Selection") ] for lShortName in hltEffLineNames: lSelName = "HltEff%sSelection" % lShortName lLineName = "%s%s" % (self.name(), lShortName) # HltEff lines are single, Velo-vertexing based lines lineFilter = FilterDesktop( DecayDescriptor=LLPLHCbName, Preambulo=DisplVerticesLinesConf.llpSelectionPreambulo, Code=self.getLLPSelection( self.validatedGetProps(lSelName, DisplVerticesLinesConf.singleCuts)), WriteP2PVRelations=False, ForceP2PVBuild=False #, OutputLevel = VERBOSE ) lineSel = Selection("".join((self.name(), lSelName)), RequiredSelections=[withVeloCandidates], Algorithm=lineFilter) line = StrippingLine( lLineName, prescale=self.validatedGetProps(lSelName, ["PreScale"])["PreScale"] # these lines MUST have an HLT filter , HLT=self.configurationParameter("HLT")[lShortName], selection=lineSel) self.registerLine(line)
def PV3D(where): """ PV3D(where) -- where must either by Hlt1 or Hlt2 """ #from HltTrackNames import HltSharedRZVeloTracksName, HltSharedTracksPrefix, _baseTrackLocation from HltVertexNames import HltSharedVerticesPrefix from HltVertexNames import HltGlobalVertexLocation from Configurables import PatPV3D from Configurables import PVOfflineTool, LSAdaptPV3DFitter from Configurables import SimplifiedMaterialLocator, TrackMasterExtrapolator if where.upper() not in ['HLT1', 'HLT2']: raise KeyError('PV3D: where must be either HLT1 or HLT2') #TODO: Move these options to HltRecoConf output3DVertices = _vertexLocation(HltSharedVerticesPrefix, HltGlobalVertexLocation, PV3DSelection) recoPV3D = PatPV3D('HltPVsPV3D') recoPV3D.addTool(PVOfflineTool, "PVOfflineTool") recoPV3D.PVOfflineTool.PVSeedingName = "PVSeed3DTool" recoPV3D.PVOfflineTool.PVFitterName = "LSAdaptPV3DFitter" recoPV3D.PVOfflineTool.addTool(LSAdaptPV3DFitter, "LSAdaptPV3DFitter") offlineTool = recoPV3D.PVOfflineTool fitter = recoPV3D.PVOfflineTool.LSAdaptPV3DFitter # Set options from HltRecoConf from Configurables import HltRecoConf for opt, value in HltRecoConf().getProp("PVOptions").iteritems(): found = False for tool in (fitter, offlineTool): if opt in tool.getProperties(): tool.setProp(opt, value) found = True if not found: raise AttributeError("HltPVs.py: no tool has property %s" % opt) ## Simplified Material for TrackMasterExtrapolator recoPV3D.PVOfflineTool.LSAdaptPV3DFitter.addTool( TrackMasterExtrapolator, "TrackMasterExtrapolator") recoPV3D.PVOfflineTool.LSAdaptPV3DFitter.TrackMasterExtrapolator.addTool( SimplifiedMaterialLocator, name="MaterialLocator") ## Simplified Material for Recalculate. Not used, but let's not load from Configurables import PVOfflineRecalculate recoPV3D.PVOfflineTool.addTool(PVOfflineRecalculate, "PVOfflineRecalculate") recoPV3D.PVOfflineTool.PVOfflineRecalculate.addTool( TrackMasterExtrapolator, "TrackMasterExtrapolator") recoPV3D.PVOfflineTool.PVOfflineRecalculate.TrackMasterExtrapolator.addTool( SimplifiedMaterialLocator, name="MaterialLocator") if HltRecoConf().getProp("FitVelo"): recoPV3D.PVOfflineTool.LSAdaptPV3DFitter.UseFittedTracks = True #recoPV3D.PVOfflineTool.LSAdaptPV3DFitter.zVtxShift = 0.0 recoPV3D.OutputVerticesName = output3DVertices from HltSharedTracking import FittedVelo, RevivedVelo velo = FittedVelo if HltRecoConf().getProp("FitVelo") else RevivedVelo pv3dAlgos = ','.join( ["'%s'" % m.getFullName() for m in velo.members() + [recoPV3D]]) recoPV3D.PVOfflineTool.InputTracks = [velo.outputSelection()] from Configurables import LoKi__HltUnit as HltUnit ## Hlt vertex beamspot filter ##-- todo: can we integrate this in the main streamers directly, using 'tee' ? ## TODO: Make this a configurable. name = "HltPV3D" makePV3DSel = HltUnit(name, Preambulo=[ 'from LoKiPhys.decorators import *', 'from LoKiTrigger.decorators import *', 'from LoKiHlt.algorithms import *' ], Code=""" execute( %(algo)s ) * VSOURCE( '%(tesInput)s' ) >> VX_SINK( '%(hltFinal)s' ) >> ~VEMPTY """ % { 'algo': pv3dAlgos, 'tesInput': recoPV3D.OutputVerticesName, 'hltFinal': PV3DSelection }) pv3d = bindMembers(name + 'Sequence', [makePV3DSel]).setOutputSelection(PV3DSelection) pv3d.output = output3DVertices return pv3d
def __init__(self, name, config): LineBuilder.__init__(self, name, config) ####################################################################### ### ### ### VELO BASED VERTEXING SEQUENCE ### ### ### ####################################################################### bestTracks = AutomaticData("Rec/Track/Best") withVeloTracksForVertexing = bestTracks if self.configurationParameter("VeloGEC")["Apply"]: from GaudiConfUtils.ConfigurableGenerators import VeloEventShapeCutsS20p3 veloGEC = VeloEventShapeCutsS20p3() self.validatedSetProps("VeloGEC", DisplVerticesLinesConf.veloGECCuts, veloGEC) withVeloTracksForVertexing = PassThroughSelection( "%sVeloGEC" % self.name(), RequiredSelection=withVeloTracksForVertexing, Algorithm=veloGEC) if self.configurationParameter("FilterVelo")["Apply"]: from GaudiConfUtils.ConfigurableGenerators import SelectVeloTracksNotFromPVS20p3 veloWithIP = SelectVeloTracksNotFromPVS20p3() self.validatedSetProps("FilterVelo", DisplVerticesLinesConf.veloWithIPCuts, veloWithIP) withVeloTracksForVertexing = Selection( "%sVeloFilteredTracks" % self.name(), RequiredSelections=[withVeloTracksForVertexing], Algorithm=veloWithIP) # Displaced Vertex reconstruction with best tracks (dominated by those with a Velo segment) from Configurables import PatPV3D, PVOfflineTool, PVSeed3DTool, LSAdaptPV3DFitter, LSAdaptPVFitter withVeloVertexAlg = PatPV3D("%sWithVeloVertexAlg" % self.name()) withVeloVertexFinder = addPrivateToolAndGet(withVeloVertexAlg, PVOfflineTool) withVeloVertexFinder.PVsChi2Separation = 0 withVeloVertexFinder.PVsChi2SeparationLowMult = 0 withVeloSeeder = addPrivateToolAndGet(withVeloVertexFinder, PVSeed3DTool) withVeloVertexFinder.PVSeedingName = withVeloSeeder.getTitleName() withVeloSeeder.MinCloseTracks = 3 withVeloFitter = addPrivateToolAndGet(withVeloVertexFinder, LSAdaptPV3DFitter) withVeloVertexFinder.PVFitterName = withVeloFitter.getTitleName() withVeloFitter.MinTracks = 4 withVeloVertexing = SelectionPatPV3DWrapper( "%sWithVeloVertexing" % self.name(), withVeloVertexAlg, RequiredSelections=[withVeloTracksForVertexing]) # Make Particles out of the RecVertices from GaudiConfUtils.ConfigurableGenerators import LLParticlesFromRecVertices rv2pWithVelo = LLParticlesFromRecVertices( VerticesFromVeloOnly=False, RequireUpstreamPV=False, WriteP2PVRelations=False, ForceP2PVBuild=False, VeloProtoParticlesLocation="Phys/%s/VeloProtoP" % self.name()) self.validatedSetProps( "RV2PWithVelo", DisplVerticesLinesConf.recoCuts + DisplVerticesLinesConf.singleCuts, rv2pWithVelo) withVeloCandidates = Selection("%sWithVeloCandidates" % self.name(), RequiredSelections=[withVeloVertexing], Algorithm=rv2pWithVelo, InputDataSetter="RecVertexLocations") ####################################################################### ### ### ### DOWNSTREAM VERTEXING SEQUENCE ### ### ### ####################################################################### from GaudiConfUtils.ConfigurableGenerators import CopyDownstreamTracks downTracks = Selection("%sDownstreamTracks" % self.name(), RequiredSelections=[bestTracks], Algorithm=CopyDownstreamTracks()) # Displaced Vertex reconstruction from downstream tracks downVertexAlg = PatPV3D("%sDownVertexAlg" % self.name()) downVertexFinder = addPrivateToolAndGet(downVertexAlg, PVOfflineTool) downVertexFinder.RequireVelo = False downVertexFinder.PVsChi2Separation = 0 downVertexFinder.PVsChi2SeparationLowMult = 0 downSeeder = addPrivateToolAndGet(downVertexFinder, PVSeed3DTool) downVertexFinder.PVSeedingName = downSeeder.getTitleName() downSeeder.TrackPairMaxDistance = 2.0 * units.mm downSeeder.zMaxSpread = 20.0 * units.mm downSeeder.MinCloseTracks = 4 downFitter = addPrivateToolAndGet(downVertexFinder, LSAdaptPVFitter) downVertexFinder.PVFitterName = downFitter.getTitleName() downFitter.MinTracks = 4 downFitter.maxChi2 = 400.0 downFitter.maxDeltaZ = 0.0005 * units.mm downFitter.maxDeltaChi2NDoF = 0.002 downFitter.acceptTrack = 0.000000001 downFitter.trackMaxChi2 = 9 downFitter.trackMaxChi2Remove = 64 downVertexing = SelectionPatPV3DWrapper( "%sDownVertexing" % self.name(), downVertexAlg, RequiredSelections=[downTracks]) # Make Particles out of the RecVertices rv2pDown = LLParticlesFromRecVertices(VerticesFromVeloOnly=False, RequireUpstreamPV=False, WriteP2PVRelations=False, ForceP2PVBuild=False #, OutputLevel = VERBOSE ) self.validatedSetProps( "RV2PDown", DisplVerticesLinesConf.recoCuts + DisplVerticesLinesConf.singleCuts, rv2pDown) downCandidates = Selection("%sDownCandidates" % self.name(), RequiredSelections=[downVertexing], Algorithm=rv2pDown, InputDataSetter="RecVertexLocations") ####################################################################### ### ### ### HLT JET SEQUENCE ### ### ### ####################################################################### # timing is already fine, so one algo with loose JetID is sufficient # Hlt prefilter and vertex candidates from Hlt2 from Configurables import HltVertexConverterS20p3 revivedHlt2Candidates = "Phys/%sHlt2Cand/Particles" % self.name() hltCandReviver = GaudiSequenceroid( ModeOR=True, ShortCircuit=False, Members=[ GaudiSequencer( "%sHlt2CandFilterTCK%s-%s" % (self.name(), tckBegin, tckEnd), Members=(LoKi_Filters( HLT2_Code= "in_range( {begin}, HLT_TCK % 0x40000000 , {end} ) & ( {decisions} )" .format(begin=tckBegin, end=tckEnd, decisions=" | ".join( "HLT_PASS('%s')" % ln for ln in hltLines))).filters( "%sHlt2DecisionFilterTCK%s-%s" % (self.name(), tckBegin, tckEnd)) + [ HltVertexConverterS20p3( "%sHltConverter%s-%s" % (self.name(), tckBegin, tckEnd), HltSelReports="Hlt2/SelReports", HltLines=hltLines, Recursive=True, Output=revivedHlt2Candidates, WriteP2PVRelations=False, ForceP2PVBuild=False) ])) for (tckBegin, tckEnd), hltLines in self.configurationParameter("HLT")["SignalLines"] ]) hltCandSelection = EventSelection("%sHltCandidates" % self.name(), Algorithm=hltCandReviver) hltVeloGEC = VeloEventShapeCutsS20p3() self.validatedSetProps("VeloGEC", DisplVerticesLinesConf.veloGECCuts, hltVeloGEC) hltVeloGEC.HistoProduce = False hltVeloGECSel = EventSelection("%sHltVeloGEC" % self.name(), Algorithm=hltVeloGEC) hlt2CandAndGECSelection = Selection( "".join((self.name(), "Hlt2CandVertices")), RequiredSelections=[ hltCandSelection, AutomaticData(revivedHlt2Candidates), hltVeloGECSel ], Algorithm=FilterDesktop( Code="( ABSID == '{pid}' )".format(pid=LLPLHCbName), WriteP2PVRelations=False, ForceP2PVBuild=False)) ####################################################################### ### ### ### LINE DEFINITIONS ### ### ### ####################################################################### # one line for every configuratoin key of the format # "Single.*Selection" # "JetSingle.*Selection" # "JetHltSingle.*Selection" # "Double.*Selection" # ".*HLTPS" # "HltEff.*Selection" ##============================== Single ===================================## singleLineNames = [ p.split("Single")[1].split("Selection")[0] for p in self.configKeys() if p.startswith("Single") and p.endswith("Selection") ] for lAcroName in singleLineNames: lShortName = "Single%s" % lAcroName # SingleMedium lSelName = "%sSelection" % lShortName # SingleMediumSelection lLineName = "%s%s" % (self.name(), lShortName ) # DisplVerticesSingleMedium # Choose between Velo-based and downstream vertexing input candidates = withVeloCandidates code = None if "Down" in lAcroName: candidates = downCandidates code = self.getLLPSelection( self.validatedGetProps( lSelName, DisplVerticesLinesConf.singleCuts + DisplVerticesLinesConf.downCuts)) else: code = self.getLLPSelection( self.validatedGetProps(lSelName, DisplVerticesLinesConf.singleCuts)) lineFilter = FilterDesktop( DecayDescriptor=LLPLHCbName, Preambulo=DisplVerticesLinesConf.llpSelectionPreambulo, Code=code, WriteP2PVRelations=False, ForceP2PVBuild=False #, OutputLevel = VERBOSE ) lineSel = Selection("".join((self.name(), lSelName)), RequiredSelections=[candidates], Algorithm=lineFilter) line = StrippingLine(lLineName, prescale=self.validatedGetProps( lSelName, ["PreScale"])["PreScale"], selection=lineSel, RequiredRawEvents=["Calo"], RelatedInfoTools=[{ "Type": "AddVeloEventShapeS21", "TopSelection": lineSel, "Location": "P2VES" }]) if lShortName in self.configurationParameter("HLT"): line.HLT2 = self.configurationParameter("HLT")[lShortName] self.registerLine(line) ##========================= Single with jets ==============================## jetSingleLineNames = [ p.split("JetSingle")[1].split("Selection")[0] for p in self.configKeys() if p.startswith("JetSingle") and p.endswith("Selection") ] for lAcroName in jetSingleLineNames: lShortName = "JetSingle%s" % lAcroName # JetSingleMedium lSelName = "%sSelection" % lShortName # JetSingleMediumSelection lLineName = "%s%s" % (self.name(), lShortName ) # DisplVerticesJetSingleMedium # Choose between Velo-based and downstream vertexing input vertexCandidates = withVeloCandidates code = self.getLLPSelection( self.validatedGetProps(lSelName, DisplVerticesLinesConf.singleCuts)) vertexFilter = FilterDesktop( DecayDescriptor=LLPLHCbName, Preambulo=DisplVerticesLinesConf.llpSelectionPreambulo, Code=code, WriteP2PVRelations=False, ForceP2PVBuild=False #, OutputLevel = VERBOSE ) goodVertices = Selection("".join( (self.name(), lSelName, "Vertices")), RequiredSelections=[vertexCandidates], Algorithm=vertexFilter) jetProps = self.validatedGetProps(lSelName, DisplVerticesLinesConf.jetCuts) vertWithJets = Selection("".join((self.name(), lSelName, "Jets")), RequiredSelections=[goodVertices], Algorithm=self.makeJetCandidateAlg( "".join((self.name(), lSelName, "JetAlg")), MinNumJets=jetProps["MinNumJets"], ConeSize=jetProps["ConeSize"], JetIDCut=jetProps["JetIDCut"], MinDOCABL=jetProps["MinDOCABL"])) jetCode = self.getLLPJetSelection(jetProps) jetCandFilter = FilterDesktop(DecayDescriptor=LLPLHCbName, Preambulo=self.jetSelectionPreambulo, Code=jetCode, WriteP2PVRelations=False, ForceP2PVBuild=False) lineSel = Selection("".join((self.name(), lSelName)), RequiredSelections=[vertWithJets], Algorithm=jetCandFilter) line = StrippingLine(lLineName, prescale=self.validatedGetProps( lSelName, ["PreScale"])["PreScale"], selection=lineSel, RequiredRawEvents=["Calo"], RelatedInfoTools=[{ "Type": "AddVeloEventShapeS21", "TopSelection": lineSel, "Location": "P2VES" }]) if lShortName in self.configurationParameter("HLT"): line.HLT2 = self.configurationParameter("HLT")[lShortName] self.registerLine(line) ##============= Single with jets based on Hlt candidate ==================## jetHltSingleLineNames = [ p.split("JetHltSingle")[1].split("Selection")[0] for p in self.configKeys() if p.startswith("JetHltSingle") and p.endswith("Selection") ] for lAcroName in jetHltSingleLineNames: lShortName = "JetHltSingle%s" % lAcroName # JetHltSingleMedium lSelName = "%sSelection" % lShortName # JetHltSingleMediumSelection lLineName = "%s%s" % (self.name(), lShortName ) # DisplVerticesJetHltSingleMedium jetProps = self.validatedGetProps(lSelName, DisplVerticesLinesConf.jetCuts) vertWithJets = Selection( "".join((self.name(), lSelName, "HltJets")), RequiredSelections=[hlt2CandAndGECSelection], Algorithm=self.makeJetCandidateAlg( "".join((self.name(), lSelName, "HltJetAlg")), MinNumJets=jetProps["MinNumJets"], ConeSize=jetProps["ConeSize"], JetIDCut=jetProps["JetIDCut"], MinDOCABL=jetProps["MinDOCABL"])) jetCode = self.getLLPJetSelection(jetProps) jetCandFilter = FilterDesktop(DecayDescriptor=LLPLHCbName, Preambulo=self.jetSelectionPreambulo, Code=jetCode, WriteP2PVRelations=False, ForceP2PVBuild=False) lineSel = Selection("".join((self.name(), lSelName)), RequiredSelections=[vertWithJets], Algorithm=jetCandFilter) line = StrippingLine(lLineName, prescale=self.validatedGetProps( lSelName, ["PreScale"])["PreScale"], selection=lineSel, RequiredRawEvents=["Calo"], RelatedInfoTools=[{ "Type": "AddVeloEventShapeS21", "TopSelection": lineSel, "Location": "P2VES" }]) if lShortName in self.configurationParameter("HLT"): line.HLT2 = self.configurationParameter("HLT")[lShortName] self.registerLine(line) ##============================== Double ===================================## doubleLineNames = [ p.split("Double")[1].split("Selection")[0] for p in self.configKeys() if p.startswith("Double") and p.endswith("Selection") ] for lAcroName in doubleLineNames: lShortName = "Double%s" % lAcroName lSelName = "%sSelection" % lShortName lLineName = "%s%s" % (self.name(), lShortName) combinationCut, motherCut = self.getResonanceSelection( self.validatedGetProps( lSelName, DisplVerticesLinesConf.doubleResonanceCuts)) lineFilter = CombineParticles( DecayDescriptor="H_10 -> %s %s" % (LLPLHCbName, LLPLHCbName), Preambulo=DisplVerticesLinesConf.llpSelectionPreambulo, DaughtersCuts={ LLPLHCbName: self.getLLPSelection( self.validatedGetProps( lSelName, DisplVerticesLinesConf.singleCuts)) }, CombinationCut=combinationCut, MotherCut=motherCut, WriteP2PVRelations=False, ForceP2PVBuild=False #, OutputLevel = VERBOSE ) lineSel = Selection("".join((self.name(), lSelName)), RequiredSelections=[withVeloCandidates], Algorithm=lineFilter) line = StrippingLine(lLineName, prescale=self.validatedGetProps( lSelName, ["PreScale"])["PreScale"], selection=lineSel, RequiredRawEvents=["Calo"], RelatedInfoTools=[{ "Type": "AddVeloEventShapeS21", "TopSelection": lineSel, "Location": "P2VES" }]) if lShortName in self.configurationParameter("HLT"): line.HLT2 = self.configurationParameter("HLT")[lShortName] self.registerLine(line) ##============================== HLT PS ===================================## hltPSLineNames = [ p.split("HLTPS")[0] for p in self.configKeys() if p.endswith("HLTPS") ] for lAcroName in hltPSLineNames: lShortName = "%sHLTPS" % lAcroName lLineName = "%s%s" % (self.name(), lShortName ) # DisplVerticesSingleMedium orFilters = [] for (tckBegin, tckEnd), hltFilter in self.validatedGetProps( "HLT", [lShortName])[lShortName]: filters = LoKi_Filters( HLT2_Code= "in_range( {begin}, HLT_TCK % 0x40000000, {end} ) & ( {decisions} )" .format(begin=tckBegin, end=tckEnd, decisions=hltFilter)).filters( "%sHlt2FilterTCK%s-%s" % (lLineName, tckBegin, tckEnd)) assert len(filters) == 1 orFilters.append(filters[0]) assert len(orFilters) == len( self.validatedGetProps("HLT", [lShortName])[lShortName]) hltSelection = EventSelection("%sHltFilter" % lLineName, Algorithm=GaudiSequenceroid( ModeOR=True, ShortCircuit=False, Members=orFilters)) line = StrippingLine( lLineName, prescale=self.validatedGetProps(lShortName, ["PreScale"])["PreScale"], selection=hltSelection, RequiredRawEvents=["Muon", "Calo", "Rich", "Velo", "Tracker"]) self.registerLine(line) ##============================== OTHER ===================================## hltEffLineNames = [ p.split("HltEff")[1].split("Selection")[0] for p in self.configKeys() if p.startswith("HltEff") and p.endswith("Selection") ] for lShortName in hltEffLineNames: lSelName = "HltEff%sSelection" % lShortName lLineName = "%s%s" % (self.name(), lShortName) # HltEff lines are single, Velo-vertexing based lines lineFilter = FilterDesktop( DecayDescriptor=LLPLHCbName, Preambulo=DisplVerticesLinesConf.llpSelectionPreambulo, Code=self.getLLPSelection( self.validatedGetProps(lSelName, DisplVerticesLinesConf.singleCuts)), WriteP2PVRelations=False, ForceP2PVBuild=False #, OutputLevel = VERBOSE ) lineSel = Selection("".join((self.name(), lSelName)), RequiredSelections=[withVeloCandidates], Algorithm=lineFilter) line = StrippingLine( lLineName, prescale=self.validatedGetProps(lSelName, ["PreScale"])["PreScale"] # these lines MUST have an HLT filter , HLT2=self.configurationParameter("HLT")[lShortName], selection=lineSel, RequiredRawEvents=["Muon", "Calo", "Rich", "Velo", "Tracker"], RelatedInfoTools=[{ "Type": "AddVeloEventShapeS21", "TopSelection": lineSel, "Location": "P2VES" }]) self.registerLine(line)
def applyConf(self): # Check the special data options for option in self.getProp("SpecialData"): if option not in self.KnownSpecialData: raise RuntimeError("Unknown SpecialData option '%s'"%option) # Phases if not self.isPropertySet("RecoSequence"): self.setProp("RecoSequence",self.DefaultSubDetsFieldOn) if self.getProp("DataType") in self.Run2DataTypes: self.setProp("RecoSequence",self.DefaultSubDetsFieldOnRun2) recoSeq = self.getProp("RecoSequence") if self.getProp("SkipTracking"): for det in self.DefaultTrackingSubdets: if det in recoSeq: recoSeq.remove(det) from Configurables import ProcessPhase ProcessPhase("Reco").DetectorList += recoSeq # Primary Vertex and V0 finding if "Vertex" in recoSeq and self.getProp("DataType") not in self.Run2DataTypes: from Configurables import PatPVOffline, TrackV0Finder pvAlg = PatPVOffline() if "2009" == self.getProp("DataType"): from PatPV import PVConf PVConf.VLoosePV().configureAlg() elif ( "veloOpen" in self.getProp("SpecialData") or "microBiasTrigger" in self.getProp("SpecialData") ): from PatPV import PVConf PVConf.LoosePV().configureAlg() elif ( not ( self.getProp("Simulation") and self.getProp("DataType") in ["2008","2009","2010","MC09"] ) ): # Default setting uses beam spot constraint from DB, available from 2011. Prior to 2011 stability of beam spot is not certain from PatPV import PVConf PVConf.StandardPV().configureAlg() # MC with particle gun cannot reconstruct PV, hence need to introduce one by hand if "pGun" in self.getProp("SpecialData"): from Configurables import PGPrimaryVertex pgPV = PGPrimaryVertex() GaudiSequencer("RecoVertexSeq").Members += [ pgPV ] else: GaudiSequencer("RecoVertexSeq").Members += [ pvAlg ]; trackV0Finder = TrackV0Finder() GaudiSequencer("RecoVertexSeq").Members += [ trackV0Finder ] # for Run 2, we run a different algorithm and don't want to have # the V0 finder in the vertex sequence (which is now after HLT1) if "Vertex" in recoSeq and self.getProp("DataType") in self.Run2DataTypes: from Configurables import PatPV3D, PVOfflineTool, LSAdaptPV3DFitter pvAlg = PatPV3D("PatPV3D") ## this should go in a configuration file when we know what to use pvAlg.addTool(PVOfflineTool,"PVOfflineTool") pvAlg.PVOfflineTool.addTool(LSAdaptPV3DFitter, "LSAdaptPV3DFitter") pvAlg.PVOfflineTool.PVFitterName = "LSAdaptPV3DFitter" pvAlg.PVOfflineTool.LSAdaptPV3DFitter.UseFittedTracks = True pvAlg.PVOfflineTool.LSAdaptPV3DFitter.AddMultipleScattering = False pvAlg.PVOfflineTool.LSAdaptPV3DFitter.TrackErrorScaleFactor = 1.0 pvAlg.PVOfflineTool.LSAdaptPV3DFitter.MinTracks = 4 pvAlg.PVOfflineTool.LSAdaptPV3DFitter.trackMaxChi2 = 12.0 pvAlg.PVOfflineTool.UseBeamSpotRCut = True pvAlg.PVOfflineTool.BeamSpotRCut = 0.2 pvAlg.PVOfflineTool.BeamSpotRHighMultiplicityCut = 0.4 pvAlg.PVOfflineTool.BeamSpotRMultiplicityTreshold = 10 pvAlg.PVOfflineTool.InputTracks = [ "Rec/Track/FittedHLT1VeloTracks" ] pvAlg.OutputVerticesName = "Rec/Vertex/Primary" pvAlg.PrimaryVertexLocation = "Rec/Vertex/PrimaryVertices" # Remove all tracks that don't belong to a PV (to save space on a DST) from Configurables import TrackContainerCleaner, SelectTrackInVertex pvVeloTracksCleaner = TrackContainerCleaner("PVVeloTracksCleaner") pvVeloTracksCleaner.inputLocation = "Rec/Track/FittedHLT1VeloTracks" pvVeloTracksCleaner.selectorName = "SelectTrackInVertex" GaudiSequencer("RecoVertexSeq").Members += [ pvAlg, pvVeloTracksCleaner ]; GaudiSequencer("RecoVertexSeq").IgnoreFilterPassed = True ## Upgrade type? if self.getProp("DataType") == 'Upgrade' : specialDataList = self.getProp("SpecialData") specialDataList.append("upgrade") self.setProp("SpecialData",specialDataList) # Tracking (Should make it more fine grained ??) DoTracking = False for seq in self.DefaultTrackingSubdets : if seq in recoSeq: DoTracking = True if DoTracking: trackConf = TrackSys() self.setOtherProps(trackConf,["SpecialData","OutputType"]) trackConf.ExpertHistos = self.expertHistos() # RICH if "RICH" in recoSeq: # The main sequence seq = GaudiSequencer("RecoRICHSeq") # Create the top level Conf object richConf = RichRecSysConf(self.richRecConfName) # set some general options self.setOtherProps(richConf,["SpecialData","Context","OutputLevel", "Simulation","DataType","OnlineMode"]) # Set the sequencer the RICH reco algs should be added to richConf.RecoSequencer = seq # Input Tracks (would be better to not hard code this. Get from TrackSys() or DstConf()) # Only set if not previously set, to allow for custom studies using non standard locations # set at the top level options file level if not richConf.trackConfig().isPropertySet("InputTracksLocation") : richConf.trackConfig().setProp("InputTracksLocation","Rec/Track/Best") # Output PID Location. Again allow for pre-defined custom locations. if not richConf.isPropertySet("RichPIDLocation") : richConf.setProp("RichPIDLocation","Rec/Rich/PIDs") # Printout import GaudiKernel.ProcessJobOptions GaudiKernel.ProcessJobOptions.PrintOn() log.debug(richConf) GaudiKernel.ProcessJobOptions.PrintOff() # CALO if "CALO" in recoSeq: import GaudiKernel.ProcessJobOptions seq = GaudiSequencer ( 'RecoCALOSeq' ) caloConf=CaloProcessor( Context = self.getProp('Context') , OutputLevel = self.getProp('OutputLevel') , UseTracks = True , EnableOnDemand = False , DataType = self.getProp ('DataType') ) GaudiKernel.ProcessJobOptions.PrintOn() seq.Members = [caloConf.caloSequence()] GaudiKernel.ProcessJobOptions.PrintOff() # MUON if "MUON" in recoSeq: from MuonID import ConfiguredMuonIDs from Configurables import RawBankReadoutStatusConverter,RawBankReadoutStatusFilter cm=ConfiguredMuonIDs.ConfiguredMuonIDs(data=self.getProp("DataType"), specialData=self.getProp("SpecialData")) MuonIDSeq=cm.getMuonIDSeq() RawBankReadoutStatusConverter("MuonProcStatus").System="Muon" RawBankReadoutStatusConverter("MuonProcStatus").BankTypes=["Muon"] RawBankReadoutStatusFilter("MuonROFilter").BankType=13 RawBankReadoutStatusFilter("MuonROFilter").RejectionMask=2067 GaudiSequencer("RecoMUONSeq").Members += [ "MuonRec", "RawBankReadoutStatusConverter/MuonProcStatus", "RawBankReadoutStatusFilter/MuonROFilter", MuonIDSeq ] # PROTO if "PROTO" in recoSeq: self.setOtherProps(GlobalRecoConf(),["DataType","SpecialData", "Context","OutputLevel"]) GlobalRecoConf().RecoSequencer = GaudiSequencer("RecoPROTOSeq") # SUMMARY if "SUMMARY" in recoSeq: from Configurables import RecSummaryAlg summary = RecSummaryAlg("RecSummary") # make a new list of uppered detectors dets = [] for det in self.getProp("Detectors"): dets.append(det.upper()) summary.Detectors = dets GaudiSequencer("RecoSUMMARYSeq").Members += [summary]
#=== options for reconstruction all PV including displaced PVs from Configurables import PatPV3D, PVOfflineTool, LSAdaptPV3DFitter, PVSeed3DTool from GaudiKernel.SystemOfUnits import mm #=== reconstruction of PV PV = PatPV3D("PV") PV.addTool(PVOfflineTool) PV.PVOfflineTool.InputTracks = ["Rec/Track/Best"] PV.OutputVerticesName = "Rec/Vertices/PV" #=== reconstruction of displaced vertices RV = PatPV3D("RV") RV.addTool(PVOfflineTool) RV.PVOfflineTool.InputVerticesName = "Rec/Vertices/PV" #takes PVs as input RV.PVOfflineTool.LookForDisplaced = True RV.PVOfflineTool.InputTracks = ["Rec/Track/Best"] RV.PVOfflineTool.PVSeedingName = "PVSeed3DTool" RV.PVOfflineTool.addTool(PVSeed3DTool()) RV.PVOfflineTool.PVSeed3DTool.TrackPairMaxDistance = 0.2 * mm RV.PVOfflineTool.PVSeed3DTool.zMaxSpread = 1 * mm RV.PVOfflineTool.addTool(LSAdaptPV3DFitter()) RV.OutputVerticesName = "Rec/Vertices/RV"
BL.BeamLineCycle = 50 # The default ensures the beam line is not saved on TES before any estmation is done. Can be avoided in the MC where I know where the BL is... # Or uncomment the following #BL.LocalVeloFrame = True # to use PVs as the UpPV... BL.MinZ = -150. BL.MaxZ = 150. BL.MaxY = 1.5 BL.MaxX = 1.5 ######################################################################## # Reconstruct the displaced vertices... A few possibilities. from Configurables import PatPV3D, PVOfflineTool, PVSeed3DTool, \ LSAdaptPV3DFitter #PatPV3D with optimised parameters (recommanded). RV = PatPV3D("RV") DVSeq.Members += [RV] RV.OutputVerticesName = "Rec/Vertices/RV" RV.OutputLevel = 3 RV.addTool(PVOfflineTool) RV.PVOfflineTool.InputTracks = ["Rec/Track/Best"] RV.PVOfflineTool.PVSeedingName = "PVSeed3DTool" RV.PVOfflineTool.addTool(PVSeed3DTool()) RV.PVOfflineTool.PVSeed3DTool.TrackPairMaxDistance = 0.2 * mm RV.PVOfflineTool.PVSeed3DTool.zMaxSpread = 1 * mm RV.PVOfflineTool.addTool(LSAdaptPV3DFitter()) RV.PVOfflineTool.LSAdaptPV3DFitter.maxIP2PV = 2 * mm RV.PVOfflineTool.LSAdaptPV3DFitter.MinTracks = 4 #Default PV reconstruction from Configurables import PatPVOffline