Belle II Software development
CDCRobustSZFitter.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/CDCRobustSZFitter.h>
9
10#include <tracking/trackFindingCDC/fitting/CDCSZFitter.h>
11
12#include <tracking/trackFindingCDC/fitting/CDCSZObservations.h>
13
14#include <tracking/trackingUtilities/eventdata/trajectories/CDCTrajectorySZ.h>
15
16#include <tracking/trackingUtilities/numerics/Median.h>
17#include <tracking/trackingUtilities/numerics/WithWeight.h>
18
19using namespace Belle2;
20using namespace TrackFindingCDC;
21using namespace TrackingUtilities;
22
24{
25 // This seems to be some other algorithm
26
27
28 CDCTrajectorySZ trajectorySZ;
29 CDCSZFitter szFitter;
30
31 if (observationsSZ.size() > 4) {
32 CDCSZObservations observationsSZFiltered;
33
34 double meanTanLambda = 0;
35 double meanStartZ = 0;
36
37 for (unsigned int i = 0; i < observationsSZ.size(); i++) {
38 for (unsigned int j = 0; j < observationsSZ.size(); j++) {
39 if (i != j) {
40 observationsSZFiltered.fill(observationsSZ.getS(j),
41 observationsSZ.getZ(j),
42 observationsSZ.getWeight(j));
43 }
44 } // for j
45
46 szFitter.update(trajectorySZ, observationsSZFiltered);
47 meanTanLambda += trajectorySZ.getTanLambda();
48 meanStartZ += trajectorySZ.getZ0();
49 } // for i
50
51 return CDCTrajectorySZ(meanTanLambda / observationsSZ.size(),
52 meanStartZ / observationsSZ.size());
53 } else {
55 }
56}
57
59{
60 std::vector<double> tanLambdas;
61 tanLambdas.reserve(szObservations.size() * (szObservations.size() - 1) / 2);
62 for (unsigned int i = 0; i < szObservations.size(); i++) {
63 for (unsigned int j = i + 1; j < szObservations.size(); j++) {
64 double s1 = szObservations.getS(i);
65 double s2 = szObservations.getS(j);
66 if (s1 == s2) continue;
67 double z1 = szObservations.getZ(i);
68 double z2 = szObservations.getZ(j);
69 tanLambdas.push_back((z2 - z1) / (s2 - s1));
70 }
71 }
72
73 const double tanLambda = median(std::move(tanLambdas));
74 const double z0 = getMedianZ0(szObservations, tanLambda);
75
76 CDCTrajectorySZ trajectorySZ(tanLambda, z0);
77 trajectorySZ.setNDF(szObservations.size());
78 return trajectorySZ;
79}
80
82{
83 std::vector<WithWeight<double> > weightedTanLambdas;
84 Weight totalWeight = 0;
85 weightedTanLambdas.reserve(szObservations.size() * (szObservations.size() - 1) / 2);
86 for (unsigned int i = 0; i < szObservations.size(); i++) {
87 for (unsigned int j = i + 1; j < szObservations.size(); j++) {
88 double s1 = szObservations.getS(i);
89 double s2 = szObservations.getS(j);
90 if (s1 == s2) continue;
91 double z1 = szObservations.getZ(i);
92 double z2 = szObservations.getZ(j);
93
94 double w1 = szObservations.getWeight(i);
95 double w2 = szObservations.getWeight(j);
96
97 // Longer legs receive proportionally longer weight.
98 Weight weight = std::abs(s2 - s1) * hypot2(w1, w2);
99 weightedTanLambdas.emplace_back((z2 - z1) / (s2 - s1), weight);
100 totalWeight += weight;
101 }
102 }
103
104 for (WithWeight<double>& weightedTanLambda : weightedTanLambdas) {
105 weightedTanLambda.weight() /= totalWeight;
106 }
107
108 const double tanLambda = weightedMedian(std::move(weightedTanLambdas));
109 const double z0 = getMedianZ0(szObservations, tanLambda);
110
111 CDCTrajectorySZ trajectorySZ(tanLambda, z0);
112 trajectorySZ.setNDF(szObservations.size());
113 return trajectorySZ;
114}
115
116double CDCRobustSZFitter::getMedianZ0(const CDCSZObservations& szObservations, double tanLambda) const
117{
118 std::vector<double> z0s;
119 z0s.reserve(szObservations.size());
120 for (unsigned int i = 0; i < szObservations.size(); i++) {
121 double s = szObservations.getS(i);
122 double z = szObservations.getZ(i);
123 z0s.push_back(z - s * tanLambda);
124 }
125 const double z0 = median(std::move(z0s));
126 return z0;
127}
TrackingUtilities::CDCTrajectorySZ fitWeightedTheilSen(const CDCSZObservations &szObservations) const
Implements the weighted Theil-Sen line fit algorithm.
TrackingUtilities::CDCTrajectorySZ fitTheilSen(const CDCSZObservations &szObservations) const
Implements the original Theil-Sen line fit algorithm.
double getMedianZ0(const CDCSZObservations &szObservations, double tanLambda) const
Compute the median z0 intercept from the given observations and an estimated slope.
TrackingUtilities::CDCTrajectorySZ fitUsingSimplifiedTheilSen(const CDCSZObservations &szObservations) const
Fit a linear sz trajectory to the reconstructed stereo segment.
Class implementing the z coordinate over travel distance line fit.
Definition CDCSZFitter.h:29
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 fill(double s, double z, double weight=1.0)
Appends the observed position.
double getWeight(int iObservation) const
Getter for the weight / inverse variance of the observation at the given index.
double getZ(int iObservation) const
Getter for the z value of the observation at the given index.
std::size_t size() const
Returns the number of observations stored.
double getS(int iObservation) const
Getter for the arc length value of the observation at the given index.
static CDCTrajectorySZ basicAssumption()
Constructs a basic assumption, what the z0 start position and the sz slope are, including some broad ...
double getTanLambda() const
Getter for the slope over the travel distance coordinate.
void setNDF(std::size_t ndf)
Setter for the number of degrees of freedom of the line fit.
double getZ0() const
Getter for the z coordinate at zero travel distance.
A mixin class to attach a weight to an object.
Definition WithWeight.h:24
Abstract base class for different kinds of events.