ATLAS Offline Software
Loading...
Searching...
No Matches
AFPSiDBasicKalmanTool Class Reference

Class reconstructing tracks using basic Kalman filter. More...

#include <AFPSiDBasicKalmanTool.h>

Inheritance diagram for AFPSiDBasicKalmanTool:
Collaboration diagram for AFPSiDBasicKalmanTool:

Public Member Functions

 AFPSiDBasicKalmanTool (const std::string &type, const std::string &name, const IInterface *parent)
virtual ~AFPSiDBasicKalmanTool () override
virtual StatusCode initialize () override
 Read parameters from job options and print tool configuration.
virtual StatusCode finalize () override
 Does nothing.
StatusCode reconstructTracks (std::unique_ptr< xAOD::AFPTrackContainer > &outputContainer, const EventContext &ctx) const override
 Does actual tracks reconstruction.
const std::string & outputContainerName () const override
void filterTrkCollection (std::list< AFPSiDBasicKalmanToolTrack > &reconstructedTracks) const
 Filters duplicate tracks from the list.
unsigned int countSharedClusters (const AFPSiDBasicKalmanToolTrack &firstTrack, const AFPSiDBasicKalmanToolTrack &secondTrack) const
 Returns number of the same clusters used to reconstruct two tracks.
void clearAllLayers (AFPLocRecoStationBasicObj &my_stationClusters) const
 clear all layers from clusters saved in #m_stationsClusters;

Private Member Functions

void fillLayersWithClusters (AFPLocRecoStationBasicObj &my_stationClusters, SG::ReadHandle< xAOD::AFPSiHitsClusterContainer > &hitsClusterContainer) const
 Fills layers with clusters of hits, dividing them into stations and layers.
void initMatrixFromVector (CLHEP::HepMatrix &matrix, const std::vector< float > &vec1D) const
 Method that initialises 2D matrix using values from the vector.
bool checkMatrixAndVectorSize (const CLHEP::HepMatrix &matrix, const std::vector< float > &vec1D) const
 Returns true if vector size equals matrix rows times columns.
bool areNeighbours (const xAOD::AFPSiHitsCluster *a, const xAOD::AFPSiHitsCluster *b, const double dist) const
 Checks if clusters are neighbours Compares distance between them to m_allowedDistanceBetweenClustersInSeed.
void saveToXAOD (const AFPSiDBasicKalmanToolTrack &recoTrack, std::unique_ptr< xAOD::AFPTrackContainer > &containerToFill, SG::ReadHandle< xAOD::AFPSiHitsClusterContainer > &hitsClusterContainer) const
 Save reconstructed track to the xAOD container.

Private Attributes

Gaudi::Property< std::string > m_tracksContainerName {this, "tracksContainerName", "AFPTrackContainer", "Name of the container in which tracks are saved"}
 Name of the xAOD container to which tracks will be saved; actual saving is done in AFPSIDLocRecoTool.
Gaudi::Property< int > m_stationID {this, "stationID", 0, "ID number of station for which tracks should be reconstructed"}
 AFP station ID for which tracks will be reconstructed.
CLHEP::HepMatrix m_observationModel
 The observation model which maps the true state space into the observed space ( \(H_{k}\))
Gaudi::Property< std::vector< float > > m_observationModelInit {this, "observationModel", {}, "vector used to initialise observation model matrix (2x4), the first four numbers correspond to the first row of the matrix"}
 A vector used to initialise m_observationModel matrix.
CLHEP::HepMatrix m_observationNoise
 The observation noise matrix.
Gaudi::Property< std::vector< float > > m_observationNoiseInit {this, "observationNoise", {}, "vector used to initialise observation noise matrix (2x2), the first two numbers correspond to the first row of the matrix"}
 A vector used to initialise m_observationNoise matrix.
CLHEP::HepMatrix m_processNoiseCov
 The covariance matrix of process noise.
Gaudi::Property< std::vector< float > > m_processNoiseCovInit {this, "processNoiseCov", {}, "A vector used to initialise process noise covariance matrix (4x4).The first 4 numbers correspond to the first row of the matrix."}
 A vector used to initialise m_processNoiseCov matrix.
CLHEP::HepMatrix m_aposterioriCov
 A posteriori error covariance matrix (a measure of the estimated accuracy of the state estimate) ( \(P_{k|k}\))
Gaudi::Property< std::vector< float > > m_aposterioriCovInit {this, "aposterioriCov", {}, "A vector used to initialise a posteriori covariance matrix (4x4). The first 4 numbers correspond to the first row of the matrix."}
 A vector used to initialise m_aposterioriCov matrix.
Gaudi::Property< int > m_numberOfLayersInStation {this, "numberOfLayersInStations", 4, "The size of the vector sets number of stations. Each element defines number of pixel layers in the station."}
 Number of layers used for reconstruction in station If not set in job options 4 stations, each with 4 layers are created.
SG::ReadHandleKey< xAOD::AFPSiHitsClusterContainerm_hitsClusterContainerKey {this, "AFPSiHitsClusterContainerKey", "AFPSiHitsClusterContainer", "Name of the container with clusters of hits from which tracks are to be reconstructed"}
 Name of the xAOD container with clusters to be used in track reconstruction.
Gaudi::Property< double > m_maxAllowedDistance {this, "maxAllowedDistance", 10, "Maximal distance at which cluster can be joined to the track"}
 Maximal distance at which cluster can be joined to the track (Default = 100 - all clusters)
Gaudi::Property< unsigned int > m_minClustersNumber {this, "minClustersNumber", 3, "Minimal number of clusters in track. If there are less clusters track is rejected"}
 Minimal number of clusters in track. If there are less clusters track is rejected (Default = 3)
Gaudi::Property< unsigned int > m_maxSharedClusters {this, "maxSharedClusters", 2, "Maximal number of hits that two tracks can share. If they share more one is deleted."}
 Maximal number of hits that two tracks can share. If they share more one is deleted.
Gaudi::Property< float > m_clusterMaxChi2 {this, "clusterMaxChi2", 3, "Maximal value of chi2 for which a cluster is added."}
 Maximal value of chi2 for which a cluster is added.
