Belle II Software  release-08-01-10
BasicTrackVarSet.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/track/BasicTrackVarSet.h>
9 
10 #include <tracking/trackFindingCDC/eventdata/tracks/CDCTrack.h>
11 
12 #include <tracking/trackFindingCDC/eventdata/hits/CDCWireHit.h>
13 #include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectory3D.h>
14 #include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectory2D.h>
15 #include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectorySZ.h>
16 
17 #include <tracking/trackFindingCDC/numerics/ToFinite.h>
18 
19 #include <tracking/trackFindingCDC/utilities/Algorithms.h>
20 #include <tracking/trackFindingCDC/utilities/Functional.h>
21 #include <numeric>
22 #include <set>
23 
24 #include <cdc/dataobjects/CDCHit.h>
25 
26 using namespace Belle2;
27 using namespace TrackFindingCDC;
28 
30 {
31  if (not track) return false;
32 
33  if (track->empty()) {
34  return false;
35  }
36 
37  // use boost accumulators, which lazily provide different statistics (mean, variance, ...) for the
38  // data that they accumulate (i.e. are "filled" with).
39  statistics_accumulator drift_length_acc; /* correlated to actual distance from hit to wire*/
40  statistics_accumulator adc_acc; /* integrated charge over the cell*/
41  statistics_accumulator empty_s_acc; /* gap within the track?!*/
42  statistics_accumulator tot_acc; /* time over threshold */
43  /* continuous layer number [from 0 to 55] (not to be distinguished from SuperLayer [from 0 to 8] or Layer (within SuperLayer, so from [0 to 7]) */
44  statistics_accumulator cont_layer_acc;
45  statistics_accumulator super_layer_acc;
46 
47  unsigned int size = track->size();
48 
49  std::vector<unsigned int> cont_layer;
50  std::vector<unsigned int> super_layer;
51  // Fill accumulators with ADC and drift circle information
52  for (const CDCRecoHit3D& recoHit : *track) {
53  drift_length_acc(recoHit.getWireHit().getRefDriftLength());
54  adc_acc(static_cast<unsigned int>(recoHit.getWireHit().getHit()->getADCCount()));
55  tot_acc(static_cast<unsigned int>(recoHit.getWireHit().getHit()->getTOT()));
56  cont_layer_acc(static_cast<unsigned int>(recoHit.getWireHit().getHit()->getICLayer()));
57  super_layer_acc(static_cast<unsigned int>(recoHit.getWireHit().getISuperLayer()));
58  cont_layer.push_back(static_cast<unsigned int>(recoHit.getWireHit().getHit()->getICLayer()));
59  super_layer.push_back(static_cast<unsigned int>(recoHit.getWireHit().getISuperLayer()));
60  }
61 
62  // extract wanted quantities from layers
63  unsigned int cont_layer_first = cont_layer.front();
64  unsigned int cont_layer_last = cont_layer.back();
65  unsigned int cont_layer_min = *std::min_element(cont_layer.begin(), cont_layer.end());
66  unsigned int cont_layer_max = *std::max_element(cont_layer.begin(), cont_layer.end());
67  unsigned int cont_layer_count = std::set<unsigned int>(cont_layer.begin(), cont_layer.end()).size();
68  double cont_layer_occupancy = (double)cont_layer_count / (double)(cont_layer_max - cont_layer_min +
69  1); // +1 b/c the first layer should also be counted
70  unsigned int super_layer_first = super_layer.front();
71  unsigned int super_layer_last = super_layer.back();
72  unsigned int super_layer_min = *std::min_element(super_layer.begin(), super_layer.end());
73  unsigned int super_layer_max = *std::max_element(super_layer.begin(), super_layer.end());
74  unsigned int super_layer_count = std::set<unsigned int>(super_layer.begin(), super_layer.end()).size();
75  double super_layer_occupancy = (double)super_layer_count / (double)(super_layer_max - super_layer_min + 1);
76 
77  double hits_per_layer = (double)size / (double)cont_layer_count;
78 
79  // Extract empty_s (ArcLength2D gap) information
80  double s_range = track->back().getArcLength2D() - track->front().getArcLength2D();
81  double avg_hit_dist = s_range / (double)cont_layer_count;
82 
83  // fill a vector with all 2D arc lengths in track
84  std::vector<double> arc_lengths;
85  auto get_arc_length = [](const CDCRecoHit3D & recoHit) { return recoHit.getArcLength2D(); };
86  std::transform(begin(*track), end(*track), back_inserter(arc_lengths), get_arc_length);
87  // Remove all NAN elements. For some reason, last hit in track is sometimes NAN
88  erase_remove_if(arc_lengths, IsNaN());
89 
90  // calculate gaps in arc length s between adjacent hits
91  // beware: first element not a difference but mapped onto itself, empty_s_gaps[0] = arc_lengths[0]
92  if (arc_lengths.size() > 1) {
93  std::vector<double> empty_s_gaps;
94  std::adjacent_difference(begin(arc_lengths), end(arc_lengths), back_inserter(empty_s_gaps));
95 
96  // Wrap a reference to empty_s_acc in a lambda, b/c it is passed by value to the following
97  // for_each. If used directly, only a copy would filled in the for_each.
98  auto empty_s_acc_ref = [&empty_s_acc](double s) { empty_s_acc(s); };
99  // start filling accumulator with hit gaps, but skip first which is not a difference
100  std::for_each(next(begin(empty_s_gaps)), end(empty_s_gaps), empty_s_acc_ref);
101  }
102 
103  unsigned int empty_s_size = bacc::count(empty_s_acc);
104 
105  // Overwrite boost-accumulator behavior for containers with 0 or 1 elements
106  // Set variances containers with for 0/1 elements to -1 (boost default: nan/0 respectively)
107  double drift_length_variance = -1;
108  double adc_variance = -1;
109  double tot_variance = -1;
110  double cont_layer_variance = -1;
111  double super_layer_variance = -1;
112  if (size > 1) {
113  // for more than two elements, calculate variance with bessel correction
114  double bessel_corr = (double)size / (size - 1.0);
115  drift_length_variance = std::sqrt(bacc::variance(drift_length_acc) * bessel_corr);
116  adc_variance = std::sqrt(bacc::variance(adc_acc) * bessel_corr);
117  tot_variance = std::sqrt(bacc::variance(tot_acc) * bessel_corr);
118  cont_layer_variance = std::sqrt(bacc::variance(cont_layer_acc) * bessel_corr);
119  super_layer_variance = std::sqrt(bacc::variance(super_layer_acc) * bessel_corr);
120  }
121  double empty_s_variance = -1;
122  if (empty_s_size > 1) {
123  double empty_s_bessel_corr = (double)empty_s_size / (empty_s_size - 1.0);
124  empty_s_variance = std::sqrt(bacc::variance(empty_s_acc) * empty_s_bessel_corr);
125  }
126 
127  const CDCTrajectory3D& trajectory3D = track->getStartTrajectory3D();
128  const CDCTrajectory2D& trajectory2D = trajectory3D.getTrajectory2D();
129  const CDCTrajectorySZ& trajectorySZ = trajectory3D.getTrajectorySZ();
130 
131  var<named("pt")>() = toFinite(trajectory2D.getAbsMom2D(), 0);
132  var<named("size")>() = size;
133  var<named("hits_per_layer")>() = hits_per_layer;
134 
135  var<named("sz_slope")>() = toFinite(trajectorySZ.getTanLambda(), 0);
136  var<named("z0")>() = toFinite(trajectorySZ.getZ0(), 0);
137  var<named("s_range")>() = toFinite(s_range, 0);
138  var<named("avg_hit_dist")>() = toFinite(avg_hit_dist, 0);
139  var<named("has_matching_segment")>() = track->getHasMatchingSegment();
140 
141  var<named("cont_layer_mean")>() = toFinite(bacc::mean(cont_layer_acc), 0);
142  var<named("cont_layer_variance")>() = toFinite(cont_layer_variance, 0);
143  var<named("cont_layer_max")>() = toFinite(cont_layer_max, 0);
144  var<named("cont_layer_min")>() = toFinite(cont_layer_min, 0);
145  var<named("cont_layer_first")>() = toFinite(cont_layer_first, 0);
146  var<named("cont_layer_last")>() = toFinite(cont_layer_last, 0);
147  var<named("cont_layer_max_vs_last")>() = toFinite(cont_layer_max - cont_layer_last, 0);
148  var<named("cont_layer_first_vs_min")>() = toFinite(cont_layer_first - cont_layer_min, 0);
149  var<named("cont_layer_count")>() = toFinite(cont_layer_count, 0);
150  var<named("cont_layer_occupancy")>() = toFinite(cont_layer_occupancy, 0);
151 
152  var<named("super_layer_mean")>() = toFinite(bacc::mean(super_layer_acc), 0);
153  var<named("super_layer_variance")>() = toFinite(super_layer_variance, 0);
154  var<named("super_layer_max")>() = toFinite(super_layer_max, 0);
155  var<named("super_layer_min")>() = toFinite(super_layer_min, 0);
156  var<named("super_layer_first")>() = toFinite(super_layer_first, 0);
157  var<named("super_layer_last")>() = toFinite(super_layer_last, 0);
158  var<named("super_layer_max_vs_last")>() = toFinite(super_layer_max - super_layer_last, 0);
159  var<named("super_layer_first_vs_min")>() = toFinite(super_layer_first - super_layer_min, 0);
160  var<named("super_layer_count")>() = toFinite(super_layer_count, 0);
161  var<named("super_layer_occupancy")>() = toFinite(super_layer_occupancy, 0);
162 
163  var<named("drift_length_mean")>() = toFinite(bacc::mean(drift_length_acc), 0);
164  var<named("drift_length_variance")>() = toFinite(drift_length_variance, 0);
165  var<named("drift_length_max")>() = toFinite(bacc::max(drift_length_acc), 0);
166  var<named("drift_length_min")>() = toFinite(bacc::min(drift_length_acc), 0);
167  var<named("drift_length_sum")>() = toFinite(bacc::sum(drift_length_acc), 0);
168 
169  var<named("adc_mean")>() = toFinite(bacc::mean(adc_acc), 0);
170  var<named("adc_variance")>() = toFinite(adc_variance, 0);
171  var<named("adc_max")>() = toFinite(bacc::max(adc_acc), 0);
172  var<named("adc_min")>() = toFinite(bacc::min(adc_acc), 0);
173  var<named("adc_sum")>() = toFinite(bacc::sum(adc_acc), 0);
174 
175  var<named("tot_mean")>() = toFinite(bacc::mean(tot_acc), 0);
176  var<named("tot_variance")>() = toFinite(tot_variance, 0);
177  var<named("tot_max")>() = toFinite(bacc::max(tot_acc), 0);
178  var<named("tot_min")>() = toFinite(bacc::min(tot_acc), 0);
179  var<named("tot_sum")>() = toFinite(bacc::sum(tot_acc), 0);
180 
181  var<named("empty_s_mean")>() = toFinite(bacc::mean(empty_s_acc), 0);
182  var<named("empty_s_sum")>() = toFinite(bacc::sum(empty_s_acc), 0);
183  var<named("empty_s_variance")>() = toFinite(empty_s_variance, 0);
184  var<named("empty_s_max")>() = toFinite(bacc::max(empty_s_acc), 0);
185  var<named("empty_s_min")>() = toFinite(bacc::min(empty_s_acc), 0);
186 
187  return true;
188 }
bool extract(const CDCTrack *track) override
Generate and assign the contained variables.
bacc::accumulator_set< double, statistics_set > statistics_accumulator
A boost accumulators set that aggregates statistics for the values it is called with.
Class representing a three dimensional reconstructed hit.
Definition: CDCRecoHit3D.h:52
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 getAbsMom2D(double bZ) const
Get the estimation for the absolute value of the transvers momentum.
Particle full three dimensional trajectory.
CDCTrajectory2D getTrajectory2D() const
Getter for the two dimensional 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 getZ0() const
Getter for the z coordinate at zero travel distance.
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
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.
Unary functor for equality comparison to NAN.
Definition: Functional.h:539