ATLAS Offline Software
PrimaryVertexReFitter.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 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"
15 
16 namespace Prompt {
17 //======================================================================================================
18 PrimaryVertexReFitter::PrimaryVertexReFitter(const std::string& name, ISvcLocator *pSvcLocator):
19  AthAlgorithm (name, pSvcLocator)
20 {}
21 
22 //=============================================================================
24 {
25  ANA_MSG_DEBUG("ReFitPriVtxName = " << m_reFitPrimaryVertexKey);
26  ANA_MSG_DEBUG("LeptonContainerName = " << m_leptonContainerKey);
27  ANA_MSG_DEBUG("PriVertexContainerName = " << m_primaryVertexContainerKey);
28 
29  ANA_MSG_DEBUG("PrintTime = " << m_printTime);
30 
31  ANA_MSG_DEBUG("DistToRefittedPriVtxName = " << m_distToRefittedPriVtxName);
32  ANA_MSG_DEBUG("NormDistToRefittedPriVtxName = " << m_normDistToRefittedPriVtxName);
33  ANA_MSG_DEBUG("RefittedVtxLinkName = " << m_lepVtxLinkName);
34  ANA_MSG_DEBUG("RefittedVtxWithoutLeptonLinkName = " << m_lepRefittedVtxWithoutLeptonLinkName);
35 
37 
38  ATH_CHECK(m_leptonContainerKey.initialize());
40 
41  ATH_CHECK(m_reFitPrimaryVertexKey.initialize());
42 
43  //
44  // Must have non-empty container name for refitted primary vertex with/without lepton
45  //
46  if(m_reFitPrimaryVertexKey.empty()) {
47  ATH_MSG_FATAL("initialize - SecVtx container invalid name: \"" << m_reFitPrimaryVertexKey << "\"");
48  return StatusCode::FAILURE;
49  }
50 
51  m_distToRefittedPriVtx = std::make_unique<decoratorFloat_t> (m_distToRefittedPriVtxName);
52  m_normdistToRefittedPriVtx = std::make_unique<decoratorFloat_t> (m_normDistToRefittedPriVtxName);
53  m_lepRefittedRMVtxLinkDec = std::make_unique<decoratorElemVtx_t>(m_lepRefittedVtxWithoutLeptonLinkName);
54 
55  ATH_CHECK(m_vertexFitterTool.retrieve());
56 
57  if(m_printTime) {
58  //
59  // Reset timers
60  //
61  m_timerAll .Reset();
62  m_timerExec.Reset();
63 
64  //
65  // Start full timer
66  //
67  m_timerAll.Start();
68  }
69 
70  return StatusCode::SUCCESS;
71 }
72 
73 //=============================================================================
75 {
76  if(m_printTime) {
77  //
78  // Print full time stopwatch
79  //
80  m_timerAll.Stop();
81 
82  ATH_MSG_INFO("Real time: " << m_timerAll.RealTime() << "\t CPU time: " << m_timerAll.CpuTime());
83  ATH_MSG_INFO("Execute time: " << PrintResetStopWatch(m_timerExec));
84  }
85 
86  return StatusCode::SUCCESS;
87 }
88 
89 //=============================================================================
91 {
92  //
93  // Start execute timer
94  //
96 
97  //
98  // Find Inner Detector tracks
99  //
101  if (!h_inDetTracks.isValid()){
102  ATH_MSG_FATAL("execute - failed to find the InDetTrackParticles");
103  return StatusCode::FAILURE;
104  }
105 
106  const xAOD::TrackParticleContainer inDetTracks = *h_inDetTracks;
107 
108  //
109  // Create output vertex collections and record them immediately
110  // in StoreGate for memory management
111  //
112  std::unique_ptr<xAOD::VertexContainer> refitVtxContainer = std::make_unique< xAOD::VertexContainer>();
113  std::unique_ptr<xAOD::VertexAuxContainer> refitVtxContainerAux = std::make_unique< xAOD::VertexAuxContainer>();
114 
115  refitVtxContainer->setStore(refitVtxContainerAux.get());
116 
117  // Take reference BEFORE pointers moved to SG
118  xAOD::VertexContainer &refitVtxContainerRef = *refitVtxContainer;
119 
121  ATH_CHECK(h_refitVtxContainer.record(
122  std::move(refitVtxContainer), std::move(refitVtxContainerAux)
123  ));
124 
125  //
126  // Retrieve containers from evtStore
127  //
129  if (!h_leptonContainer.isValid()){
130  ATH_MSG_FATAL("execute - failed to find the lepton container");
131  return StatusCode::FAILURE;
132  }
133 
135  if (!h_vertices.isValid()){
136  ATH_MSG_FATAL("execute - failed to find the vertices");
137  return StatusCode::FAILURE;
138  }
139 
140  const xAOD::IParticleContainer leptonContainer = *h_leptonContainer;
141  const xAOD::VertexContainer vertices = *h_vertices;
142 
143  Prompt::FittingInput fittingInput(&inDetTracks, 0, 0);
144 
145  for(const xAOD::Vertex *vertex: vertices) {
146  if(vertex->vertexType() == 1) {
147  fittingInput.priVtx = dynamic_cast<const xAOD::Vertex*>(vertex);
148  break;
149  }
150  }
151 
152  if(!fittingInput.priVtx) {
153  ATH_MSG_INFO("Failed to find primary vertices - save empty containers");
154  return StatusCode::SUCCESS;
155  }
156 
157  //
158  // Collect tracks used for primary vertex fit
159  //
160  std::vector<const xAOD::TrackParticle *> priVtx_tracks;
161  priVtx_tracks.reserve(fittingInput.priVtx->nTrackParticles());
162 
163  for(unsigned k = 0; k < fittingInput.priVtx->nTrackParticles(); ++k) {
164  const xAOD::TrackParticle *track = fittingInput.priVtx->trackParticle(k);
165 
166  if(track) {
167  priVtx_tracks.push_back(track);
168  }
169  }
170 
171  // Refit primary vertex
172  std::unique_ptr<xAOD::Vertex> refittedPriVtx = m_vertexFitterTool->fitVertexWithSeed(
173  fittingInput, priVtx_tracks,
174  fittingInput.priVtx->position(),
176  );
177 
178  if(!refittedPriVtx) {
179  ATH_MSG_WARNING("Failed to refit primary vertex - save empty containers");
180  return StatusCode::SUCCESS;
181  }
182 
183  //
184  // Save refitted primary vertex for fitting service
185  //
186  fittingInput.refittedPriVtx = refittedPriVtx.get();
187 
188  ATH_MSG_DEBUG("execute -- primary vertex NTrack = " << fittingInput.priVtx ->nTrackParticles());
189  ATH_MSG_DEBUG("execute -- refitted primary vertex NTrack = " << fittingInput.refittedPriVtx->nTrackParticles());
190 
191  //
192  // Dynamic cast IParticle container to electron or muon container
193  //
194  ATH_MSG_DEBUG("======================================="
195  << "\n\t\t\t Size of lepton container: " << leptonContainer.size()
196  << "\n-----------------------------------------------------------------");
197 
198  for(const xAOD::IParticle *lepton: leptonContainer) {
199  const xAOD::TrackParticle *tracklep = 0;
200  const xAOD::Electron *elec = dynamic_cast<const xAOD::Electron*>(lepton);
201  const xAOD::Muon *muon = dynamic_cast<const xAOD::Muon*>(lepton);
202 
203  if(elec) {
204  //
205  // get GSF track
206  //
207  const xAOD::TrackParticle *bestmatchedGSFElTrack=elec->trackParticle(0);
208 
209  //
210  // get origin ID track for later study
211  //
212  tracklep = xAOD::EgammaHelpers::getOriginalTrackParticleFromGSF(bestmatchedGSFElTrack);
213  }
214  else if(muon) {
215  if(muon->inDetTrackParticleLink().isValid()) {
216  tracklep = *(muon->inDetTrackParticleLink());
217  }
218  else {
219  ATH_MSG_DEBUG("PrimaryVertexReFitter::execute - skip muon without valid inDetTrackParticleLink()");
220  continue;
221  }
222  }
223 
224  if(!tracklep) {
225  ATH_MSG_WARNING("PrimaryVertexReFitter::execute - cannot find muon->inDetTrackParticleLink() nor electron->trackParticle()");
226  continue;
227  }
228 
229  decorateLepWithReFitPrimaryVertex(fittingInput, tracklep, lepton, priVtx_tracks, refitVtxContainerRef);
230  }
231 
232  h_refitVtxContainer->push_back(std::move(refittedPriVtx));
233 
234  ATH_MSG_DEBUG("SV Vertex container " << m_reFitPrimaryVertexKey << " recorded in store");
235 
236  ATH_MSG_DEBUG("execute - all done");
237  ATH_MSG_DEBUG("=======================================");
238 
239  return StatusCode::SUCCESS;
240 }
241 
242 //=============================================================================
244  const FittingInput &input,
245  const xAOD::TrackParticle* tracklep,
246  const xAOD::IParticle *lep,
247  const std::vector<const xAOD::TrackParticle*> &tracks,
248  xAOD::VertexContainer &refitVtxContainer)
249 {
250  //
251  // Check if the lepton track has been used for primary vertex reconstruction.
252  // if true, then remove the lepton track from the input track list, re-fit primary vertex again.
253  // Save the ElementLink of the re-fit primary vertex to the lepton
254  //
255  if(!input.priVtx) {
256  ATH_MSG_WARNING("decorateLepWithReFitPrimaryVertex - invalid input primary vertex pointer");
257  return false;
258  }
259 
260  //--------------------------------------------------------
261  // Remove the lepton track from the track list
262  // get re-fitted non-prompt primary vertex
263  //
264  std::vector<const xAOD::TrackParticle*> priVtx_tracks_pass;
265  bool isRefit = false;
266 
267  for(const xAOD::TrackParticle *track: tracks) {
268  if(track == tracklep) {
269  isRefit = true;
270  ATH_MSG_DEBUG("decorateLepWithReFitPrimaryVertex -- lepton has been used, lepton pT =" << tracklep->pt() << ", track pT =" << track->pt());
271  continue;
272  }
273 
274  priVtx_tracks_pass.push_back(track);
275  }
276 
277  ElementLink<xAOD::VertexContainer> refittedRM_pv_link;
278 
279  if(!isRefit) {
280  ATH_MSG_DEBUG("decorateLepWithReFitPrimaryVertex -- Skip the primary vertex without lepton track");
281 
282  (*m_lepRefittedRMVtxLinkDec)(*lep) = refittedRM_pv_link;
283  return false;
284  }
285 
286  if(priVtx_tracks_pass.size() < 2) {
287  ATH_MSG_DEBUG("decorateLepWithReFitPrimaryVertex -- Skip the primary vertex refitting: N tracks =" << priVtx_tracks_pass.size());
288 
289  (*m_lepRefittedRMVtxLinkDec)(*lep) = refittedRM_pv_link;
290  return false;
291  }
292 
293  // TODO: probably need to fix memory management here
294  // but I'm not sure what happens with the ElementLink later
295  // so didn't want the vertex to be deleted by accident
296  xAOD::Vertex* refittedVtxRMLep = m_vertexFitterTool->fitVertexWithSeed(
297  input, priVtx_tracks_pass, input.priVtx->position(),
299  ).release();
300 
301  if(refittedVtxRMLep) {
302  //
303  // Record vertex with output container
304  //
305  refitVtxContainer.push_back(refittedVtxRMLep);
306 
307  // TODO: I don't know if this is the correct use of an ElementLink
308  //
309  // Add refitted non-prompt vertex ElementLink to the lepton
310  //
311  refittedRM_pv_link.toContainedElement(refitVtxContainer, refittedVtxRMLep);
312 
313  ATH_MSG_DEBUG("decorateLepWithReFitPrimaryVertex -- save refitted non-prompt primary vertex with NTrack = " << refittedVtxRMLep->nTrackParticles());
314 
315  if(input.refittedPriVtx) {
316  (*m_distToRefittedPriVtx) (*refittedVtxRMLep) = Prompt::getDistance(input.refittedPriVtx->position(), refittedVtxRMLep->position());
317  (*m_normdistToRefittedPriVtx)(*refittedVtxRMLep) = Prompt::getNormDist(
318  input.refittedPriVtx->position(),
319  refittedVtxRMLep->position(),
320  refittedVtxRMLep->covariance(),
321  msg(MSG::WARNING)
322  );
323  }
324  }
325 
326  (*m_lepRefittedRMVtxLinkDec)(*lep) = refittedRM_pv_link;
327 
328  return true;
329 }
330 }
xAOD::TrackParticle_v1::pt
virtual double pt() const override final
The transverse momentum ( ) of the particle.
Definition: TrackParticle_v1.cxx:73
xAOD::muon
@ muon
Definition: TrackingPrimitives.h:195
Prompt
Definition: DecoratePLIT.h:28
Prompt::PrimaryVertexReFitter::m_timerExec
TStopwatch m_timerExec
Definition: PrimaryVertexReFitter.h:114
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:70
Prompt::PrimaryVertexReFitter::m_vertexFitterTool
ToolHandle< Prompt::VertexFittingTool > m_vertexFitterTool
Definition: PrimaryVertexReFitter.h:91
Prompt::PrimaryVertexReFitter::m_timerAll
TStopwatch m_timerAll
Definition: PrimaryVertexReFitter.h:113
Prompt::PrimaryVertexReFitter::m_distToRefittedPriVtx
std::unique_ptr< decoratorFloat_t > m_distToRefittedPriVtx
Definition: PrimaryVertexReFitter.h:137
Prompt::PrimaryVertexReFitter::m_leptonContainerKey
SG::ReadHandleKey< xAOD::IParticleContainer > m_leptonContainerKey
Definition: PrimaryVertexReFitter.h:121
PrimaryVertexReFitter.h
Prompt::PrimaryVertexReFitter::finalize
virtual StatusCode finalize() override
Definition: PrimaryVertexReFitter.cxx:74
Prompt::PrimaryVertexReFitter::m_reFitPrimaryVertexKey
SG::WriteHandleKey< xAOD::VertexContainer > m_reFitPrimaryVertexKey
Definition: PrimaryVertexReFitter.h:130
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::m_lepRefittedRMVtxLinkDec
std::unique_ptr< decoratorElemVtx_t > m_lepRefittedRMVtxLinkDec
Definition: PrimaryVertexReFitter.h:139
Prompt::PrimaryVertexReFitter::PrimaryVertexReFitter
PrimaryVertexReFitter(const std::string &name, ISvcLocator *pSvcLocator)
Definition: PrimaryVertexReFitter.cxx:18
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_normdistToRefittedPriVtx
std::unique_ptr< decoratorFloat_t > m_normdistToRefittedPriVtx
Definition: PrimaryVertexReFitter.h:138
Prompt::PrimaryVertexReFitter::m_normDistToRefittedPriVtxName
Gaudi::Property< std::string > m_normDistToRefittedPriVtxName
Definition: PrimaryVertexReFitter.h:103
xAOD::Muon_v1
Class describing a Muon.
Definition: Muon_v1.h:38
Prompt::PrimaryVertexReFitter::m_lepVtxLinkName
Gaudi::Property< std::string > m_lepVtxLinkName
Definition: PrimaryVertexReFitter.h:106
python.utils.AtlRunQueryTimer.timer
def timer(name, disabled=False)
Definition: AtlRunQueryTimer.py:86
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
Prompt::PrimaryVertexReFitter::decorateLepWithReFitPrimaryVertex
bool decorateLepWithReFitPrimaryVertex(const FittingInput &input, const xAOD::TrackParticle *tracklep, const xAOD::IParticle *lep, const std::vector< const xAOD::TrackParticle * > &tracks, xAOD::VertexContainer &refitVtxContainer)
Definition: PrimaryVertexReFitter.cxx:243
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
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Prompt::PrimaryVertexReFitter::initialize
virtual StatusCode initialize() override
Definition: PrimaryVertexReFitter.cxx:23
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:98
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
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
Prompt::PrimaryVertexReFitter::m_lepRefittedVtxWithoutLeptonLinkName
Gaudi::Property< std::string > m_lepRefittedVtxWithoutLeptonLinkName
Definition: PrimaryVertexReFitter.h:109
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:76
Trk::vertex
@ vertex
Definition: MeasurementType.h:21
Prompt::PrimaryVertexReFitter::m_inDetTracksKey
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_inDetTracksKey
Definition: PrimaryVertexReFitter.h:117
Prompt::PrimaryVertexReFitter::m_primaryVertexContainerKey
SG::ReadHandleKey< xAOD::VertexContainer > m_primaryVertexContainerKey
Definition: PrimaryVertexReFitter.h:126
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:100
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
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:90
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
VertexAuxContainer.h
fitman.k
k
Definition: fitman.py:528
ANA_MSG_DEBUG
#define ANA_MSG_DEBUG(xmsg)
Macro printing debug messages.
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:288