Gaudi::Property< float > m_trackMaxChi2 {this, "trackMaxChi2", 3, "Maximal value of chi2 for the track."}
 Maximal value of chi2 for the track.
Gaudi::Property< double > m_allowedDistanceBetweenClustersInSeed {this, "allowedDistanceBetweenClustersInSeed", 0.5, "Maximum allowed distance between clusters in a seed to be considered coming from the same proton; if the difference between clusters is 2 layers (3 layers), this distance is multiplied by 2 (3)"}
 Maximum allowed distance between clusters to be considered coming from the same proton.
Gaudi::Property< std::vector< std::pair< int, int > > > m_layersForSeeds {this, "layersForSeeds", {{0,1}}, "Pairs of layers that are used to create seeds."}
 Vector of pairs of layers. These pairs will be used to make seeds.
ToolHandle< GenericMonitoringToolm_monTool {this, "MonTool", "", "Monitoring tool"}
 Monitoring.

Detailed Description

Class reconstructing tracks using basic Kalman filter.

The idea of the reconstruction is presented in the talk https://indico.cern.ch/event/275484/contributions/1618277/attachments/499062/689421/mdyndal_2013-10-15_AFP_Gen.pdf

Definition at line 49 of file AFPSiDBasicKalmanTool.h.

Constructor & Destructor Documentation

◆ AFPSiDBasicKalmanTool()

AFPSiDBasicKalmanTool::AFPSiDBasicKalmanTool ( const std::string & type,
const std::string & name,
const IInterface * parent )

Definition at line 29 of file AFPSiDBasicKalmanTool.cxx.

31 :
32 base_class( type, name, parent )
33{
34}

◆ ~AFPSiDBasicKalmanTool()

virtual AFPSiDBasicKalmanTool::~AFPSiDBasicKalmanTool ( )
inlineoverridevirtual

Definition at line 57 of file AFPSiDBasicKalmanTool.h.

57{}

Member Function Documentation

◆ areNeighbours()

bool AFPSiDBasicKalmanTool::areNeighbours ( const xAOD::AFPSiHitsCluster * a,
const xAOD::AFPSiHitsCluster * b,
const double dist ) const
private

Checks if clusters are neighbours Compares distance between them to m_allowedDistanceBetweenClustersInSeed.

Definition at line 215 of file AFPSiDBasicKalmanTool.cxx.

216{
217 const double dx = a->xLocal() - b->xLocal();
218 const double dy = a->yLocal() - b->yLocal();
219 const double maxDistanceSq = allowedDistanceBetweenClustersInSeed * allowedDistanceBetweenClustersInSeed;
220
221 return dx * dx + dy * dy <= maxDistanceSq;
222}
TList * a

◆ checkMatrixAndVectorSize()

bool AFPSiDBasicKalmanTool::checkMatrixAndVectorSize ( const CLHEP::HepMatrix & matrix,
const std::vector< float > & vec1D ) const
inlineprivate

Returns true if vector size equals matrix rows times columns.

Definition at line 204 of file AFPSiDBasicKalmanTool.h.

205 {return ((int)vec1D.size()) == matrix.num_row()*matrix.num_col();}

◆ clearAllLayers()

void AFPSiDBasicKalmanTool::clearAllLayers ( AFPLocRecoStationBasicObj & my_stationClusters) const
inline

clear all layers from clusters saved in #m_stationsClusters;

Definition at line 92 of file AFPSiDBasicKalmanTool.h.

93 {my_stationClusters.clear();}
void clear()
Clear clusters from each layer.

◆ countSharedClusters()

unsigned int AFPSiDBasicKalmanTool::countSharedClusters ( const AFPSiDBasicKalmanToolTrack & firstTrack,
const AFPSiDBasicKalmanToolTrack & secondTrack ) const

Returns number of the same clusters used to reconstruct two tracks.

Definition at line 410 of file AFPSiDBasicKalmanTool.cxx.

411{
412 unsigned int sharedClustersN = 0;
413
414 for (const xAOD::AFPSiHitsCluster* firstCluster : firstTrack.clustersInTrack())
415 for (const xAOD::AFPSiHitsCluster* secondCluster : secondTrack.clustersInTrack())
416 if (firstCluster == secondCluster) {
417 ++sharedClustersN;
418 break;
419 }
420
421 return sharedClustersN;
422}
const std::list< const xAOD::AFPSiHitsCluster * > & clustersInTrack() const
Clusters used to reconstruct the track.
AFPSiHitsCluster_v1 AFPSiHitsCluster

◆ fillLayersWithClusters()

void AFPSiDBasicKalmanTool::fillLayersWithClusters ( AFPLocRecoStationBasicObj & my_stationClusters,
SG::ReadHandle< xAOD::AFPSiHitsClusterContainer > & hitsClusterContainer ) const
private

Fills layers with clusters of hits, dividing them into stations and layers.

Definition at line 199 of file AFPSiDBasicKalmanTool.cxx.

200{
201 // retrieve clusters
202 try {
203 // fill layers with clusters
204 for (const xAOD::AFPSiHitsCluster* theCluster : *hitsClusterContainer)
205 if (theCluster->stationID() == m_stationID) // check if cluster is from the correct station
206 my_stationClusters.clustersInLayer(theCluster->pixelLayerID()).push_back(theCluster);
207 }
208 catch (const std::out_of_range& outOfRange) {
209 ATH_MSG_WARNING("Cluster with station or pixel ID outside expected range. Aborting track reconstruction.");
210 clearAllLayers(my_stationClusters);
211 }
212
213 }
#define ATH_MSG_WARNING(x)
std::vector< const xAOD::AFPSiHitsCluster * > & clustersInLayer(const unsigned int layerID)
Returns vector of clusters in the layer with given ID.
Gaudi::Property< int > m_stationID
AFP station ID for which tracks will be reconstructed.
void clearAllLayers(AFPLocRecoStationBasicObj &my_stationClusters) const
clear all layers from clusters saved in m_stationsClusters;

◆ filterTrkCollection()

void AFPSiDBasicKalmanTool::filterTrkCollection ( std::list< AFPSiDBasicKalmanToolTrack > & reconstructedTracks) const

Filters duplicate tracks from the list.

The tracks are considered duplicates if more than m_maxSharedClusters clusters are the same in both tracks. In such situation track quality is calculated according to the formula \(q = N_{clusters} + ((\chi^2_{trk, max} - \chi^2{trk})/(\chi^2_{trk, max} + 1))\). The track with smaller value of \(q\) is deleted.

Definition at line 350 of file AFPSiDBasicKalmanTool.cxx.

351{
352 //filtering tracking collection using shared hits + quality requirement
353 std::list<AFPSiDBasicKalmanToolTrack>::iterator mainIterator = tracksList.begin();
354 while (mainIterator != tracksList.end()) {
355
356 bool deletedMain = false;
357 // start comparing from the next object to the one currently testing
358 std::list<AFPSiDBasicKalmanToolTrack>::iterator compareIterator = mainIterator;
359 ++compareIterator;
360 while (compareIterator != tracksList.end())
361 {
362 const unsigned int sharedClusters = countSharedClusters(*mainIterator, *compareIterator);
363 bool removeMain = false;
364 bool removeCompare = false;
365
366 if(sharedClusters > m_maxSharedClusters)
367 {
368 // calculate quality of the tracks preferring tracks with more clusters
369 const AFPSiDBasicKalmanToolTrack& mainTrk = (*mainIterator);
370 const double mainTrkQuality = mainTrk.chi2Smooth().size() + ((m_trackMaxChi2 - mainTrk.trkChi2NDFSmooth()) / (m_trackMaxChi2 + 1.));
371 AFPSiDBasicKalmanToolTrack& compareTrk = (*compareIterator);
372 const double compareTrkQuality = compareTrk.chi2Smooth().size() + ((m_trackMaxChi2 - compareTrk.trkChi2NDFSmooth()) / (m_trackMaxChi2 + 1.));
373
374 if(mainTrkQuality >= compareTrkQuality)
375 {
376 removeCompare = true;
377 }
378 else
379 {
380 removeMain = true;
381 }
382 }
383 else if(sharedClusters == mainIterator->clustersInTrack().size() && sharedClusters == compareIterator->clustersInTrack().size())
384 {
385 // these are the same tracks
386 removeCompare = true;
387 }
388
389 if (removeCompare)
390 {
391 tracksList.erase(compareIterator++);
392 continue;
393 }
394 else if(removeMain)
395 {
396 tracksList.erase(mainIterator++);
397 deletedMain = true;
398 break;
399 }
400
401 ++compareIterator;
402 } // end while (compareIterator)
403
404 // go to the next object only if the main was not deleted, because iterator was already moved when deleting
405 if (!deletedMain) ++mainIterator;
406
407 } // end mainIterator
408}
double trkChi2NDFSmooth() const
Chi2 per degrees of freedom (clusters) for the whole smoothed track.
const std::list< double > & chi2Smooth() const
History of chi2 for each step after smoothing.
unsigned int countSharedClusters(const AFPSiDBasicKalmanToolTrack &firstTrack, const AFPSiDBasicKalmanToolTrack &secondTrack) const
Returns number of the same clusters used to reconstruct two tracks.
Gaudi::Property< float > m_trackMaxChi2
Maximal value of chi2 for the track.
Gaudi::Property< unsigned int > m_maxSharedClusters
Maximal number of hits that two tracks can share. If they share more one is deleted.

◆ finalize()

StatusCode AFPSiDBasicKalmanTool::finalize ( )
overridevirtual

Does nothing.

Definition at line 194 of file AFPSiDBasicKalmanTool.cxx.

195{
196 return StatusCode::SUCCESS;
197}

◆ initialize()

StatusCode AFPSiDBasicKalmanTool::initialize ( )
overridevirtual

Read parameters from job options and print tool configuration.

Definition at line 36 of file AFPSiDBasicKalmanTool.cxx.

37{
38 CHECK( m_hitsClusterContainerKey.initialize() );
39
40 // monitoring
41 if (!(m_monTool.name().empty())) {
42 CHECK( m_monTool.retrieve() );
43 ATH_MSG_DEBUG("m_monTool name: " << m_monTool);
44 }
45
46 // === Kalman matrices initialization ===
47
48 // --- initialise observation model matrix ---
49 m_observationModel = CLHEP::HepMatrix(2, 4, 0);
50 // if proper m_observationModelInit is available use it
53 }
54 else {
55 // otherwise use default unit transformation
56 m_observationModel[0][0] = 1.;
57 m_observationModel[1][2] = 1.;
58 }
59 ATH_MSG_DEBUG("Observation model matrix (Hk) is initialised to: "<<m_observationModel);
60
61 // --- set observation noise matrix ---
62 m_observationNoise = CLHEP::HepMatrix(2, 2, 0);
64 // use matrix from job options if set
66 }
67 else {
68 // if matrix is not initialised from the job options use pixel sizes
69 const double pixelSizeX = 0.05;
70 const double pixelSizeY = 0.25;
71 m_observationNoise[0][0] = pixelSizeX*pixelSizeX;
72 m_observationNoise[1][1] = pixelSizeY*pixelSizeY;
73 }
74 ATH_MSG_DEBUG("Observation noise matrix (Vk) is initialised to: "<<m_observationNoise);
75
76 // --- set covariance matrix of the process noise
77 m_processNoiseCov = CLHEP::HepMatrix(4, 4, 0); // initialise with default values
79 // use matrix from job options if set
81 }
82 ATH_MSG_DEBUG("Process noise covariance matrix (Qk) is initialised to: "<<m_processNoiseCov);
83
84
85 // --- set initial value of the a posteriori error covariance matrix ---
86 m_aposterioriCov = CLHEP::HepMatrix(4, 4, 0);
88 // use matrix from job options if set
90 }
91 else {
92 // set default matrix if not defined in job options
93 const float planesZDist = 9.;
94
95 const float pixelSizeX = 0.05;
96 m_aposterioriCov[0][0] = pixelSizeX * pixelSizeX / 3.;
97 m_aposterioriCov[1][1] = pixelSizeX * pixelSizeX / (planesZDist*planesZDist*3.);
98
99 const float pixelSizeY = 0.25;
100 m_aposterioriCov[2][2] = pixelSizeY * pixelSizeY / 3.;
101 m_aposterioriCov[3][3] = pixelSizeY * pixelSizeY / (planesZDist*planesZDist*3.);
102 }
103 ATH_MSG_DEBUG("A posteriori error covariance matrix (Pkk) is initialised to: "<<m_aposterioriCov);
104
105
106 // print information about initialised layers and stations
108 {
109 ATH_MSG_DEBUG("Station with ID="<<m_stationID <<" will have "<<m_numberOfLayersInStation<<" layers.");
110 }
111 else
112 {
113 ATH_MSG_ERROR("Impossible to reconstruct tracks with less than 2 layers in station, but configured to run with "<<m_numberOfLayersInStation<<".");
114 return StatusCode::FAILURE;
115 }
116
117
118 if(m_layersForSeeds.size()==0)
119 {
120 ATH_MSG_ERROR("Impossible to make seeds when length of m_layersForSeeds is 0 ");
121 return StatusCode::FAILURE;
122 }
123
124 for(auto lfs = m_layersForSeeds.begin(); lfs != m_layersForSeeds.end(); )
125 {
126 if(lfs->first == lfs->second)
127 {
128 ATH_MSG_WARNING("Both layer IDs in m_layersForSeeds are equal to "<<lfs->first<<", removing this pair of layer IDs");
129 lfs=m_layersForSeeds.erase(lfs);
130 }
131 else if(lfs->first >= m_numberOfLayersInStation || lfs->second >= m_numberOfLayersInStation || lfs->first < 0 || lfs->second < 0)
132 {
133 ATH_MSG_WARNING("First layer ID is "<<lfs->first<<", second layer ID is "<<lfs->second<<", while number of layers is "<<m_numberOfLayersInStation<<", removing this pair");
134 lfs=m_layersForSeeds.erase(lfs);
135 }
136 else
137 {
138 if(lfs->first > lfs->second)
139 {
140 ATH_MSG_INFO("The first layer ID for seeds ("<<lfs->first<<") is higher than the second layer ID ("<<lfs->second<<"), swapping");
141 int tmp=lfs->first;
142 lfs->first=lfs->second;
143 lfs->second=tmp;
144 }
145
146 ++lfs;
147 }
148 }
149
150 if(m_layersForSeeds.size()>=2)
151 {
153 auto lfs1 = m_layersForSeeds.begin();
154 auto lfs2 = m_layersForSeeds.begin()+1;
155 for(;lfs2!=m_layersForSeeds.end();)
156 {
157 if(*lfs1==*lfs2)
158 {
159 ATH_MSG_WARNING("Found duplicity for {"<<lfs2->first<<","<<lfs2->second<<"}, removing the duplicity");
160 lfs2=m_layersForSeeds.erase(lfs2);
161 }
162 else
163 {
164 ++lfs1;
165 ++lfs2;
166 }
167 }
168 }
169
170 if(m_layersForSeeds.size()==0)
171 {
172 ATH_MSG_ERROR("Nothing is left in m_layersForSeeds after cleaning, please fix the setup");
173 return StatusCode::FAILURE;
174 }
175
176 std::string stringLayersForSeeds="{";
177 for(auto lfs = m_layersForSeeds.begin(); lfs != m_layersForSeeds.end(); ++lfs)
178 {
179 stringLayersForSeeds+="{"+std::to_string(lfs->first)+","+std::to_string(lfs->second)+"},";
180 }
181 stringLayersForSeeds.pop_back();
182 ATH_MSG_DEBUG("Pairs of layer IDs that will make track seeds = "<<stringLayersForSeeds<<"}");
183
184
185 // print information about remaining parameters
186 ATH_MSG_DEBUG("Maximal distance at which cluster can be joined to the track m_maxAllowedDistance = "<<m_maxAllowedDistance);
187 ATH_MSG_DEBUG("Minimal number of clusters in track. If there are less clusters track is rejected m_minClustersNumber = "<<m_minClustersNumber);
188 ATH_MSG_DEBUG("Maximal chi2 of cluster to be added to track = "<<m_clusterMaxChi2);
189 ATH_MSG_DEBUG("Maximal chi2 of the track = "<<m_trackMaxChi2);
190
191 return StatusCode::SUCCESS;
192}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
#define CHECK(...)
Evaluate an expression and check for errors.
CLHEP::HepMatrix m_observationModel
The observation model which maps the true state space into the observed space ( )
CLHEP::HepMatrix m_aposterioriCov
A posteriori error covariance matrix (a measure of the estimated accuracy of the state estimate) ( )
void initMatrixFromVector(CLHEP::HepMatrix &matrix, const std::vector< float > &vec1D) const
Method that initialises 2D matrix using values from the vector.
Gaudi::Property< std::vector< float > > m_observationNoiseInit
A vector used to initialise m_observationNoise matrix.
Gaudi::Property< std::vector< float > > m_observationModelInit
A vector used to initialise m_observationModel matrix.
Gaudi::Property< std::vector< float > > m_aposterioriCovInit
A vector used to initialise m_aposterioriCov matrix.
Gaudi::Property< unsigned int > m_minClustersNumber
Minimal number of clusters in track. If there are less clusters track is rejected (Default = 3)
SG::ReadHandleKey< xAOD::AFPSiHitsClusterContainer > m_hitsClusterContainerKey
Name of the xAOD container with clusters to be used in track reconstruction.
CLHEP::HepMatrix m_observationNoise
The observation noise matrix.
Gaudi::Property< float > m_clusterMaxChi2
Maximal value of chi2 for which a cluster is added.
bool checkMatrixAndVectorSize(const CLHEP::HepMatrix &matrix, const std::vector< float > &vec1D) const
Returns true if vector size equals matrix rows times columns.
Gaudi::Property< int > m_numberOfLayersInStation
Number of layers used for reconstruction in station If not set in job options 4 stations,...
ToolHandle< GenericMonitoringTool > m_monTool
Monitoring.
Gaudi::Property< std::vector< float > > m_processNoiseCovInit
A vector used to initialise m_processNoiseCov matrix.
Gaudi::Property< std::vector< std::pair< int, int > > > m_layersForSeeds
Vector of pairs of layers. These pairs will be used to make seeds.
CLHEP::HepMatrix m_processNoiseCov
The covariance matrix of process noise.
Gaudi::Property< double > m_maxAllowedDistance
Maximal distance at which cluster can be joined to the track (Default = 100 - all clusters)
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.

◆ initMatrixFromVector()

void AFPSiDBasicKalmanTool::initMatrixFromVector ( CLHEP::HepMatrix & matrix,
const std::vector< float > & vec1D ) const
private

Method that initialises 2D matrix using values from the vector.

The method checks if the matrix size agrees with the vector size (N_columns*N_rows = N_vector). If the sizes are incompatible the matrix is unchanged.

Parameters
[out]thematrix to be initialised
[in]thevector with values to be copied to the matrix

Definition at line 424 of file AFPSiDBasicKalmanTool.cxx.

425{
426 const int rowsN = matrix.num_row();
427 const int columnsN = matrix.num_col();
428
429 // check if size of matrix and vector are compatible
430 if ( ((int)vec1D.size()) == rowsN*columnsN) {
431 // if sizes are compatible initialise matrix
432 for (int rowID = 0; rowID < rowsN; rowID++)
433 for (int columnID = 0; columnID < columnsN; columnID++)
434 matrix[rowID][columnID] = vec1D[rowID*columnsN + columnID];
435 }
436 else {
437 // if sizes are incompatible print warning message and do nothing
438 std::stringstream warningMessage;
439 warningMessage<<"Matrix size ("<<rowsN<<"x"<<columnsN
440 <<" = "<<rowsN*columnsN<<") is not compatible with vector size: "
441 <<vec1D.size()<<".";
442 warningMessage<<"Matrix will not be initialised. The vector contains following numbers: ";
443 for (const float number : vec1D)
444 warningMessage<<number<<" ";
445
446 ATH_MSG_WARNING (warningMessage.str());
447 }
448}
std::string number(const double &d, const std::string &s)
Definition utils.cxx:186

◆ outputContainerName()

const std::string & AFPSiDBasicKalmanTool::outputContainerName ( ) const
inlineoverride

Definition at line 76 of file AFPSiDBasicKalmanTool.h.

Gaudi::Property< std::string > m_tracksContainerName
Name of the xAOD container to which tracks will be saved; actual saving is done in AFPSIDLocRecoTool.

◆ reconstructTracks()

StatusCode AFPSiDBasicKalmanTool::reconstructTracks ( std::unique_ptr< xAOD::AFPTrackContainer > & outputContainer,
const EventContext & ctx ) const
override

Does actual tracks reconstruction.

  1. Reads clusters from the xAOD container.
  2. Creates seeds by making all combinations of clusters in the first and second planes.
  3. For each seed all remaining layers are checked for clusters that fit the track. If the cluster is found it is added to the track if not a number of holes (xAOD::AFPTrack::m_holes) is incremented.
  4. If the track has more clusters than m_minClustersNumber a smoothing algorithm is run on it and added to the output list.
  5. The output list of tracks if filtered for duplicates using AFPSiDBasicKalmanTool::filterTrkCollection().
  6. The output list is saved to xAOD containers and objects.

Definition at line 224 of file AFPSiDBasicKalmanTool.cxx.

