ATLAS Offline Software
Loading...
Searching...
No Matches
NewVrtSecInclusiveAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4
6 // NewVrtSecInclusiveAlg.cxx, (c) ATLAS Detector software
7 // Author: Vadim Kostyukhin (vadim.kostyukhin@cern.ch)
14
15#include "TLorentzVector.h"
16#include "CxxUtils/sincos.h"
17
18namespace Rec {
19
22 static const SG::AuxElement::Decorator<float> bvrtPhi("bvrtPhi");
23 static const SG::AuxElement::Decorator<float> bvrtEta("bvrtEta");
26 static const SG::AuxElement::Decorator<float> mindRBTagSV("mindRBTagSV");
27
28 NewVrtSecInclusiveAlg::NewVrtSecInclusiveAlg(const std::string& name, ISvcLocator* pSvcLocator) :
29 AthReentrantAlgorithm( name, pSvcLocator )
30 {
31 }
32
34 {
35 ATH_CHECK( m_tpContainerKey.initialize() );
36 ATH_CHECK( m_gsfContainerKey.initialize() );
37 ATH_CHECK( m_muonContainerKey.initialize() );
38 ATH_CHECK( m_electronContainerKey.initialize() );
39 ATH_CHECK( m_pvContainerKey.initialize() );
40 ATH_CHECK( m_jetContainerKey.initialize() );
41 ATH_CHECK( m_btsvContainerKey.initialize() );
42 ATH_CHECK( m_foundVerticesKey.initialize() );
43 ATH_CHECK( m_bvertextool.retrieve() );
44 return StatusCode::SUCCESS;
45 }
46
48 {
49 return StatusCode::SUCCESS;
50 }
51
52 StatusCode NewVrtSecInclusiveAlg::execute(const EventContext &ctx) const
53 {
54
55 const xAOD::Vertex* pv = nullptr;
56 std::unordered_set<const xAOD::TrackParticle*> tp_set{};
57 if (m_addIDTracks) addInDetTracks(ctx, tp_set);
58 if (m_addMuonTracks) addMuonTracks(ctx, tp_set);
59 if (m_addGSFTracks) addGSFTracks(ctx, tp_set);
60 if (m_addElectronTracks) addElectronTracks(ctx, tp_set);
61 ATH_MSG_DEBUG("Found " << tp_set.size() << " useful tracks in this event" );
62
63 std::vector<const xAOD::TrackParticle*> trkparticles(tp_set.begin(), tp_set.end());
64
65 //-- Extract Primary Vertex
67 if ( !pv_cont.isValid() ) {
68 ATH_MSG_WARNING( "No Primary Vertices container found in TDS" );
69 }else{
70 //-- Extract PV itself
71 for ( const auto *v : *pv_cont ) {
72 if (v->vertexType()==xAOD::VxType::PriVtx) { pv = v; break; }
73 }
74 }
75
76 //-- Extract SV from b-jets Vertices
78 if ( !btsv_cont.isValid() ) {
79 ATH_MSG_WARNING( "No BTagging Vertices container found in TDS" );
80 }
81
82 //-- Extract Jets
84 if ( !jet_cont.isValid() ) {
85 ATH_MSG_WARNING( "No AntiKt4EMPFlowJet container found in TES" );
86 }
87
88 //-- create container for new vertices
89 auto bVertexContainer = std::make_unique<xAOD::VertexContainer>();
90 auto bVertexAuxContainer = std::make_unique<xAOD::VertexAuxContainer>();
91 bVertexContainer->setStore(bVertexAuxContainer.get());
92
93 if( pv && trkparticles.size()>1 ){
94 std::unique_ptr<Trk::VxSecVertexInfo> foundVrts = m_bvertextool->findAllVertices(trkparticles,*pv);
95 if(foundVrts && !foundVrts->vertices().empty()){
96 const std::vector<xAOD::Vertex*> vtmp=foundVrts->vertices();
97 double mindRSVPV=1.e3; // Check coincidence with existing SV1 vertex
98 for(const auto & iv : vtmp) {
99 if( btsv_cont.isValid() ){
100 for ( const auto *btsv : *btsv_cont ) mindRSVPV=std::min(Amg::deltaR(btsv->position()-pv->position(),iv->position()-pv->position()),mindRSVPV);
101 }
102 if (m_removeNonLepVerts && vertexHasNoLep(ctx, iv)) {
103 delete iv;
104 continue;
105 }
106 bVertexContainer->push_back(iv);
107 std::vector< Trk::VxTrackAtVertex > & vtrk = iv->vxTrackAtVertex();
108 TLorentzVector VSUM(0.,0.,0.,0.);
109 TLorentzVector tmp;
110 for(auto & it : vtrk){
111 const Trk::Perigee* mPer = dynamic_cast<const Trk::Perigee*>(it.perigeeAtVertex());
112 CxxUtils::sincos phi(mPer->parameters()[Trk::phi]);
113 CxxUtils::sincos theta(mPer->parameters()[Trk::theta]);
114 double absP = 1./std::abs(mPer->parameters()[Trk::qOverP]);
115 tmp.SetXYZM( phi.cs*theta.sn*absP, phi.sn*theta.sn*absP, theta.cs*absP, Trk::ParticleMasses::mass[Trk::pion]);
116 VSUM+=tmp;
117 }
118 bvrtM(*iv) =VSUM.M();
119 bvrtPt(*iv) =VSUM.Pt();
120 bvrtEta(*iv)=VSUM.Eta();
121 bvrtPhi(*iv)=VSUM.Phi();
122 TVector3 SVmPV(iv->x()-pv->x(),iv->y()-pv->y(),iv->z()-pv->z());
123 double mindRMOM=1.e3, mindRSV=1.e3;
124 if( jet_cont.isValid() ){
125 for(const auto *jet : (*jet_cont)) {
126 mindRMOM=std::min(VSUM.DeltaR(jet->p4()),mindRMOM);
127 mindRSV =std::min(SVmPV.DeltaR(jet->p4().Vect()),mindRSV);
128 }
129 }
130 mindRBTagSV(*iv) =mindRSVPV;
131 mindRjetP(*iv) =mindRMOM;
132 mindRjetV(*iv) =mindRSV;
133 }
134 }
135 }
136 ATH_MSG_DEBUG("Found Vertices in this event: " << bVertexContainer->size());
137 //
138 //--Update track ElementLinks
139 for(auto iv : (*bVertexContainer)){
140 std::vector< ElementLink< xAOD::TrackParticleContainer > > newLinkVec;
141 for(auto &it : iv->trackParticleLinks()){
143 const xAOD::TrackParticleContainer* tp_cont = dynamic_cast<const xAOD:: TrackParticleContainer*>((*it)->container());
144 tmpLnk.setStorableObject(*tp_cont);
145 newLinkVec.push_back(tmpLnk);
146 }
147 iv->setTrackParticleLinks(newLinkVec);
148 }
149
151 ATH_CHECK( vrtInThisEvent.record (std::move(bVertexContainer),
152 std::move(bVertexAuxContainer)) );
153 return StatusCode::SUCCESS;
154 }
155
156 void NewVrtSecInclusiveAlg::addInDetTracks(const EventContext &ctx, std::unordered_set<const xAOD::TrackParticle*> &trkparticles) const {
157 //-- Extract IDTrackParticles
159 if ( !tp_cont.isValid() ) {
160 ATH_MSG_WARNING( "No TrackParticle container found in TES" );
161 return;
162 }
163 trkparticles.reserve(trkparticles.size() + tp_cont->size());
164
165 for (const auto *tp : (*tp_cont)) { trkparticles.insert(tp); }
166 }
167
168 void NewVrtSecInclusiveAlg::addMuonTracks(const EventContext &ctx, std::unordered_set<const xAOD::TrackParticle*> &trkparticles) const {
169 //-- Extract Muons
171 if ( !muon_cont.isValid() ) {
172 ATH_MSG_WARNING( "No muon container found in TES" );
173 return;
174 }
175 trkparticles.reserve(trkparticles.size() + muon_cont->size());
176
177 for (const auto *muon : (*muon_cont)) {
178 const auto *tp = muon->trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
179 if (!tp) { continue; }
180 trkparticles.insert(tp);
181 }
182 }
183
184 void NewVrtSecInclusiveAlg::addGSFTracks(const EventContext &ctx, std::unordered_set<const xAOD::TrackParticle*> &trkparticles) const {
185 //-- Extract GSFTrackParticles
187 if ( !gsf_cont.isValid() ) {
188 ATH_MSG_WARNING( "No GSF container found in TES" );
189 return;
190 }
191 trkparticles.reserve(trkparticles.size() + gsf_cont->size());
192
193 for (const auto *gsf : (*gsf_cont)) {
194 trkparticles.insert(gsf);
195 // remove the corresponding ID track from the list if it exists already.
197 }
198 }
199
200 void NewVrtSecInclusiveAlg::addElectronTracks(const EventContext &ctx, std::unordered_set<const xAOD::TrackParticle*> &trkparticles) const {
201 //-- Extract Electrons
203 if ( !electron_cont.isValid() ) {
204 ATH_MSG_WARNING( "No electron container found in TES" );
205 return;
206 }
207 trkparticles.reserve(trkparticles.size() + electron_cont->size());
208
209 for(const auto *electron : (*electron_cont)) {
210 if( 0 == electron->nTrackParticles() ) continue;
211 // the 0th GSF TP is the best matched one.
212 const auto *gsf = electron->trackParticle(0);
213 if (!gsf) continue;
214 trkparticles.insert(gsf);
215 // remove the corresponding ID track from the list if it exists already.
217 }
218 }
219
220 bool NewVrtSecInclusiveAlg::vertexHasNoLep(const EventContext &ctx, const xAOD::Vertex* vertex) const {
221 std::unordered_set<const xAOD::TrackParticle*> trkparts{};
222 trkparts.reserve(vertex->nTrackParticles());
223 for (const auto &trk : vertex->trackParticleLinks()) {
224 trkparts.insert(*trk);
225 }
226
227 //-- Extract Muons
229 if ( muon_cont.isValid() ) {
230 for (const auto *muon : (*muon_cont)) {
231 const auto *tp = muon->trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
232 if (!tp) { continue; }
233 if(trkparts.count(tp)) return false;
234 }
235 }
236
237 //-- Extract Electrons
239 if ( electron_cont.isValid() ) {
240 for(const auto *electron : (*electron_cont)) {
241 if( 0 == electron->nTrackParticles() ) continue;
242 // the 0th GSF TP is the best matched one.
243 const auto *gsf = electron->trackParticle(0);
244 if (!gsf) continue;
245 if(trkparts.count(gsf)) return false;
246 if(trkparts.count(xAOD::EgammaHelpers::getOriginalTrackParticleFromGSF(gsf))) return false;
247 }
248 }
249 // If both containers are missing, or no leptons are found in the vertex, return true.
250 return true;
251 }
252}
253
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
An algorithm that can be simultaneously executed in multiple threads.
Gaudi::Property< bool > m_addElectronTracks
Gaudi::Property< bool > m_addGSFTracks
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_tpContainerKey
ToolHandle< Rec::IVrtInclusive > m_bvertextool
SG::ReadHandleKey< xAOD::ElectronContainer > m_electronContainerKey
bool vertexHasNoLep(const EventContext &, const xAOD::Vertex *) const
SG::ReadHandleKey< xAOD::JetContainer > m_jetContainerKey
void addGSFTracks(const EventContext &, std::unordered_set< const xAOD::TrackParticle * > &) const
Gaudi::Property< bool > m_removeNonLepVerts
Gaudi::Property< bool > m_addIDTracks
NewVrtSecInclusiveAlg(const std::string &name, ISvcLocator *pSvcLocator)
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_gsfContainerKey
SG::ReadHandleKey< xAOD::VertexContainer > m_pvContainerKey
void addElectronTracks(const EventContext &, std::unordered_set< const xAOD::TrackParticle * > &) const
void addMuonTracks(const EventContext &, std::unordered_set< const xAOD::TrackParticle * > &) const
void addInDetTracks(const EventContext &, std::unordered_set< const xAOD::TrackParticle * > &) const
SG::WriteHandleKey< xAOD::VertexContainer > m_foundVerticesKey
StatusCode execute(const EventContext &ctx) const override
Gaudi::Property< bool > m_addMuonTracks
SG::ReadHandleKey< xAOD::MuonContainer > m_muonContainerKey
SG::ReadHandleKey< xAOD::VertexContainer > m_btsvContainerKey
SG::Decorator< T, ALLOC > Decorator
Definition AuxElement.h:575
virtual bool isValid() override final
Can the handle be successfully dereferenced?
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
double deltaR(const Amg::Vector3D &v1, const Amg::Vector3D &v2)
Gaudi Tools.
static const SG::AuxElement::Decorator< float > bvrtPt("bvrtPt")
static const SG::AuxElement::Decorator< float > mindRBTagSV("mindRBTagSV")
static const SG::AuxElement::Decorator< float > mindRjetV("mindRjetV")
static const SG::AuxElement::Decorator< float > bvrtEta("bvrtEta")
static const SG::AuxElement::Decorator< float > bvrtPhi("bvrtPhi")
static const SG::AuxElement::Decorator< float > bvrtM("bvrtM")
static const SG::AuxElement::Decorator< float > mindRjetP("mindRjetP")
constexpr double mass[PARTICLEHYPOTHESES]
the array of masses
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ theta
Definition ParamDefs.h:66
@ qOverP
perigee
Definition ParamDefs.h:67
@ phi
Definition ParamDefs.h:75
const xAOD::TrackParticle * getOriginalTrackParticleFromGSF(const xAOD::TrackParticle *trkPar)
Helper function for getting the "Original" Track Particle (i.e before GSF) via the GSF Track Particle...
@ PriVtx
Primary vertex.
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
Vertex_v1 Vertex
Define the latest version of the vertex class.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
Helper to simultaneously calculate sin and cos of the same angle.
Helper to simultaneously calculate sin and cos of the same angle.
Definition sincos.h:39