From fb8c02b7bc1a4b1eb0c2cac74062c99b0719dc5b Mon Sep 17 00:00:00 2001
From: Rosen Matev <r.matev@gmail.com>
Date: Mon, 18 Apr 2016 10:36:07 +0200
Subject: [PATCH] Add RecVertices to persist reco and refactor code to use
 PersistRecoPacking

---
 Hlt/HltConf/doc/release.notes                |   3 +
 Hlt/HltConf/python/HltConf/HltPersistReco.py | 194 ++++++-------------
 2 files changed, 64 insertions(+), 133 deletions(-)

diff --git a/Hlt/HltConf/doc/release.notes b/Hlt/HltConf/doc/release.notes
index e6301a0c5..f1397ebdd 100755
--- a/Hlt/HltConf/doc/release.notes
+++ b/Hlt/HltConf/doc/release.notes
@@ -4,6 +4,9 @@
 ! Purpose     : HLT Configuration
 ! -----------------------------------------------------------------------------
 
+! 2016-04-18 - Rosen Matev
+ - Add RecVertices to persist reco and refactor code to use PersistRecoPacking
+
 !========================= HltConf v13r8 2016-04-11 =========================
 
 ! 2016-04-11 - Rosen Matev
diff --git a/Hlt/HltConf/python/HltConf/HltPersistReco.py b/Hlt/HltConf/python/HltConf/HltPersistReco.py
index 20c8ad05d..b487c0fda 100644
--- a/Hlt/HltConf/python/HltConf/HltPersistReco.py
+++ b/Hlt/HltConf/python/HltConf/HltPersistReco.py
@@ -6,8 +6,16 @@ from LHCbKernel.Configuration import *
 from Configurables import GaudiSequencer as Sequence
 from Configurables import HltPackedDataWriter
 
+from GaudiConf.PersistRecoConf import PersistRecoPacking
+
 from HltTracking.Hlt2TrackingConfigurations import Hlt2BiKalmanFittedForwardTracking
 from HltTracking.Hlt2TrackingConfigurations import Hlt2BiKalmanFittedDownstreamTracking
+from HltTracking.HltSharedTracking import FittedVelo
+from HltTracking.HltVertexNames import Hlt3DPrimaryVerticesName as PV3DSelection
+from HltTracking.HltVertexNames import HltSharedVerticesPrefix, HltGlobalVertexLocation
+from HltTracking.HltVertexNames import _vertexLocation
+from HltTracking.HltPVs import PV3D
+
 from Configurables import CaloProcessor, RichRecSysConf, ChargedProtoANNPIDConf
 
 __author__ = "Sean Benson, Rosen Matev"
@@ -31,7 +39,6 @@ class HltPersistRecoConf(LHCbConfigurableUser):
         "Sequence":        None,
         "CaloHypoPrefix":  "Hlt2/PID/CALO/Calo",
         "OutputLevel":     WARNING,
-        "_packersCache":   None,
     }
 
     def __apply_configuration__(self):
@@ -40,6 +47,7 @@ class HltPersistRecoConf(LHCbConfigurableUser):
         from Configurables import GaudiSequencer
         from Configurables import LoKi__HDRFilter
         from Configurables import TrackToDST
+        from Configurables import MoveRecVertexTracks
 
         persistRecoSeq = self.getProp("Sequence")
         if not self.getProp("Sequence"):
@@ -52,159 +60,79 @@ class HltPersistRecoConf(LHCbConfigurableUser):
         # Cut down states in tracks first
         tracks = Hlt2BiKalmanFittedForwardTracking().hlt2PrepareTracks()
         tracksDown = Hlt2BiKalmanFittedDownstreamTracking().hlt2PrepareTracks()
-        longStateCutter = TrackToDST("TrackToDSTLong")
+        longStateCutter = TrackToDST("Hlt2TrackToDSTLong")
         longStateCutter.TracksInContainer = tracks.outputSelection()
-        downStateCutter = TrackToDST("TrackToDSTDown")
+        downStateCutter = TrackToDST("Hlt2TrackToDSTDown")
         downStateCutter.TracksInContainer = tracksDown.outputSelection()
         persistRecoSeq.Members += [longStateCutter]
         persistRecoSeq.Members += [downStateCutter]
 
+        # Remove all tracks that don't belong to a PV (to save space in the raw bank)
+        movePVTracks = MoveRecVertexTracks("Hlt2MovePVTracks")
+        movePVTracks.VertexLocation = PV3D("Hlt2").output
+        movePVTracks.OutputLocation = self.__pvTrackLocation()
+        persistRecoSeq.Members += [movePVTracks]
+
+        fittedVeloTracksCutter = TrackToDST("Hlt2TrackToDSTVeloPV", veloStates=["ClosestToBeam"])
+        fittedVeloTracksCutter.TracksInContainer = self.__pvTrackLocation()
+        persistRecoSeq.Members += [fittedVeloTracksCutter]
+
         # Setup packers and add them to the sequence
