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