Belle II Software development
CDCSZFitter.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#include <tracking/trackFindingCDC/fitting/CDCSZFitter.h>
9
10#include <tracking/trackFindingCDC/fitting/EigenObservationMatrix.h>
11#include <tracking/trackFindingCDC/fitting/CDCSZObservations.h>
12#include <tracking/trackFindingCDC/fitting/CDCObservations2D.h>
13
14#include <tracking/trackingUtilities/eventdata/tracks/CDCTrack.h>
15#include <tracking/trackingUtilities/eventdata/tracks/CDCSegmentPair.h>
16
17#include <tracking/trackingUtilities/eventdata/segments/CDCSegment3D.h>
18#include <tracking/trackingUtilities/eventdata/segments/CDCSegment2D.h>
19
20#include <tracking/trackingUtilities/eventdata/trajectories/CDCTrajectorySZ.h>
21#include <tracking/trackingUtilities/eventdata/trajectories/CDCTrajectory2D.h>
22
23#include <tracking/trackingUtilities/geometry/SZParameters.h>
24
25#include <tracking/trackingUtilities/numerics/EigenView.h>
26
27#include <framework/logging/Logger.h>
28
29#include <Eigen/Eigen>
30#include <Eigen/QR>
31#include <Eigen/Core>
32
33using namespace Belle2;
34using namespace TrackFindingCDC;
35using namespace TrackingUtilities;
36
38{
39 static CDCSZFitter szFitter;
40 return szFitter;
41}
42
43namespace {
44 UncertainSZLine fitZ(const Eigen::Matrix<double, 3, 3>& sumMatrixWSZ)
45 {
46 // Solve the normal equation X * n = y
47 Eigen::Matrix<double, 2, 2> sumMatrixWS = sumMatrixWSZ.block<2, 2>(0, 0);
48 Eigen::Matrix<double, 2, 1> sumVectorZOverWS = sumMatrixWSZ.block<2, 1>(0, 2);
49 Eigen::Matrix<double, 2, 1> nZOverWS = sumMatrixWS.llt().solve(sumVectorZOverWS);
50 double chi2 = sumMatrixWSZ(2, 2) - nZOverWS.transpose() * sumVectorZOverWS;
51
52 using namespace NSZParameterIndices;
53 SZParameters szParameters;
54 szParameters(c_TanL) = nZOverWS(1);
55 szParameters(c_Z0) = nZOverWS(0);
56
57 SZPrecision szPrecision;
58 szPrecision(c_TanL, c_TanL) = sumMatrixWS(1, 1);
59 szPrecision(c_Z0, c_TanL) = sumMatrixWS(0, 1);
60 szPrecision(c_TanL, c_Z0) = sumMatrixWS(1, 0);
61 szPrecision(c_Z0, c_Z0) = sumMatrixWS(0, 0);
62
63 SZCovariance szCovariance = SZUtil::covarianceFromFullPrecision(szPrecision);
64 return UncertainSZLine(szParameters, szCovariance, chi2);
65 }
66
67 // Declare function as currently unused to avoid compiler warning
68 UncertainSZLine fitSZ(const Eigen::Matrix<double, 3, 3>& sumMatrixWSZ) __attribute__((__unused__));
69
71 UncertainSZLine fitSZ(const Eigen::Matrix<double, 3, 3>& sumMatrixWSZ)
72 {
73
74 // Matrix of averages
75 Eigen::Matrix<double, 3, 3> averageMatrixWSZ = sumMatrixWSZ / sumMatrixWSZ(0);
76
77 // Measurement means
78 Eigen::Matrix<double, 3, 1> meansWSZ = averageMatrixWSZ.row(0);
79
80 // Covariance matrix
81 Eigen::Matrix<double, 3, 3> covMatrixWSZ = averageMatrixWSZ - meansWSZ * meansWSZ.transpose();
82
83 Eigen::Matrix<double, 2, 2> covMatrixSZ = covMatrixWSZ.block<2, 2>(1, 1);
84 Eigen::Matrix<double, 2, 1> meansSZ = meansWSZ.segment<2>(1);
85
86 Eigen::SelfAdjointEigenSolver<Eigen::Matrix<double, 2, 2>> eigensolver(covMatrixSZ);
87 if (eigensolver.info() != Eigen::Success) {
88 B2WARNING(
89 "SelfAdjointEigenSolver could not compute the eigen values of the observation matrix");
90 }
91
92 // the eigenvalues are generated in increasing order
93 // we are interested in the lowest one since we want to compute the normal vector of the line
94 // here
95 Eigen::Matrix<double, 2, 1> nSZ = eigensolver.eigenvectors().col(0);
96 B2INFO("nSZ " << nSZ);
97 nSZ /= std::copysign(nSZ.norm(), -nSZ(1)); // Making n2 negative to normalize to forward along s
98 Eigen::Matrix<double, 3, 1> nWSZ;
99 // cppcheck-suppress constStatement
100 nWSZ << -meansSZ.transpose() * nSZ, nSZ;
101 B2INFO("nWSZ " << nWSZ);
102
103 double chi2 = nWSZ.transpose() * sumMatrixWSZ * nWSZ;
104
105 Eigen::Matrix<double, 3, 3> precN = sumMatrixWSZ;
106
107 using namespace NSZParameterIndices;
108 SZParameters szParameters;
109 szParameters(c_TanL) = -nWSZ(1) / nWSZ(2);
110 szParameters(c_Z0) = -nWSZ(0) / nWSZ(2);
111
112 Eigen::Matrix<double, 3, 2> ambiguitySZToN = Eigen::Matrix<double, 3, 2>::Zero();
113 ambiguitySZToN(0, c_Z0) = -nWSZ(2);
114 ambiguitySZToN(0, c_TanL) = -nWSZ(1) * nWSZ(0);
115 ambiguitySZToN(1, c_TanL) = -nWSZ(2) * nWSZ(2) * nWSZ(2);
116 ambiguitySZToN(2, c_TanL) = nWSZ(1) * nWSZ(2) * nWSZ(2);
117
118 SZPrecision szPrecision;
119 mapToEigen(szPrecision) = ambiguitySZToN.transpose() * precN * ambiguitySZToN;
120
121 SZCovariance szCovariance = SZUtil::covarianceFromFullPrecision(szPrecision);
122 return UncertainSZLine(szParameters, szCovariance, chi2);
123 }
124}
125
127{
128 const bool onlyStereo = true;
129 CDCSZObservations observationsSZ(EFitVariance::c_Proper, onlyStereo);
130 observationsSZ.appendRange(track);
131 if (observationsSZ.size() > 3) {
132 CDCTrajectorySZ szTrajectory;
133 update(szTrajectory, observationsSZ);
134 return szTrajectory;
135 } else {
137 }
138}
139
141 const CDCTrajectory2D& axialTrajectory2D) const
142{
143 B2ASSERT("Expected stereo segment", not stereoSegment.isAxial());
144
145 CDCTrajectorySZ trajectorySZ;
146 update(trajectorySZ, stereoSegment, axialTrajectory2D);
147 return trajectorySZ;
148}
149
151{
152 CDCSZObservations observationsSZ;
153 observationsSZ.appendRange(segment3D);
154 return fit(std::move(observationsSZ));
155}
156
158{
159 CDCTrajectorySZ trajectorySZ;
160 update(trajectorySZ, observationsSZ);
161 return trajectorySZ;
162}
163
164void CDCSZFitter::update(const CDCSegmentPair& segmentPair) const
165{
166 const CDCSegment2D* ptrStereoSegment = segmentPair.getStereoSegment();
167 const CDCSegment2D* ptrAxialSegment = segmentPair.getAxialSegment();
168
169 assert(ptrStereoSegment);
170 assert(ptrAxialSegment);
171
172 const CDCSegment2D& stereoSegment = *ptrStereoSegment;
173 const CDCSegment2D& axialSegment = *ptrAxialSegment;
174 const CDCTrajectory2D& axialTrajectory2D = axialSegment.getTrajectory2D();
175
176 CDCTrajectorySZ trajectorySZ;
177 update(trajectorySZ, stereoSegment, axialTrajectory2D);
178
179 CDCTrajectory3D trajectory3D(axialTrajectory2D, trajectorySZ);
180 segmentPair.setTrajectory3D(trajectory3D);
181}
182
184{
185 CDCSZObservations szObservations;
186 for (size_t i = 0; i < observations2D.size(); ++i) {
187 const double s = observations2D.getX(i);
188 const double z = observations2D.getY(i);
189 szObservations.fill(s, z);
190 }
191 return fit(std::move(szObservations));
192}
193
195 const CDCSegment2D& stereoSegment,
196 const CDCTrajectory2D& axialTrajectory2D) const
197{
198 B2ASSERT("Expected stereo segment", not stereoSegment.isAxial());
199
200 // recostruct the stereo segment
201 CDCSZObservations observationsSZ;
202 for (const CDCRecoHit2D& recoHit2D : stereoSegment) {
203 CDCRecoHit3D recoHit3D = CDCRecoHit3D::reconstruct(recoHit2D, axialTrajectory2D);
204 observationsSZ.append(recoHit3D);
205 }
206
207 update(trajectorySZ, observationsSZ);
208}
209
210void CDCSZFitter::update(CDCTrajectorySZ& trajectorySZ, CDCSZObservations& observationsSZ) const
211{
212 trajectorySZ.clear();
213 if (observationsSZ.size() < 3) {
214 return;
215 }
216
217 // Determine NDF : Line fit eats up 2 degrees of freedom.
218 size_t ndf = observationsSZ.size() - 2;
219
220 // Matrix of weighted sums
221 Eigen::Matrix<double, 3, 3> sumMatrixWSZ = getWSZSumMatrix(observationsSZ);
222 UncertainSZLine uncertainSZLine = fitZ(sumMatrixWSZ);
223
224 uncertainSZLine.setNDF(ndf);
225 trajectorySZ.setSZLine(uncertainSZLine);
226}
Class serving as a storage of observed drift circles to present to the Riemann fitter.
double getX(int iObservation) const
Getter for the x value of the observation at the given index.
double getY(int iObservation) const
Getter for the y value of the observation at the given index.
std::size_t size() const
Returns the number of observations stored.
Class implementing the z coordinate over travel distance line fit.
Definition CDCSZFitter.h:29
TrackingUtilities::CDCTrajectorySZ fitWithStereoHits(const TrackingUtilities::CDCTrack &track) const
Returns the fitted sz trajectory of the track with the z-information of all stereo hits of the number...
TrackingUtilities::CDCTrajectorySZ fit(const TrackingUtilities::CDCSegment2D &stereoSegment, const TrackingUtilities::CDCTrajectory2D &axialTrajectory2D) const
Returns a fitted trajectory.
static const CDCSZFitter & getFitter()
Getter for a standard sz line fitter instance.
void update(const TrackingUtilities::CDCSegmentPair &segmentPair) const
Updates the trajectory of the axial stereo segment pair inplace.
Class serving as a storage of observed sz positions to present to the sz line fitters.
std::size_t append(const TrackingUtilities::CDCRecoHit3D &recoHit3D)
Appends the observed position.
std::size_t fill(double s, double z, double weight=1.0)
Appends the observed position.
std::size_t appendRange(const std::vector< TrackingUtilities::CDCRecoHit3D > &recoHit3Ds)
Appends all reconstructed hits from the three dimensional track.
std::size_t size() const
Returns the number of observations stored.
Class representing a two dimensional reconstructed hit in the central drift chamber.
Class representing a three dimensional reconstructed hit.
static CDCRecoHit3D reconstruct(const CDCRecoHit2D &recoHit2D, const CDCTrajectory2D &trajectory2D)
Reconstructs the three dimensional hit from the two dimensional and the two dimensional trajectory.
A reconstructed sequence of two dimensional hits in one super layer.
A segment consisting of three dimensional reconstructed hits.
Class representing a pair of one reconstructed axial segment and one stereo segment in adjacent super...
const CDCSegment2D * getAxialSegment() const
Getter for the axial segment.
void setTrajectory3D(const CDCTrajectory3D &trajectory3D) const
Setter for the three dimensional trajectory.
const CDCSegment2D * getStereoSegment() const
Getter for the stereo segment.
bool isAxial() const
Indicator if the underlying wires are axial.
Definition CDCSegment.h:45
CDCTrajectory2D & getTrajectory2D() const
Getter for the two dimensional trajectory fitted to the segment.
Definition CDCSegment.h:69
Class representing a sequence of three dimensional reconstructed hits.
Definition CDCTrack.h:39
Particle trajectory as it is seen in xy projection represented as a circle.
Particle full three dimensional trajectory.
static CDCTrajectorySZ basicAssumption()
Constructs a basic assumption, what the z0 start position and the sz slope are, including some broad ...
void setSZLine(const UncertainSZLine &szLine)
Setter for the line in sz space.
void clear()
Clears all information from this trajectory line.
A line in sz where s is the transverse travel distance as seen in the xy projection with uncertaintie...
void setNDF(std::size_t ndf)
Setter for the number of degrees of freediom used in the line fit.
Namespace to hide the contained enum constants.
Abstract base class for different kinds of events.