Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
VertexFittingTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
6 // Local
9 
10 // Athena
12 
13 // C/C++
14 #include <cmath>
15 #include <iostream>
16 #include <sstream>
17 
18 using namespace std;
19 
20 //=============================================================================
22  const std::string& t, const std::string &name, const IInterface* p
23 ): AthAlgTool(t, name, p)
24 {
25  declareInterface<Prompt::IVertexFittingTool>(this);
26 }
27 
28 //=============================================================================
30 {
31  ATH_CHECK(m_vertexFitter.retrieve());
32 
33  if(m_doSeedVertexFit) {
34  ATH_CHECK(m_seedVertexFitter.retrieve());
35  }
36 
37  m_distToPriVtx = std::make_unique<SG::AuxElement::Decorator<float> > (m_distToPriVtxName);
38  m_normDistToPriVtx = std::make_unique<SG::AuxElement::Decorator<float> > (m_normDistToPriVtxName);
39  m_distToRefittedPriVtx = std::make_unique<SG::AuxElement::Decorator<float> > (m_distToRefittedPriVtxName);
40  m_normDistToRefittedPriVtx = std::make_unique<SG::AuxElement::Decorator<float> > (m_normDistToRefittedPriVtxName);
41  m_distToRefittedRmLepPriVtx = std::make_unique<SG::AuxElement::Decorator<float> > (m_distToRefittedRmLepPriVtxName);
42  m_normDistToRefittedRmLepPriVtx = std::make_unique<SG::AuxElement::Decorator<float> > (m_normDistToRefittedRmLepPriVtxName);
43 
44  m_timer.Reset();
45 
46  ATH_MSG_DEBUG("VertexFittingSvc::initialize - doSeedVertexFit = " << m_doSeedVertexFit);
47  ATH_MSG_DEBUG("VertexFittingSvc::initialize - vertexFitter = " << m_vertexFitter.name());
48 
49  return StatusCode::SUCCESS;
50 }
51 
52 //=============================================================================
54 {
55  //
56  // Delete pointers
57  //
58  m_timer.Stop();
59 
60  ATH_MSG_INFO("VertexFittingSvc::finalize - number of total fits: " << m_countNumberOfFits);
61  ATH_MSG_INFO("VertexFittingSvc::finalize - number of failed fits: " << m_countNumberOfFitsFailed);
62  ATH_MSG_INFO("VertexFittingSvc::finalize - number of invalid vtxs: " << m_countNumberOfFitsInvalid);
63  ATH_MSG_INFO("VertexFittingSvc::finalize - fitting timer: " << PrintResetStopWatch(m_timer));
64 
65  return StatusCode::SUCCESS;
66 }
67 
68 //=============================================================================
70  const FittingInput &input,
71  const std::vector<const xAOD::TrackParticle* > &tracks,
72  VtxType vtxType
73 )
74 {
75  //
76  // Make new secondary vertex
77  //
78  TimerScopeHelper timer(m_timer);
79  m_countNumberOfFits++;
80 
81  if(!input.priVtx) {
82  ATH_MSG_WARNING("fitVertexWithPrimarySeed -- missing primary vertex");
83  return nullptr;
84  }
85 
86  // Fit a new secondary vertex
87  std::unique_ptr<xAOD::Vertex> secondaryVtx = getSecondaryVertexWithSeed(
88  tracks, input.inDetTracks, input.priVtx->position()
89  );
90 
91  if(!secondaryVtx) {
92  m_countNumberOfFitsFailed++;
93  ATH_MSG_WARNING("fitVertexWithPrimarySeed -- failed to fit vertex");
94  return nullptr;
95  }
96 
97  if(!isValidVertex(secondaryVtx.get())) {
98  m_countNumberOfFitsInvalid++;
99 
100  ATH_MSG_WARNING("fitVertexWithPrimarySeed -- failed to get valid vertex");
101  return nullptr;
102  }
103 
104  m_secondaryVertexIndex++;
105 
106  // Decorate the newly created vertex
107  static const SG::AuxElement::Accessor<int> indexAcc("SecondaryVertexIndex");
108  static const SG::AuxElement::Accessor<int> typeAcc("SVType");
109 
110  indexAcc(*secondaryVtx) = m_secondaryVertexIndex;
111  typeAcc(*secondaryVtx) = static_cast<int>(vtxType);
112 
113  decorateNewSecondaryVertex(input, secondaryVtx.get());
114 
115  return secondaryVtx;
116 }
117 
118 //=============================================================================
119 std::unique_ptr<xAOD::Vertex> Prompt::VertexFittingTool::fitVertexWithSeed(
120  const FittingInput &input,
121  const std::vector<const xAOD::TrackParticle* > &tracks,
122  const Amg::Vector3D& seed,
123  VtxType vtxType
124 )
125 {
126  //
127  // Make new secondary vertex
128  //
129  TimerScopeHelper timer(m_timer);
130  m_countNumberOfFits++;
131 
132  std::unique_ptr<xAOD::Vertex> secondaryVtx = getSecondaryVertexWithSeed(
133  tracks, input.inDetTracks, seed
134  );
135 
136  if(!secondaryVtx) {
137  m_countNumberOfFitsFailed++;
138 
139  ATH_MSG_WARNING("fitVertexWithSeed -- failed to fit vertex");
140  return nullptr;
141  }
142 
143  if(!isValidVertex(secondaryVtx.get())) {
144  m_countNumberOfFitsInvalid++;
145 
146  ATH_MSG_WARNING("fitVertexWithSeed -- failed to get valid vertex");
147  return nullptr;
148  }
149 
150  m_secondaryVertexIndex++;
151 
152  // Decorate the newly created vertex
153  static const SG::AuxElement::Accessor<int> indexAcc("SecondaryVertexIndex");
154  static const SG::AuxElement::Accessor<int> typeAcc("SVType");
155 
156  indexAcc(*secondaryVtx) = m_secondaryVertexIndex;
157  typeAcc(*secondaryVtx) = static_cast<int>(vtxType);
158 
159  decorateNewSecondaryVertex(input, secondaryVtx.get());
160 
161  return secondaryVtx;
162 }
163 
164 //=============================================================================
166 {
167  //
168  // Check if vertex is valid
169  //
170  bool bad_vtx = false;
171 
172  if(!vtx){
173  ATH_MSG_WARNING("VertexFittingSvc::Validate_Vertex -- invalid vtx pointer!!!");
174  return false;
175  }
176 
177  if(vtx->covariance().empty()) {
178  bad_vtx = true;
179  ATH_MSG_WARNING("VertexFittingSvc::Validate_Vertex -- empty vtx covariance!!!");
180  }
181 
182  float chisquared = -9999;
183 
184  if(!getVar(vtx, chisquared, "chiSquared")) {
185  bad_vtx = true;
186  ATH_MSG_WARNING("VertexFittingSvc::Validate_Vertex -- not valid vtx chiSquared!!!");
187  }
188 
189  float numberdof = -9999;
190 
191  if(!getVar(vtx, numberdof, "numberDoF")) {
192  bad_vtx = true;
193  ATH_MSG_WARNING("VertexFittingSvc::Validate_Vertex -- not valid vtx numberDoF!!!");
194  }
195 
196  if(std::isnan(vtx->x()) || std::isnan(vtx->y()) || std::isnan(vtx->z())) {
197  bad_vtx = true;
198  ATH_MSG_WARNING("VertexFittingSvc::Validate_Vertex -- vertex coordinate is nan");
199  }
200 
201  if(bad_vtx) {
202  ATH_MSG_WARNING("VertexFittingSvc::Validate_Vertex -- bad vertex!!!");
203  ATH_MSG_INFO(printPromptVertexAsStr(vtx, msg(MSG::WARNING)));
204  }
205 
206  return !bad_vtx;
207 }
208 
209 //=============================================================================
210 void Prompt::VertexFittingTool::removeDoubleEntries(std::vector<const xAOD::TrackParticle*>& tracks)
211 {
212  const unsigned nbefore = tracks.size();
213 
214  sort(tracks.begin(), tracks.end());
215 
216  typename std::vector<const xAOD::TrackParticle*>::iterator TransfEnd = std::unique(tracks.begin(), tracks.end());
217 
218  tracks.erase(TransfEnd, tracks.end());
219 
220  if(nbefore != tracks.size()) {
221  ATH_MSG_DEBUG("removeDoubleEntries nbefore != tracks.size()): " << nbefore << " != " << tracks.size());
222  }
223 }
224 
225 //=============================================================================
227  const FittingInput &input,
228  xAOD::Vertex *secVtx
229 )
230 {
231  //
232  // Decorate secondary vertex with all useful information
233  //
234  if(!secVtx) {
235  ATH_MSG_WARNING("decorateNewSecondaryVertex - invalid pointer");
236  return false;
237  }
238 
239  //
240  // Decorate secondary vertex with the distance/norm_distance it from Prmary Vertex, Refitted Primary vertex and Refitted Primary Vertex that removed lepton itself.
241  //
242  float distToPriVtx = -1;
243  float normDistToPriVtx = -1;
244  float distToRefittedPriVtx = -1;
245  float normDistToRefittedPriVtx = -1;
246  float distToRefittedRmLepPriVtx = -1;
247  float normDistToRefittedRmLepPriVtx = -1;
248 
249  if(input.priVtx) {
250  distToPriVtx = Prompt::getDistance(input.priVtx->position(), secVtx->position());
251  normDistToPriVtx = Prompt::getNormDist(input.priVtx->position(), secVtx->position(), secVtx->covariance(), msg(MSG::WARNING));
252  }
253 
254  if(input.refittedPriVtx) {
255  distToRefittedPriVtx = Prompt::getDistance(input.refittedPriVtx->position(), secVtx->position());
256  normDistToRefittedPriVtx = Prompt::getNormDist(input.refittedPriVtx->position(), secVtx->position(), secVtx->covariance(), msg(MSG::WARNING));
257  }
258 
259  if(input.refittedPriVtxWithoutLep) {
260  distToRefittedRmLepPriVtx = Prompt::getDistance(input.refittedPriVtxWithoutLep->position(), secVtx->position());
261  normDistToRefittedRmLepPriVtx = Prompt::getNormDist(input.refittedPriVtxWithoutLep->position(), secVtx->position(), secVtx->covariance(), msg(MSG::WARNING));
262  }
263 
264  (*m_distToPriVtx) (*secVtx) = distToPriVtx;
265  (*m_normDistToPriVtx) (*secVtx) = normDistToPriVtx;
266  (*m_distToRefittedPriVtx) (*secVtx) = distToRefittedPriVtx;
267  (*m_normDistToRefittedPriVtx) (*secVtx) = normDistToRefittedPriVtx;
268  (*m_distToRefittedRmLepPriVtx) (*secVtx) = distToRefittedRmLepPriVtx;
269  (*m_normDistToRefittedRmLepPriVtx)(*secVtx) = normDistToRefittedRmLepPriVtx;
270 
271  return true;
272 }
273 
274 //=============================================================================
276  const std::vector<const xAOD::TrackParticle*> &tracks,
277  const xAOD::TrackParticleContainer *inDetTracks,
278  const Amg::Vector3D& seed
279 )
280 {
281  //
282  // Fit one vertex with given tracks
283  //
284  std::vector<const xAOD::TrackParticle*> tracksForFit(tracks);
285 
286  ATH_MSG_DEBUG("getSecondaryVertexWithSeed -- before remove " << tracksForFit.size());
287 
288  removeDoubleEntries(tracksForFit);
289 
290  ATH_MSG_DEBUG("getSecondaryVertexWithSeed -- after remove " << tracksForFit.size());
291 
292  if(tracksForFit.size() < 2) {
293  ATH_MSG_WARNING("getSecondaryVertexWithSeed -- cannot fit vertex with one or zero input track: ntrack=" << tracksForFit.size());
294  return 0;
295  }
296 
297  //
298  // Run fit
299  //
300  ATH_MSG_DEBUG(name() << "::getSecondaryVertexWithSeed -- N tracks = " << tracksForFit.size());
301 
302  for(const xAOD::TrackParticle* track: tracksForFit) {
303  ATH_MSG_DEBUG( name() << "::getSecondaryVertexWithSeed -- track pt, eta = " << track->pt() << "," << track->eta());
304  ATH_MSG_DEBUG( name() << "::getSecondaryVertexWithSeed -- track chi2 = " << track->chiSquared());
305  }
306 
307  xAOD::Vertex *newVertex = 0;
308  std::unique_ptr<xAOD::Vertex> seedVertex;
309 
310  if(m_doSeedVertexFit) {
311  seedVertex = std::unique_ptr<xAOD::Vertex>(m_seedVertexFitter->fit(tracksForFit, seed));
312 
313  if(seedVertex.get() && !isValidVertex(seedVertex.get())) {
314  ATH_MSG_DEBUG("getSecondaryVertexWithSeed -- failed to fit seed vertex");
315 
316  seedVertex.reset();
317  }
318  }
319 
320  if(seedVertex.get()) {
321  newVertex = m_vertexFitter->fit(tracksForFit, seedVertex->position());
322  }
323  else {
324  newVertex = m_vertexFitter->fit(tracksForFit, seed);
325  }
326 
327  if(!newVertex) {
328  ATH_MSG_INFO("getSecondaryVertexWithSeed -- failed to fit vertex and fitter returned null xAOD::Vertex pointer");
329  return 0;
330  }
331 
332  //
333  // Save vertex tracks
334  //
335  std::vector<ElementLink< xAOD::TrackParticleContainer> > tpLinks;
336 
337  if(inDetTracks) {
338  //
339  // Record links to ID tracks if container pointer is provided
340  //
341  for(const xAOD::TrackParticle *selectedtrack: tracksForFit) {
343 
344  tpLink.toContainedElement(*inDetTracks, selectedtrack);
345  tpLinks.push_back(tpLink);
346  }
347  }
348 
349  newVertex->setTrackParticleLinks(tpLinks);
350 
351  TLorentzVector Momentum;
352 
353  for(const xAOD::TrackParticle* track: tracksForFit) {
354  Momentum += static_cast<TLorentzVector>(track->p4());
355  }
356 
357  xAOD::SecVtxHelper::setVertexMass(newVertex, Momentum.M()); // "mass"
358 
359  // newVertex was returned from the vertex fitter as a raw pointer
360  // It looks like Trk::IVertexFitter::fit function expects
361  // memory management to be done by the caller.
362  // Therefore, we take ownership by casting to a unique_ptr
363 
364  std::unique_ptr<xAOD::Vertex> returnPtr(newVertex);
365 
366  return returnPtr;
367 }
368 
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
xAOD::Vertex_v1::x
float x() const
Returns the x position.
PromptUtils.h
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:68
Prompt::getVar
bool getVar(T1 &obj, T2 &value, const std::string &var_name)
Definition: PromptUtils.h:72
VertexFittingTool.h
Prompt::VertexFittingTool::getSecondaryVertexWithSeed
std::unique_ptr< xAOD::Vertex > getSecondaryVertexWithSeed(const std::vector< const xAOD::TrackParticle * > &tracks, const xAOD::TrackParticleContainer *inDetTracks, const Amg::Vector3D &seed)
Definition: VertexFittingTool.cxx:275
xAOD::Vertex_v1::position
const Amg::Vector3D & position() const
Returns the 3-pos.
Prompt::VertexFittingTool::finalize
virtual StatusCode finalize() override
Definition: VertexFittingTool.cxx:53
SecVtxHelper.h
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
Prompt::FittingInput
Definition: IVertexFittingTool.h:60
Prompt::PrintResetStopWatch
std::string PrintResetStopWatch(TStopwatch &watch)
Definition: PromptUtils.cxx:244
Prompt::VertexFittingTool::fitVertexWithSeed
virtual std::unique_ptr< xAOD::Vertex > fitVertexWithSeed(const FittingInput &input, const std::vector< const xAOD::TrackParticle * > &tracks, const Amg::Vector3D &seed, VtxType vtxType) override
Definition: VertexFittingTool.cxx:119
std::sort
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
Definition: DVL_algorithms.h:554
python.utils.AtlRunQueryTimer.timer
def timer(name, disabled=False)
Definition: AtlRunQueryTimer.py:86
Prompt::getNormDist
double getNormDist(const Amg::Vector3D &PrimVtx, const Amg::Vector3D &SecVtx, const std::vector< float > &ErrorMatrix, MsgStream &msg)
Definition: PromptUtils.cxx:57
Prompt::VertexFittingTool::fitVertexWithPrimarySeed
virtual std::unique_ptr< xAOD::Vertex > fitVertexWithPrimarySeed(const FittingInput &input, const std::vector< const xAOD::TrackParticle * > &tracks, VtxType vtx) override
Definition: VertexFittingTool.cxx:69
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
Prompt::getDistance
double getDistance(const xAOD::Vertex *vtx1, const xAOD::Vertex *vtx2)
Definition: PromptUtils.cxx:41
Prompt::VertexFittingTool::VertexFittingTool
VertexFittingTool(const std::string &t, const std::string &name, const IInterface *p)
Definition: VertexFittingTool.cxx:21
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
std::unique
std::reverse_iterator< DataModel_detail::iterator< DVL > > unique(typename std::reverse_iterator< DataModel_detail::iterator< DVL > > beg, typename std::reverse_iterator< DataModel_detail::iterator< DVL > > end, BinaryPredicate pred)
Specialization of unique for DataVector/List.
Definition: DVL_algorithms.h:199
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Prompt::printPromptVertexAsStr
std::string printPromptVertexAsStr(const xAOD::Vertex *vtx, MsgStream &msg)
Definition: PromptUtils.cxx:127
xAOD::Vertex_v1::setTrackParticleLinks
void setTrackParticleLinks(const TrackParticleLinks_t &trackParticles)
Set all track particle links at once.
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Prompt::VertexFittingTool::isValidVertex
virtual bool isValidVertex(const xAOD::Vertex *vtx) const override
Definition: VertexFittingTool.cxx:165
xAOD::Vertex_v1::z
float z() const
Returns the z position.
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
Prompt::VertexFittingTool::initialize
virtual StatusCode initialize() override
Definition: VertexFittingTool.cxx:29
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Prompt::VertexFittingTool::decorateNewSecondaryVertex
bool decorateNewSecondaryVertex(const FittingInput &input, xAOD::Vertex *secVtx)
Definition: VertexFittingTool.cxx:226
Prompt::VtxType
VtxType
Definition: IVertexFittingTool.h:48
xAOD::Vertex_v1::covariance
const std::vector< float > & covariance() const
Returns the covariance matrix as a simple vector of values.
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
Prompt::VertexFittingTool::removeDoubleEntries
void removeDoubleEntries(std::vector< const xAOD::TrackParticle * > &tracks)
Definition: VertexFittingTool.cxx:210
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
xAOD::Vertex_v1::y
float y() const
Returns the y position.
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
AthAlgTool
Definition: AthAlgTool.h:26
Prompt::TimerScopeHelper
Definition: PromptUtils.h:112
xAOD::SecVtxHelper::setVertexMass
void setVertexMass(xAOD::Vertex *, float value)
Definition: SecVtxHelper.cxx:18
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7