Belle II Software development
StandaloneCosmicsCollector Class Reference

Track finding algorithm class for linear tracks produced by cosmics in the VXD without magnetic field. More...

#include <StandaloneCosmicsCollector.h>

Public Member Functions

 StandaloneCosmicsCollector ()=default
 Constructor.
 
 ~StandaloneCosmicsCollector ()=default
 Destructor.
 
void setSortingMode (unsigned short index)
 Set sorting mode used in addSpacePoints.
 
void addSpacePoints (std::vector< StoreArray< SpacePoint > > SPs)
 Function to initialize the track finder anew for an event with its set of SpacePoints provided via their StoreArray.
 
bool doFit (double qualityCut, int maxRejected, int minSPs)
 Function to perform the actual line fit based on the StoreArray of SpacePoints provided.
 
std::pair< std::vector< double >, std::vector< double > > getResult ()
 Getter for the position and momentum seed resulting from the linear fit.
 
std::vector< const SpacePoint * > getSPTC ()
 Getter for the sorted list of SpacePoints used for the final fit which met the given requirements.
 
double getReducedChi2 ()
 Getter for the final reduced chi squared value obtained for the set of SpacePoints used for the last performed fit.
 

Private Member Functions

void addSpacePoint (const SpacePoint *SP)
 Adding single SpacePoint to the sorted member vector m_spacePoints, beginning with the SpacePoint with the smallest radius sqrt(x^2 + y^2).
 
bool doLineFit (int minSPs)
 Function performing the actual line fit via a principal component analysis method yielding a direction vector based on the eigen vector corresponding to the largest eigenvalue and a seed position calculated as the mean of all given SpacePoints.
 
bool compareRads (const SpacePoint *a, const SpacePoint *b)
 Compare function used by addSpacePoint to sort the member vector of SpacePoints m_spacePoints by the radius calculated with x^2 + y^2.
 
void resortHits ()
 Function to resort the member vector of SpacePoints m_spacePoints based on the members m_start and m_direction obtained by the fit, so that the track candidate starts form the outermost hit and the following hits are sorted following the direction m_direction.
 
bool comparePars (const SpacePoint *a, const SpacePoint *b)
 Comparison function to compare two SpacePoints based on the distance between the start point of the fitted line m_start and their intersect with the fitted line.
 

Private Attributes

std::vector< double > m_start {0., 0., 0.}
 Start point obtained by the last performed line fit.
 
std::vector< double > m_direction {0., 0., 0.}
 Direction of the line obtained by the last performed line fit.
 
std::vector< const SpacePoint * > m_spacePoints
 Member vector of SpacePoints holding the SpacePoints considered for the track candidate.
 
std::pair< double, int > m_largestChi2 = std::pair<double, int>(0., 0)
 Pair containing the index of the vector m_spacePoints for the SpacePoint with the largest contribution to the chi2 value of the last fit and the respectiv contribution first: contribution to the total chi2 value of the last fit second: index of the SpacePoint with this largest contribution in the vector m_spacePoints.
 
double m_reducedChi2 = 10
 Member variable containing the reduced chi squared value of the current line fit.
 
unsigned short m_sortingMode = 1
 Storing identifier for sorting algorithm to be used for the function addSpacePoint.
 

Detailed Description

Track finding algorithm class for linear tracks produced by cosmics in the VXD without magnetic field.

The algorithm uses a simple principal component analysis approach to find a momentum and position seed assuming the presence of only the one track produced by the cosmic in the detector. SpacePoints produced by detector noise can be discarded by the TF by removing the biggest outlier until an adequate reduced chi squared value is reached. The track finder requires a minimal number of SpacePoints for a track, a reduced chi squared value below a given threshold, and the number of rejected SpacePoints to be below a given maximum.

Definition at line 33 of file StandaloneCosmicsCollector.h.

Member Function Documentation

◆ addSpacePoint()

void addSpacePoint ( const SpacePoint * SP)
inlineprivate

Adding single SpacePoint to the sorted member vector m_spacePoints, beginning with the SpacePoint with the smallest radius sqrt(x^2 + y^2).

Parameters
SP

Definition at line 157 of file StandaloneCosmicsCollector.h.

158 {
159 auto forwardIt = std::lower_bound(m_spacePoints.begin(), m_spacePoints.end(), SP,
160 [this](const SpacePoint * lhs, const SpacePoint * rhs)
161 -> bool { return this->compareRads(lhs, rhs); });
162 m_spacePoints.insert(forwardIt, SP);
163 }

◆ addSpacePoints()

void addSpacePoints ( std::vector< StoreArray< SpacePoint > > SPs)
inline

Function to initialize the track finder anew for an event with its set of SpacePoints provided via their StoreArray.

This also resets all internal variables for the new event.

Parameters
SPsStoreArray of SpacePoints of the event to be analyzed.

Definition at line 66 of file StandaloneCosmicsCollector.h.

67 {
68 m_spacePoints.clear();
69 m_direction.clear();
70 m_start.clear();
71 m_reducedChi2 = 10;
72 for (const auto& spArray : SPs) {
73 for (const auto& sp : spArray) {
74 addSpacePoint(&sp);
75 }
76 }
77 }

◆ comparePars()

bool comparePars ( const SpacePoint * a,
const SpacePoint * b )
inlineprivate

Comparison function to compare two SpacePoints based on the distance between the start point of the fitted line m_start and their intersect with the fitted line.

Parameters
aleft hand side SpacePoint
bright hand side SpacePoint
Returns
boolean true if a is closer to the start of the fitted line than b

Definition at line 317 of file StandaloneCosmicsCollector.h.

318 {
319 Eigen::Matrix<double, 3, 1> posA(a->getPosition().X(), a->getPosition().Y(), a->getPosition().Z());
320 Eigen::Matrix<double, 3, 1> posB(b->getPosition().X(), b->getPosition().Y(), b->getPosition().Z());
321
322 Eigen::Matrix<double, 3, 1> direction(m_direction[0], m_direction[1], m_direction[2]);
323 Eigen::Matrix<double, 3, 1> origin(m_start[0], m_start[1], m_start[2]);
324
325 Eigen::ParametrizedLine<double, 3> line(origin, direction.normalized());
326 Eigen::Hyperplane<double, 3> planeA(direction.normalized(), posA);
327 Eigen::Hyperplane<double, 3> planeB(direction.normalized(), posB);
328
329 double parA = line.intersectionParameter(planeA);
330 double parB = line.intersectionParameter(planeB);
331 return parA < parB;
332 }

◆ compareRads()

bool compareRads ( const SpacePoint * a,
const SpacePoint * b )
inlineprivate

Compare function used by addSpacePoint to sort the member vector of SpacePoints m_spacePoints by the radius calculated with x^2 + y^2.

The square root is omitted, as it does not matter for the comparison.

Parameters
aleft hand side SpacePoint
bright hand side SpacePoint
Returns
true if radius of a smaller than radius of b

Definition at line 269 of file StandaloneCosmicsCollector.h.

270 {
271 if (m_sortingMode == 1) {
272 double radA = a->getPosition().X() * a->getPosition().X() + a->getPosition().Y() * a->getPosition().Y();
273 double radB = b->getPosition().X() * b->getPosition().X() + b->getPosition().Y() * b->getPosition().Y();
274 return radA < radB;
275 } else if (m_sortingMode == 2) {
276 double xA = a->getPosition().X();
277 double xB = b->getPosition().X();
278 return xA < xB;
279 } else if (m_sortingMode == 3) {
280 double yA = a->getPosition().Y();
281 double yB = b->getPosition().Y();
282 return yA < yB;
283 } else {
284 B2FATAL("Invalid sorting mode chosen! You used " << m_sortingMode
285 << ". Must be one of 1 (by radius), 2 (by x) or 3 (by y).");
286 }
287 }

◆ doFit()

bool doFit ( double qualityCut,
int maxRejected,
int minSPs )
inline

Function to perform the actual line fit based on the StoreArray of SpacePoints provided.

The fit performs a principal component analysis based on the provided 3D-points, refitting the SpacePoints again with the worst Point removed, if the given qualityCut on the reduced chi squared value is not reached. This is done until the requirement is met, or a maximal number of rejected SpacePoints (maxRejected) is reached. Furthermore the fitting is aborted, if not a minimal number of SpacePoints (minSPs) is provided. The function returns true, if a track candidate fulfilling these requirements is found.

Parameters
qualityCut
maxRejected
minSPs
Returns
boolean true, if a sufficient track candidate is found, else false.

Definition at line 92 of file StandaloneCosmicsCollector.h.

93 {
94 bool fitting = true;
95 int rejected = 0;
96
97 while (m_reducedChi2 > qualityCut && fitting) {
98 fitting = doLineFit(minSPs);
99 if (not fitting) {return false;}
100 if (m_reducedChi2 > qualityCut) {
101 B2DEBUG(20, "Refitting without sp with index " << m_largestChi2.second
102 << " and chi2 contribution " << m_largestChi2.first << "...");
103 m_spacePoints.erase(m_spacePoints.begin() + m_largestChi2.second);
104 rejected++;
105 }
106 if (rejected > maxRejected) { B2DEBUG(20, "Rejected " << rejected << "!"); return false; }
107 }
108 return fitting;
109 }

◆ doLineFit()

bool doLineFit ( int minSPs)
inlineprivate

Function performing the actual line fit via a principal component analysis method yielding a direction vector based on the eigen vector corresponding to the largest eigenvalue and a seed position calculated as the mean of all given SpacePoints.

The function sets the member m_reducedChi2 which is calculated based on the distance of all given points to the fitted line. The final value is divided by the number of SPs in the track candidate, yielding a reduced chi2. If the provided SpacePoints are less than a given minimal length the fit will be aborted returning false. If enough SpacePoints are provided, the function returns true independent from the value of the calculated reduced chi2.

Parameters
minSPs
Returns
boolean

Definition at line 178 of file StandaloneCosmicsCollector.h.

179 {
180 int nHits = m_spacePoints.size();
181 B2DEBUG(20, "Trying fit with " << nHits << " hits...");
182 // Aborting fit and returning false if the minimal number of SpacePoints required is not met.
183 if (nHits < minSPs) { B2DEBUG(20, "Only " << nHits << " hits!"); return false; };
184
185 Eigen::Matrix<double, 3, 1> average = Eigen::Matrix<double, 3, 1>::Zero(3, 1);
186 Eigen::Matrix<double, Eigen::Dynamic, 3> data = Eigen::Matrix<double, Eigen::Dynamic, 3>::Zero(nHits, 3);
187 Eigen::Matrix<double, Eigen::Dynamic, 3> P = Eigen::Matrix<double, Eigen::Dynamic, 3>::Zero(nHits, 3);
188
189 for (const auto& sp : m_spacePoints) {
190 average(0) += sp->getPosition().X();
191 average(1) += sp->getPosition().Y();
192 average(2) += sp->getPosition().Z();
193 }
194 average *= 1. / nHits;
195
196 int index = 0;
197 for (const auto& sp : m_spacePoints) {
198 data(index, 0) = sp->getPosition().X();
199 data(index, 1) = sp->getPosition().Y();
200 data(index, 2) = sp->getPosition().Z();
201
202 P(index, 0) = sp->getPosition().X() - average(0);
203 P(index, 1) = sp->getPosition().Y() - average(1);
204 P(index, 2) = sp->getPosition().Z() - average(2);
205 index++;
206 }
207
208 //Principal component analysis
209 Eigen::Matrix<double, 3, 3> product = P.transpose() * P;
210
211 Eigen::EigenSolver<Eigen::Matrix<double, 3, 3>> eigencollection(product);
212 Eigen::Matrix<double, 3, 1> eigenvalues = eigencollection.eigenvalues().real();
213 Eigen::Matrix<std::complex<double>, 3, 3> eigenvectors = eigencollection.eigenvectors();
214 Eigen::Matrix<double, 3, 1>::Index maxRow, maxCol;
215 eigenvalues.maxCoeff(&maxRow, &maxCol);
216
217 Eigen::Matrix<double, 3, 1> e = eigenvectors.col(maxRow).real();
218
219 // Setting starting point to the data point with larges radius
220 Eigen::Matrix<double, 3, 1> start = data.row(nHits - 1).transpose();
221 Eigen::Matrix<double, 3, 1> second = data.row(nHits - 2).transpose();
222 m_start = {start(0), start(1), start(2)};
223 // Setting direction vector towards the inside of the detector
224 m_direction = {e(0), e(1), e(2)};
225 Eigen::Hyperplane<double, 3> plane(e.normalized(), start);
226 Eigen::ParametrizedLine<double, 3> line(second, e.normalized());
227 double factor = line.intersectionParameter(plane);
228 if (factor > 0) {
229 m_direction = { -e(0), -e(1), -e(2)};
230 }
231
232 // Resorting SpacePoints based on the obtained line fit result.
233 resortHits();
234
235 // Calculating reduced chi2 value of the line fit using the distances of the SpacePoints to the obtained line and
236 // keeping the m_spacePoints index and the chi2 contribution of the SpacePoint with the largest contribution.
237 m_reducedChi2 = 0;
238 m_largestChi2 = std::pair<double, int>(0., 0);
239 int largestChi2_index = 0;
240 for (const auto& sp : m_spacePoints) {
241 Eigen::Matrix<double, 3, 1> origin(sp->getPosition().X(), sp->getPosition().Y(), sp->getPosition().Z());
242 plane = Eigen::Hyperplane<double, 3>(e.normalized(), origin);
243
244 Eigen::Matrix<double, 3, 1> point = line.intersectionPoint(plane);
245
246 double delta_chi2 = (point - origin).transpose() * (point - origin);
247 m_reducedChi2 += delta_chi2;
248
249 if (delta_chi2 > m_largestChi2.first) {
250 m_largestChi2.first = delta_chi2;
251 m_largestChi2.second = largestChi2_index;
252 }
253 largestChi2_index++;
254 }
255
256 m_reducedChi2 *= 1. / nHits;
257 B2DEBUG(20, "Reduced chi2 result is " << m_reducedChi2 << "...");
258 return true;
259 }

◆ getReducedChi2()

