Belle II Software development
CDCObservations2D.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/CDCObservations2D.h>
9
10#include <tracking/trackFindingCDC/fitting/EigenObservationMatrix.h>
11
12#include <tracking/trackFindingCDC/eventdata/tracks/CDCTrack.h>
13#include <tracking/trackFindingCDC/eventdata/tracks/CDCAxialSegmentPair.h>
14#include <tracking/trackFindingCDC/eventdata/segments/CDCSegment3D.h>
15#include <tracking/trackFindingCDC/eventdata/segments/CDCSegment2D.h>
16#include <tracking/trackFindingCDC/eventdata/segments/CDCWireHitSegment.h>
17#include <tracking/trackFindingCDC/eventdata/hits/CDCFacet.h>
18#include <tracking/trackFindingCDC/eventdata/hits/CDCRLWireHitTriple.h>
19#include <tracking/trackFindingCDC/eventdata/hits/CDCRLWireHitPair.h>
20#include <tracking/trackFindingCDC/eventdata/hits/CDCRLWireHit.h>
21#include <tracking/trackFindingCDC/eventdata/hits/CDCWireHit.h>
22
23#include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectory2D.h>
24
25#include <tracking/trackFindingCDC/topology/CDCWire.h>
26
27#include <tracking/trackFindingCDC/geometry/Vector2D.h>
28
29using namespace Belle2;
30using namespace TrackFindingCDC;
31
33{
36}
37
38std::size_t
39CDCObservations2D::fill(double x, double y, double signedRadius, double weight)
40{
41 if (std::isnan(x)) return 0;
42 if (std::isnan(y)) return 0;
43
44 if (std::isnan(signedRadius)) {
45 B2WARNING("Signed radius is nan. Skipping observation");
46 return 0;
47 }
48
49 if (std::isnan(weight)) {
50 B2WARNING("Weight is nan. Skipping observation");
51 return 0;
52 }
53
54 m_observations.push_back(x);
55 m_observations.push_back(y);
56 m_observations.push_back(signedRadius);
57 m_observations.push_back(weight);
58 return 1;
59}
60
61std::size_t
62CDCObservations2D::fill(const Vector2D& pos2D, double signedRadius, double weight)
63{
64 return fill(pos2D.x(), pos2D.y(), signedRadius, weight);
65}
66
67std::size_t CDCObservations2D::append(const CDCWireHit& wireHit, ERightLeft rlInfo)
68{
69 const Vector2D& wireRefPos2D = wireHit.getRefPos2D();
70
71 double signedDriftLength = 0;
72 if (m_fitPos == EFitPos::c_RLDriftCircle and isValid(rlInfo)) {
73 signedDriftLength = static_cast<double>(rlInfo) * wireHit.getRefDriftLength();
74 } else {
75 signedDriftLength = 0;
76 }
77
78 double variance = 1;
79 if (m_fitVariance == EFitVariance::c_Unit) {
80 variance = 1;
81 } else if (m_fitVariance == EFitVariance::c_Nominal) {
83 } else if (m_fitVariance == EFitVariance::c_DriftLength) {
84 const double driftLength = wireHit.getRefDriftLength();
85 variance = fabs(driftLength);
86 } else if (m_fitVariance == EFitVariance::c_Pseudo) {
87 variance = getPseudoDriftLengthVariance(wireHit);
88 } else if (m_fitVariance == EFitVariance::c_Proper) {
89 if (abs(rlInfo) != 1) {
90 variance = getPseudoDriftLengthVariance(wireHit);
91 } else {
92 variance = wireHit.getRefDriftLengthVariance();
93 }
94 }
95 return fill(wireRefPos2D, signedDriftLength, 1 / variance);
96}
97
98std::size_t CDCObservations2D::append(const CDCWireHit* wireHit, ERightLeft rlInfo)
99{
100 if (wireHit) {
101 return append(*(wireHit), rlInfo);
102 } else {
103 return 0;
104 }
105}
106
107std::size_t CDCObservations2D::append(const CDCRLWireHit& rlWireHit)
108{
109 const ERightLeft rlInfo = rlWireHit.getRLInfo();
110
111 const double driftLength = rlWireHit.getRefDriftLength();
112 const double driftLengthVariance = rlWireHit.getRefDriftLengthVariance();
113
114 const Vector2D& wireRefPos2D = rlWireHit.getRefPos2D();
115
116 double signedDriftLength = 0;
117 if (m_fitPos == EFitPos::c_RLDriftCircle and isValid(rlInfo)) {
118 signedDriftLength = static_cast<double>(rlInfo) * driftLength;
119 } else {
120 signedDriftLength = 0;
121 }
122
123 double variance = 1;
124 if (m_fitVariance == EFitVariance::c_Unit) {
125 variance = 1;
126 } else if (m_fitVariance == EFitVariance::c_Nominal) {
128 } else if (m_fitVariance == EFitVariance::c_DriftLength) {
129 variance = fabs(driftLength);
130 } else if (m_fitVariance == EFitVariance::c_Pseudo) {
131 variance = getPseudoDriftLengthVariance(driftLength, driftLengthVariance);
132 } else if (m_fitVariance == EFitVariance::c_Proper) {
133 if (abs(rlInfo) != 1) {
134 variance = getPseudoDriftLengthVariance(driftLength, driftLengthVariance);
135 } else {
136 variance = driftLengthVariance;
137 }
138 }
139
140 return fill(wireRefPos2D, signedDriftLength, 1 / variance);
141}
142
143std::size_t CDCObservations2D::append(const CDCRLWireHitPair& rlWireHitPair)
144{
145 return append(rlWireHitPair.getFromRLWireHit()) + append(rlWireHitPair.getToRLWireHit());
146}
147
148std::size_t CDCObservations2D::append(const CDCRLWireHitTriple& rlWireHitTriple)
149{
150 return append(rlWireHitTriple.getStartRLWireHit()) +
151 append(rlWireHitTriple.getMiddleRLWireHit()) + append(rlWireHitTriple.getEndRLWireHit());
152}
153
154std::size_t CDCObservations2D::append(const CDCFacet& facet)
155{
156 if (m_fitPos == EFitPos::c_RecoPos) {
157 return append(facet.getStartRecoHit2D()) + append(facet.getMiddleRecoHit2D()) +
158 append(facet.getEndRecoHit2D());
159 } else {
160 const CDCRLWireHitTriple& rlWireHitTriple = facet;
161 return append(rlWireHitTriple);
162 }
163}
164
165std::size_t CDCObservations2D::append(const CDCRecoHit2D& recoHit2D)
166{
167 Vector2D fitPos2D;
168 double signedDriftLength = 0;
169 if (m_fitPos == EFitPos::c_RecoPos) {
170 fitPos2D = recoHit2D.getRecoPos2D();
171 signedDriftLength = 0;
172
173 // Fall back to the rl circle in case position is not setup
174 if (fitPos2D.hasNAN()) {
175 fitPos2D = recoHit2D.getWire().getRefPos2D();
176 signedDriftLength = recoHit2D.getSignedRefDriftLength();
177 }
178
179 } else if (m_fitPos == EFitPos::c_RLDriftCircle) {
180 fitPos2D = recoHit2D.getWire().getRefPos2D();
181 signedDriftLength = recoHit2D.getSignedRefDriftLength();
182 } else if (m_fitPos == EFitPos::c_WirePos) {
183 fitPos2D = recoHit2D.getWire().getRefPos2D();
184 signedDriftLength = 0;
185 }
186
187 const double driftLength = recoHit2D.getRefDriftLength();
188 const ERightLeft rlInfo = recoHit2D.getRLInfo();
189
190 double variance = recoHit2D.getRefDriftLengthVariance();
191 if (m_fitVariance == EFitVariance::c_Unit) {
192 variance = 1;
193 } else if (m_fitVariance == EFitVariance::c_Nominal) {
195 } else if (m_fitVariance == EFitVariance::c_DriftLength) {
196 variance = std::fabs(driftLength);
197 } else if (m_fitVariance == EFitVariance::c_Pseudo or abs(rlInfo) != 1) {
198 // Fall back to the pseudo variance if the rl information is not known
199 variance = getPseudoDriftLengthVariance(driftLength, variance);
200 } else if (m_fitVariance == EFitVariance::c_Proper) {
201 variance = recoHit2D.getRefDriftLengthVariance();
202 }
203 return fill(fitPos2D, signedDriftLength, 1 / variance);
204}
205
206std::size_t CDCObservations2D::append(const CDCRecoHit3D& recoHit3D)
207{
208 Vector2D fitPos2D = recoHit3D.getRecoPos2D();
209 double signedDriftLength = 0;
210 if (m_fitPos == EFitPos::c_RecoPos) {
211 fitPos2D = recoHit3D.getRecoPos2D();
212 signedDriftLength = 0;
213 } else if (m_fitPos == EFitPos::c_RLDriftCircle) {
214 fitPos2D = recoHit3D.getRecoWirePos2D();
215 signedDriftLength = recoHit3D.getSignedRecoDriftLength();
216 } else if (m_fitPos == EFitPos::c_WirePos) {
217 fitPos2D = recoHit3D.getRecoWirePos2D();
218 signedDriftLength = 0;
219 }
220
221 const double driftLength = std::fabs(recoHit3D.getSignedRecoDriftLength());
222 const ERightLeft rlInfo = recoHit3D.getRLInfo();
223
224 double variance = recoHit3D.getRecoDriftLengthVariance();
225 if (m_fitVariance == EFitVariance::c_Unit) {
226 variance = 1;
227 } else if (m_fitVariance == EFitVariance::c_Nominal) {
229 } else if (m_fitVariance == EFitVariance::c_DriftLength) {
230 variance = std::fabs(driftLength);
231 } else if (m_fitVariance == EFitVariance::c_Pseudo or abs(rlInfo) != 1) {
232 // Fall back to the pseudo variance if the rl information is not known
233 variance = getPseudoDriftLengthVariance(driftLength, variance);
234 } else if (m_fitVariance == EFitVariance::c_Proper) {
235 variance = recoHit3D.getRecoDriftLengthVariance();
236 }
237 return fill(fitPos2D, signedDriftLength, 1 / variance);
238}
239
240std::size_t CDCObservations2D::appendRange(const CDCSegment2D& segment2D)
241{
242 std::size_t nAppendedHits = 0;
243 for (const CDCRecoHit2D& recoHit2D : segment2D) {
244 nAppendedHits += append(recoHit2D);
245 }
246 return nAppendedHits;
247}
248
249std::size_t CDCObservations2D::appendRange(const CDCSegment3D& segment3D)
250{
251 std::size_t nAppendedHits = 0;
252 for (const CDCRecoHit3D& recoHit3D : segment3D) {
253 nAppendedHits += append(recoHit3D);
254 }
255 return nAppendedHits;
256}
257
258std::size_t CDCObservations2D::appendRange(const CDCAxialSegmentPair& axialSegmentPair)
259{
260 std::size_t nAppendedHits = 0;
261 const CDCSegment2D* ptrStartSegment2D = axialSegmentPair.getStartSegment();
262 if (ptrStartSegment2D) {
263 const CDCSegment2D& startSegment2D = *ptrStartSegment2D;
264 nAppendedHits += appendRange(startSegment2D);
265 }
266
267 const CDCSegment2D* ptrEndSegment2D = axialSegmentPair.getEndSegment();
268 if (ptrEndSegment2D) {
269 const CDCSegment2D& endSegment2D = *ptrEndSegment2D;
270 nAppendedHits += appendRange(endSegment2D);
271 }
272 return nAppendedHits;
273}
274
276{
277 std::size_t nAppendedHits = 0;
278 for (const CDCRecoHit3D& recoHit3D : track) {
279 nAppendedHits += append(recoHit3D);
280 }
281 return nAppendedHits;
282}
283
284std::size_t CDCObservations2D::appendRange(const std::vector<const CDCWire*>& wires)
285{
286 std::size_t nAppendedHits = 0;
287 for (const CDCWire* ptrWire : wires) {
288 if (not ptrWire) continue;
289 const CDCWire& wire = *ptrWire;
290 const Vector2D& wirePos = wire.getRefPos2D();
291 const double driftLength = 0.0;
292 const double weight = 1.0;
293 nAppendedHits += fill(wirePos, driftLength, weight);
294 }
295 return nAppendedHits;
296}
297
299{
300 std::size_t nAppendedHits = 0;
301 for (const CDCWireHit* ptrWireHit : wireHits) {
302 if (not ptrWireHit) continue;
303 const CDCWireHit& wireHit = *ptrWireHit;
304 nAppendedHits += append(wireHit);
305 }
306 return nAppendedHits;
307}
308
309double CDCObservations2D::getTotalPerpS(const CDCTrajectory2D& trajectory2D) const
310{
311 return trajectory2D.calcArcLength2DBetween(getFrontPos2D(), getBackPos2D());
312}
313
315{
316 std::size_t result = 0;
317 Index nObservations = size();
318
319 for (Index iObservation = 0; iObservation < nObservations; ++iObservation) {
320 const double driftLength = getDriftLength(iObservation);
321 bool hasDriftLength = (driftLength != 0.0);
322 result += hasDriftLength ? 1 : 0;
323 }
324
325 return result;
326}
327
329{
330 std::size_t n = size();
331 if (n == 0) return Vector2D(NAN, NAN);
332 std::size_t i = n / 2;
333
334 if (isEven(n)) {
335 // For even number of observations use the middle one with the bigger distance from IP
336 Vector2D center1(getX(i), getY(i));
337 Vector2D center2(getX(i - 1), getY(i - 1));
338 return center1.normSquared() > center2.normSquared() ? center1 : center2;
339 } else {
340 Vector2D center1(getX(i), getY(i));
341 return center1;
342 }
343}
344
346{
347 Eigen::Matrix<double, 1, 2> eigenOrigin(origin.x(), origin.y());
348 EigenObservationMatrix eigenObservations = getEigenObservationMatrix(this);
349 eigenObservations.leftCols<2>().rowwise() -= eigenOrigin;
350}
351
353{
354 // Pick an observation at the center
355 Vector2D centralPoint = getCentralPoint();
356 passiveMoveBy(centralPoint);
357 return centralPoint;
358}
Class representing a pair of reconstructed axial segments in adjacent superlayer.
const CDCAxialSegment2D * getEndSegment() const
Getter for the end segment.
const CDCAxialSegment2D * getStartSegment() const
Getter for the start segment.
Class representing a triple of neighboring oriented wire with additional trajectory information.
Definition: CDCFacet.h:32
CDCRecoHit2D getEndRecoHit2D() const
Getter for the third reconstructed hit.
Definition: CDCFacet.cc:120
CDCRecoHit2D getMiddleRecoHit2D() const
Getter for the second reconstructed hit.
Definition: CDCFacet.cc:115
CDCRecoHit2D getStartRecoHit2D() const
Getter for the first reconstructed hit.
Definition: CDCFacet.cc:110
EFitPos m_fitPos
Indicator which positional information should preferably be extracted from hits in calls to append.
static double getPseudoDriftLengthVariance(double driftLength, double driftLengthVariance)
Gets the pseudo variance.
double getX(int iObservation) const
Getter for the x value of the observation at the given index.
Vector2D getBackPos2D() const
Get the position of the first observation.
Vector2D centralize()
Picks one observation as a reference point and transform all observations to that new origin.
double getY(int iObservation) const
Getter for the y value of the observation at the given index.
Vector2D getCentralPoint() const
Extracts the observation center that is at the index in the middle.
std::size_t append(const CDCWireHit &wireHit, ERightLeft rlInfo=ERightLeft::c_Unknown)
Appends the hit circle at wire reference position without a right left passage hypotheses.
double getDriftLength(int iObservation) const
Getter for the signed drift radius of the observation at the given index.
Vector2D getFrontPos2D() const
Get the position of the first observation.
std::size_t appendRange(const CDCSegment2D &segment2D)
Appends all reconstructed hits from the two dimensional segment.
std::size_t fill(double x, double y, double signedRadius=0.0, double weight=1.0)
Appends the observed position.
void passiveMoveBy(const Vector2D &origin)
Moves all observations passively such that the given vector becomes to origin of the new coordinate s...
double getTotalPerpS(const CDCTrajectory2D &trajectory2D) const
Calculate the total transverse travel distance traversed by these observations comparing the travel d...
EFitVariance m_fitVariance
Indicator which variance information should preferably be extracted from hits in calls to append.
std::size_t size() const
Returns the number of observations stored.
std::size_t getNObservationsWithDriftRadius() const
Returns the number of observations having a drift radius radius.
std::vector< double > m_observations
Memory for the individual observations.
CDCRLWireHit & getToRLWireHit()
Getter for the second oriented wire hit.
CDCRLWireHit & getFromRLWireHit()
Getter for the first oriented wire hit.
Class representing a triple of neighboring wire hits.
CDCRLWireHit & getStartRLWireHit()
Getter for the first oriented wire hit.
CDCRLWireHit & getEndRLWireHit()
Getter for the third oriented wire hit.
CDCRLWireHit & getMiddleRLWireHit()
Getter for the second oriented wire hit.
Class representing an oriented hit wire including a hypotheses whether the causing track passes left ...
Definition: CDCRLWireHit.h:41
double getRefDriftLengthVariance() const
Getter for the variance of the drift length at the reference position of the wire.
Definition: CDCRLWireHit.h:222
double getRefDriftLength() const
Getter for the drift length at the reference position of the wire.
Definition: CDCRLWireHit.h:204
const Vector2D & getRefPos2D() const
The two dimensional reference position of the underlying wire.
ERightLeft getRLInfo() const
Getter for the right left passage information.
Definition: CDCRLWireHit.h:234
Class representing a two dimensional reconstructed hit in the central drift chamber.
Definition: CDCRecoHit2D.h:47
double getRefDriftLengthVariance() const
Getter for the uncertainty in the drift length at the wire reference position.
Definition: CDCRecoHit2D.h:232
double getRefDriftLength() const
Getter for the drift length at the wire reference position.
Definition: CDCRecoHit2D.h:217
const CDCWire & getWire() const
Getter for the wire the reconstructed hit associated to.
Definition: CDCRecoHit2D.h:175
double getSignedRefDriftLength() const
Getter for the drift length at the wire reference position signed with the right left passage hypothe...
Definition: CDCRecoHit2D.h:226
Vector2D getRecoPos2D() const
Getter for the position in the reference plane.
Definition: CDCRecoHit2D.h:238
ERightLeft getRLInfo() const
Getter for the right left passage information.
Definition: CDCRecoHit2D.h:205
Class representing a three dimensional reconstructed hit.
Definition: CDCRecoHit3D.h:52
double getSignedRecoDriftLength() const
Returns the drift length next to the reconstructed position.
Definition: CDCRecoHit3D.h:346
const Vector2D & getRecoPos2D() const
Getter for the 2d position of the hit.
Definition: CDCRecoHit3D.h:297
Vector2D getRecoWirePos2D() const
Returns the position of the wire in the xy plain the reconstructed position is located in.
double getRecoDriftLengthVariance() const
Returns the drift length variance next to the reconstructed position.
Definition: CDCRecoHit3D.h:358
ERightLeft getRLInfo() const
Getter for the right left passage information.
Definition: CDCRecoHit3D.h:267
A reconstructed sequence of two dimensional hits in one super layer.
Definition: CDCSegment2D.h:39
A segment consisting of three dimensional reconstructed hits.
Definition: CDCSegment3D.h:26
Class representing a sequence of three dimensional reconstructed hits.
Definition: CDCTrack.h:41
Particle trajectory as it is seen in xy projection represented as a circle.
double calcArcLength2DBetween(const Vector2D &fromPoint, const Vector2D &toPoint) const
Calculate the travel distance between the two given positions Returns the travel distance on the traj...
A segment consisting of two dimensional reconstructed hits.
Class representing a hit wire in the central drift chamber.
Definition: CDCWireHit.h:55
double getRefDriftLengthVariance() const
Getter for the variance of the drift length at the reference position of the wire.
Definition: CDCWireHit.h:230
double getRefDriftLength() const
Getter for the drift length at the reference position of the wire.
Definition: CDCWireHit.h:224
static constexpr const double c_simpleDriftLengthVariance
A default value for the drift length variance if no variance from the drift length translation is ava...
Definition: CDCWireHit.h:64
const Vector2D & getRefPos2D() const
The two dimensional reference position (z=0) of the underlying wire.
Definition: CDCWireHit.cc:212
Class representing a sense wire in the central drift chamber.
Definition: CDCWire.h:58
const Vector2D & getRefPos2D() const
Getter for the wire reference position for 2D tracking Gives the wire's reference position projected ...
Definition: CDCWire.h:229
A two dimensional vector which is equipped with functions for correct handling of orientation relate...
Definition: Vector2D.h:32
double x() const
Getter for the x coordinate.
Definition: Vector2D.h:595
double normSquared() const
Calculates .
Definition: Vector2D.h:169
bool hasNAN() const
Checks if one of the coordinates is NAN.
Definition: Vector2D.h:149
double y() const
Getter for the y coordinate.
Definition: Vector2D.h:605
ERightLeft
Enumeration to represent the distinct possibilities of the right left passage.
Definition: ERightLeft.h:25
Abstract base class for different kinds of events.