225{
226 SG::ReadHandle<xAOD::AFPSiHitsClusterContainer> hitsClusterContainer( m_hitsClusterContainerKey, ctx );
227 if(!hitsClusterContainer.isValid())
228 {
229 // this is allowed, there might be no AFP data in the input
230 return StatusCode::SUCCESS;
231 }
232
233
234 using LayersIter_t = std::vector<std::vector<const xAOD::AFPSiHitsCluster *>>::const_iterator;
235
236 // prepare list for storing temporary reconstructed tracks
237 std::list<AFPSiDBasicKalmanToolTrack> reconstructedTracks;
238
239 AFPLocRecoStationBasicObj my_stationClusters;
240
241 // the track reconstruction will seg fault if there are less than 2 layers (seed cannot be created)
243
244
245 clearAllLayers(my_stationClusters);
246 fillLayersWithClusters(my_stationClusters, hitsClusterContainer);
247
248 // ===== do tracks reconstruction =====
249 // start with making seeds by combining all hits from the first and second layer IDs
250
251 for(auto layersForSeeds = m_layersForSeeds.begin(); layersForSeeds != m_layersForSeeds.end(); ++layersForSeeds)
252 {
253 const LayersIter_t layersEnd = my_stationClusters.layers().end();
254 const LayersIter_t layersBegin = my_stationClusters.layers().begin();
255
256 // make all combinations between first and second layer ID
257 LayersIter_t firstLayer = layersBegin+layersForSeeds->first;
258 LayersIter_t secondLayer = layersBegin+layersForSeeds->second;
259
260 for (const xAOD::AFPSiHitsCluster* firstCluster : *firstLayer)
261 {
262 for (const xAOD::AFPSiHitsCluster* secondCluster : *secondLayer)
263 {
264 // skip if clusters are too far, one "m_allowedDistanceBetweenClustersInSeed" per 1 layer difference
265 if(!areNeighbours(firstCluster, secondCluster, m_allowedDistanceBetweenClustersInSeed*(layersForSeeds->second-layersForSeeds->first)))
266 {
267 continue;
268 }
269
270 // make the seed
271 reconstructedTracks.emplace_back(firstCluster, secondCluster, m_observationModel, m_observationNoise, m_aposterioriCov);
272 AFPSiDBasicKalmanToolTrack& theTrack = reconstructedTracks.back();
273
274 // loop over remaining layers
275 for (LayersIter_t remainingLayersIT = layersBegin; remainingLayersIT != layersEnd; ++remainingLayersIT)
276 {
277 if(remainingLayersIT==firstLayer || remainingLayersIT==secondLayer) continue;
278
279 const xAOD::AFPSiHitsCluster* closestCluster = theTrack.findNearestCluster(*remainingLayersIT, m_maxAllowedDistance);
280 if (closestCluster != nullptr) // if there is a cluster near the track add it to the track
281 theTrack.addCluster(closestCluster, m_clusterMaxChi2);
282 else // if there is no cluster add a hole (missing cluster in the layer)
283 theTrack.addHole();
284 }
285
286 // process the track only if there are enough clusters, remove the ones with less tracks
287 if (theTrack.clustersInTrack().size() >= m_minClustersNumber)
288 theTrack.smooth();
289 else
290 reconstructedTracks.pop_back();
291
292 } // end of loop over seeds (all combinations between the first and second layer
293 }
294 }
295
296 filterTrkCollection(reconstructedTracks);
297
298 // === Save result to xAOD container ===
299 for (const AFPSiDBasicKalmanToolTrack& track : reconstructedTracks)
300 {
301 saveToXAOD(track, outputContainer, hitsClusterContainer);
302 }
303
304 // monitoring
305 auto trkStationID = Monitored::Collection("TrkStationID",*outputContainer, &xAOD::AFPTrack::stationID);
306 auto trkXLocal = Monitored::Collection("TrkXLocal", *outputContainer, &xAOD::AFPTrack::xLocal);
307 auto trkYLocal = Monitored::Collection("TrkYLocal", *outputContainer, &xAOD::AFPTrack::yLocal);
308 auto trkZLocal = Monitored::Collection("TrkZLocal", *outputContainer, &xAOD::AFPTrack::zLocal);
309 auto trkXSlope = Monitored::Collection("TrkXSlope", *outputContainer, &xAOD::AFPTrack::xSlope);
310 auto trkYSlope = Monitored::Collection("TrkYSlope", *outputContainer, &xAOD::AFPTrack::ySlope);
311 auto trkNClusters = Monitored::Collection("TrkNClusters",*outputContainer, &xAOD::AFPTrack::nClusters);
312 auto trkNHoles = Monitored::Collection("TrkNHoles", *outputContainer, &xAOD::AFPTrack::nHoles);
313 auto trkChi2 = Monitored::Collection("TrkChi2", *outputContainer, &xAOD::AFPTrack::chi2);
314 int statID = m_stationID;
315 auto trkMask = Monitored::Collection("TrkMask",*outputContainer, [statID](const xAOD::AFPTrack* t){return t->stationID()==statID;});
316 Monitored::Group(m_monTool, trkStationID, trkXLocal, trkYLocal, trkZLocal, trkXSlope, trkYSlope, trkNClusters, trkNHoles, trkChi2, trkMask);
317
318 return StatusCode::SUCCESS;
319}
void setNumberOfLayers(const unsigned int layersN)
Sets vector containing layers to the specified size.
std::vector< std::vector< const xAOD::AFPSiHitsCluster * > > & layers()
Returns vector layers, each layer is a vector of clusters.
void smooth()
Run smoothing algorithm.
void addHole()
Increase number of holes by 1. (see m_holes)
void addCluster(const xAOD::AFPSiHitsCluster *cluster, const float htiMaxChi2)
Adds a new cluster to the track and updates history and position.
const xAOD::AFPSiHitsCluster * findNearestCluster(const std::vector< const xAOD::AFPSiHitsCluster * > &clusters, const float maxAllowedDistance) const
Finds the cluster which is nearest to the track, returns nullptr if no is found.
void filterTrkCollection(std::list< AFPSiDBasicKalmanToolTrack > &reconstructedTracks) const
Filters duplicate tracks from the list.
void saveToXAOD(const AFPSiDBasicKalmanToolTrack &recoTrack, std::unique_ptr< xAOD::AFPTrackContainer > &containerToFill, SG::ReadHandle< xAOD::AFPSiHitsClusterContainer > &hitsClusterContainer) const
Save reconstructed track to the xAOD container.
void fillLayersWithClusters(AFPLocRecoStationBasicObj &my_stationClusters, SG::ReadHandle< xAOD::AFPSiHitsClusterContainer > &hitsClusterContainer) const
Fills layers with clusters of hits, dividing them into stations and layers.
bool areNeighbours(const xAOD::AFPSiHitsCluster *a, const xAOD::AFPSiHitsCluster *b, const double dist) const
Checks if clusters are neighbours Compares distance between them to m_allowedDistanceBetweenClustersI...
Gaudi::Property< double > m_allowedDistanceBetweenClustersInSeed
Maximum allowed distance between clusters to be considered coming from the same proton.
float xLocal() const
Track position along X axis in station local coordinate system.
int stationID() const
Index of the station where track was reconstructed.
float xSlope() const
Slope of the reconstructed track along X axis in local coordinate system.
float yLocal() const
Track position along Y axis in station local coordinate system.
float chi2() const
value of the track fit to the selected clusters.
int nClusters() const
Number of clusters used to reconstruct the track.
float ySlope() const
Slope of the reconstructed track along Y axis in local coordinate system.
unsigned int nHoles() const
Number of empty layers that the track passes through.
float zLocal() const
Track position along Z axis in station local coordinate system.
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
AFPTrack_v2 AFPTrack
Definition AFPTrack.h:12

◆ saveToXAOD()

void AFPSiDBasicKalmanTool::saveToXAOD ( const AFPSiDBasicKalmanToolTrack & recoTrack,
std::unique_ptr< xAOD::AFPTrackContainer > & containerToFill,
SG::ReadHandle< xAOD::AFPSiHitsClusterContainer > & hitsClusterContainer ) const
private

Save reconstructed track to the xAOD container.

Definition at line 321 of file AFPSiDBasicKalmanTool.cxx.

