Skip to content
Snippets Groups Projects
Commit d6b201cf authored by Alex Pearce's avatar Alex Pearce Committed by Alex Pearce
Browse files

Add working neutral-matching logic, tidy up.

parent 6fc9415d
No related branches found
No related tags found
2 merge requests!526Draft: S29r2p2 cache,!101Trying to get TurboSP and MC with truthmatching to work
......@@ -21,6 +21,7 @@ from Configurables import (
DecodeRawEvent,
DstConf,
EventSelector,
Gaudi__DataLink as DataLink,
GaudiSequencer,
HltPackedDataDecoder,
HltRoutingBitsFilter,
......@@ -172,6 +173,7 @@ class Tesla(LHCbConfigurableUser):
writerName = "DstWriter"
teslaSeq = GaudiSequencer("TeslaSequence")
base = "Turbo/"
neutral_pp2mc_loc = "Relations/Turbo/NeutralPP2MC"
def _safeSet(self,conf,param):
......@@ -211,12 +213,10 @@ class Tesla(LHCbConfigurableUser):
SequencerTimerTool().OutputLevel = WARNING
def _configureTrackTruth(self,assocpp,trackLoc) :
assoctr = TrackAssociator("TurboAssocTr"+trackLoc)
assoctr = TrackAssociator("TurboAssocTr"+trackLoc.replace('/', ''))
assoctr.OutputLevel = self.getProp('OutputLevel')
assoctr.TracksInContainer = trackLoc
assoctr.TracksInContainer = trackLoc
assocpp.TrackLocations += [ trackLoc ]
#assocpp.OutputLevel = 1
# Add it to a sequence
return assoctr
......@@ -229,18 +229,11 @@ class Tesla(LHCbConfigurableUser):
clusterTabLoc = self.base + "Relations/CaloClusters"
assoccluster = CaloClusterMCTruth("TurboClusterAssoc")
#assoccluster.OutputLevel = self.getProp('OutputLevel')
#assoccluster.OutputLevel = 1
assoccluster.OutputLevel = self.getProp('OutputLevel')
assoccluster.Input = digits
assoccluster.Output = clusterTabLoc
#assoccluster.Clusters += clusters
assoccluster.Clusters += [ "/Event/Turbo/PID/Calo/EcalClusters", "/Event/Turbo/PID/Calo/EcalSplitClusters", "/Event/Turbo/PID/Calo/CaloClusters" ]
assoccluster.Clusters += clusters
# When filtering MC, the relations table cloners will copy the tables
# to /Event/Turbo for us. Otherwise we create them there directly
#protoTabLoc = "Relations/Turbo/NeutralPP2MC"
if not self.getProp("FilterMC"):
protoTabLoc = os.path.join(self.base, protoTabLoc)
assocneutral = NeutralPP2MC("TurboNeutralPP2MC")
assocneutral.InputData += protos
assocneutral.OutputLevel = self.getProp('OutputLevel')
......@@ -248,7 +241,7 @@ class Tesla(LHCbConfigurableUser):
assocneutral.MCCaloTable = clusterTabLoc
retSeq.Members += [assoccluster,assocneutral]
return protoTabLoc, retSeq
return retSeq
def _unpackMC(self):
DataOnDemandSvc().NodeMap['/Event/MC'] = 'DataObject'
......@@ -500,7 +493,8 @@ class Tesla(LHCbConfigurableUser):
# Configure
self._configureDigitsTruth()
protoneutral, retSeq = self._configureClustersAndProtosTruth(outputDigiLoc,neutralClustersTot,neutralProtosTot)
protoneutral = os.path.join(tesROOT, self.neutral_pp2mc_loc)
retSeq = self._configureClustersAndProtosTruth(outputDigiLoc,neutralClustersTot,neutralProtosTot,protoneutral)
NeutralProtoSeq.Members+=[retSeq]
# Add standard Turbo locations if not packing
......@@ -598,81 +592,96 @@ class Tesla(LHCbConfigurableUser):
TeslaReportAlgoSeq.Members += [TeslaOutputStreamsSequence]
def _configureTruthMatching(self, name, packing):
# Locations of the objects we want to truth-match
track_locs = [packing.outputs['Hlt2LongTracks'],
packing.outputs['Hlt2DownstreamTracks']]
proto_locs = [packing.outputs['Hlt2LongProtos'],
packing.outputs['Hlt2DownstreamProtos']]
cluster_locs = [packing.outputs['Hlt2CaloClusters']]
neutral_locs = [packing.outputs['Hlt2NeutralProtos']]
# When filtering MC, the relations table cloners will copy the
# tables to /Event/Turbo for us. Otherwise we create them there
# directly
tesROOT = "/Event"
if not self.getProp("FilterMC"):
tesROOT = os.path.join(tesROOT, self.base)
# CHARGED STUFF #####################################################################
# Get the location of all tracks and all protoparticles we want to truthmatch
track_locs = [v for v in packing.outputs.values() if 'track' in v.lower()]
proto_locs = [v for v in packing.outputs.values() if 'proto' in v.lower()]
ChargedProtoSeq = GaudiSequencer("ChargedTruthSequencer")
assocpp = ChargedPP2MC("TurboProtoAssocPP")
assocpp.OutputLevel = self.getProp('OutputLevel')
#assocpp.OutputLevel = 1
assocpp.VetoEmpty=True
#assocpp.RootInTES = '/Event/Turbo'
assocpp.VetoEmpty = True
assocpp.RootInTES = tesROOT
# Make all track -> MCParticle linker tables
for loc in track_locs:
truthSeq = self._configureTrackTruth(assocpp,loc)
ChargedProtoSeq.Members.append( truthSeq )
trackTruthSeq = GaudiSequencer('TurboTrackTruthSequencer')
trackTruthSeq.Members = [self._configureTrackTruth(assocpp, loc)
for loc in track_locs]
# Make the protoparticle -> track linker tables
assocpp.InputData += proto_locs
ChargedProtoSeq.Members.append( assocpp )
#relationsLocations = [os.path.join('Relations', path)
# for path in assocpp.InputData]
#relationsLocations.append(protoneutral)
print "++++++++++++++++"
print proto_locs
relationsLocations = [ loc.replace('/Event', '/Event/Relations') for loc in proto_locs ]
print relationsLocations
print "++++++++++++++++"
filterMCSeq = self._filterMCParticlesSequence(relationsLocations)
ChargedProtoSeq.Members += [filterMCSeq]
# NEUTRAL STUFF ################################################################
NeutralProtoSeq = GaudiSequencer("NeutralTruthSequencer")
## Add the digits associator
assocdigits = CaloDigit2MCLinks2Table("TurboDigitAssoc")
#assocdigits.OutputLevel = self.getProp('OutputLevel')
#assocdigits.OutputLevel = 1
outputDigiLoc = self.base+"Relations/CaloDigits"
assocdigits.Output = outputDigiLoc
assocdigits.Inputs = [ "Turbo/Raw/Ecal/Digits", "Turbo/Raw/Hcal/Digits"]
## Finally configure the neutral PP2MC associator
NeutralProtoSeq.Members+=[assocdigits]
# Gather all protos and clusters
neutralClustersTot=[]
neutralProtosTot=[]
print " ------> Neutral stuff <-------------"
print self.base
print " ------> Neutral stuff <-------------"
# Add standard Turbo
#neutralClustersTot+=[self.base+"Hlt2/Rec/Neutral/CaloClusters"]
neutralClustersTot+=[self.base+"CaloClusters"]
neutralProtosTot+=[self.base+"Protos"]
print " ------> Neutral stuff <-------------"
print neutralClustersTot
print " ------> Neutral stuff <-------------"
# Configure
self._configureDigitsTruth()
protoneutral, retSeq = self._configureClustersAndProtosTruth(outputDigiLoc,neutralClustersTot,neutralProtosTot, "Turbo/Relations/NeutralPP2MC")
NeutralProtoSeq.Members+=[retSeq]
assocDigits = CaloDigit2MCLinks2Table("TurboDigitAssoc")
# The digits relations table maker will try to find the linker table
# for digits at `Raw/{det}/Digits` at `Link/Raw/{det}/Digits`. Our
# digits are at `Turbo/Raw/{det}/Digits`, but we can't remake a linker
# table at `Link/Turbo/Raw/{det}/Digits because the information needed
# to make one is lost after Boole.
# Instead, exploit the fact that the digits under `Turbo/` are a subset
# of the originals, and just symlink the original linker table to the
# location expected for the Turbo digits
assocDigits.RespectInputDigitLocation = False
digit_locs = [l.replace('/Event/', '')
for l in assocDigits.getDefaultProperty('Inputs')]
turbo_digit_locs = [os.path.join(self.base, l) for l in digit_locs]
linkingSeq = GaudiSequencer('TurboLinkTableLinkers')
for digit_loc in digit_locs:
link_loc = os.path.join('Link', digit_loc)
turbo_link_loc = os.path.join('Link', self.base, digit_loc)
name = '{0}Linker'.format(link_loc.replace('/', ''))
dl = DataLink(name, What=link_loc, Target=turbo_link_loc)
linkingSeq.Members.append(dl)
# DataLinks don't create the ancestor TES structure, so do it
# manually
path = ''
for node in turbo_link_loc.split(os.path.sep)[:-1]:
path = os.path.join(path, node)
DataOnDemandSvc().NodeMap[path] = 'DataObject'
# Add the CaloDigit <-> MCParticle associator
assocDigits.OutputLevel = self.getProp('OutputLevel')
# Can use a magic string here as this table is only temporary
assocDigits.Output = "Relations/CaloDigits"
assocDigits.Inputs = turbo_digit_locs
# Add the CaloCluster <-> MCParticle and neutral ProtoParticle <->
# MCParticle associators
neutral_rels_loc = os.path.join(tesROOT, self.neutral_pp2mc_loc)
assocClustersNeutrals = self._configureClustersAndProtosTruth(
assocDigits.Output,
cluster_locs,
neutral_locs,
neutral_rels_loc
)
chargedProtoSeq = GaudiSequencer("ChargedTruthSequencer")
chargedProtoSeq.Members = [trackTruthSeq, assocpp]
neutralProtoSeq = GaudiSequencer("NeutralTruthSequencer")
neutralProtoSeq.Members = [linkingSeq, assocDigits, assocClustersNeutrals]
truthSeq = GaudiSequencer("TurboTruthSequencer")
truthSeq.Members = [chargedProtoSeq, neutralProtoSeq]
# Sequence to copy the relations tables, and the subset of MC
# particles used by those tables, into /Event/Turbo
if self.getProp("FilterMC"):
relationsLocations = [
os.path.join('Relations', path.replace('/Event/', ''))
for path in assocpp.InputData
]
relationsLocations.append(neutral_rels_loc)
filterMCSeq = self._filterMCParticlesSequence(relationsLocations)
truthSeq.Members += [filterMCSeq]
return truthSeq
return NeutralProtoSeq
def _configureOutputStream(self, stream, lines_dict):
'''
The lines dictionary should have the following form:
......@@ -860,7 +869,8 @@ class Tesla(LHCbConfigurableUser):
#decoder.OutputLevel = 1
decoders_seq.Members.append(decoder)
DecodeRawEvent().DataOnDemand = False
# Need the DoD for decoding the Ecal digits
DecodeRawEvent().DataOnDemand = simulation
self._safeSet(DstConf(), ['SplitRawEventOutput'])
# This decoder is setup by TurboConf
......@@ -998,11 +1008,10 @@ class Tesla(LHCbConfigurableUser):
ApplicationMgr().ExtSvc.append(dod)
# Check that the DoD is running
#dod.OutputLevel = 1
self._unpackMC()
stream_seq.Members.append(self._configureTruthMatching(name, packing))
# No need to clone if the output prefix is empty (everything stays
# under /Event/Turbo)
if output_prefix:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment