From 14511df7a5ec09cf4a0a7a39e7ee97468b56b9f2 Mon Sep 17 00:00:00 2001
From: Bertrand Martin <martindl@cern.ch>
Date: Tue, 5 Jan 2021 20:44:18 +0100
Subject: [PATCH] xAODTau: protection against tau track thinning

Hello,

This MR is mostly importing !26767 from 21.2 to master, with the original MR description pasted below.

A protection is added against invalid TauTrack links when retrieving the tau tracks or the number of tau tracks.
This is required to support tau track thinning, used e.g. in DAOD_PHYS.
Now, only the tau tracks that have a valid link are considered in the TauJets interface class.
In particular, the behaviour of nAllTracks() had to be changed to be consistent with allTracks().size().
If one only keeps e.g. classifiedCharged tau tracks by thinning away the other tracks, nAllTracks() will now return the number of classifiedCharged tracks.

Something new compared to the R21 MR: to keep track of the total number of tracks associated with the tau in the reconstruction, a new Aux variable is introduced (mapped to xAOD::TauJetParameters::nAllTracks). So the user is now able to tell if tracks were thinned in the AOD->DAOD step, by comparing tau->nAllTracks() to tau->detail(xAOD::TauJetParameters::nAllTracks, nTracksTot).

Cheers,
Bertrand
---
 .../xAOD/xAODTau/Root/TauJetAccessors_v3.icc  |  7 +-
 .../xAODTau/Root/TauJetAuxContainer_v3.cxx    |  5 +-
 Event/xAOD/xAODTau/Root/TauJet_v3.cxx         | 72 +++++++------------
 Event/xAOD/xAODTau/xAODTau/TauDefs.h          |  4 +-
 .../xAODTau/versions/TauJetAuxContainer_v3.h  |  3 +-
 .../tauRecTools/src/TauTrackFinder.cxx        | 12 ++--
 6 files changed, 40 insertions(+), 63 deletions(-)

diff --git a/Event/xAOD/xAODTau/Root/TauJetAccessors_v3.icc b/Event/xAOD/xAODTau/Root/TauJetAccessors_v3.icc
index 34c935fffec..519d09dd71b 100644
--- a/Event/xAOD/xAODTau/Root/TauJetAccessors_v3.icc
+++ b/Event/xAOD/xAODTau/Root/TauJetAccessors_v3.icc
@@ -1,11 +1,9 @@
 // Dear emacs, this is -*- c++ -*-
 
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id: TauJetAccessors_v2.icc 638520 2015-01-09 13:21:05Z janus $
-
 #ifndef XAODTAU_TAUACCESSORS_V3_ICC
 #define XAODTAU_TAUACCESSORS_V3_ICC
 
@@ -226,6 +224,7 @@ break;
       DEFINE_TAUJETPARAMETER_ACCESSOR( int, nChargedTracks );
       DEFINE_TAUJETPARAMETER_ACCESSOR( int, nIsolatedTracks );
       DEFINE_TAUJETPARAMETER_ACCESSOR( int, nModifiedIsolationTracks ); 
+      DEFINE_TAUJETPARAMETER_ACCESSOR( int, nAllTracks );
 
     default:
       std::cerr << "xAOD::TauJetParameters ERROR Unknown integer detail ("
@@ -267,5 +266,3 @@ break;
 #endif //TAUTRACK_V1_ACCESSORS  to aid with link issues
 
 #endif // XAODTAU_TAUJETACCESSORS_V3_ICC
-
-//  LocalWords:  EMPOverTrkSysPCorrected
diff --git a/Event/xAOD/xAODTau/Root/TauJetAuxContainer_v3.cxx b/Event/xAOD/xAODTau/Root/TauJetAuxContainer_v3.cxx
index 32dc32e9af2..3569d907372 100644
--- a/Event/xAOD/xAODTau/Root/TauJetAuxContainer_v3.cxx
+++ b/Event/xAOD/xAODTau/Root/TauJetAuxContainer_v3.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 // $Id: TauJetAuxContainer_v3.cxx 725228 2016-02-19 22:59:42Z griffith $
@@ -270,7 +270,8 @@ namespace xAOD {
     //RNN tau eVeto
     AUX_VARIABLE( RNNEleScore );
     AUX_VARIABLE( RNNEleScoreSigTrans ); 
-    
+
+    AUX_VARIABLE( nAllTracks );
   }
   
 } // namespace xAOD
diff --git a/Event/xAOD/xAODTau/Root/TauJet_v3.cxx b/Event/xAOD/xAODTau/Root/TauJet_v3.cxx
index ec71140fae7..f95105c8a98 100644
--- a/Event/xAOD/xAODTau/Root/TauJet_v3.cxx
+++ b/Event/xAOD/xAODTau/Root/TauJet_v3.cxx
@@ -1,10 +1,7 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id: TauJet_v3.cxx 725228 2016-02-19 22:59:42Z griffith $
-
-
 // System include(s):
 #include <cstdint>
 #include <bitset>
@@ -27,19 +24,19 @@ namespace xAOD {
   }
   
 
+  //primitive setters and getters for default 4-vector
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, pt)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, eta)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, phi)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, m)
 
-
-  //primitive setters and getters for jetseed 4-vector
+  //primitive setters and getters for JetSeed 4-vector
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, ptJetSeed)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, etaJetSeed)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, phiJetSeed)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, mJetSeed)
 
-  //primitive setters and getters for jetseed 4-vector
+  //primitive setters and getters for DetectorAxis 4-vector
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, ptDetectorAxis)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, etaDetectorAxis)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, phiDetectorAxis)
@@ -56,38 +53,32 @@ namespace xAOD {
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, etaTauEnergyScale)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, phiTauEnergyScale)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, mTauEnergyScale)
-  // double TauJet_v3::etaTauEnergyScale() const { return etaIntermediateAxis(); }
-  // double TauJet_v3::phiTauEnergyScale() const { return phiIntermediateAxis(); }
-  // double TauJet_v3::mTauEnergyScale() const { return 0; }
 
-
-  //primitive setters and getters for jetseed 4-vector
+  //primitive setters and getters for ptTauEtaCalib 4-vector - deprecated in R22
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, ptTauEtaCalib)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, etaTauEtaCalib)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, phiTauEtaCalib)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, mTauEtaCalib)
-  // double TauJet_v3::phiTauEtaCalib() const { return phiIntermediateAxis(); }
-  // double TauJet_v3::mTauEtaCalib() const { return 0; }
 
-  //primitive setters and getters for jetseed 4-vector
+  //primitive setters and getters for PanTauCellBasedProto 4-vector - deprecated in R22
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, ptPanTauCellBasedProto)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, etaPanTauCellBasedProto)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, phiPanTauCellBasedProto)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, mPanTauCellBasedProto)
 
-  //primitive setters and getters for jetseed 4-vector
+  //primitive setters and getters for PanTauCellBased 4-vector
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, ptPanTauCellBased)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, etaPanTauCellBased)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, phiPanTauCellBased)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, mPanTauCellBased)
 
-  //primitive setters and getters for HLT 4-vector
+  //primitive setters and getters for TrigCaloOnly 4-vector
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, ptTrigCaloOnly)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, etaTrigCaloOnly)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, phiTrigCaloOnly)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, mTrigCaloOnly)
 
-  //primitive setters and getters for HLT 4-vector
+  //primitive setters and getters for FinalCalib 4-vector
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, ptFinalCalib)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, etaFinalCalib)
   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TauJet_v3, float, double, phiFinalCalib)
@@ -280,16 +271,14 @@ namespace xAOD {
     //-------------------------------------------------------------------------
     // Accept
     //-------------------------------------------------------------------------
-    bool TauJet_v3::isTau(
-            TauJetParameters::IsTauFlag flag ) const
+    bool TauJet_v3::isTau( TauJetParameters::IsTauFlag flag ) const
     {
       static const Accessor< uint32_t > acc( "isTauFlags" );
       std::bitset<32> isTauFlags( acc( *this ) );
       return isTauFlags[flag];
     }
 
-    void TauJet_v3::setIsTau(
-            TauJetParameters::IsTauFlag flag, bool value )
+    void TauJet_v3::setIsTau( TauJetParameters::IsTauFlag flag, bool value )
     {
       static const Accessor< uint32_t > acc( "isTauFlags" );
       std::bitset<32> isTauFlags( acc( *this ) );
@@ -297,28 +286,6 @@ namespace xAOD {
       acc( *this ) = isTauFlags.to_ulong();
     }
 
-  //r21 cleanup
-    // //-------------------------------------------------------------------------
-    // // Veto flags accessors
-    // //-------------------------------------------------------------------------
-    // void TauJet_v3::setFlag(
-    //         TauJetParameters::VetoFlags flag, bool value )
-    // {
-    //   static const Accessor< uint32_t > acc( "vetoFlags" );
-    //   std::bitset<32> vetoFlags( acc( *this ) );
-    //   vetoFlags[flag] = value;
-    //   acc( *this ) = vetoFlags.to_ulong();
-    // }
-
-    // bool TauJet_v3::flag(
-    //         TauJetParameters::VetoFlags flag ) const
-    // {
-    //   static const Accessor< uint32_t > acc( "vetoFlags" );
-    //   std::bitset<32> vetoFlags( acc( *this ) );
-    //   return vetoFlags[flag];
-    // }
-
-
 
   //-------------------------------------------------------------------------
   // Get int detail via enum
@@ -468,6 +435,8 @@ namespace xAOD {
   const TauJet_v3::TauTrackLinks_t TauJet_v3::tauTrackLinksWithMask(unsigned int mask) const{
     TauJet_v3::TauTrackLinks_t links;
     for(const ElementLink< xAOD::TauTrackContainer >& link : tauTrackAcc(*this) ){
+      // protection against tau track thinning
+      if(!link.isValid()) continue;
       if( (*link)->flagWithMask(mask))
 	links.push_back(link);
     }
@@ -488,6 +457,8 @@ namespace xAOD {
     uint tracks_pass_mask=0;
 
     for(const ElementLink< xAOD::TauTrackContainer >& link : tauTrackAcc(*this) ){
+      // protection against tau track thinning
+      if(!link.isValid()) continue;
       const TauTrack* trk = *link;
       if(trk->flagWithMask(mask)){
 	if(tracks_pass_mask==i) {
@@ -526,9 +497,11 @@ namespace xAOD {
   }
 
   /// Get the v<const pointer> to a given tauTrack collection associated with this tau
-  std::vector<const TauTrack*> TauJet_v3::tracksWithMask(unsigned int mask )const {
+  std::vector<const TauTrack*> TauJet_v3::tracksWithMask( unsigned int mask ) const {
   std::vector<const TauTrack*> trks;
     for(const ElementLink< xAOD::TauTrackContainer >& link : tauTrackAcc(*this) ){
+      // protection against tau track thinning
+      if(!link.isValid()) continue;
       const TauTrack* trk = *link;
       if(trk->flagWithMask(mask)){
 	trks.push_back(trk);
@@ -585,6 +558,8 @@ namespace xAOD {
   size_t TauJet_v3::nTracksWithMask(unsigned int flags) const{
     size_t n(0);
     for(const ElementLink< xAOD::TauTrackContainer >& link : tauTrackAcc(*this) ){
+      // protection against tau track thinning
+      if(!link.isValid()) continue;
       const TauTrack* trk = *link;
       if(trk->flagWithMask(flags)) n++;
     }    
@@ -593,7 +568,11 @@ namespace xAOD {
 
   //all tracks regardless of classification or lack thereof
   size_t TauJet_v3::nAllTracks() const{
-    return tauTrackAcc( *this ).size();
+    // unsafe w.r.t. tau track thinning
+    //return tauTrackAcc( *this ).size();
+    // return the number of tracks with valid element link
+    TauTrack::TrackFlagType mask=0;
+    return nTracksWithMask( mask );
   }
 
   /// add a TauTrack to the tau
@@ -1021,4 +1000,3 @@ namespace xAOD {
   
 } // namespace xAOD
 
-//  LocalWords:  panTauDetail mJetSeed
diff --git a/Event/xAOD/xAODTau/xAODTau/TauDefs.h b/Event/xAOD/xAODTau/xAODTau/TauDefs.h
index 67715716a56..141d50ddce8 100644
--- a/Event/xAOD/xAODTau/xAODTau/TauDefs.h
+++ b/Event/xAOD/xAODTau/xAODTau/TauDefs.h
@@ -1,10 +1,9 @@
 // Dear emacs, this is -*- c++ -*-
 
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id: TauDefs.h 796092 2017-02-08 00:14:16Z griffith $
 #ifndef XAODTAU_TAUDEFS_H
 #define XAODTAU_TAUDEFS_H
 
@@ -327,6 +326,7 @@ namespace TauJetParameters
       nChargedTracks=109,
       nIsolatedTracks=110,
       nModifiedIsolationTracks=111,//no static variable for now
+      nAllTracks=112,
 
       //Tau/Ele BDTVars
 
diff --git a/Event/xAOD/xAODTau/xAODTau/versions/TauJetAuxContainer_v3.h b/Event/xAOD/xAODTau/xAODTau/versions/TauJetAuxContainer_v3.h
index 58fa1316fe7..e8821912be5 100644
--- a/Event/xAOD/xAODTau/xAODTau/versions/TauJetAuxContainer_v3.h
+++ b/Event/xAOD/xAODTau/xAODTau/versions/TauJetAuxContainer_v3.h
@@ -1,7 +1,7 @@
 // Dear emacs, this is -*- c++ -*-
 
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef XAODTAU_VERSIONS_TAUJETAUXCONTAINER_V3_H
@@ -117,6 +117,7 @@ namespace xAOD {
     //after the first pass of TauTrackFinder
     std::vector< int > nChargedTracks;
     std::vector< int > nIsolatedTracks;
+    std::vector< int > nAllTracks;
 
     typedef std::vector< ElementLink< IParticleContainer > > IParticleLink_t;
     std::vector< IParticleLink_t > clusterLinks;//actually xAOD::CaloClusters
diff --git a/Reconstruction/tauRecTools/src/TauTrackFinder.cxx b/Reconstruction/tauRecTools/src/TauTrackFinder.cxx
index 18dac06cc77..cfbd16fc26e 100644
--- a/Reconstruction/tauRecTools/src/TauTrackFinder.cxx
+++ b/Reconstruction/tauRecTools/src/TauTrackFinder.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef XAOD_ANALYSIS
@@ -7,7 +7,6 @@
 #include "TrkParametersIdentificationHelpers/TrackParametersIdHelper.h"
 
 #include "xAODTau/TauJet.h"
-#include "xAODTau/TauJetContainer.h"
 #include "xAODTau/TauTrackContainer.h"
 
 #include "TauTrackFinder.h"
@@ -208,6 +207,8 @@ StatusCode TauTrackFinder::executeTrackFinder(xAOD::TauJet& pTau, xAOD::TauTrack
   //These are set again in TauTrackClassifier                                                                                                                  
   pTau.setDetail(xAOD::TauJetParameters::nChargedTracks, (int) pTau.nTracks());
   pTau.setDetail(xAOD::TauJetParameters::nIsolatedTracks, (int) pTau.nTracks(xAOD::TauJetParameters::classifiedIsolation));
+  // keep track of total number of associated tracks, in case of tau track thinning
+  pTau.setDetail(xAOD::TauJetParameters::nAllTracks, (int) pTau.nAllTracks());
 
   for (unsigned int i = 0; i < otherTracks.size(); ++i) {
     const xAOD::TrackParticle* trackParticle = otherTracks.at(i);
@@ -295,8 +296,7 @@ StatusCode TauTrackFinder::executeTrackFinder(xAOD::TauJet& pTau, xAOD::TauTrack
   // store information only in ExtraDetailsContainer
   if(!m_bypassExtrapolator)
     {
-      StatusCode sc;
-      sc = extrapolateToCaloSurface(pTau);
+      StatusCode sc = extrapolateToCaloSurface(pTau);
       if (sc.isFailure() && !sc.isRecoverable()) {
 	ATH_MSG_ERROR("couldn't extrapolate tracks to calo surface");
 	return StatusCode::FAILURE;
@@ -530,7 +530,7 @@ float TauTrackFinder::getZ0(const xAOD::TrackParticle* track, const xAOD::Vertex
 
     if (!track) return MAX;
 
-    const Trk::Perigee* perigee = 0;
+    const Trk::Perigee* perigee = nullptr;
     if (vertex) perigee = m_trackToVertexTool->perigeeAtVertex(*track, vertex->position());
     else        perigee = m_trackToVertexTool->perigeeAtVertex(*track); //will use beamspot or 0,0,0 instead
 
@@ -553,7 +553,7 @@ bool TauTrackFinder::isLargeD0Track(const xAOD::TrackParticle* track) const
     ATH_MSG_DEBUG("LargeD0Track found");
     return true;
   }
-  return false;
 
+  return false;
 }
 #endif
-- 
GitLab