Belle II Software  release-08-01-10
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 
29 using namespace Belle2;
30 using namespace TrackFindingCDC;
31 
33 {
35  wireHit.getRefDriftLengthVariance());
36 }
37 
38 std::size_t
39 CDCObservations2D::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 
61 std::size_t
62 CDCObservations2D::fill(const Vector2D& pos2D, double signedRadius, double weight)
63 {
64  return fill(pos2D.x(), pos2D.y(), signedRadius, weight);
65 }
66 
67 std::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 
98 std::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 
107 std::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 
143 std::size_t CDCObservations2D::append(const CDCRLWireHitPair& rlWireHitPair)
144 {
145  return append(rlWireHitPair.getFromRLWireHit()) + append(rlWireHitPair.getToRLWireHit());
146 }
147 
148 std::size_t CDCObservations2D::append(const CDCRLWireHitTriple& rlWireHitTriple)
149 {
150  return append(rlWireHitTriple.getStartRLWireHit()) +
151  append(rlWireHitTriple.getMiddleRLWireHit()) + append(rlWireHitTriple.getEndRLWireHit());
152 }
153 
154 std::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 
165 std::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 
206 std::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 
240 std::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 
249 std::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 
258 std::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 
275 std::size_t CDCObservations2D::appendRange(const CDCTrack& track)
276 {
277  std::size_t nAppendedHits = 0;
278  for (const CDCRecoHit3D& recoHit3D : track) {
279  nAppendedHits += append(recoHit3D);
280  }
281  return nAppendedHits;
282 }
283 
284 std::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 
309 double 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 segements in adjacent superlayer.
const CDCAxialSegment2D * getStartSegment() const
Getter for the start segment.
const CDCAxialSegment2D * getEndSegment() const
Getter for the end segment.
Class representing a triple of neighboring oriented wire with additional trajectory information.
Definition: CDCFacet.h:32
CDCRecoHit2D getEndRecoHit2D() const
Getter for the third reconstucted hit.
Definition: CDCFacet.cc:120
CDCRecoHit2D getMiddleRecoHit2D() const
Getter for the second reconstucted hit.
Definition: CDCFacet.cc:115
CDCRecoHit2D getStartRecoHit2D() const
Getter for the first reconstucted 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 postion 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 postion 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 transvers travel distance traversed by these observations comparing the travel di...
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 & getFromRLWireHit()
Getter for the first oriented wire hit.
CDCRLWireHit & getToRLWireHit()
Getter for the second oriented wire hit.
Class representing a triple of neighboring wire hits.
CDCRLWireHit & getEndRLWireHit()
Getter for the third oriented wire hit.
CDCRLWireHit & getMiddleRLWireHit()
Getter for the second oriented wire hit.
CDCRLWireHit & getStartRLWireHit()
Getter for the first 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
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
const CDCWire & getWire() const
Getter for the wire the reconstructed hit assoziated to.
Definition: CDCRecoHit2D.h:175
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
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
const Vector2D & getRecoPos2D() const
Getter for the 2d position of the hit.
Definition: CDCRecoHit3D.h:297
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 reconsturcted 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 handeling of orientation relat...
Definition: Vector2D.h:35
double x() const
Getter for the x coordinate.
Definition: Vector2D.h:607
double normSquared() const
Calculates .
Definition: Vector2D.h:181
bool hasNAN() const
Checks if one of the coordinates is NAN.
Definition: Vector2D.h:161
double y() const
Getter for the y coordinate.
Definition: Vector2D.h:617
ERightLeft
Enumeration to represent the distinct possibilities of the right left passage.
Definition: ERightLeft.h:25
Abstract base class for different kinds of events.