double getReducedChi2 ( )
inline

Getter for the final reduced chi squared value obtained for the set of SpacePoints used for the last performed fit.

Returns
double chi square value for the last fit performed for the event.

Definition at line 144 of file StandaloneCosmicsCollector.h.

145 {
146 return m_reducedChi2;
147 }

◆ getResult()

std::pair< std::vector< double >, std::vector< double > > getResult ( )
inline

Getter for the position and momentum seed resulting from the linear fit.

The momentum is rather only a vector giving the direction of the straight fit with a sufficiently large magnitude. The position seed is set to be the outermost SpacePoint with the direction seed pointing towards the next inner hit. If the fit does not meet the given requirements, the result of the last try for this event is returned. If the event does not have the required minimal number of SpacePoints, vectors with zeros are returned.

Returns
pair of vectors of double. First is position seed, second the direction/momentum seed.

Definition at line 121 of file StandaloneCosmicsCollector.h.

122 {
123 return std::pair<std::vector<double>, std::vector<double>> (m_start, m_direction);
124 }

◆ getSPTC()

std::vector< const SpacePoint * > getSPTC ( )
inline

Getter for the sorted list of SpacePoints used for the final fit which met the given requirements.

The SpacePoints are sorted, starting at the position seed and towards the direction obtained by the final fit. If the fit did not meet the requirements, the last set which was used for the current event is returned.

Returns
vector of sorted SpacePoints used for the final fit.

Definition at line 133 of file StandaloneCosmicsCollector.h.

134 {
135 return m_spacePoints;
136 }

◆ resortHits()

void resortHits ( )
inlineprivate

Function to resort the member vector of SpacePoints m_spacePoints based on the members m_start and m_direction obtained by the fit, so that the track candidate starts form the outermost hit and the following hits are sorted following the direction m_direction.

This sorting is done using the comparison function comparePars.

Definition at line 296 of file StandaloneCosmicsCollector.h.

297 {
298 std::vector<const SpacePoint*> sortedSPs;
299 for (auto& SP : m_spacePoints) {
300 auto forwardIt = std::lower_bound(sortedSPs.begin(), sortedSPs.end(), SP,
301 [this](const SpacePoint * lhs, const SpacePoint * rhs) -> bool {
302 return this->comparePars(lhs, rhs);
303 });
304 sortedSPs.insert(forwardIt, SP);
305 }
306 m_spacePoints = sortedSPs;
307 }

◆ setSortingMode()

void setSortingMode ( unsigned short index)
inline

Set sorting mode used in addSpacePoints.

One can choose to sort 1: by radius 2: by x-coordinate 3: by y-coordinate by calling this function with the respective index. If the function is not used, the default set at the declaration of m_sortingMode is used.

Definition at line 51 of file StandaloneCosmicsCollector.h.

52 {
53 if ((index < 1) or (index > 3)) {
54 B2FATAL("Invalid sorting mode chosen! You used " << m_sortingMode
55 << ". Must be one of 1 (by radius), 2 (by x) or 3 (by y).");
56 }
57 m_sortingMode = index;
58 }

Member Data Documentation

◆ m_direction

std::vector<double> m_direction {0., 0., 0.}
private

Direction of the line obtained by the last performed line fit.

Definition at line 338 of file StandaloneCosmicsCollector.h.

338{0., 0., 0.};

◆ m_largestChi2

std::pair<double, int> m_largestChi2 = std::pair<double, int>(0., 0)
private

Pair containing the index of the vector m_spacePoints for the SpacePoint with the largest contribution to the chi2 value of the last fit and the respectiv contribution first: contribution to the total chi2 value of the last fit second: index of the SpacePoint with this largest contribution in the vector m_spacePoints.

Definition at line 349 of file StandaloneCosmicsCollector.h.

◆ m_reducedChi2

double m_reducedChi2 = 10
private

Member variable containing the reduced chi squared value of the current line fit.

The value is obtained by dividing the actual chi2 value by the number of SPs in the track candidate. Is reset to 10 in addSpacePoints.

Definition at line 355 of file StandaloneCosmicsCollector.h.

◆ m_sortingMode

unsigned short m_sortingMode = 1
private

Storing identifier for sorting algorithm to be used for the function addSpacePoint.

1: by radius (default) 2: by x-value 3: by y-value

Definition at line 362 of file StandaloneCosmicsCollector.h.

◆ m_spacePoints

std::vector<const SpacePoint*> m_spacePoints
private

Member vector of SpacePoints holding the SpacePoints considered for the track candidate.

Definition at line 341 of file StandaloneCosmicsCollector.h.

◆ m_start

std::vector<double> m_start {0., 0., 0.}
private

Start point obtained by the last performed line fit.

Definition at line 335 of file StandaloneCosmicsCollector.h.

335{0., 0., 0.};

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