ATLAS Offline Software
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 
18 namespace Prompt {
19 //======================================================================================================
20 PrimaryVertexReFitter::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 
38 
39  ATH_CHECK(m_leptonContainerKey.initialize());
41 
42  ATH_CHECK(m_reFitPrimaryVertexKey.initialize());
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 }
xAOD::TrackParticle_v1::pt
virtual double pt() const override final
The transverse momentum ( ) of the particle.
Definition: TrackParticle_v1.cxx:74
Prompt::PrimaryVertexReFitter::decorateLepWithReFitPrimaryVertex
bool decorateLepWithReFitPrimaryVertex(const FittingInput &input, const xAOD::TrackParticle *tracklep, const std::vector< const xAOD::TrackParticle * > &tracks, xAOD::VertexContainer &refitVtxContainer)
Definition: PrimaryVertexReFitter.cxx:251
xAOD::muon
@ muon
Definition: TrackingPrimitives.h:196
Prompt
Definition: DecoratePLIT.h:29
Prompt::PrimaryVertexReFitter::m_timerExec
TStopwatch m_timerExec
Definition: PrimaryVertexReFitter.h:109
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
PromptUtils.h
xAOD::Vertex_v1::nTrackParticles
size_t nTrackParticles() const
Get the number of tracks associated with this vertex.
Definition: Vertex_v1.cxx:270
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Muon.h
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
Prompt::PrimaryVertexReFitter::m_vertexFitterTool
ToolHandle< Prompt::VertexFittingTool > m_vertexFitterTool
Definition: PrimaryVertexReFitter.h:92
Prompt::PrimaryVertexReFitter::m_timerAll
TStopwatch m_timerAll
Definition: PrimaryVertexReFitter.h:108
Prompt::PrimaryVertexReFitter::m_leptonContainerKey
SG::ReadHandleKey< xAOD::IParticleContainer > m_leptonContainerKey
Definition: PrimaryVertexReFitter.h:116
PrimaryVertexReFitter.h
Prompt::PrimaryVertexReFitter::finalize
virtual StatusCode finalize() override
Definition: PrimaryVertexReFitter.cxx:75
Prompt::PrimaryVertexReFitter::m_reFitPrimaryVertexKey
SG::WriteHandleKey< xAOD::VertexContainer > m_reFitPrimaryVertexKey
Definition: PrimaryVertexReFitter.h:125
xAOD::Electron_v1::trackParticle
const xAOD::TrackParticle * trackParticle(size_t index=0) const
Pointer to the xAOD::TrackParticle/s that match the electron candidate.
Definition: Electron_v1.cxx:55
xAOD::Vertex_v1::position
const Amg::Vector3D & position() const
Returns the 3-pos.
Prompt::PrimaryVertexReFitter::PrimaryVertexReFitter
PrimaryVertexReFitter(const std::string &name, ISvcLocator *pSvcLocator)
Definition: PrimaryVertexReFitter.cxx:20
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:41
Prompt::FittingInput
Definition: IVertexFittingTool.h:60
Prompt::PrintResetStopWatch
std::string PrintResetStopWatch(TStopwatch &watch)
Definition: PromptUtils.cxx:244
Prompt::PrimaryVertexReFitter::m_normDistToRefittedPriVtxName
Gaudi::Property< std::string > m_normDistToRefittedPriVtxName
Definition: PrimaryVertexReFitter.h:104
Prompt::PrimaryVertexReFitter::m_lepRefittedVtxWithoutLeptonLinkName
SG::WriteDecorHandleKey< xAOD::IParticleContainer > m_lepRefittedVtxWithoutLeptonLinkName
Definition: PrimaryVertexReFitter.h:136
xAOD::Muon_v1
Class describing a Muon.
Definition: Muon_v1.h:38
python.utils.AtlRunQueryTimer.timer
def timer(name, disabled=False)
Definition: AtlRunQueryTimer.py:85
Prompt::kRefittedPriVtxWithoutLep
@ kRefittedPriVtxWithoutLep
Definition: IVertexFittingTool.h:66
Prompt::getNormDist
double getNormDist(const Amg::Vector3D &PrimVtx, const Amg::Vector3D &SecVtx, const std::vector< float > &ErrorMatrix, MsgStream &msg)
Definition: PromptUtils.cxx:57
EgammaxAODHelpers.h
Prompt::getDistance
double getDistance(const xAOD::Vertex *vtx1, const xAOD::Vertex *vtx2)
Definition: PromptUtils.cxx:41
Prompt::FittingInput::priVtx
const xAOD::Vertex * priVtx
Definition: IVertexFittingTool.h:71
Prompt::kRefittedPriVtx
@ kRefittedPriVtx
Definition: IVertexFittingTool.h:65
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
SG::WriteDecorHandle
Handle class for adding a decoration to an object.
Definition: StoreGate/StoreGate/WriteDecorHandle.h:100
WriteDecorHandle.h
Handle class for adding a decoration to an object.
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Prompt::PrimaryVertexReFitter::initialize
virtual StatusCode initialize() override
Definition: PrimaryVertexReFitter.cxx:25
xAOD::Vertex_v1::trackParticle
const TrackParticle * trackParticle(size_t i) const
Get the pointer to a given track that was used in vertex reco.
Definition: Vertex_v1.cxx:249
Prompt::PrimaryVertexReFitter::m_printTime
Gaudi::Property< bool > m_printTime
Definition: PrimaryVertexReFitter.h:99
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
AthAlgorithm
Definition: AthAlgorithm.h:47
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Prompt::FittingInput::refittedPriVtx
const xAOD::Vertex * refittedPriVtx
Definition: IVertexFittingTool.h:72
Prompt::PrimaryVertexReFitter::m_normdistToRefittedPriVtx
std::optional< accessorFloat_t > m_normdistToRefittedPriVtx
Definition: PrimaryVertexReFitter.h:133
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
xAOD::EgammaHelpers::getOriginalTrackParticleFromGSF
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...
Definition: ElectronxAODHelpers.cxx:22
xAOD::Electron_v1
Definition: Electron_v1.h:34
TrackParticle.h
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
Trk::vertex
@ vertex
Definition: MeasurementType.h:21
Prompt::PrimaryVertexReFitter::m_inDetTracksKey
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_inDetTracksKey
Definition: PrimaryVertexReFitter.h:112
Prompt::PrimaryVertexReFitter::m_primaryVertexContainerKey
SG::ReadHandleKey< xAOD::VertexContainer > m_primaryVertexContainerKey
Definition: PrimaryVertexReFitter.h:121
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Electron.h
Prompt::PrimaryVertexReFitter::m_distToRefittedPriVtxName
Gaudi::Property< std::string > m_distToRefittedPriVtxName
Definition: PrimaryVertexReFitter.h:101
xAOD::track
@ track
Definition: TrackingPrimitives.h:513
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
Prompt::TimerScopeHelper
Definition: PromptUtils.h:112
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
Prompt::PrimaryVertexReFitter::execute
virtual StatusCode execute() override
Definition: PrimaryVertexReFitter.cxx:91
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
VertexAuxContainer.h
fitman.k
k
Definition: fitman.py:528
Prompt::PrimaryVertexReFitter::m_distToRefittedPriVtx
std::optional< accessorFloat_t > m_distToRefittedPriVtx
Definition: PrimaryVertexReFitter.h:132
ANA_MSG_DEBUG
#define ANA_MSG_DEBUG(xmsg)
Macro printing debug messages.
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:288