-        packerAlgs = self._packers()
+        packing = self.__packing()
+        packerAlgs = packing.packers()
+        for alg in packerAlgs:
+            alg.AlwaysCreateOutput = True
+            alg.DeleteInput = False
+            alg.OutputLevel = self.getProp("OutputLevel")
         persistRecoSeq.Members += packerAlgs
 
         # Configure HltPackedDataWriter algorithm to add to the raw banks
         pdwriter = HltPackedDataWriter("Hlt2PackedDataWriter")
-        pdwriter.Containers = [out for inp, out in self.packedObjectLocations()]
+        pdwriter.PackedContainers = packing.packedLocations()
+        pdwriter.ContainerMap = packing.inputToPackedLocationMap()
         persistRecoSeq.Members += [pdwriter]
 
         # Register the mapping of output locations and integers
-        self._registerToHltANNSvc()
-
-    def packedObjectLocations(self):
-        """Return a list with the (unpacked, packed) object locations."""
-        return [(alg.InputName, alg.OutputName) for alg in self._packers()]
+        self.__registerToHltANNSvc(packing.packedLocations() +
+                                   packing.externalLocations())
 
-    def _registerToHltANNSvc(self):
+    def __registerToHltANNSvc(self, locations):
         """Register the packed object locations in the HltANNSvc."""
         from Configurables import HltANNSvc
-        locations = list(itertools.chain(*self.packedObjectLocations()))
-        # We need to register the locations of (non-reconstructed) data
-        # that is referenced by the some of the packed objects.
-        locations += [
-            '/Event/Raw/Ecal/Digits',
-            '/Event/Raw/Prs/Digits',
-            '/Event/Raw/Spd/Digits',
-        ]
         location_ids = {loc: i+1 for i, loc in enumerate(locations)}
         HltANNSvc().PackedObjectLocations = location_ids
 
-    def _packers(self):
-        """Return a list with the packer algorithms."""
-
-        try:
-            return self._packersCache
-        except AttributeError:
-            pass
+    def __pvTrackLocation(self):
+        return FittedVelo.outputSelection() + 'InPV'
 
+    def __packing(self):
+        """Return a PersistRecoPacking object."""
+        pvLocation = _vertexLocation(HltSharedVerticesPrefix, HltGlobalVertexLocation, PV3DSelection)
         longTracking = Hlt2BiKalmanFittedForwardTracking()
         downstreamTracking = Hlt2BiKalmanFittedDownstreamTracking()
         caloHypoPrefix = self.getProp("CaloHypoPrefix")
 
