ATLAS Offline Software
Loading...
Searching...
No Matches
SecVertexMergingTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4//Author: Lianyou Shan <lianyou.shan@cern.ch>
5
11#include <cmath>
12#include <vector>
13
14namespace Trk{
15
16 //constructor
17 SecVertexMergingTool::SecVertexMergingTool ( const std::string& t, const std::string& n, const IInterface* p )
18 : AthAlgTool ( t,n,p ),
20 m_minDist(3),
21 m_iVertexFitter("Trk::AdaptiveVertexFitter", this )
22 {
23 declareInterface<IVertexMergingTool> ( this );
24 declareProperty("VertexFitterTool", m_iVertexFitter);
25 declareProperty("CompatibilityDimension", m_Compatidime, "0 for z0, 1 for d0, 2 for all" ) ;
26 declareProperty("MininumDistance", m_minDist, "in sigma" ) ;
27 }
28
29 //destructor
31
32//initialize
34 {
35
36 if ( m_iVertexFitter.retrieve().isFailure() ) {
37 ATH_MSG_ERROR("Failed to retrieve tool " << m_iVertexFitter);
38 return StatusCode::FAILURE;
39 }
40
41 ATH_MSG_DEBUG("Re-merging tool initialization successful");
42 return StatusCode::SUCCESS;
43 }
44
46 {
47 return StatusCode::SUCCESS;
48 }
49
50 std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
52 const EventContext& ctx,
53 const xAOD::VertexContainer& MyVxCont) const
54
55 {
56
57 ATH_MSG_DEBUG("Run vertex remerging");
58
59 // new output containers to be filled
60 xAOD::VertexContainer* NewContainer = new xAOD::VertexContainer();
62 NewContainer->setStore(auxNewContainer);
63
64 static const SG::Decorator<float> mDecor_sumPt2("sumPt2");
65 static const SG::Decorator<float> mDecor_mass("mass");
66 static const SG::Decorator<float> mDecor_energy("ee");
67 static const SG::Decorator<int> mDecor_nrobbed("nrobbed");
68 static const SG::Decorator<int> mDecor_intrk("NumInputTrk");
69
70 static const SG::Accessor<float> mAcc_sumPt2("sumPt2");
71 static const SG::Accessor<int> mAcc_momdir ("MomentaDirection");
72 static const SG::Accessor<float> mAcc_mass("mass");
73 static const SG::Accessor<float> mAcc_energy("ee");
74 static const SG::Accessor<int> mAcc_intrk("NumInputTrk");
75 static const SG::Accessor<float> mAcc_radpat("radiiPattern");
76 static const SG::Accessor<std::vector<float> > mAcc_trkwt("trkWeight");
77 static const SG::Accessor<int> mAcc_numtav("NumTrkAtVtx");
78 static const SG::Accessor<std::vector<float> > mAcc_trkdoe("trkDistOverError");
79
80 bool moreDeco = mAcc_momdir.isAvailable(*MyVxCont.front());
81
82 if (!moreDeco)
83 ATH_MSG_DEBUG("Missing decoration !!! ");
84
92
93 // add remerged flags to all
94 std::vector<bool> remerged(MyVxCont.size(), false);
95
96 xAOD::VertexContainer::const_iterator beginIter = MyVxCont.begin();
97 xAOD::VertexContainer::const_iterator endIter = MyVxCont.end();
98 unsigned int Ni = 0;
99 for (xAOD::VertexContainer::const_iterator i = beginIter; i != endIter;
100 ++i, Ni++) {
101 auto vx = std::make_unique<xAOD::Vertex>(**i);
102
103 if (remerged[Ni])
104 continue; // skip vertices already merged into another
105
106 std::vector<const xAOD::TrackParticle*> combinedTracks;
107 std::vector<ElementLink<xAOD::TrackParticleContainer>> tpLinks1 =
108 vx->trackParticleLinks();
109 if (!tpLinks1.empty()) {
110 for (const auto& tp_EL : tpLinks1) {
111 const xAOD::TrackParticle* trk = *tp_EL;
112 combinedTracks.push_back(trk);
113 }
114
115 unsigned int Nj = Ni + 1;
116 bool newmerge = false;
117 for (xAOD::VertexContainer::const_iterator j = i + 1; j != endIter;
118 ++j, Nj++) {
119 const xAOD::Vertex* mergeCand = (*j);
120 if (remerged[Nj])
121 continue;
122
123 if (newmerge) {
124 combinedTracks.clear();
125 tpLinks1 = vx->trackParticleLinks();
126 if (tpLinks1.empty())
127 break;
128 for (const auto& tp_EL : tpLinks1) {
129 const xAOD::TrackParticle* trk = *tp_EL;
130 combinedTracks.push_back(trk);
131 }
132 newmerge = false;
133 }
134
135 // not dummy and not already merged into earlier vertex, so consider
136 // it as merging candidate
137 if (!checkCompatibility(vx.get(), mergeCand))
138 continue;
139
140 ATH_MSG_DEBUG("To merge vertices " << Ni << " and " << Nj);
141 // get all the track particles to fit
142
143 const std::vector<ElementLink<xAOD::TrackParticleContainer>>
144 tpLinks2 = mergeCand->trackParticleLinks();
145 if (tpLinks2.empty())
146 continue;
147
148 for (const auto& tp_EL : tpLinks2) {
149 const xAOD::TrackParticle* trk = *tp_EL;
150 combinedTracks.push_back(trk);
151 }
152
153 ATH_MSG_DEBUG("Tracks input : " << tpLinks1.size() << " + "
154 << tpLinks2.size());
155
156 // call the fitter -> using xAOD::TrackParticle it should set the
157 // track links for us
158 // no interface for no constraint and no starting point, so use
159 // starting point of original vertex
160 Amg::Vector3D start(0.5 * (vx->position() + mergeCand->position()));
161 std::unique_ptr<xAOD::Vertex> mergedVtx = m_iVertexFitter->fit(ctx, combinedTracks, start);
162
163 ATH_MSG_DEBUG("Merged vertices " << mergedVtx->nTrackParticles());
164
165 remerged[Nj] = true;
166 remerged[Ni] = true;
167 newmerge = true;
168
169 // update the decors
170 float pt1 = sqrt(mAcc_sumPt2(*vx));
171 float pt2 = sqrt(mAcc_sumPt2(*mergeCand));
172 float ntrk1 = 1.0 * ((vx->trackParticleLinks()).size());
173 float ntrk2 = 1.0 * ((mergeCand->trackParticleLinks()).size());
174 float wght1 =
175 0.6 * pt1 / (pt1 + pt2) + 0.4 * ntrk1 / (ntrk1 + ntrk2);
176 float wght2 =
177 0.6 * pt2 / (pt1 + pt2) + 0.4 * ntrk2 / (ntrk1 + ntrk2);
178
179 xAOD::VxType::VertexType typ1 = vx->vertexType();
180 xAOD::VxType::VertexType typ2 = mergeCand->vertexType();
181 float mas1 = mAcc_mass(*vx);
182 float mas2 = mAcc_mass(*mergeCand);
183 float e1 = mAcc_energy(*vx);
184 float e2 = mAcc_energy(*mergeCand);
185 int inNtrk1 = mAcc_intrk(*vx);
186 int inNtrk2 = mAcc_intrk(*mergeCand);
187
188 int ntrks = 0;
189 float md1 = 0., md2 = 0., hf1 = 0., hf2 = 0.;
190 std::vector<float> trkW1, trkW2, doe1, doe2;
191 if (moreDeco) {
192 doe1 = mAcc_trkdoe(*vx);
193 doe2 = mAcc_trkdoe(*mergeCand);
194 doe2.insert(doe2.end(), doe1.begin(), doe1.end());
195 md1 = mAcc_momdir(*vx);
196 md2 = mAcc_momdir(*mergeCand);
197 hf1 = mAcc_radpat(*vx);
198 hf2 = mAcc_radpat(*mergeCand);
199 trkW1 = mAcc_trkwt(*vx);
200 trkW2 = mAcc_trkwt(*mergeCand);
201 trkW2.insert(trkW2.end(), trkW1.begin(), trkW1.end());
202 ntrks = mAcc_numtav(*vx) + mAcc_numtav(*mergeCand);
203 }
204
205 // overwrite with merged vertex
206 vx = std::move(mergedVtx);
207
208 if (wght1 >= wght2)
209 vx->setVertexType(typ1);
210 else
211 vx->setVertexType(typ2);
212
213 if (moreDeco) {
214 mAcc_trkdoe(*vx) = doe2;
215 mAcc_momdir(*vx) = wght1 * md1 + wght2 * md2;
216 mAcc_radpat(*vx) = wght1 * hf1 + wght2 * hf2;
217 mAcc_trkwt(*vx) = trkW2;
218 mAcc_numtav(*vx) = ntrks;
219 }
220
221 mDecor_sumPt2(*vx) = pt1 * pt1 + pt2 * pt2;
222 mDecor_mass(*vx) = wght1 * mas1 + wght2 * mas2;
223 mDecor_energy(*vx) = wght1 * e1 + wght2 * e2;
224 mDecor_nrobbed(*vx) = 0;
225 mDecor_intrk(*vx) = (int)(wght1 * inNtrk1 + wght1 * inNtrk2);
226
227 } // loop over j
228 } // if vx found partner in compatibility
229
230 // whether we merged or not, can add vx to the container
231 if (vx != nullptr){
232 ATH_MSG_DEBUG("Merged sumPt2 " << mAcc_sumPt2(*vx));
233 NewContainer->push_back(std::move(vx));
234 }
235 }
236
237 return std::make_pair(NewContainer, auxNewContainer);
238
239 }
240
241 bool
243 const xAOD::Vertex* v2) const
244 {
245
246 float sigma = 100 ;
247
248 Amg::Vector3D vdif = v1->position() - v2->position() ;
249 AmgSymMatrix(3) vErrs = v1->covariancePosition() + v2->covariancePosition() ;
250 vErrs = vErrs.inverse().eval();
251
252 if ( m_Compatidime == 2 ) // 3 dimension
253 {
254 sigma = sqrt( vdif.dot( vErrs * vdif ) ) ;
255 } else if ( m_Compatidime == 1 ) // d0
256 {
257 sigma = vdif(0)*vdif(0)*vErrs(0,0) + vdif(1)*vdif(1)*vErrs(1,1) + 2*vdif(0)*vdif(1)*vErrs(0,1) ;
258 sigma = std::sqrt( sigma ) ;
259
260 } else { // z0
261
262 sigma = vdif(2)*sqrt( vErrs(2,2) );
263 }
264
265// ATH_MSG_DEBUG(" Compatibility/significance when merging vertices : " << sigma );
266 ATH_MSG_DEBUG(" Compatibility/significance when merging vertices : " << sigma );
267
268 return sigma < m_minDist;
269
270 }
271
272}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
Helper class to provide type-safe access to aux data.
Helper class to provide type-safe access to aux data.
#define AmgSymMatrix(dim)
size_t size() const
Number of registered mappings.
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
value_type push_back(value_type pElem)
Add an element to the end of the collection.
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
const T * front() const
Access the first element in the collection as an rvalue.
size_type size() const noexcept
Returns the number of elements in the collection.
Helper class to provide type-safe access to aux data.
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
SecVertexMergingTool(const std::string &t, const std::string &n, const IInterface *p)
constructor
virtual StatusCode initialize() override
bool checkCompatibility(const xAOD::Vertex *vx1, const xAOD::Vertex *vx2) const
virtual std::pair< xAOD::VertexContainer *, xAOD::VertexAuxContainer * > mergeVertexContainer(const EventContext &ctx, const xAOD::VertexContainer &MyVxCont) const override
Merging.
ToolHandle< Trk::IVertexFitter > m_iVertexFitter
virtual StatusCode finalize() override
EndOfInitialize.
virtual ~SecVertexMergingTool()
destructor
const TrackParticleLinks_t & trackParticleLinks() const
Get all the particles associated with the vertex.
VxType::VertexType vertexType() const
The type of the vertex.
const Amg::Vector3D & position() const
Returns the 3-pos.
Eigen::Matrix< double, 3, 1 > Vector3D
SG::Decorator< T, ALLOC > Decorator
Helper class to provide type-safe access to aux data, specialized for JaggedVecElt.
Definition AuxElement.h:576
Ensure that the ATLAS eigen extensions are properly loaded.
VertexType
Vertex types.
VertexAuxContainer_v1 VertexAuxContainer
Definition of the current jet auxiliary container.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Vertex_v1 Vertex
Define the latest version of the vertex class.