From b8b6f5cfb5f40cbb150cc8a95d67f20b8b2b6b8e Mon Sep 17 00:00:00 2001
From: Guillermo Nicolas Hamity <guillermo.nicolas.hamity@cern.ch>
Date: Mon, 26 Oct 2020 10:34:07 +0000
Subject: [PATCH] support LRT in tau reconstruction (ATLTAU-1721)

LRT track container included in TauTrackFinder
Using InDetLargeD0TrackParticles as LRT container
name will make this happen
---
 .../tauRec/python/TauAlgorithmsHolder.py      |  2 +
 Reconstruction/tauRec/python/tauRecFlags.py   |  8 ++-
 .../tauRecTools/src/TauTrackFinder.cxx        | 61 +++++++++++++++++--
 .../tauRecTools/src/TauTrackFinder.h          |  2 +
 4 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/Reconstruction/tauRec/python/TauAlgorithmsHolder.py b/Reconstruction/tauRec/python/TauAlgorithmsHolder.py
index 080de883f7f..87befaaad05 100644
--- a/Reconstruction/tauRec/python/TauAlgorithmsHolder.py
+++ b/Reconstruction/tauRec/python/TauAlgorithmsHolder.py
@@ -21,6 +21,7 @@ bAODmode = False
 # standard container names
 _DefaultVertexContainer = "PrimaryVertices"
 _DefaultTrackContainer ="InDetTrackParticles"
+_DefaultLargeD0TrackContainer ="InDetLargeD0TrackParticles"
 
 ######################################################################## 
 def setPrefix(prefix): 
@@ -664,6 +665,7 @@ def getTauTrackFinder(removeDuplicateTracks=True):
                                     tauParticleCache = getParticleCache(),
                                     removeDuplicateCoreTracks = removeDuplicateTracks,
                                     Key_trackPartInputContainer = _DefaultTrackContainer,
+                                    Key_LargeD0TrackInputContainer = _DefaultLargeD0TrackContainer if tauFlags.useLargeD0Tracks else "",
                                     TrackToVertexIPEstimator = getTauTrackToVertexIPEstimator(),
                                     #maxDeltaZ0wrtLeadTrk = 2, #in mm
                                     #removeTracksOutsideZ0wrtLeadTrk = True
diff --git a/Reconstruction/tauRec/python/tauRecFlags.py b/Reconstruction/tauRec/python/tauRecFlags.py
index c7f4f6ca7f3..c233c3eae75 100644
--- a/Reconstruction/tauRec/python/tauRecFlags.py
+++ b/Reconstruction/tauRec/python/tauRecFlags.py
@@ -58,6 +58,12 @@ class doTJVA(JobProperty):
     allowedTypes=['bool']
     StoredValue=True
 