322{
323 auto *track = containerToFill->push_back(std::make_unique<xAOD::AFPTrack>());
324
325 const xAOD::AFPSiHitsCluster* firstCluster = recoTrack.clustersInTrack().front();
326 const CLHEP::HepVector& firstPoint = recoTrack.positionAndSlopeSmooth().back(); // reading from smoothed collection which is done in reversed order
327
328 track->setStationID(firstCluster->stationID());
329 track->setXLocal(firstPoint[0]);
330 track->setYLocal(firstPoint[2]);
331 track->setZLocal(firstCluster->zLocal());
332 track->setXSlope(firstPoint[1]);
333 track->setYSlope(firstPoint[3]);
334 track->setNClusters(recoTrack.clustersInTrack().size());
335 track->setNHoles(recoTrack.holes());
336 track->setChi2(recoTrack.trkChi2NDFSmooth());
338
339 // add links to clusters
340 ATH_MSG_DEBUG("Track position: (x="<<track->xLocal()<<", y="<<track->yLocal()<<", z="<<track->zLocal()<<") slope: (dx="<<track->xSlope()<<", dy="<<track->ySlope()<<") chi2="<<track->chi2()<<", nHoles="<<track->nHoles()<<", nClusters="<<track->nClusters());
341 for (const xAOD::AFPSiHitsCluster* theCluster : recoTrack.clustersInTrack()) {
342 ElementLink< xAOD::AFPSiHitsClusterContainer > clusterLink;
343 clusterLink.toContainedElement(*hitsClusterContainer, theCluster);
344 track->addCluster(clusterLink);
345
346 ATH_MSG_DEBUG("cluster position: (x="<<theCluster->xLocal()<<", y="<<theCluster->yLocal()<<", z="<<theCluster->zLocal()<<")");
347 }
348}
const std::list< CLHEP::HepVector > & positionAndSlopeSmooth() const
Vectors of reconstructed true positions for each step after smoothing .
float zLocal() const
Cluster position along Z axis in station local coordinate system.
int stationID() const
Index of the station with pixels cluster.
static constexpr int basicKalman
basic Kalman algorithm id=0

Member Data Documentation

◆ m_allowedDistanceBetweenClustersInSeed

Gaudi::Property<double> AFPSiDBasicKalmanTool::m_allowedDistanceBetweenClustersInSeed {this, "allowedDistanceBetweenClustersInSeed", 0.5, "Maximum allowed distance between clusters in a seed to be considered coming from the same proton; if the difference between clusters is 2 layers (3 layers), this distance is multiplied by 2 (3)"}
private

Maximum allowed distance between clusters to be considered coming from the same proton.

Definition at line 185 of file AFPSiDBasicKalmanTool.h.

185{this, "allowedDistanceBetweenClustersInSeed", 0.5, "Maximum allowed distance between clusters in a seed to be considered coming from the same proton; if the difference between clusters is 2 layers (3 layers), this distance is multiplied by 2 (3)"};

◆ m_aposterioriCov

CLHEP::HepMatrix AFPSiDBasicKalmanTool::m_aposterioriCov
private

A posteriori error covariance matrix (a measure of the estimated accuracy of the state estimate) ( \(P_{k|k}\))

This is 4x4 matrix. If the matrix is not defined in job options it set to 0.

Definition at line 154 of file AFPSiDBasicKalmanTool.h.

◆ m_aposterioriCovInit

Gaudi::Property<std::vector<float> > AFPSiDBasicKalmanTool::m_aposterioriCovInit {this, "aposterioriCov", {}, "A vector used to initialise a posteriori covariance matrix (4x4). The first 4 numbers correspond to the first row of the matrix."}
private

A vector used to initialise m_aposterioriCov matrix.

The first 4 numbers correspond to the first row of the matrix.

Definition at line 159 of file AFPSiDBasicKalmanTool.h.

159{this, "aposterioriCov", {}, "A vector used to initialise a posteriori covariance matrix (4x4). The first 4 numbers correspond to the first row of the matrix."};

◆ m_clusterMaxChi2

Gaudi::Property<float> AFPSiDBasicKalmanTool::m_clusterMaxChi2 {this, "clusterMaxChi2", 3, "Maximal value of chi2 for which a cluster is added."}
private

Maximal value of chi2 for which a cluster is added.

Definition at line 179 of file AFPSiDBasicKalmanTool.h.

179{this, "clusterMaxChi2", 3, "Maximal value of chi2 for which a cluster is added."};

◆ m_hitsClusterContainerKey

SG::ReadHandleKey<xAOD::AFPSiHitsClusterContainer> AFPSiDBasicKalmanTool::m_hitsClusterContainerKey {this, "AFPSiHitsClusterContainerKey", "AFPSiHitsClusterContainer", "Name of the container with clusters of hits from which tracks are to be reconstructed"}
private

Name of the xAOD container with clusters to be used in track reconstruction.

Definition at line 167 of file AFPSiDBasicKalmanTool.h.

167{this, "AFPSiHitsClusterContainerKey", "AFPSiHitsClusterContainer", "Name of the container with clusters of hits from which tracks are to be reconstructed"};

◆ m_layersForSeeds

Gaudi::Property<std::vector<std::pair<int,int> > > AFPSiDBasicKalmanTool::m_layersForSeeds {this, "layersForSeeds", {{0,1}}, "Pairs of layers that are used to create seeds."}
private

Vector of pairs of layers. These pairs will be used to make seeds.

Definition at line 188 of file AFPSiDBasicKalmanTool.h.

188{this, "layersForSeeds", {{0,1}}, "Pairs of layers that are used to create seeds."};

◆ m_maxAllowedDistance

Gaudi::Property<double> AFPSiDBasicKalmanTool::m_maxAllowedDistance {this, "maxAllowedDistance", 10, "Maximal distance at which cluster can be joined to the track"}
private

Maximal distance at which cluster can be joined to the track (Default = 100 - all clusters)

Definition at line 170 of file AFPSiDBasicKalmanTool.h.

170{this, "maxAllowedDistance", 10, "Maximal distance at which cluster can be joined to the track"};

◆ m_maxSharedClusters

Gaudi::Property<unsigned int> AFPSiDBasicKalmanTool::m_maxSharedClusters {this, "maxSharedClusters", 2, "Maximal number of hits that two tracks can share. If they share more one is deleted."}
private

Maximal number of hits that two tracks can share. If they share more one is deleted.

Definition at line 176 of file AFPSiDBasicKalmanTool.h.

