ATLAS Offline Software
Loading...
Searching...
No Matches
RefitTracksAndVertex.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 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
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(trackParametersToFit, position );
195 if(vertex){
196 theVertexContainer->push_back (vertex);
197 vertex->setVertexType(xAOD::VxType::PriVtx);
198
199 ATH_MSG_DEBUG("Old Vtx " << primaryVertex->position());
200 ATH_MSG_DEBUG("New Vtx " << vertex->position());
201 }
202 }
203 }
204
205
206
207
208
209 return StatusCode::SUCCESS;
210} // execute(.)
211
212
214 Trk::DefinedParameter z0 ( mp->parameters()[Trk::z0], Trk::z0 ) ;
215 Trk::DefinedParameter theta( mp->parameters()[Trk::theta], Trk::theta ) ;
216 std::vector<Trk::DefinedParameter> defPar ;
217 defPar.push_back( z0 ) ;
218 defPar.push_back( theta ) ;
219 if( !mp->covariance() ) return nullptr;
220 Trk::LocalParameters parFromSi( defPar ) ;
221 AmgSymMatrix(2) covFromSi;
222
223 covFromSi( 0, 0 ) = (*mp->covariance())( Trk::z0,Trk::z0 ) ;
224 covFromSi( 1, 1 ) = (*mp->covariance())( Trk::theta,Trk::theta ) ;
225 covFromSi( 1, 0 ) = (*mp->covariance())( Trk::z0, Trk::theta ) ;
226 covFromSi( 0, 1 ) = (*mp->covariance())( Trk::z0, Trk::theta ) ;
227
228 const Trk::Surface& mpSurf = mp->associatedSurface() ;
229
231 , covFromSi
232 , mpSurf
233 ) ;
234 return pm ;
235}
236
238 Trk::MeasurementSet sortedMS ;
239 sortedMS.push_back( pm ) ;
240 for( int i=0, i_max=ms.size() ; i!=i_max ; ++i ) {
241 sortedMS.push_back( ms[i] ) ;
242 }
243 return sortedMS ;
244}
245
247 Trk::MeasurementSet setSCT ;
248 Trk::MeasurementSet setPix ;
249 Trk::MeasurementSet setTRT ;
250
251 const Trk::Perigee* perTrk = track->perigeeParameters();
252 if( !perTrk ) {
253 ATH_MSG_WARNING("RefitTracksAndVertex() : No Perigee parameter on track!");
254 return nullptr ;
255 }
256
257 if( perTrk->eta() < m_selEtaMin || perTrk->eta() > m_selEtaMax)
258 return nullptr ;
259
260 if( perTrk->pT() < m_selPtMin)
261 return nullptr ;
262
263
264 //store all silicon measurements into the measurementset
265 DataVector<const Trk::MeasurementBase>::const_iterator it = track->measurementsOnTrack()->begin();
266 DataVector<const Trk::MeasurementBase>::const_iterator itEnd = track->measurementsOnTrack()->end();
267 for ( ; it!=itEnd; ++it){
268 if( !(*it) ) {
269 // log (MSG::WARNING) << "The MeasurementBase set has a void"
270 // << " member! Skip it.." << endmsg;
271 } else {
272 const Trk::RIO_OnTrack* rio = dynamic_cast <const Trk::RIO_OnTrack*>(*it);
273 if (rio != nullptr) {
274 const Identifier& surfaceID = (rio->identify()) ;
275 if( m_idHelper->is_sct(surfaceID) ) {
276 setSCT.push_back ( *it ) ;
277 } else if( m_idHelper->is_trt(surfaceID) ) {
278 setTRT.push_back ( *it ) ;
279 } else if( m_idHelper->is_pixel(surfaceID) ){
280 setPix.push_back ( *it ) ;
281 }
282 }
283 }
284 }
285
286 if( (int)setSCT.size() < m_selNHitSCTMin )
287 return nullptr;
288
289 ATH_MSG_DEBUG("RefitTracksAndVertex() : Found " << setSCT.size() << " SCT measurm's!" ) ;
290 ATH_MSG_DEBUG("RefitTracksAndVertex() : Found " << setPix.size() << " Pix measurm's!" ) ;
291 ATH_MSG_DEBUG("RefitTracksAndVertex() : Found " << setTRT.size() << " TRT measurm's!") ;
292
293
294 ATH_MSG_DEBUG( std::setiosflags( std::ios::scientific )) ;
295 ATH_MSG_DEBUG (std::setprecision( 7 )) ;
296 ATH_MSG_VERBOSE( std::setiosflags( std::ios::scientific )) ;
297 ATH_MSG_VERBOSE( std::setprecision( 7 )) ;
298
299 // now add z_0 and theta from original track as PseudoMeas to the TRT MeasurementSet
300 if(m_addPM){
301 const Trk::PseudoMeasurementOnTrack *pmFromSi = createPMfromSi( perTrk ) ;
302 if( !pmFromSi ) {
303 ATH_MSG_ERROR("RefitTracksAndVertex() : PseudoMeasurementOnTrack creation failed! " );
304 return nullptr ;
305 }
306 ATH_MSG_DEBUG( "RefitTracksAndVertex() : pmFromSi " << *pmFromSi) ;
307 Trk::MeasurementSet setSCT = addPM( setSCT, pmFromSi ) ;
308 }
309
310 // Add TRT hits as they do no harm
311 for( int i=0, i_max=setTRT.size() ; i!=i_max ; ++i ) {
312 setSCT.push_back( setTRT[i] ) ;
313 }
314
315 ATH_MSG_VERBOSE ( "RefitTracksAndVertex() : Si+PM MeasurementSet : " );
316 for( int i=0, i_max=setSCT.size() ; i!=i_max ; ++i ) {
317 ATH_MSG_VERBOSE ("============== i=" << i << " =============");
318 ATH_MSG_VERBOSE ( *(setSCT[i]));
319 }
320 ATH_MSG_VERBOSE ("==========================================");
321
322 // fit TRT part of the track with PseudoMeas on z_0, theta
323 Trk::Track* trkSCT=(m_trackFitter->fit(Gaudi::Hive::currentContext()
324 ,setSCT
325 , *perTrk
326 , true
327 , Trk::pion
328 //, Trk::muon
329 //, Trk::nonInteracting
330 )).release() ;
331 if( !trkSCT ) {
332 ATH_MSG_DEBUG( "RefitTracksAndVertex() : Fit of SCT part of the track failed! " ) ;
333 return nullptr ;
334 }
335 const Trk::Perigee* perSCT = trkSCT->perigeeParameters();
336 ATH_MSG_VERBOSE( "RefitTracksAndVertex() : perSCT " << *perSCT) ;
337
338 return trkSCT;
339}
340
341MsgStream& operator<<( MsgStream& outst, const RefitTracksAndVertex& alg ) {
342 return alg.dump( outst ) ;
343}
344
345MsgStream& RefitTracksAndVertex::dump( MsgStream& outst ) const {
346 outst << std::endl ;
347 outst << "|-------------------------------------------------------------------";
348 outst << "-----------------------------|" << std::endl ;
349 outst << "| processed : "
350 << std::setw(7) << m_nTracksProcessed
351 << " tracks |"
352 << std::endl ;
353 outst << "| accepted by track presel. : "
354 << std::setw(7) << m_nTracksPresel
355 << " tracks |"
356 << std::endl ;
357 outst << "| accepted by track presel. + PM : "
358 << std::setw(7) << m_nTracksAccepted
359 << " tracks |"
360 << std::endl ;
361 outst << "| ------------------------------------------------------------------";
362 outst << "---------------------------- |" << std::endl ;
363 outst << "| reject by # PIX hits : "
364 << std::setw(7) << m_nRejectPIX
365 << " tracks |"
366 << std::endl ;
367 outst << "| reject by # SCT hits : "
368 << std::setw(7) << m_nRejectSCT
369 << " tracks |"
370 << std::endl ;
371 outst << "| reject by # TRT hits : "
372 << std::setw(7) << m_nRejectTRT
373 << " tracks |"
374 << std::endl ;
375 outst << "| ------------------------------------------------------------------";
376 outst << "---------------------------- |" << std::endl ;
377 outst << "| reject by exist. PM(TRT) : "
378 << std::setw(7) << m_nRejectPM
379 << " tracks |"
380 << std::endl ;
381 outst << "|-------------------------------------------------------------------";
382 outst << "-----------------------------|" << std::endl ;
383 return outst ;
384}
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 with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
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)
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.
StatusCode execute()
execute method of this algorithm that is called for each event
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.
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.