ATLAS Offline Software
Loading...
Searching...
No Matches
RefitTracksAndVertex.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5// @file RefitTracksAndVertex.cxx
6// Anthony Morley
7//
8
10#include "GaudiKernel/TypeNameString.h"
11#include "GaudiKernel/SystemOfUnits.h"
18#include "Identifier/Identifier.h"
24
25
26
27RefitTracksAndVertex::RefitTracksAndVertex( const std::string& name, ISvcLocator* pSvcLocator )
28 : AthAlgorithm (name, pSvcLocator)
29 , m_idHelper(nullptr)
30 , m_vertexListInput("PrimaryVertices")
31 , m_trackListOutput("SiTracksWithRefitTracksAndVertex")
32 , m_outputVertexContainerName("RefittedPrimaryVertex")
33 , m_trackFitter("Trk::GlobalChi2Fitter/InDetTrackFitter")
34 , m_vertexFitter("Trk::FullVertexFitter")
35 , m_applyTrkSel(false)
36 , m_refitTracks(true)
37 , m_addPM(false)
38 , m_selPtMin(0)
39 , m_selEtaMin(-2.5)
40 , m_selEtaMax(2.5)
46 , m_nRejectPIX(0)
47 , m_nRejectSCT(0)
48 , m_nRejectTRT(0)
49 , m_nRejectPM(0)
50{
51 // declare algorithm parameters
52 declareProperty("VertexListInput" , m_vertexListInput) ;
53 declareProperty("TrackListOutput" , m_trackListOutput) ;
54 declareProperty("OutputVertexContainer" , m_outputVertexContainerName) ;
55 declareProperty("TrackFitter" , m_trackFitter) ;
56 declareProperty("VertexFitterTool" , m_vertexFitter);
57 declareProperty("ApplyTrkSel" , m_applyTrkSel) ;
58 declareProperty("RefitTracks" , m_refitTracks) ;
59 declareProperty("AddPseudoMeasurement", m_addPM);
60 declareProperty("SelPtMin" , m_selPtMin) ;
61 declareProperty("SelEtaMin" , m_selEtaMin) ;
62 declareProperty("SelEtaMax" , m_selEtaMax) ;
63 declareProperty("SelNHitPIXMin" , m_selNHitPIXMin) ;
64 declareProperty("SelNHitSCTMin" , m_selNHitSCTMin) ;
65
66}
67
69
71 //retrieve the DetectorStore service
72 StatusCode status=detStore().retrieve() ;
73 if( status.isFailure() ) {
74 ATH_MSG_FATAL( "DetectorStore service not found !" );
75 return status;
76 }else{
77 ATH_MSG_DEBUG( "DetectorStore retrieved!" );
78 }
79
80 if (detStore()->retrieve(m_idHelper, "AtlasID").isFailure()) {
81 ATH_MSG_FATAL( "Could not get AtlasDetectorID helper" );
82 return StatusCode::FAILURE;
83 }
84
85 // Set up fitter
86 status = m_trackFitter.retrieve();
87 if (status.isFailure()) {
88 ATH_MSG_FATAL( "Could not find tool " << m_trackFitter << ". Exiting.");
89 return status ;
90 } else {
91 ATH_MSG_DEBUG( " Got " << m_trackFitter << " as TrackFitter. " ) ;
92 }
93
94 // Set up fitter
95 status = m_vertexFitter.retrieve();
96 if (status.isFailure()) {
97 ATH_MSG_FATAL( "Could not find tool " << m_vertexFitter << ". Exiting.");
98 return status ;
99 } else {
100 ATH_MSG_DEBUG( " Got " << m_vertexFitter << " as VertexFitter. " ) ;
101 }
102
103 // Print input properties
104 if( m_applyTrkSel ) {
106 "Track selection will be applied:"
107 << "\n " << m_selEtaMin << " < eta < " << m_selEtaMax
108 << "\n pT > " << m_selPtMin/Gaudi::Units::GeV << " GeV"
109 << "\n number_of_PIXEL_hits >= " << m_selNHitPIXMin
110 << "\n number_of_SCT_hits >= " << m_selNHitSCTMin
111 ) ;
112 } else {
113 ATH_MSG_DEBUG( "NO selection will be applied to tracks" ) ;
114 }
115 return StatusCode::SUCCESS;
116} // initialize(.)
117
119 ATH_MSG_DEBUG( (*this) ) ;
120 return StatusCode::SUCCESS;
121}
122
123StatusCode RefitTracksAndVertex::execute(const EventContext& ctx) {
124
125 TrackCollection* outputtracks = new TrackCollection() ;
126
127 //---------------------------
128 // Primary Vertex
129 //---------------------------
130 const xAOD::VertexContainer* vertices = nullptr;
131 if ( !evtStore()->retrieve( vertices, m_vertexListInput ).isSuccess() ){ // retrieve arguments: container type, container key
132 ATH_MSG_WARNING("execute() Failed to retrieve Reconstructed vertex container. " << m_vertexListInput );
133 //ATH_MSG_ERROR(evtStore()->dump());
134 delete outputtracks;
135 return StatusCode::SUCCESS; //?? really
136 }
137
138 if( evtStore()->record( outputtracks, m_trackListOutput ).isFailure() ) {
139 ATH_MSG_ERROR( "Failed to record trackcollection with name " << m_trackListOutput );
140 }
141
142 xAOD::VertexContainer* theVertexContainer = new xAOD::VertexContainer;
143 xAOD::VertexAuxContainer* theVertexAuxContainer = new xAOD::VertexAuxContainer;
144 theVertexContainer->setStore( theVertexAuxContainer );
145
146 CHECK( evtStore()->record(theVertexContainer, m_outputVertexContainerName) );
147 CHECK( evtStore()->record(theVertexAuxContainer, m_outputVertexContainerName + "Aux.") );
148
149 const xAOD::Vertex* primaryVertex = nullptr;
150 for( const xAOD::Vertex* vertex: *vertices ) {
151 if( vertex->vertexType() == xAOD::VxType::PriVtx ) {
152 primaryVertex = vertex;
153 break;
154 }
155 }
156
157 std::vector< const Trk::TrackParameters* > trackParametersToFit;
158
159 // Check we have found a PV
160 if( primaryVertex ){
161 if(primaryVertex->nTrackParticles() < 2)
162 return StatusCode::SUCCESS;
163
164 //Loop over all tracks in the PV
165 for(unsigned int i =0; i< primaryVertex->nTrackParticles(); ++i ){
166 auto trackParticle = primaryVertex->trackParticle( i );
167 auto track = trackParticle->track();
168 // Check that there is Trk::Track
169 if(track){
170 //Refit Track using on the SCT hits
171 if(m_refitTracks){
172 auto newTrack = fitSCTOnlyTrack( track ) ;
173 if(newTrack){
174 outputtracks->push_back( newTrack ) ;
175 if(newTrack->perigeeParameters())
176 trackParametersToFit.push_back( newTrack->perigeeParameters() );
177 }
178 } else {
179 if(track->perigeeParameters())
180 trackParametersToFit.push_back( track->perigeeParameters() );
181 }
182 }
183 }
184 m_nTracksProcessed += primaryVertex->nTrackParticles() ;
185 m_nTracksAccepted += outputtracks->size() ;
186 // Make sure there are at least 2 tracks to fit in the vertex fit
187
188 ATH_MSG_DEBUG(" From: " << primaryVertex->nTrackParticles() << " tracks " << trackParametersToFit.size() << " will be used" );
189
190 if(trackParametersToFit.size() > 1){
191
192 Amg::Vector3D position = primaryVertex->position();
193 // Fit and store vertex
194 auto vertex = m_vertexFitter->fit(ctx, trackParametersToFit, position );
195 if(vertex){
196 ATH_MSG_DEBUG("Old Vtx " << primaryVertex->position());
197 ATH_MSG_DEBUG("New Vtx " << vertex->position());
198 vertex->setVertexType(xAOD::VxType::PriVtx);
199 theVertexContainer->push_back (std::move(vertex));
200 }
201 }
202 }
203
204
205
206
207
208 return StatusCode::SUCCESS;
209} // execute(.)
210
211
213 Trk::DefinedParameter z0 ( mp->parameters()[Trk::z0], Trk::z0 ) ;
214 Trk::DefinedParameter theta( mp->parameters()[Trk::theta], Trk::theta ) ;
215 std::vector<Trk::DefinedParameter> defPar ;
216 defPar.push_back( z0 ) ;
217 defPar.push_back( theta ) ;
218 if( !mp->covariance() ) return nullptr;
219 Trk::LocalParameters parFromSi( defPar ) ;
220 AmgSymMatrix(2) covFromSi;
221
222 covFromSi( 0, 0 ) = (*mp->covariance())( Trk::z0,Trk::z0 ) ;
223 covFromSi( 1, 1 ) = (*mp->covariance())( Trk::theta,Trk::theta ) ;
224 covFromSi( 1, 0 ) = (*mp->covariance())( Trk::z0, Trk::theta ) ;
225 covFromSi( 0, 1 ) = (*mp->covariance())( Trk::z0, Trk::theta ) ;
226
227 const Trk::Surface& mpSurf = mp->associatedSurface() ;
228
230 , covFromSi
231 , mpSurf
232 ) ;
233 return pm ;
234}
235
237 Trk::MeasurementSet sortedMS ;
238 sortedMS.push_back( pm ) ;
239 for( int i=0, i_max=ms.size() ; i!=i_max ; ++i ) {
240 sortedMS.push_back( ms[i] ) ;
241 }
242 return sortedMS ;
243}
244
246 Trk::MeasurementSet setSCT ;
247 Trk::MeasurementSet setPix ;
248 Trk::MeasurementSet setTRT ;
249
250 const Trk::Perigee* perTrk = track->perigeeParameters();
251 if( !perTrk ) {
252 ATH_MSG_WARNING("RefitTracksAndVertex() : No Perigee parameter on track!");
253 return nullptr ;
254 }
255
256 if( perTrk->eta() < m_selEtaMin || perTrk->eta() > m_selEtaMax)
257 return nullptr ;
258
259 if( perTrk->pT() < m_selPtMin)
260 return nullptr ;
261
262
263 //store all silicon measurements into the measurementset
264 DataVector<const Trk::MeasurementBase>::const_iterator it = track->measurementsOnTrack()->begin();
265 DataVector<const Trk::MeasurementBase>::const_iterator itEnd = track->measurementsOnTrack()->end();
266 for ( ; it!=itEnd; ++it){
267 if( !(*it) ) {
268 // log (MSG::WARNING) << "The MeasurementBase set has a void"
269 // << " member! Skip it.." << endmsg;
270 } else {
271 const Trk::RIO_OnTrack* rio = dynamic_cast <const Trk::RIO_OnTrack*>(*it);
272 if (rio != nullptr) {
273 const Identifier& surfaceID = (rio->identify()) ;
274 if( m_idHelper->is_sct(surfaceID) ) {
275 setSCT.push_back ( *it ) ;
276 } else if( m_idHelper->is_trt(surfaceID) ) {
277 setTRT.push_back ( *it ) ;
278 } else if( m_idHelper->is_pixel(surfaceID) ){
279 setPix.push_back ( *it ) ;
280 }
281 }
282 }
283 }
284
285 if( (int)setSCT.size() < m_selNHitSCTMin )
286 return nullptr;
287
288 ATH_MSG_DEBUG("RefitTracksAndVertex() : Found " << setSCT.size() << " SCT measurm's!" ) ;
289 ATH_MSG_DEBUG("RefitTracksAndVertex() : Found " << setPix.size() << " Pix measurm's!" ) ;
290 ATH_MSG_DEBUG("RefitTracksAndVertex() : Found " << setTRT.size() << " TRT measurm's!") ;
291
292
293 ATH_MSG_DEBUG( std::setiosflags( std::ios::scientific )) ;
294 ATH_MSG_DEBUG (std::setprecision( 7 )) ;
295 ATH_MSG_VERBOSE( std::setiosflags( std::ios::scientific )) ;
296 ATH_MSG_VERBOSE( std::setprecision( 7 )) ;
297
298 // now add z_0 and theta from original track as PseudoMeas to the TRT MeasurementSet
299 if(m_addPM){
300 const Trk::PseudoMeasurementOnTrack *pmFromSi = createPMfromSi( perTrk ) ;
301 if( !pmFromSi ) {
302 ATH_MSG_ERROR("RefitTracksAndVertex() : PseudoMeasurementOnTrack creation failed! " );
303 return nullptr ;
304 }
305 ATH_MSG_DEBUG( "RefitTracksAndVertex() : pmFromSi " << *pmFromSi) ;
306 Trk::MeasurementSet setSCT = addPM( setSCT, pmFromSi ) ;
307 }
308
309 // Add TRT hits as they do no harm
310 for( int i=0, i_max=setTRT.size() ; i!=i_max ; ++i ) {
311 setSCT.push_back( setTRT[i] ) ;
312 }
313
314 ATH_MSG_VERBOSE ( "RefitTracksAndVertex() : Si+PM MeasurementSet : " );
315 for( int i=0, i_max=setSCT.size() ; i!=i_max ; ++i ) {
316 ATH_MSG_VERBOSE ("============== i=" << i << " =============");
317 ATH_MSG_VERBOSE ( *(setSCT[i]));
318 }
319 ATH_MSG_VERBOSE ("==========================================");
320
321 // fit TRT part of the track with PseudoMeas on z_0, theta
322 Trk::Track* trkSCT=(m_trackFitter->fit(Gaudi::Hive::currentContext()
323 ,setSCT
324 , *perTrk
325 , true
326 , Trk::pion
327 //, Trk::muon
328 //, Trk::nonInteracting
329 )).release() ;
330 if( !trkSCT ) {
331 ATH_MSG_DEBUG( "RefitTracksAndVertex() : Fit of SCT part of the track failed! " ) ;
332 return nullptr ;
333 }
334 const Trk::Perigee* perSCT = trkSCT->perigeeParameters();
335 ATH_MSG_VERBOSE( "RefitTracksAndVertex() : perSCT " << *perSCT) ;
336
337 return trkSCT;
338}
339
340MsgStream& operator<<( MsgStream& outst, const RefitTracksAndVertex& alg ) {
341 return alg.dump( outst ) ;
342}
343
344MsgStream& RefitTracksAndVertex::dump( MsgStream& outst ) const {
345 outst << std::endl ;
346 outst << "|-------------------------------------------------------------------";
347 outst << "-----------------------------|" << std::endl ;
348 outst << "| processed : "
349 << std::setw(7) << m_nTracksProcessed
350 << " tracks |"
351 << std::endl ;
352 outst << "| accepted by track presel. : "
353 << std::setw(7) << m_nTracksPresel
354 << " tracks |"
355 << std::endl ;
356 outst << "| accepted by track presel. + PM : "
357 << std::setw(7) << m_nTracksAccepted
358 << " tracks |"
359 << std::endl ;
360 outst << "| ------------------------------------------------------------------";
361 outst << "---------------------------- |" << std::endl ;
362 outst << "| reject by # PIX hits : "
363 << std::setw(7) << m_nRejectPIX
364 << " tracks |"
365 << std::endl ;
366 outst << "| reject by # SCT hits : "
367 << std::setw(7) << m_nRejectSCT
368 << " tracks |"
369 << std::endl ;
370 outst << "| reject by # TRT hits : "
371 << std::setw(7) << m_nRejectTRT
372 << " tracks |"
373 << std::endl ;
374 outst << "| ------------------------------------------------------------------";
375 outst << "---------------------------- |" << std::endl ;
376 outst << "| reject by exist. PM(TRT) : "
377 << std::setw(7) << m_nRejectPM
378 << " tracks |"
379 << std::endl ;
380 outst << "|-------------------------------------------------------------------";
381 outst << "-----------------------------|" << std::endl ;
382 return outst ;
383}
Scalar theta() const
theta method
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
This class provides an interface to generate or decode an identifier for the upper levels of the dete...
#define CHECK(...)
Evaluate an expression and check for errors.
#define AmgSymMatrix(dim)
MsgStream & operator<<(MsgStream &outst, const RefitTracksAndVertex &alg)
DataVector< Trk::Track > TrackCollection
This typedef represents a collection of Trk::Track objects.
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
ServiceHandle< StoreGateSvc > & evtStore()
const ServiceHandle< StoreGateSvc > & detStore() const
DataModel_detail::const_iterator< DataVector > const_iterator
Standard const_iterator.
Definition DataVector.h:838
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.
std::string m_vertexListInput
Name of the TrackCollection (input).
StatusCode execute(const EventContext &ctx)
execute method of this algorithm that is called for each event
size_t m_nTracksPresel
Counter for number of tracks passing the preselection.
const AtlasDetectorID * m_idHelper
Detector ID helper.
double m_selEtaMax
maximal eta cut value for the TrackSelection
const Trk::MeasurementSet addPM(Trk::MeasurementSet &ms, const Trk::PseudoMeasurementOnTrack *pm)
adds a PseudoMeasurement to a MeasurementSet
StatusCode initialize()
initialize method of this algorithm.
MsgStream & dump(MsgStream &outst) const
double m_selEtaMin
minimal eta cut value for the TrackSelection
Trk::Track * fitSCTOnlyTrack(const Trk::Track *track)
Strips of all TRT hits from the track and replaces them with a TRT momentum constraint from a the TRT...
int m_selNHitSCTMin
minimal number of SCT hits cut value for the TrackSelection
int m_selNHitPIXMin
minimal number of PIX hits cut value for the TrackSelection
RefitTracksAndVertex(const std::string &name, ISvcLocator *pSvcLocator)
The RefitTracksAndVertex is an implementation to add the so-called TRT momentum constraint on a track...
const Trk::PseudoMeasurementOnTrack * createPMfromSi(const Trk::Perigee *mp)
creates a PseudoMeasurement with (z0, theta) from extended track perigee parameters
size_t m_nRejectSCT
Counter for number of tracks failing the min number of SCT hits req.
ToolHandle< Trk::IVertexFitter > m_vertexFitter
The TrackFitter to refit the tracks (segment, momentum constraint).
size_t m_nTracksProcessed
Counter for number of tracks processed.
std::string m_outputVertexContainerName
Name of vertex container.
size_t m_nRejectPM
Counter for number of tracks failing the addition of a pseudo-measurement (PM).
size_t m_nRejectPIX
Counter for number of tracks failing the min number of PIX hits req.
StatusCode finalize()
finalize method of this algorithm.
bool m_refitTracks
refitTracks
double m_selPtMin
minimal pT cut value for the TrackSelection
bool m_applyTrkSel
apply a selection on tracks or not
size_t m_nRejectTRT
Counter for number of tracks failing the min number of TRT hits req.
ToolHandle< Trk::ITrackFitter > m_trackFitter
The TrackFitter to refit the tracks (segment, momentum constraint).
std::string m_trackListOutput
Name of the TrackCollection (Output).
bool m_addPM
apply a pseudo measurement based on the original track (theta,z0)
size_t m_nTracksAccepted
Counter for number of tracks passing the preselection and with PM.
double eta() const
Access method for pseudorapidity - from momentum.
double pT() const
Access method for transverse momentum.
virtual const S & associatedSurface() const override final
Access to the Surface method.
Class to handle pseudo-measurements in fitters and on track objects.
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
Definition RIO_OnTrack.h:70
Identifier identify() const
return the identifier -extends MeasurementBase
Abstract Base Class for tracking surfaces.
Definition Surface.h:79
const Perigee * perigeeParameters() const
return Perigee.
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.
Eigen::Matrix< double, 3, 1 > Vector3D
std::vector< const MeasurementBase * > MeasurementSet
vector of fittable measurements
Definition FitterTypes.h:30
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ theta
Definition ParamDefs.h:66
@ z0
Definition ParamDefs.h:64
std::pair< double, ParamDefs > DefinedParameter
Typedef to of a std::pair<double, ParamDefs> to identify a passed-through double as a specific type o...
@ PriVtx
Primary vertex.
VertexAuxContainer_v1 VertexAuxContainer
Definition of the current jet auxiliary container.
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Vertex_v1 Vertex
Define the latest version of the vertex class.