176{this, "maxSharedClusters", 2, "Maximal number of hits that two tracks can share. If they share more one is deleted."};

◆ m_minClustersNumber

Gaudi::Property<unsigned int> AFPSiDBasicKalmanTool::m_minClustersNumber {this, "minClustersNumber", 3, "Minimal number of clusters in track. If there are less clusters track is rejected"}
private

Minimal number of clusters in track. If there are less clusters track is rejected (Default = 3)

Definition at line 173 of file AFPSiDBasicKalmanTool.h.

173{this, "minClustersNumber", 3, "Minimal number of clusters in track. If there are less clusters track is rejected"};

◆ m_monTool

ToolHandle<GenericMonitoringTool> AFPSiDBasicKalmanTool::m_monTool {this, "MonTool", "", "Monitoring tool"}
private

Monitoring.

Definition at line 215 of file AFPSiDBasicKalmanTool.h.

215{this, "MonTool", "", "Monitoring tool"};

◆ m_numberOfLayersInStation

Gaudi::Property<int> AFPSiDBasicKalmanTool::m_numberOfLayersInStation {this, "numberOfLayersInStations", 4, "The size of the vector sets number of stations. Each element defines number of pixel layers in the station."}
private

Number of layers used for reconstruction in station If not set in job options 4 stations, each with 4 layers are created.

Definition at line 164 of file AFPSiDBasicKalmanTool.h.

164{this, "numberOfLayersInStations", 4, "The size of the vector sets number of stations. Each element defines number of pixel layers in the station."};

◆ m_observationModel

CLHEP::HepMatrix AFPSiDBasicKalmanTool::m_observationModel
private

The observation model which maps the true state space into the observed space ( \(H_{k}\))

This is 2x4 matrix, where dimension 2 comes from two position variables (x, y) and dimension 4 comes from position and slope in each of the two directions. \(z_{k} = H_{k} x_{k} + v_{k}\)

If no proper observationModel array is defined in python configuration the default unit transformation is used - X and Y position are simply copied.

Definition at line 114 of file AFPSiDBasicKalmanTool.h.

◆ m_observationModelInit

Gaudi::Property<std::vector<float> > AFPSiDBasicKalmanTool::m_observationModelInit {this, "observationModel", {}, "vector used to initialise observation model matrix (2x4), the first four numbers correspond to the first row of the matrix"}
private

A vector used to initialise m_observationModel matrix.

The first four numbers correspond to the first row of the matrix.

Definition at line 119 of file AFPSiDBasicKalmanTool.h.

119{this, "observationModel", {}, "vector used to initialise observation model matrix (2x4), the first four numbers correspond to the first row of the matrix"};

◆ m_observationNoise

CLHEP::HepMatrix AFPSiDBasicKalmanTool::m_observationNoise
private

The observation noise matrix.

( \(v_{k}\))

This is 2x2 matrix In standard Kalman it is assumed to be zero mean Gaussian white noise with covariance specified by the matrix. \(z_{k} = H_{k} x_{k} + v_{k}\)

If the matrix is not defined in job options it set to be diagonal matrix with squared sizes of pixel.

Definition at line 130 of file AFPSiDBasicKalmanTool.h.

◆ m_observationNoiseInit

Gaudi::Property<std::vector<float> > AFPSiDBasicKalmanTool::m_observationNoiseInit {this, "observationNoise", {}, "vector used to initialise observation noise matrix (2x2), the first two numbers correspond to the first row of the matrix"}
private

A vector used to initialise m_observationNoise matrix.

The first two numbers correspond to the first row of the matrix.

Definition at line 135 of file AFPSiDBasicKalmanTool.h.

135{this, "observationNoise", {}, "vector used to initialise observation noise matrix (2x2), the first two numbers correspond to the first row of the matrix"};

◆ m_processNoiseCov

CLHEP::HepMatrix AFPSiDBasicKalmanTool::m_processNoiseCov
private

The covariance matrix of process noise.

( \(Q_{k}\))

This is 4x4 matrix. If the matrix is not defined in job options it set to 0.

Definition at line 142 of file AFPSiDBasicKalmanTool.h.

◆ m_processNoiseCovInit

Gaudi::Property<std::vector<float> > AFPSiDBasicKalmanTool::m_processNoiseCovInit {this, "processNoiseCov", {}, "A vector used to initialise process noise covariance matrix (4x4).The first 4 numbers correspond to the first row of the matrix."}
private

A vector used to initialise m_processNoiseCov matrix.

The first 4 numbers correspond to the first row of the matrix.

Definition at line 147 of file AFPSiDBasicKalmanTool.h.

147{this, "processNoiseCov", {}, "A vector used to initialise process noise covariance matrix (4x4).The first 4 numbers correspond to the first row of the matrix."};

◆ m_stationID

Gaudi::Property<int> AFPSiDBasicKalmanTool::m_stationID {this, "stationID", 0, "ID number of station for which tracks should be reconstructed"}
private

AFP station ID for which tracks will be reconstructed.

Definition at line 102 of file AFPSiDBasicKalmanTool.h.

102{this, "stationID", 0, "ID number of station for which tracks should be reconstructed"};

◆ m_trackMaxChi2

Gaudi::Property<float> AFPSiDBasicKalmanTool::m_trackMaxChi2 {this, "trackMaxChi2", 3, "Maximal value of chi2 for the track."}
private

Maximal value of chi2 for the track.

Definition at line 182 of file AFPSiDBasicKalmanTool.h.

182{this, "trackMaxChi2", 3, "Maximal value of chi2 for the track."};

◆ m_tracksContainerName

Gaudi::Property<std::string> AFPSiDBasicKalmanTool::m_tracksContainerName {this, "tracksContainerName", "AFPTrackContainer", "Name of the container in which tracks are saved"}
private

Name of the xAOD container to which tracks will be saved; actual saving is done in AFPSIDLocRecoTool.

Definition at line 99 of file AFPSiDBasicKalmanTool.h.

99{this, "tracksContainerName", "AFPTrackContainer", "Name of the container in which tracks are saved"};

The documentation for this class was generated from the following files: