ATLAS Offline Software
Loading...
Searching...
No Matches
PrimaryVertexReFitter.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// Local
8
9// Athena
11#include "xAODMuon/Muon.h"
12#include "xAODEgamma/Electron.h"
16#include "GaudiKernel/ThreadLocalContext.h"
17
18namespace Prompt {
19//======================================================================================================
20PrimaryVertexReFitter::PrimaryVertexReFitter(const std::string& name, ISvcLocator *pSvcLocator):
21 AthAlgorithm (name, pSvcLocator)
22{}
23
24//=============================================================================
26{
27 ANA_MSG_DEBUG("ReFitPriVtxName = " << m_reFitPrimaryVertexKey);
28 ANA_MSG_DEBUG("LeptonContainerName = " << m_leptonContainerKey);
29 ANA_MSG_DEBUG("PriVertexContainerName = " << m_primaryVertexContainerKey);
30
31 ANA_MSG_DEBUG("PrintTime = " << m_printTime);
32
33 ANA_MSG_DEBUG("DistToRefittedPriVtxName = " << m_distToRefittedPriVtxName);
34 ANA_MSG_DEBUG("NormDistToRefittedPriVtxName = " << m_normDistToRefittedPriVtxName);
35 ANA_MSG_DEBUG("RefittedVtxWithoutLeptonLinkName = " << m_lepRefittedVtxWithoutLeptonLinkName.key());
36
37 ATH_CHECK(m_inDetTracksKey.initialize());
38
39 ATH_CHECK(m_leptonContainerKey.initialize());
41
43
44 //
45 // Must have non-empty container name for refitted primary vertex with/without lepton
46 //
47 if(m_reFitPrimaryVertexKey.empty()) {
48 ATH_MSG_FATAL("initialize - SecVtx container invalid name: \"" << m_reFitPrimaryVertexKey << "\"");
49 return StatusCode::FAILURE;
50 }
51
55
56 ATH_CHECK(m_vertexFitterTool.retrieve());
57
58 if(m_printTime) {
59 //
60 // Reset timers
61 //
62 m_timerAll .Reset();
63 m_timerExec.Reset();
64
65 //
66 // Start full timer
67 //
68 m_timerAll.Start();
69 }
70
71 return StatusCode::SUCCESS;
72}
73
74//=============================================================================
76{
77 if(m_printTime) {
78 //
79 // Print full time stopwatch
80 //
81 m_timerAll.Stop();
82
83 ATH_MSG_INFO("Real time: " << m_timerAll.RealTime() << "\t CPU time: " << m_timerAll.CpuTime());
84 ATH_MSG_INFO("Execute time: " << PrintResetStopWatch(m_timerExec));
85 }
86
87 return StatusCode::SUCCESS;
88}
89
90//=============================================================================
92{
93 const EventContext& ctx = Gaudi::Hive::currentContext();
94
95 //
96 // Start execute timer
97 //
99
100 //
101 // Find Inner Detector tracks
102 //
104 if (!h_inDetTracks.isValid()){
105 ATH_MSG_FATAL("execute - failed to find the InDetTrackParticles");
106 return StatusCode::FAILURE;
107 }
108
109 const xAOD::TrackParticleContainer inDetTracks = *h_inDetTracks;
110
111 //
112 // Create output vertex collections and record them immediately
113 // in StoreGate for memory management
114 //
115 std::unique_ptr<xAOD::VertexContainer> refitVtxContainer = std::make_unique< xAOD::VertexContainer>();
116 std::unique_ptr<xAOD::VertexAuxContainer> refitVtxContainerAux = std::make_unique< xAOD::VertexAuxContainer>();
117
118 refitVtxContainer->setStore(refitVtxContainerAux.get());
119
121 ATH_CHECK(h_refitVtxContainer.record(
122 std::move(refitVtxContainer), std::move(refitVtxContainerAux)
123 ));
124 xAOD::VertexContainer &refitVtxContainerRef = *h_refitVtxContainer;
125
126 //
127 // Retrieve containers from evtStore
128 //
130 if (!h_leptonContainer.isValid()){
131 ATH_MSG_FATAL("execute - failed to find the lepton container");
132 return StatusCode::FAILURE;
133 }
134
136 if (!h_vertices.isValid()){
137 ATH_MSG_FATAL("execute - failed to find the vertices");
138 return StatusCode::FAILURE;
139 }
140
141 const xAOD::IParticleContainer leptonContainer = *h_leptonContainer;
142 const xAOD::VertexContainer vertices = *h_vertices;
143
144 Prompt::FittingInput fittingInput(&inDetTracks, 0, 0);
145
146 for(const xAOD::Vertex *vertex: vertices) {
147 if(vertex->vertexType() == 1) {
148 fittingInput.priVtx = dynamic_cast<const xAOD::Vertex*>(vertex);
149 break;
150 }
151 }
152
153 if(!fittingInput.priVtx) {
154 ATH_MSG_INFO("Failed to find primary vertices - save empty containers");
155 return StatusCode::SUCCESS;
156 }
157
158 //
159 // Collect tracks used for primary vertex fit
160 //
161 std::vector<const xAOD::TrackParticle *> priVtx_tracks;
162 priVtx_tracks.reserve(fittingInput.priVtx->nTrackParticles());
163
164 for(unsigned k = 0; k < fittingInput.priVtx->nTrackParticles(); ++k) {
165 const xAOD::TrackParticle *track = fittingInput.priVtx->trackParticle(k);
166
167 if(track) {
168 priVtx_tracks.push_back(track);
169 }
170 }
171
172 // Refit primary vertex
173 std::unique_ptr<xAOD::Vertex> refittedPriVtx = m_vertexFitterTool->fitVertexWithSeed(
174 fittingInput, priVtx_tracks,
175 fittingInput.priVtx->position(),
177 );
178
179 if(!refittedPriVtx) {
180 ATH_MSG_WARNING("Failed to refit primary vertex - save empty containers");
181 return StatusCode::SUCCESS;
182 }
183
184 //
185 // Save refitted primary vertex for fitting service
186 //
187 fittingInput.refittedPriVtx = refittedPriVtx.get();
188
189 ATH_MSG_DEBUG("execute -- primary vertex NTrack = " << fittingInput.priVtx ->nTrackParticles());
190 ATH_MSG_DEBUG("execute -- refitted primary vertex NTrack = " << fittingInput.refittedPriVtx->nTrackParticles());
191
192 //
193 // Dynamic cast IParticle container to electron or muon container
194 //
195 ATH_MSG_DEBUG("======================================="
196 << "\n\t\t\t Size of lepton container: " << leptonContainer.size()
197 << "\n-----------------------------------------------------------------");
198
200 lepRefittedRMVtxLinkDec (m_lepRefittedVtxWithoutLeptonLinkName, ctx);
201
202 DataLink<xAOD::VertexContainer> refitVtxContainerLink (refitVtxContainerRef, ctx);
203 for(const xAOD::IParticle *lepton: leptonContainer) {
204 const xAOD::TrackParticle *tracklep = 0;
205 const xAOD::Electron *elec = dynamic_cast<const xAOD::Electron*>(lepton);
206 const xAOD::Muon *muon = dynamic_cast<const xAOD::Muon*>(lepton);
207
208 if(elec) {
209 //
210 // get GSF track
211 //
212 const xAOD::TrackParticle *bestmatchedGSFElTrack=elec->trackParticle(0);
213
214 //
215 // get origin ID track for later study
216 //
217 tracklep = xAOD::EgammaHelpers::getOriginalTrackParticleFromGSF(bestmatchedGSFElTrack);
218 }
219 else if(muon) {
220 if(muon->inDetTrackParticleLink().isValid()) {
221 tracklep = *(muon->inDetTrackParticleLink());
222 }
223 else {
224 ATH_MSG_DEBUG("PrimaryVertexReFitter::execute - skip muon without valid inDetTrackParticleLink()");
225 continue;
226 }
227 }
228
229 if(!tracklep) {
230 ATH_MSG_WARNING("PrimaryVertexReFitter::execute - cannot find muon->inDetTrackParticleLink() nor electron->trackParticle()");
231 continue;
232 }
233
234 if (decorateLepWithReFitPrimaryVertex(fittingInput, tracklep, priVtx_tracks, refitVtxContainerRef))
235 {
236 lepRefittedRMVtxLinkDec(*lepton) = ElementLink<xAOD::VertexContainer>(refitVtxContainerLink, refitVtxContainerRef.size()-1);
237 }
238 }
239
240 h_refitVtxContainer->push_back(std::move(refittedPriVtx));
241
242 ATH_MSG_DEBUG("SV Vertex container " << m_reFitPrimaryVertexKey << " recorded in store");
243
244 ATH_MSG_DEBUG("execute - all done");
245 ATH_MSG_DEBUG("=======================================");
246
247 return StatusCode::SUCCESS;
248}
249
250//=============================================================================
252 const FittingInput &input,
253 const xAOD::TrackParticle* tracklep,
254 const std::vector<const xAOD::TrackParticle*> &tracks,
255 xAOD::VertexContainer &refitVtxContainer)
256{
257 //
258 // Check if the lepton track has been used for primary vertex reconstruction.
259 // if true, then remove the lepton track from the input track list, re-fit primary vertex again.
260 // Save the ElementLink of the re-fit primary vertex to the lepton
261 //
262 if(!input.priVtx) {
263 ATH_MSG_WARNING("decorateLepWithReFitPrimaryVertex - invalid input primary vertex pointer");
264 return false;
265 }
266
267 //--------------------------------------------------------
268 // Remove the lepton track from the track list
269 // get re-fitted non-prompt primary vertex
270 //
271 std::vector<const xAOD::TrackParticle*> priVtx_tracks_pass;
272 bool isRefit = false;
273
274 for(const xAOD::TrackParticle *track: tracks) {
275 if(track == tracklep) {
276 isRefit = true;
277 ATH_MSG_DEBUG("decorateLepWithReFitPrimaryVertex -- lepton has been used, lepton pT =" << tracklep->pt() << ", track pT =" << track->pt());
278 continue;
279 }
280
281 priVtx_tracks_pass.push_back(track);
282 }
283
284 if(!isRefit) {
285 ATH_MSG_DEBUG("decorateLepWithReFitPrimaryVertex -- Skip the primary vertex without lepton track");
286
287 return false;
288 }
289
290 if(priVtx_tracks_pass.size() < 2) {
291 ATH_MSG_DEBUG("decorateLepWithReFitPrimaryVertex -- Skip the primary vertex refitting: N tracks =" << priVtx_tracks_pass.size());
292
293 return false;
294 }
295
296 std::unique_ptr<xAOD::Vertex> refittedVtxRMLep = m_vertexFitterTool->fitVertexWithSeed(
297 input, priVtx_tracks_pass, input.priVtx->position(),
299
300 if(refittedVtxRMLep) {
301 ATH_MSG_DEBUG("decorateLepWithReFitPrimaryVertex -- save refitted non-prompt primary vertex with NTrack = " << refittedVtxRMLep->nTrackParticles());
302
303 if(input.refittedPriVtx) {
304 (*m_distToRefittedPriVtx) (*refittedVtxRMLep) = Prompt::getDistance(input.refittedPriVtx->position(), refittedVtxRMLep->position());
305 (*m_normdistToRefittedPriVtx)(*refittedVtxRMLep) = Prompt::getNormDist(
306 input.refittedPriVtx->position(),
307 refittedVtxRMLep->position(),
308 refittedVtxRMLep->covariance(),
309 msg(MSG::WARNING)
310 );
311 }
312 //
313 // Record vertex with output container
314 //
315 refitVtxContainer.push_back(std::move(refittedVtxRMLep));
316
317 return true;
318 }
319 return false;
320}
321}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define ANA_MSG_DEBUG(xmsg)
Macro printing debug messages.
Handle class for adding a decoration to an object.
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
MsgStream & msg() const
value_type push_back(value_type pElem)
Add an element to the end of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
SG::WriteDecorHandleKey< xAOD::IParticleContainer > m_lepRefittedVtxWithoutLeptonLinkName
SG::ReadHandleKey< xAOD::VertexContainer > m_primaryVertexContainerKey
SG::ReadHandleKey< xAOD::IParticleContainer > m_leptonContainerKey
std::optional< accessorFloat_t > m_normdistToRefittedPriVtx
SG::WriteHandleKey< xAOD::VertexContainer > m_reFitPrimaryVertexKey
std::optional< accessorFloat_t > m_distToRefittedPriVtx
virtual StatusCode finalize() override
PrimaryVertexReFitter(const std::string &name, ISvcLocator *pSvcLocator)
Gaudi::Property< std::string > m_distToRefittedPriVtxName
Gaudi::Property< bool > m_printTime
virtual StatusCode initialize() override
virtual StatusCode execute() override
Gaudi::Property< std::string > m_normDistToRefittedPriVtxName
bool decorateLepWithReFitPrimaryVertex(const FittingInput &input, const xAOD::TrackParticle *tracklep, const std::vector< const xAOD::TrackParticle * > &tracks, xAOD::VertexContainer &refitVtxContainer)
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_inDetTracksKey
ToolHandle< Prompt::VertexFittingTool > m_vertexFitterTool
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Handle class for adding a decoration to an object.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
const xAOD::TrackParticle * trackParticle(size_t index=0) const
Pointer to the xAOD::TrackParticle/s that match the electron candidate.
Class providing the definition of the 4-vector interface.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
size_t nTrackParticles() const
Get the number of tracks associated with this vertex.
const TrackParticle * trackParticle(size_t i) const
Get the pointer to a given track that was used in vertex reco.
const Amg::Vector3D & position() const
Returns the 3-pos.
std::string PrintResetStopWatch(TStopwatch &watch)
@ kRefittedPriVtxWithoutLep
double getNormDist(const Amg::Vector3D &PrimVtx, const Amg::Vector3D &SecVtx, const std::vector< float > &ErrorMatrix, MsgStream &msg)
double getDistance(const xAOD::Vertex *vtx1, const xAOD::Vertex *vtx2)
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...
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.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
Muon_v1 Muon
Reference the current persistent version:
Electron_v1 Electron
Definition of the current "egamma version".
DataVector< IParticle > IParticleContainer
Simple convenience declaration of IParticleContainer.
const xAOD::Vertex * refittedPriVtx
const xAOD::Vertex * priVtx