+class useLargeD0Tracks(JobProperty):
+    """ Use LRT tracks in tau track finding """
+    statusOn=False
+    allowedTypes=['bool']
+    StoredValue=False
+
 #deprecated
 class TauDiscriminantCVMFSPath(JobProperty):
     """ path to cvmfs file location
@@ -224,7 +230,7 @@ class tauRecFlags(JobPropertyContainer):
 jobproperties.add_Container(tauRecFlags)
 
 # I want always the following flags in the Rec container  
-_list_tau=[Enabled,doTauRec,isStandalone,tauRecSeedJetCollection,tauRecToolsCVMFSPath,doTJVA,TauDiscriminantCVMFSPath,tauRecMVATrackClassification,tauRecRNNTrackClassification,tauRecMVATrackClassificationConfig,tauRecRNNTrackClassificationConfig,tauRecDecayModeNNClassifierConfig,tauRecSeedMinPt,tauRecSeedMaxEta,tauRecToolsDevToolList,tauRecToolsDevToolListProcessor,doRunTauDiscriminant,useVertexBasedConvFinder,useNewPIDBasedConvFinder,doPanTau,doPi0,pi0EtCuts,pi0MVACuts_1prong,pi0MVACuts_mprong,shotPtCut_1Photon,shotPtCut_2Photons,useOldVertexFitterAPI,useSubtractedCluster]
+_list_tau=[Enabled,doTauRec,isStandalone,tauRecSeedJetCollection,tauRecToolsCVMFSPath,doTJVA,TauDiscriminantCVMFSPath,tauRecMVATrackClassification,tauRecRNNTrackClassification,tauRecMVATrackClassificationConfig,tauRecRNNTrackClassificationConfig,tauRecDecayModeNNClassifierConfig,tauRecSeedMinPt,tauRecSeedMaxEta,tauRecToolsDevToolList,tauRecToolsDevToolListProcessor,doRunTauDiscriminant,useVertexBasedConvFinder,useNewPIDBasedConvFinder,doPanTau,doPi0,pi0EtCuts,pi0MVACuts_1prong,pi0MVACuts_mprong,shotPtCut_1Photon,shotPtCut_2Photons,useOldVertexFitterAPI,useSubtractedCluster,useLargeD0Tracks]
 for j in _list_tau: 
     jobproperties.tauRecFlags.add_JobProperty(j)
 del _list_tau
diff --git a/Reconstruction/tauRecTools/src/TauTrackFinder.cxx b/Reconstruction/tauRecTools/src/TauTrackFinder.cxx
index 829ba59ab80..18dac06cc77 100644
--- a/Reconstruction/tauRecTools/src/TauTrackFinder.cxx
+++ b/Reconstruction/tauRecTools/src/TauTrackFinder.cxx
@@ -37,6 +37,8 @@ StatusCode TauTrackFinder::initialize() {
     ATH_CHECK( m_trackPartInputContainer.initialize(SG::AllowEmpty) );
     // use CaloExtensionTool when key is empty 
     ATH_CHECK( m_ParticleCacheKey.initialize(SG::AllowEmpty) );
+    // allow empty for LRT
+    ATH_CHECK( m_largeD0TracksInputContainer.initialize(SG::AllowEmpty) );
 
     if (inTrigger()) {
       ATH_CHECK(m_beamSpotKey.initialize());
@@ -51,7 +53,8 @@ StatusCode TauTrackFinder::executeTrackFinder(xAOD::TauJet& pTau, xAOD::TauTrack
   std::vector<const xAOD::TrackParticle*> tauTracks;
   std::vector<const xAOD::TrackParticle*> wideTracks;
   std::vector<const xAOD::TrackParticle*> otherTracks;
-  
+
+  //Retrieve standard tracking for offline
   const xAOD::TrackParticleContainer* trackParticleCont = nullptr; 
   
   if (! m_trackPartInputContainer.empty()) { // MT version of trigger or offline
@@ -72,13 +75,33 @@ StatusCode TauTrackFinder::executeTrackFinder(xAOD::TauJet& pTau, xAOD::TauTrack
     }
   }
 
+  //Retrieve LRT tracking container
+  const xAOD::TrackParticleContainer* largeD0TracksParticleCont = nullptr; 
+  
+  if (! m_largeD0TracksInputContainer.empty()) { 
+    SG::ReadHandle<xAOD::TrackParticleContainer> trackPartInHandle( m_largeD0TracksInputContainer );
+    if (!trackPartInHandle.isValid()) {
+      ATH_MSG_VERBOSE ("Could not retrieve HiveDataObj with key " << trackPartInHandle.key());
+      ATH_MSG_VERBOSE ("LRT container " << trackPartInHandle.key()<<" is not being used for tau tracks");
+    }
+    else { largeD0TracksParticleCont = trackPartInHandle.cptr();
+}
+  
+  }
+
   // get the primary vertex
   const xAOD::Vertex* pVertex = nullptr;
   if (pTau.vertexLink().isValid()) pVertex = pTau.vertex();
 
   // retrieve tracks wrt a vertex                                                                                                                              
   // as a vertex is used: tau origin / PV / beamspot / 0,0,0 (in this order, depending on availability)                                                        
+
   getTauTracksFromPV(pTau, *trackParticleCont, pVertex, tauTracks, wideTracks, otherTracks);
+  bool foundLRTCont = bool (largeD0TracksParticleCont != nullptr);
+  // additional LRT with vertex association added to tracks
+  if (foundLRTCont){
+    getTauTracksFromPV(pTau, *largeD0TracksParticleCont, pVertex, tauTracks, wideTracks, otherTracks);
+  }
 
   // remove core and wide tracks outside a maximal delta z0 wrt lead core track                                                                                
   if (m_applyZ0cut) {
@@ -118,7 +141,14 @@ StatusCode TauTrackFinder::executeTrackFinder(xAOD::TauJet& pTau, xAOD::TauTrack
     tauTrackCon.push_back(track);
 
     ElementLink<xAOD::TrackParticleContainer> linkToTrackParticle;
-    linkToTrackParticle.toContainedElement(*trackParticleCont, trackParticle);
+    if (foundLRTCont && isLargeD0Track(trackParticle)){//Check LRT track and link to container
+      linkToTrackParticle.toContainedElement(*largeD0TracksParticleCont, trackParticle);
+      ATH_MSG_VERBOSE(name()     << " core track nr: " << i << "is LargeD0Track"	    );
+
+    }else{
+      linkToTrackParticle.toContainedElement(*trackParticleCont, trackParticle);
+    }
+
     track->addTrackLink(linkToTrackParticle);
 
     track->setP4(trackParticle->pt(), trackParticle->eta(), trackParticle->phi(), trackParticle->m());
@@ -152,7 +182,13 @@ StatusCode TauTrackFinder::executeTrackFinder(xAOD::TauJet& pTau, xAOD::TauTrack
     tauTrackCon.push_back(track);
 
     ElementLink<xAOD::TrackParticleContainer> linkToTrackParticle;
-    linkToTrackParticle.toContainedElement(*trackParticleCont, trackParticle);
+    if (foundLRTCont && isLargeD0Track(trackParticle)){//Check LRT track and link to container
+      linkToTrackParticle.toContainedElement(*largeD0TracksParticleCont, trackParticle);
+      ATH_MSG_VERBOSE(name()     << " wide track nr: " << i << "is LargeD0Track"	    );
+    }else{
+
+      linkToTrackParticle.toContainedElement(*trackParticleCont, trackParticle);
+    }
     track->addTrackLink(linkToTrackParticle);
 
     track->setP4(trackParticle->pt(), trackParticle->eta(), trackParticle->phi(), trackParticle->m());
@@ -185,7 +221,12 @@ StatusCode TauTrackFinder::executeTrackFinder(xAOD::TauJet& pTau, xAOD::TauTrack
     tauTrackCon.push_back(track);
 
     ElementLink<xAOD::TrackParticleContainer> linkToTrackParticle;
-    linkToTrackParticle.toContainedElement(*trackParticleCont, trackParticle);
+    if (foundLRTCont && isLargeD0Track(trackParticle)){//Check LRT track and link to container
+      linkToTrackParticle.toContainedElement(*largeD0TracksParticleCont, trackParticle);
+      ATH_MSG_VERBOSE(name()     << " other track nr: " << i << "is LargeD0Track"    );
+    }else{
+      linkToTrackParticle.toContainedElement(*trackParticleCont, trackParticle);
+    }
     track->addTrackLink(linkToTrackParticle);
 
     track->setP4(trackParticle->pt(), trackParticle->eta(), trackParticle->phi(), trackParticle->m());
@@ -300,6 +341,7 @@ void TauTrackFinder::getTauTracksFromPV( const xAOD::TauJet& pTau,
         const xAOD::TrackParticle *trackParticle = *tpcItr;
 
         TauTrackType type = tauTrackType(pTau, *trackParticle, primaryVertex);
+		
         if (type == TauTrackCore)
 	  tauTracks.push_back(trackParticle);
         else if (type == TauTrackWide)
@@ -503,4 +545,15 @@ float TauTrackFinder::getZ0(const xAOD::TrackParticle* track, const xAOD::Vertex
 
     return z0;
 }
+
+bool TauTrackFinder::isLargeD0Track(const xAOD::TrackParticle* track) const
+{
+  const std::bitset<xAOD::NumberOfTrackRecoInfo> patternReco = track->patternRecoInfo();
+  if (patternReco.test(xAOD::TrackPatternRecoInfo::SiSpacePointsSeedMaker_LargeD0)) {
+    ATH_MSG_DEBUG("LargeD0Track found");
+    return true;
+  }
+  return false;
+
+}
 #endif
diff --git a/Reconstruction/tauRecTools/src/TauTrackFinder.h b/Reconstruction/tauRecTools/src/TauTrackFinder.h
index 0850ce3b5f3..120c8e18f57 100644
--- a/Reconstruction/tauRecTools/src/TauTrackFinder.h
+++ b/Reconstruction/tauRecTools/src/TauTrackFinder.h
@@ -88,6 +88,7 @@ private:
     //! Some internally used functions
     //-------------------------------------------------------------
     float getZ0(const xAOD::TrackParticle* track, const xAOD::Vertex* vertex) const;   //xAOD version
+    bool  isLargeD0Track(const xAOD::TrackParticle* track) const;   
 
     //-------------------------------------------------------------
     //! tools
@@ -107,6 +108,7 @@ private:
     Gaudi::Property<bool> m_bypassExtrapolator {this, "BypassExtrapolator", false};
 
     SG::ReadHandleKey<xAOD::TrackParticleContainer> m_trackPartInputContainer{this,"Key_trackPartInputContainer", "InDetTrackParticles", "input track particle container key"};
+ 	SG::ReadHandleKey<xAOD::TrackParticleContainer> m_largeD0TracksInputContainer{this,"Key_LargeD0TrackInputContainer", "", "input LRT particle container key"}; //Expecting InDetLargeD0TrackParticles (offline tracks) if using LRT used
     SG::ReadHandleKey<CaloExtensionCollection>  m_ParticleCacheKey{this,"tauParticleCache", "ParticleCaloExtension", "Name of the particle measurement extrapolation cache for TauTrackFinder"};
     
     SG::ReadCondHandleKey<InDet::BeamSpotData> m_beamSpotKey { this, "BeamSpotKey", "BeamSpotData", "SG key for beam spot" };
-- 
GitLab