-        from Configurables import PackProtoParticle
-        from Configurables import DataPacking__Pack_LHCb__RichPIDPacker_ as PackRichPIDs
-        from Configurables import DataPacking__Pack_LHCb__MuonPIDPacker_ as PackMuonPIDs
-        from Configurables import PackTrack
-        from Configurables import PackProtoParticle
-        from Configurables import DataPacking__Pack_LHCb__CaloClusterPacker_ as PackCaloClusters
-        # from Configurables import DataPacking__Pack_LHCb__CaloHypoPacker_ as PackCaloHypos
-        from Configurables import PackCaloHypo as PackCaloHypos
-
-        algs = [
-            # ProtoParticles
-            PackProtoParticle(
-                name="Hlt2PackChargedProtos",
-                InputName=longTracking.hlt2ChargedAllPIDsProtos().outputSelection(),
-                OutputName="Hlt2/pRec/long/Protos"),
-            PackProtoParticle(
-                name="Hlt2PackChargedDownProtos",
-                InputName=downstreamTracking.hlt2ChargedNoPIDsProtos().outputSelection(),
-                OutputName="Hlt2/pRec/down/Protos"),
-            # RICH PIDs
-            PackRichPIDs(
-                name="Hlt2PackLongRichPIDs",
-                InputName=longTracking.hlt2RICHID().outputSelection(),
-                OutputName="Hlt2/pRec/long/RichPIDs"),
-            PackRichPIDs(
-                name="Hlt2PackDownRichPIDs",
-                InputName=downstreamTracking.hlt2RICHID().outputSelection(),
-                OutputName="Hlt2/pRec/down/RichPIDs"),
-            # MUON PIDs
-            PackMuonPIDs(
-                name="Hlt2PackMuonPIDs",
-                InputName=longTracking.hlt2MuonID().outputSelection(),
-                OutputName="Hlt2/pRec/long/MuonIDs"),
-            # Tracks
-            PackTrack(
-                name="Hlt2PackLongTracks",
-                InputName=longTracking.hlt2PrepareTracks().outputSelection(),
-                OutputName="Hlt2/pRec/long/Tracks"),
-            PackTrack(
-                name="Hlt2PackDownTracks",
-                InputName=downstreamTracking.hlt2PrepareTracks().outputSelection(),
-                OutputName="Hlt2/pRec/down/Tracks"),
-            PackTrack(
-                name="Hlt2PackDownPIDMuonSegments",
-                InputName=downstreamTracking._trackifiedMuonIDLocation(),
-                OutputName="Hlt2/pRec/down/PID/MuonSegments"),
-
-            # Neutral protoparticles are in the same place as the charged with "Neutrals" replacing "Charged"
-            PackProtoParticle(
-                name="Hlt2PackNeutralProtoP",
-                InputName=longTracking.hlt2NeutralProtos().outputSelection(),
-                OutputName="Hlt2/pRec/neutral/Protos"),
-            # Neutral CaloClusters
-            PackCaloClusters(
-                name="Hlt2PackCaloClusters",
-                InputName="Hlt/Calo/EcalClusters",
-                OutputName="Hlt2/pRec/neutral/CaloClusters"),
-            PackCaloClusters(
-                name="Hlt2PackEcalSplitClusters",
-                InputName=caloHypoPrefix + "/EcalSplitClusters",
-                OutputName="Hlt2/pRec/neutral/EcalSplitClusters"),
-            # Neutral Calo Hypos
-            PackCaloHypos(
-                name="Hlt2PackCaloElectronHypos",
-                InputName=caloHypoPrefix + "/Electrons",
-                OutputName="Hlt2/pRec/neutral/Electrons"),
-            PackCaloHypos(
-                name="Hlt2PackCaloPhotonsHypos",
-                InputName=caloHypoPrefix + "/Photons",
-                OutputName="Hlt2/pRec/neutral/Photons"),
-            PackCaloHypos(
-                name="Hlt2PackCaloMergedPi0Hypos",
-                InputName=caloHypoPrefix + "/MergedPi0s",
-                OutputName="Hlt2/pRec/neutral/MergedPi0s"),
-            PackCaloHypos(
-                name="Hlt2PackCaloSplitPhotonHypos",
-                InputName=caloHypoPrefix + "/SplitPhotons",
-                OutputName="Hlt2/pRec/neutral/SplitPhotons"),
-        ]
-
-        for alg in algs:
-            alg.AlwaysCreateOutput = True
-            alg.DeleteInput = False
-            alg.OutputLevel = self.getProp("OutputLevel")
-            if not alg.InputName.startswith('/Event/'):
-                # This is needed to have the full locations registered in ANNSvc
-                alg.InputName = '/Event/' + alg.InputName
-
-        # Check that the output locations are consistent with the decoder
-        from DAQSys.Decoders import DecoderDB
-        try:
-            decoder = DecoderDB["HltPackedDataDecoder/Hlt2PackedDataDecoder"]
-        except KeyError:
-            # TODO remove that for a release on the most recent DAQSys
-            decoder = None
-        if decoder:
-            decoder_outputs = sorted(decoder.listOutputs())
-            configured_outputs = sorted(alg.OutputName for alg in algs)
-            if configured_outputs != decoder_outputs:
-                log.warning('Configured output locations: {}'.format(configured_outputs))
-                log.warning('Configured decoder locations: {}'.format(decoder_outputs))
-                raise ValueError('Configured output locations do not match the decoder!' +
-                                 'Please update the DecoderDB (Decoders.py)!'
-                                )
-
-        self._packersCache = algs
-        return algs
+        inputs = {
+            "Hlt2LongProtos":                longTracking.hlt2ChargedAllPIDsProtos().outputSelection(),
+            "Hlt2DownstreamProtos":          downstreamTracking.hlt2ChargedNoPIDsProtos().outputSelection(),
+            "Hlt2LongRichPIDs":              longTracking.hlt2RICHID().outputSelection(),
+            "Hlt2DownstreamRichPIDs":        downstreamTracking.hlt2RICHID().outputSelection(),
+            "Hlt2LongMuonPIDs":              longTracking.hlt2MuonID().outputSelection(),
+            "Hlt2DownstreamPIDMuonSegments": downstreamTracking._trackifiedMuonIDLocation(),
+            "Hlt2LongTracks":                longTracking.hlt2PrepareTracks().outputSelection(),
+            "Hlt2DownstreamTracks":          downstreamTracking.hlt2PrepareTracks().outputSelection(),
+            "Hlt2VeloPVTracks":              self.__pvTrackLocation(),
+            "Hlt2RecVertices":               pvLocation,
+            "Hlt2NeutralProtos":             longTracking.hlt2NeutralProtos().outputSelection(),
+            "Hlt2CaloClusters":              "Hlt/Calo/EcalClusters",
+            "Hlt2EcalSplitClusters":         caloHypoPrefix + "/EcalSplitClusters",
+            "Hlt2CaloElectronHypos":         caloHypoPrefix + "/Electrons",
+            "Hlt2CaloPhotonHypos":           caloHypoPrefix + "/Photons",
+            "Hlt2CaloMergedPi0Hypos":        caloHypoPrefix + "/MergedPi0s",
+            "Hlt2CaloSplitPhotonHypos":      caloHypoPrefix + "/SplitPhotons",
+        }
+        for k in inputs:
+            if not inputs[k].startswith('/Event/'):
+                inputs[k] = '/Event/' + inputs[k]
+
+        return PersistRecoPacking(inputs=inputs)
-- 
GitLab