Belle II Software  release-08-01-10
SegmentTrackVarSet.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/filters/segmentTrack/SegmentTrackVarSet.h>
9 
10 #include <tracking/trackFindingCDC/fitting/CDCObservations2D.h>
11 #include <tracking/trackFindingCDC/fitting/CDCRiemannFitter.h>
12 #include <tracking/trackFindingCDC/fitting/CDCSZFitter.h>
13 
14 #include <tracking/trackFindingCDC/eventdata/tracks/CDCTrack.h>
15 #include <tracking/trackFindingCDC/eventdata/segments/CDCSegment2D.h>
16 #include <tracking/trackFindingCDC/eventdata/hits/CDCWireHit.h>
17 #include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectorySZ.h>
18 
19 #include <tracking/trackFindingCDC/topology/CDCWire.h>
20 
21 #include <tracking/trackFindingCDC/numerics/ToFinite.h>
22 
23 using namespace Belle2;
24 using namespace TrackFindingCDC;
25 
27 {
28  const CDCTrack* track = testPair->getFrom();
29  const CDCSegment2D* segment = testPair->getTo();
30 
31  assert(segment);
32  assert(track);
33 
34  double maxmimumTrajectoryDistanceFront = 0;
35  double maxmimumTrajectoryDistanceBack = 0;
36  double maxmimumHitDistanceFront = 0;
37  double maxmimumHitDistanceBack = 0;
38  double outOfCDC = 0; // 0 means no, 1 means yes
39  double hitsInSameRegion = 0;
40  double hitsInCommon = 0;
41 
42  const CDCRecoHit2D& front = segment->front();
43  const CDCRecoHit2D& back = segment->back();
44 
45  // Calculate distances
46  const CDCTrajectory3D& trajectoryTrack3D = track->getStartTrajectory3D();
47  const CDCTrajectory2D& trajectoryTrack2D = trajectoryTrack3D.getTrajectory2D();
48  const CDCTrajectorySZ& szTrajectoryTrack = trajectoryTrack3D.getTrajectorySZ();
49  double radius = trajectoryTrack2D.getGlobalCircle().absRadius();
50 
51  maxmimumTrajectoryDistanceFront = trajectoryTrack2D.getDist2D(front.getWireHit().getRefPos2D());
52  maxmimumTrajectoryDistanceBack = trajectoryTrack2D.getDist2D(back.getWireHit().getRefPos2D());
53 
54  var<named("z_distance")>() = 0;
55  var<named("theta_distance")>() = 0;
56 
57  if (segment->getStereoKind() == EStereoKind::c_Axial) {
58  CDCTrajectory2D& trajectorySegment = segment->getTrajectory2D();
59  if (not trajectoryTrack2D.isFitted()) {
61  fitter.update(trajectorySegment, *segment);
62  }
63  } else {
64  CDCObservations2D observations;
65  for (const CDCRecoHit2D& recoHit : *segment) {
66  const CDCRLWireHit& rlWireHit = recoHit.getRLWireHit();
67  CDCRecoHit3D recoHit3D = CDCRecoHit3D::reconstruct(rlWireHit, trajectoryTrack2D);
68  double s = recoHit3D.getArcLength2D();
69  double z = recoHit3D.getRecoZ();
70  observations.fill(s, z);
71  }
72 
73  if (observations.size() > 3) {
74  const CDCSZFitter& fitter = CDCSZFitter::getFitter();
75  const CDCTrajectorySZ& szTrajectorySegments = fitter.fit(observations);
76 
77  double startZTrack = szTrajectoryTrack.getZ0();
78  double startZSegments = szTrajectorySegments.getZ0();
79 
80  var<named("z_distance")>() = startZTrack - startZSegments;
81  var<named("theta_distance")>() = szTrajectoryTrack.getTanLambda() - szTrajectorySegments.getTanLambda();
82  }
83  }
84 
85  // Calculate if it is out of the CDC
86  Vector3D frontRecoPos3D = front.reconstruct3D(trajectoryTrack2D);
87  Vector3D backRecoPos3D = back.reconstruct3D(trajectoryTrack2D);
88 
89  if (segment->getStereoKind() != EStereoKind::c_Axial) {
90  double forwardZ = front.getWire().getWireLine().forwardZ();
91  double backwardZ = front.getWire().getWireLine().backwardZ();
92 
93  if (frontRecoPos3D.z() > forwardZ or frontRecoPos3D.z() < backwardZ or backRecoPos3D.z() > forwardZ
94  or backRecoPos3D.z() < backwardZ) {
95  outOfCDC = 1.0;
96  }
97  }
98 
99  // Get perpS of track in the beginning and the end
100  double perpSOfFront = trajectoryTrack2D.calcArcLength2D(segment->front().getRecoPos2D());
101  double perpSOfBack = trajectoryTrack2D.calcArcLength2D(segment->back().getRecoPos2D());
102 
103  double perpSMinimum = std::min(perpSOfFront, perpSOfBack);
104  double perpSMaximum = std::max(perpSOfFront, perpSOfBack);
105 
106  // Count number of hits in the same region
107  for (const CDCRecoHit3D& recoHit : *track) {
108  if (recoHit.getArcLength2D() < 0.8 * perpSMinimum or
109  recoHit.getArcLength2D() > 1.2 * perpSMaximum) {
110  continue;
111  }
112  if (recoHit.getISuperLayer() == segment->getISuperLayer()) {
113  hitsInSameRegion++;
114  } else if (abs(recoHit.getISuperLayer() - segment->getISuperLayer()) == 1) {
115  double distanceFront = (front.getWireHit().getRefPos2D() - recoHit.getRecoPos2D()).norm();
116  if (distanceFront > maxmimumHitDistanceFront) {
117  maxmimumHitDistanceFront = distanceFront;
118  }
119  double distanceBack = (back.getWireHit().getRefPos2D() - recoHit.getRecoPos2D()).norm();
120  if (distanceBack > maxmimumHitDistanceBack) {
121  maxmimumHitDistanceBack = distanceBack;
122  }
123  }
124  }
125 
126  // Count number of common hits
127  for (const CDCRecoHit3D& trackHit : *track) {
128  if (std::find_if(segment->begin(), segment->end(), [&trackHit](const CDCRecoHit2D & segmentHit) {
129  return segmentHit.getWireHit().getHit() == trackHit.getWireHit().getHit();
130  }) != segment->end()) {
131  hitsInCommon += 1;
132  }
133  }
134 
135  // Make a fit with all the hits and one with only the hits in the near range
136  CDCObservations2D observationsFull;
137  CDCObservations2D observationsNeigh;
138 
139  // Collect the observations
140  bool isAxialSegment = segment->getStereoKind() != EStereoKind::c_Axial;
141 
142  for (const CDCRecoHit3D& recoHit : *track) {
143  if (isAxialSegment and recoHit.getStereoKind() == EStereoKind::c_Axial) {
144  observationsFull.fill(recoHit.getWireHit().getRefPos2D());
145  if (abs(recoHit.getISuperLayer() - segment->getISuperLayer()) < 3) {
146  observationsNeigh.fill(recoHit.getWireHit().getRefPos2D());
147  }
148  } else if (not isAxialSegment and recoHit.getStereoKind() != EStereoKind::c_Axial) {
149  double s = recoHit.getArcLength2D();
150  double z = recoHit.getRecoZ();
151  observationsFull.fill(s, z);
152  if (abs(recoHit.getISuperLayer() - segment->getISuperLayer()) < 3) {
153  observationsNeigh.fill(s, z);
154  }
155  }
156  }
157 
158  const CDCTrajectorySZ& trajectorySZ = track->getStartTrajectory3D().getTrajectorySZ();
159  double tanLambda = trajectorySZ.getTanLambda();
160 
161  bool hasZInformation = tanLambda != 0;
162  double max_hit_z_distance = -1;
163  double sum_hit_z_distance = 0;
164  double stereo_quad_tree_distance = 0;
165 
166  if (hasZInformation) {
167  double thetaFirstSegmentHit = -10;
168 
169  for (const CDCRecoHit2D& recoHit2D : *segment) {
170  Vector3D reconstructedPosition = recoHit2D.reconstruct3D(trajectoryTrack2D);
171  const Vector2D& recoPos2D = recoHit2D.getRecoPos2D();
172  double perpS = trajectoryTrack2D.calcArcLength2D(recoPos2D);
173 
174 
175  double current_z_distance = std::abs(trajectorySZ.getZDist(perpS, reconstructedPosition.z()));
176  if (std::isnan(current_z_distance)) {
177  continue;
178  }
179 
180  if (thetaFirstSegmentHit == -10) {
181  thetaFirstSegmentHit = reconstructedPosition.theta();
182  }
183  sum_hit_z_distance += current_z_distance;
184  if (current_z_distance > max_hit_z_distance) {
185  max_hit_z_distance = current_z_distance;
186  }
187  }
188 
189  double thetaTrack = trajectoryTrack3D.getFlightDirection3DAtSupport().theta();
190  stereo_quad_tree_distance = thetaTrack - thetaFirstSegmentHit;
191  }
192 
193 
194  for (const CDCRecoHit2D& recoHit : *segment) {
195  if (isAxialSegment) {
196  observationsFull.fill(recoHit.getRecoPos2D());
197  observationsNeigh.fill(recoHit.getRecoPos2D());
198  } else {
199  const CDCRLWireHit& rlWireHit = recoHit.getRLWireHit();
200  CDCRecoHit3D recoHit3D = CDCRecoHit3D::reconstruct(rlWireHit, trajectoryTrack2D);
201  double s = recoHit3D.getArcLength2D();
202  double z = recoHit3D.getRecoZ();
203  observationsFull.fill(s, z);
204  observationsNeigh.fill(s, z);
205  }
206  }
207 
208  // Do the fit
209  var<named("fit_neigh")>() = 0;
210  var<named("fit_full")>() = 0;
211  if (segment->getStereoKind() == EStereoKind::c_Axial) {
213  var<named("fit_full")>() = fitter.fit(observationsFull).getPValue();
214  } else {
215  const CDCSZFitter& fitter = CDCSZFitter::getFitter();
216  var<named("fit_full")>() = toFinite(fitter.fit(observationsFull).getPValue(), 0);
217 
218  if (observationsNeigh.size() > 3) {
219  var<named("fit_neigh")>() = toFinite(fitter.fit(observationsNeigh).getPValue(), 0);
220  } else {
221  var<named("fit_neigh")>() = 0;
222  }
223  }
224 
225  if (observationsFull.size() == observationsNeigh.size()) {
226  var<named("fit_neigh")>() = -1;
227  }
228 
229  var<named("is_stereo")>() = segment->getStereoKind() != EStereoKind::c_Axial;
230  var<named("segment_size")>() = segment->size();
231  var<named("track_size")>() = track->size();
232  var<named("mean_hit_z_distance")>() = sum_hit_z_distance;
233  var<named("max_hit_z_distance")>() = max_hit_z_distance;
234  var<named("stereo_quad_tree_distance")>() = toFinite(stereo_quad_tree_distance, 0);
235 
236  var<named("pt_of_track")>() = toFinite(std::isnan(trajectoryTrack2D.getAbsMom2D()) ? 0.0 : trajectoryTrack2D.getAbsMom2D(), 0);
237  var<named("track_is_curler")>() = trajectoryTrack2D.getExit().hasNAN();
238 
239  var<named("superlayer_already_full")>() = not trajectoryTrack2D.getOuterExit().hasNAN() and hitsInSameRegion > 5;
240 
241  var<named("maxmimum_trajectory_distance_front")>() = toFinite(maxmimumTrajectoryDistanceFront, 999);
242  var<named("maxmimum_trajectory_distance_back")>() = toFinite(maxmimumTrajectoryDistanceBack, 999);
243 
244  var<named("maxmimum_hit_distance_front")>() = maxmimumHitDistanceFront;
245  var<named("maxmimum_hit_distance_back")>() = maxmimumHitDistanceBack;
246 
247  var<named("out_of_CDC")>() = outOfCDC;
248  var<named("hits_in_same_region")>() = hitsInSameRegion;
249 
250  var<named("number_of_hits_in_common")>() = hitsInCommon;
251 
252  var<named("segment_super_layer")>() = segment->getISuperLayer();
253 
254  double phiBetweenTrackAndSegment = trajectoryTrack2D.getMom2DAtSupport().angleWith(segment->front().getRecoPos2D());
255 
256  var<named("phi_between_track_and_segment")>() = toFinite(phiBetweenTrackAndSegment, 0);
257  var<named("perp_s_of_front")>() = toFinite(perpSOfFront / radius, 0);
258  var<named("perp_s_of_back")>() = toFinite(perpSOfBack / radius, 0);
259 
260  return true;
261 }
Class serving as a storage of observed drift circles to present to the Riemann fitter.
std::size_t fill(double x, double y, double signedRadius=0.0, double weight=1.0)
Appends the observed position.
std::size_t size() const
Returns the number of observations stored.
Class representing an oriented hit wire including a hypotheses whether the causing track passes left ...
Definition: CDCRLWireHit.h:41
Class representing a two dimensional reconstructed hit in the central drift chamber.
Definition: CDCRecoHit2D.h:47
Vector3D reconstruct3D(const CDCTrajectory2D &trajectory2D, const double z=0) const
Reconstruct the three dimensional position (especially of stereo hits) by determinating the z coordin...
const CDCWireHit & getWireHit() const
Getter for the wire hit assoziated with the reconstructed hit.
Definition: CDCRecoHit2D.h:193
const CDCWire & getWire() const
Getter for the wire the reconstructed hit assoziated to.
Definition: CDCRecoHit2D.h:175
Class representing a three dimensional reconstructed hit.
Definition: CDCRecoHit3D.h:52
static CDCRecoHit3D reconstruct(const CDCRecoHit2D &recoHit2D, const CDCTrajectory2D &trajectory2D)
Reconstructs the three dimensional hit from the two dimensional and the two dimensional trajectory.
Definition: CDCRecoHit3D.cc:56
double getRecoZ() const
Getter for the z coordinate of the reconstructed position.
Definition: CDCRecoHit3D.h:303
double getArcLength2D() const
Getter for the travel distance in the xy projection.
Definition: CDCRecoHit3D.h:370
Class implementing the Riemann fit for two dimensional trajectory circle.
static const CDCRiemannFitter & getFitter()
Static getter for a general Riemann fitter.
Class implementing the z coordinate over travel distance line fit.
Definition: CDCSZFitter.h:27
static const CDCSZFitter & getFitter()
Getter for a standard sz line fitter instance.
Definition: CDCSZFitter.cc:36
A reconstructed sequence of two dimensional hits in one super layer.
Definition: CDCSegment2D.h:39
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.
Vector2D getMom2DAtSupport(const double bZ) const
Get the momentum at the support point of the trajectory.
PerigeeCircle getGlobalCircle() const
Getter for the circle in global coordinates.
Vector2D getOuterExit(double factor=1) const
Calculates the point where the trajectory meets the outer wall of the CDC.
double calcArcLength2D(const Vector2D &point) const
Calculate the travel distance from the start position of the trajectory.
double getAbsMom2D(double bZ) const
Get the estimation for the absolute value of the transvers momentum.
bool isFitted() const
Checks if the circle is already set to a valid value.
Vector2D getExit() const
Calculates the point where the trajectory leaves the CDC.
double getDist2D(const Vector2D &point) const
Calculates the distance from the point to the trajectory as seen from the xy projection.
Particle full three dimensional trajectory.
CDCTrajectory2D getTrajectory2D() const
Getter for the two dimensional trajectory.
Vector3D getFlightDirection3DAtSupport() const
Get the unit momentum at the start point of the trajectory.
CDCTrajectorySZ getTrajectorySZ() const
Getter for the sz trajectory.
Linear trajectory in sz space.
double getTanLambda() const
Getter for the slope over the travel distance coordinate.
double getZDist(const double s, const double z) const
Calculates the distance along between the given point an the sz trajectory.
double getZ0() const
Getter for the z coordinate at zero travel distance.
const Vector2D & getRefPos2D() const
The two dimensional reference position (z=0) of the underlying wire.
Definition: CDCWireHit.cc:212
const WireLine & getWireLine() const
Getter for the wire line represenation of the wire.
Definition: CDCWire.h:188
AObject Object
Type of the object to be analysed.
Definition: Filter.dcl.h:33
double absRadius() const
Gives the signed radius of the circle. If it was a line this will be infinity.
bool extract(const BaseSegmentTrackFilter::Object *testPair) final
Generate and assign the contained variables.
constexpr static int named(const char *name)
Getter for the index from the name.
Definition: VarSet.h:78
Float_t & var()
Reference getter for the value of the ith variable. Static version.
Definition: VarSet.h:93
A two dimensional vector which is equipped with functions for correct handeling of orientation relat...
Definition: Vector2D.h:35
bool hasNAN() const
Checks if one of the coordinates is NAN.
Definition: Vector2D.h:161
double angleWith(const Vector2D &rhs) const
The angle between this and rhs.
Definition: Vector2D.h:209
A three dimensional vector.
Definition: Vector3D.h:33
double z() const
Getter for the z coordinate.
Definition: Vector3D.h:496
double theta() const
Getter for the polar angle.
Definition: Vector3D.h:546
double backwardZ() const
Gives the backward z coodinate.
Definition: WireLine.h:134
double forwardZ() const
Gives the forward z coodinate.
Definition: WireLine.h:130
Abstract base class for different kinds of events.