diff --git a/Reconstruction/tauRec/python/TauAlgorithmsHolder.py b/Reconstruction/tauRec/python/TauAlgorithmsHolder.py index 68fd84169e394df3dc802a21ebf9a485a5adb694..ca4a3f08fdcd41a329098a2423cdfefe1684644b 100644 --- a/Reconstruction/tauRec/python/TauAlgorithmsHolder.py +++ b/Reconstruction/tauRec/python/TauAlgorithmsHolder.py @@ -74,12 +74,19 @@ def getTauAxis(): if _name in cached_instances: return cached_instances[_name] + from JetRec.JetRecFlags import jetFlags + + doJetVertexCorrection = False + if tauFlags.isStandalone: + doJetVertexCorrection = True + if jetFlags.useVertices() and jetFlags.useTracks(): + doJetVertexCorrection = True + from tauRecTools.tauRecToolsConf import TauAxisSetter TauAxisSetter = TauAxisSetter( name = _name, ClusterCone = 0.2, VertexCorrection = True, - TauVertexCorrection = getTauVertexCorrection(), - UseSubtractedCluster = tauFlags.useSubtractedCluster() ) + JetVertexCorrection = doJetVertexCorrection) cached_instances[_name] = TauAxisSetter return TauAxisSetter diff --git a/Reconstruction/tauRecTools/src/TauAxisSetter.cxx b/Reconstruction/tauRecTools/src/TauAxisSetter.cxx index cb465266aa7378414bba3046a1a46d3e4369a5f6..04260136c458c00ce963ceff4713276106f67199 100644 --- a/Reconstruction/tauRecTools/src/TauAxisSetter.cxx +++ b/Reconstruction/tauRecTools/src/TauAxisSetter.cxx @@ -10,31 +10,22 @@ #include "xAODTau/TauJetContainer.h" #include "xAODTau/TauJetAuxContainer.h" #include "xAODTau/TauJet.h" +#include "xAODCaloEvent/CaloVertexedTopoCluster.h" -//______________________________________________________________________________ -TauAxisSetter::TauAxisSetter(const std::string& name) : -TauRecToolBase(name) { -} -//______________________________________________________________________________ -TauAxisSetter::~TauAxisSetter() { -} - - -StatusCode TauAxisSetter::initialize() { - ATH_CHECK(m_tauVertexCorrection.retrieve()); - return StatusCode::SUCCESS; +TauAxisSetter::TauAxisSetter(const std::string& name) : +TauRecToolBase(name) { } -StatusCode TauAxisSetter::execute(xAOD::TauJet& pTau) const { - if (! pTau.jetLink().isValid()) { +StatusCode TauAxisSetter::execute(xAOD::TauJet& tau) const { + if (! tau.jetLink().isValid()) { ATH_MSG_ERROR("Tau jet link is invalid."); return StatusCode::FAILURE; } - const xAOD::Jet* jetSeed = pTau.jet(); + const xAOD::Jet* jetSeed = tau.jet(); // Barycenter is the sum of cluster p4 in the seed jet TLorentzVector baryCenter; @@ -47,7 +38,7 @@ StatusCode TauAxisSetter::execute(xAOD::TauJet& pTau) const { ATH_MSG_DEBUG("barycenter (eta, phi): " << baryCenter.Eta() << " " << baryCenter.Phi()); - // Detector axis is the sum of cluster p4 within dR core of the seed jet + // Detector axis is the total p4 of clusterswithin m_clusterCone core of the barycenter TLorentzVector tauDetectorAxis; int nConstituents = 0; @@ -67,49 +58,138 @@ StatusCode TauAxisSetter::execute(xAOD::TauJet& pTau) const { } ATH_MSG_DEBUG("detector axis:" << tauDetectorAxis.Pt()<< " " << tauDetectorAxis.Eta() << " " << tauDetectorAxis.Phi() << " " << tauDetectorAxis.E()); - pTau.setP4(tauDetectorAxis.Pt(), tauDetectorAxis.Eta(), tauDetectorAxis.Phi(), pTau.m()); - pTau.setP4(xAOD::TauJetParameters::DetectorAxis, tauDetectorAxis.Pt(), tauDetectorAxis.Eta(), tauDetectorAxis.Phi(), tauDetectorAxis.M()); + tau.setP4(tauDetectorAxis.Pt(), tauDetectorAxis.Eta(), tauDetectorAxis.Phi(), tau.m()); + tau.setP4(xAOD::TauJetParameters::DetectorAxis, tauDetectorAxis.Pt(), tauDetectorAxis.Eta(), tauDetectorAxis.Phi(), tauDetectorAxis.M()); if (m_doVertexCorrection) { - const xAOD::Vertex* jetVertex = m_tauVertexCorrection->getJetVertex(*jetSeed); + // Tau intermediate axis (corrected for tau vertex) + TLorentzVector tauInterAxis; + const xAOD::Vertex* jetVertex = getJetVertex(*jetSeed); + const xAOD::Vertex* tauVertex = nullptr; - if (pTau.vertexLink().isValid()) tauVertex = pTau.vertex(); + if (tau.vertexLink().isValid()) tauVertex = tau.vertex(); + + // Redo the vertex correction when tau vertex is different from jet vertex + if (jetVertex != tauVertex) { + // If seed jet has a vertex, then tau must have one + if (tauVertex == nullptr) { + ATH_MSG_WARNING("The seed jet has a vertex, while the tau candidate does not. It should not happen."); + return StatusCode::FAILURE; + } - // calculate tau intermediate axis (corrected for tau vertex) - TLorentzVector tauInterAxis; + // Relative position of the tau vertex and jet vertex + Amg::Vector3D position = tauVertex->position(); + if (jetVertex != nullptr) { + position -= jetVertex->position(); + } - if (tauVertex == jetVertex) { - tauInterAxis = tauDetectorAxis; - } - else { - // barycenter at the tau vertex + // Barycenter at the tau vertex TLorentzVector baryCenterTauVertex; - + + // Loop over the jet constituents, and calculate the barycenter using the four momentum + // correctd to point at tau vertex for (const xAOD::JetConstituent* constituent : constituents) { - TLorentzVector constituentP4 = m_tauVertexCorrection->getVertexCorrectedP4(*constituent, tauVertex, jetVertex); + TLorentzVector constituentP4 = getVertexCorrectedP4(*constituent, position); baryCenterTauVertex += constituentP4; } ATH_MSG_DEBUG("barycenter (eta, phi) at tau vertex: " << baryCenterTauVertex.Eta() << " " << baryCenterTauVertex.Phi()); - + // Tau intrmediate axis is the four momentum (corrected to point at tau verteex) of clusters + // within m_clusterCone of the baryon center for (const xAOD::JetConstituent* constituent : constituents) { - TLorentzVector constituentP4 = m_tauVertexCorrection->getVertexCorrectedP4(*constituent, tauVertex, jetVertex); - + TLorentzVector constituentP4 = getVertexCorrectedP4(*constituent, position); double dR = baryCenterTauVertex.DeltaR(constituentP4); if (dR > m_clusterCone) continue; tauInterAxis += constituentP4; } } + else { + tauInterAxis = tauDetectorAxis; + } ATH_MSG_DEBUG("tau axis:" << tauInterAxis.Pt()<< " " << tauInterAxis.Eta() << " " << tauInterAxis.Phi() << " " << tauInterAxis.E() ); - pTau.setP4(tauInterAxis.Pt(), tauInterAxis.Eta(), tauInterAxis.Phi(), pTau.m()); - pTau.setP4(xAOD::TauJetParameters::IntermediateAxis, tauInterAxis.Pt(), tauInterAxis.Eta(), tauInterAxis.Phi(), tauInterAxis.M()); - } + tau.setP4(tauInterAxis.Pt(), tauInterAxis.Eta(), tauInterAxis.Phi(), tau.m()); + tau.setP4(xAOD::TauJetParameters::IntermediateAxis, tauInterAxis.Pt(), tauInterAxis.Eta(), tauInterAxis.Phi(), tauInterAxis.M()); + } // End of m_doVertexCorrection return StatusCode::SUCCESS; } + + +const xAOD::Vertex* TauAxisSetter::getJetVertex(const xAOD::Jet& jet) const { + + const xAOD::Vertex* jetVertex = nullptr; + + if (m_doJetVertexCorrection && !inTrigger()) { + bool isAvailable = jet.getAssociatedObject("OriginVertex", jetVertex); + if (!isAvailable) { + ATH_MSG_WARNING("OriginVertex not available !"); + jetVertex = nullptr; + } + } + + return jetVertex; +} + + + +TLorentzVector TauAxisSetter::getVertexCorrectedP4(const xAOD::JetConstituent& constituent, + const Amg::Vector3D& position) const { + TLorentzVector vertexCorrectedP4; + + if (constituent.type() == xAOD::Type::CaloCluster) { + const xAOD::CaloCluster* cluster = static_cast<const xAOD::CaloCluster*>(constituent.rawConstituent()); + vertexCorrectedP4 = xAOD::CaloVertexedTopoCluster(*cluster, position).p4();; + } + else if (constituent.type() == xAOD::Type::ParticleFlow) { + const xAOD::PFO* pfo = static_cast<const xAOD::PFO*>(constituent.rawConstituent()); + vertexCorrectedP4 = getVertexCorrectedP4(*pfo, position); + } + else { + ATH_MSG_WARNING("Seed jet constituent type not supported, will not do vertex correction !"); + vertexCorrectedP4 = tauRecTools::GetConstituentP4(constituent); + } + + return vertexCorrectedP4; +} + + + +TLorentzVector TauAxisSetter::getVertexCorrectedP4(const xAOD::PFO& pfo, + const Amg::Vector3D& position) const { + TLorentzVector vertexCorrectedP4; + + // Only perfrom vertex corretion for neutral PFO + if (!pfo.isCharged()) { + // Convert the type to TVector3 for PFO + TVector3 pos(position.x(), position.y(), position.z()); + + // If there is a vertex correction in jet reconstruction, then pfo.p4() is the four momentum + // at EM scale. Otherwise, pfo.p4() is at LC scale (not clear), and pfo.p4EM() is the four + // momentum at EM scale. + // TODO: May need further modifications, depending on how the jet reconstruction fix ATLJETMET-1280 + // The strategy only works for PFlow at EM scale. + if (m_doJetVertexCorrection && !inTrigger()) { + vertexCorrectedP4 = pfo.GetVertexCorrectedFourVec(pos); + } + else { + vertexCorrectedP4 = pfo.GetVertexCorrectedEMFourVec(pos); + } + } + else { + vertexCorrectedP4 = pfo.p4(); + } + + ATH_MSG_DEBUG("Original pfo four momentum, pt: " << pfo.pt() << + " eta: " << pfo.eta() << " phi: " << pfo.phi() << " e: " << pfo.e()); + ATH_MSG_DEBUG("Vertex corrected four momentum, pt: " << vertexCorrectedP4.Pt() << + " eta: " << vertexCorrectedP4.Eta() << " phi: " << vertexCorrectedP4.Phi() << " e: " << vertexCorrectedP4.E()); + + return vertexCorrectedP4; +} + #endif diff --git a/Reconstruction/tauRecTools/src/TauAxisSetter.h b/Reconstruction/tauRecTools/src/TauAxisSetter.h index b62c2478aa5390f89915176d86532265990bf7d7..3205430370c043c326b2ffdd419304d48afc50ad 100644 --- a/Reconstruction/tauRecTools/src/TauAxisSetter.h +++ b/Reconstruction/tauRecTools/src/TauAxisSetter.h @@ -6,7 +6,6 @@ #define TAUREC_TAUAXISSETTER_H #include "tauRecTools/TauRecToolBase.h" -#include "tauRecTools/ITauVertexCorrection.h" #include "AsgTools/ToolHandle.h" @@ -33,22 +32,27 @@ class TauAxisSetter : public TauRecToolBase { TauAxisSetter(const std::string& name); /** @brief Destructor */ - ~TauAxisSetter(); + virtual ~TauAxisSetter() = default; - /** @brief Initialization of this tool */ - virtual StatusCode initialize() override; - /** @brief Execution of this tool */ - virtual StatusCode execute(xAOD::TauJet& pTau) const override; + virtual StatusCode execute(xAOD::TauJet& tau) const override; private: + + /** Get the jet vertex */ + const xAOD::Vertex* getJetVertex(const xAOD::Jet& jet) const; + + /**@brief Get the vertex corrected four momentum */ + TLorentzVector getVertexCorrectedP4(const xAOD::JetConstituent& constituent, + const Amg::Vector3D& position) const; + + /**@brief Get the vertex corrected four momentum */ + TLorentzVector getVertexCorrectedP4(const xAOD::PFO& pfo, + const Amg::Vector3D& position) const; Gaudi::Property<double> m_clusterCone {this, "ClusterCone", 0.2, "cone of tau candidate"}; Gaudi::Property<bool> m_doVertexCorrection {this, "VertexCorrection", true, "switch of tau vertex correction"}; - Gaudi::Property<bool> m_useSubtractedCluster {this, "UseSubtractedCluster", true, "use shower subtracted clusters in calo calculations"}; - - ToolHandle<ITauVertexCorrection> m_tauVertexCorrection { this, - "TauVertexCorrection", "TauVertexCorrection", "Tool to perform the vertex correction"}; + Gaudi::Property<bool> m_doJetVertexCorrection {this, "JetVertexCorrection", true, "switch of jet vertex correction"}; }; #endif diff --git a/Trigger/TrigAlgorithms/TrigTauRec/python/TrigTauAlgorithmsHolder.py b/Trigger/TrigAlgorithms/TrigTauRec/python/TrigTauAlgorithmsHolder.py index b695a47bdc19c8834167160fcaf9142baa4e4ec0..6b7a3da19b9c4b62eb80d163a26b29d5ca066720 100644 --- a/Trigger/TrigAlgorithms/TrigTauRec/python/TrigTauAlgorithmsHolder.py +++ b/Trigger/TrigAlgorithms/TrigTauRec/python/TrigTauAlgorithmsHolder.py @@ -101,7 +101,7 @@ def getTauAxis(): TauAxisSetter = TauAxisSetter( name = _name, ClusterCone = 0.2, VertexCorrection = doVertexCorrection, - TauVertexCorrection = getTauVertexCorrection() + JetVertexCorrection = False ) # No Axis correction at trigger level