Belle II Software  release-06-02-00
HitInfoExtractor.h
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 
9 #pragma once
10 #include <tracking/trackFindingVXD/variableExtractors/VariableExtractor.h>
11 #include <tracking/dataobjects/RecoTrack.h>
12 #include <tracking/dataobjects/RecoHitInformation.h>
13 
14 #include <genfit/KalmanFitterInfo.h>
15 #include <genfit/TrackPoint.h>
16 #include <numeric>
17 #include <algorithm>
18 #include <optional>
19 
20 namespace Belle2 {
27  public:
32  explicit HitInfoExtractor(std::vector<Named<float*>>& variableSet) :
34  {
35  addVariable("N_TrackPoints_without_KalmanFitterInfo", variableSet);
36  addVariable("N_Hits_without_TrackPoint", variableSet);
37 
38  initializeStats("weight", variableSet);
39  initializeStats("smoothedChi2", variableSet);
40  }
41 
43  void extractVariables(const RecoTrack& recoTrack)
44  {
45  // get fitting parameters
46  const std::vector<RecoHitInformation*>& recoHitInformations = recoTrack.getRecoHitInformations(true);
47  std::vector<const genfit::KalmanFitterInfo*> kalmanFitterInfos;
48  kalmanFitterInfos.reserve(recoHitInformations.size());
49 
50  int n_no_trackPoint = 0; // number of recoHitInformations without related track points
51  int n_no_KalmanFitterInfo = 0; // number of track points without related KalmanFitterInfo
52  for (const RecoHitInformation* recoHitInformation : recoHitInformations) {
53  const genfit::TrackPoint* trackPoint = recoTrack.getCreatedTrackPoint(recoHitInformation);
54  if (trackPoint) {
55  const genfit::KalmanFitterInfo* kalmanFitterInfo = trackPoint->getKalmanFitterInfo();
56  if (kalmanFitterInfo) {
57  kalmanFitterInfos.push_back(kalmanFitterInfo);
58  } else {
59  n_no_KalmanFitterInfo++;
60  }
61  } else {
62  n_no_trackPoint++;
63  }
64  }
65  m_variables.at("N_Hits_without_TrackPoint") = n_no_trackPoint;
66  m_variables.at("N_TrackPoints_without_KalmanFitterInfo") = n_no_KalmanFitterInfo;
67 
68  // define lambda to which checks if hitinfo has kalman info and is from a specific detector
69  // use that via std::find_if to find first/last fitted hits from that detector
70  const auto hitHasKalmanInfoAndIsFromDetector =
71  [&recoTrack, this](const auto & recoHitInformation,
72  RecoHitInformation::RecoHitDetector trackingDetector) {
73  return (this->getKalmanFitterInfo(recoTrack, recoHitInformation)
74  and (recoHitInformation->getTrackingDetector() == trackingDetector));
75  };
76  const auto hitHasKalmanInfoAndIsFromCDC = std::bind(hitHasKalmanInfoAndIsFromDetector,
77  std::placeholders::_1,
78  RecoHitInformation::c_CDC);
79  const auto hitHasKalmanInfoAndIsFromSVD = std::bind(hitHasKalmanInfoAndIsFromDetector,
80  std::placeholders::_1,
81  RecoHitInformation::c_SVD);
82 
83  // find first CDC hit with Kalman info and extract weight and Chi2
84  const auto firstHitWithCDCKalmanInfoIter = std::find_if(recoHitInformations.begin(),
85  recoHitInformations.end(),
86  hitHasKalmanInfoAndIsFromCDC);
87  std::optional<float> weight_firstCDCHit;
88  std::optional<float> smoothedChi2_firstCDCHit;
89  if (firstHitWithCDCKalmanInfoIter != recoHitInformations.end()) {
90  const genfit::KalmanFitterInfo* kalmanFitterInfo = this->getKalmanFitterInfo(recoTrack, *firstHitWithCDCKalmanInfoIter);
91  weight_firstCDCHit = kalmanFitterInfo->getWeights().front();
92  smoothedChi2_firstCDCHit = this->getSmoothedChi2(kalmanFitterInfo);
93  }
94  m_variables.at("weight_firstCDCHit") = weight_firstCDCHit.value_or(m_valueIfNAN);
95  m_variables.at("smoothedChi2_firstCDCHit") = smoothedChi2_firstCDCHit.value_or(m_valueIfNAN);
96 
97  // find last SVD hit with Kalman info and extract weight and Chi2
98  const auto lastHitWithSVDKalmanInfoIter = std::find_if(recoHitInformations.rbegin(),
99  recoHitInformations.rend(),
100  hitHasKalmanInfoAndIsFromSVD);
101  std::optional<float> weight_lastSVDHit;
102  std::optional<float> smoothedChi2_lastSVDHit;
103  if (lastHitWithSVDKalmanInfoIter != recoHitInformations.rend()) {
104  const genfit::KalmanFitterInfo* kalmanFitterInfo = this->getKalmanFitterInfo(recoTrack, *lastHitWithSVDKalmanInfoIter);
105  weight_lastSVDHit = kalmanFitterInfo->getWeights().front();
106  smoothedChi2_lastSVDHit = this->getSmoothedChi2(kalmanFitterInfo);
107  }
108  m_variables.at("weight_lastSVDHit") = weight_lastSVDHit.value_or(m_valueIfNAN);
109  m_variables.at("smoothedChi2_lastSVDHit") = smoothedChi2_lastSVDHit.value_or(m_valueIfNAN);
110 
111  std::vector<float> fitWeights;
112  std::vector<float> chi2Values;
113  fitWeights.reserve(kalmanFitterInfos.size());
114  chi2Values.reserve(kalmanFitterInfos.size());
115  for (const auto& kalmanFitterInfo : kalmanFitterInfos) {
116  fitWeights.push_back(kalmanFitterInfo->getWeights().front());
117  chi2Values.push_back(this->getSmoothedChi2(kalmanFitterInfo).value_or(m_valueIfNAN));
118  }
119  setStats("weight", fitWeights);
120  setStats("smoothedChi2", chi2Values);
121  }
122 
123  protected:
125  void initializeStats(const std::string& identifier, std::vector<Named<float*>>& variables)
126  {
127  addVariable(identifier + "_max", variables);
128  addVariable(identifier + "_min", variables);
129  addVariable(identifier + "_mean", variables);
130  addVariable(identifier + "_std", variables);
131  addVariable(identifier + "_median", variables);
132  addVariable(identifier + "_n_zeros", variables);
133  addVariable(identifier + "_firstCDCHit", variables);
134  addVariable(identifier + "_lastSVDHit", variables);
135  }
136 
138  void setStats
139  (const std::string& identifier, std::vector<float>& values)
140  {
141  int size = values.size();
142  if (values.size() == 0) {
143  m_variables.at(identifier + "_max") = m_valueIfNAN;
144  m_variables.at(identifier + "_min") = m_valueIfNAN;
145  m_variables.at(identifier + "_mean") = m_valueIfNAN;
146  m_variables.at(identifier + "_std") = m_valueIfNAN;
147  m_variables.at(identifier + "_median") = m_valueIfNAN;
148  m_variables.at(identifier + "_n_zeros") = m_valueIfNAN;
149  m_variables.at(identifier + "_firstCDCHit") = m_valueIfNAN;
150  m_variables.at(identifier + "_lastSVDHit") = m_valueIfNAN;
151  return;
152  }
153 
154  std::sort(values.begin(), values.end());
155 
156  float sum = std::accumulate(values.begin(), values.end(), 0.0);
157  float mean = sum / size;
158  m_variables.at(identifier + "_mean") = mean;
159  float variance = 0.;
160  int n_zeros = 0;
161  for (float value : values) {
162  variance += (value - mean) * (value - mean);
163  if (value == 0)
164  n_zeros++;
165  }
166  m_variables.at(identifier + "_n_zeros") = n_zeros;
167  variance /= size - 1;
168  float stddev = std::sqrt(variance);
169  m_variables.at(identifier + "_std") = stddev;
170  m_variables.at(identifier + "_min") = values.front();
171  m_variables.at(identifier + "_max") = values.back();
172  // only in the case size==0 there would be a negative container index, but that case is handled above. So the suppress for cppcheck:
173  // cppcheck-suppress negativeContainerIndex
174  float median = (size % 2) ? values[size / 2] : 0.5 * (values[size / 2] + values[size / 2 - 1]);
175  m_variables.at(identifier + "_median") = median;
176  }
177 
178  private:
181  const RecoHitInformation* recoHitInformation)
182  {
183  const genfit::TrackPoint* trackPointPtr = recoTrack.getCreatedTrackPoint(recoHitInformation);
184  if (trackPointPtr) {
185  return trackPointPtr->getKalmanFitterInfo();
186  } else {
187  return nullptr;
188  }
189  }
192  std::optional<float> getSmoothedChi2(const genfit::KalmanFitterInfo* kalmanFitterInfo)
193  {
194  try {
195  return kalmanFitterInfo->getSmoothedChi2();
196  } catch (const std::exception& e) {
197  B2WARNING("HitInfoExtractor: Caught exception in kalmanFitterInfos[i]->getSmoothedChi2() \n"
198  << "-->" << e.what());
199  return std::nullopt;
200  }
201  }
202 
207  const float m_valueIfNAN = -1.0;
208  };
210 }
class to extract info from individual clusters and combine for SPTC
genfit::KalmanFitterInfo * getKalmanFitterInfo(const RecoTrack &recoTrack, const RecoHitInformation *recoHitInformation)
Helper function to get Kalman fitter info from RecoHitInformation if available.
const float m_valueIfNAN
Define a default value to use if a variable cannot be calculated.
HitInfoExtractor(std::vector< Named< float * >> &variableSet)
Constructor fills variableSet with variables to be extracted.
std::optional< float > getSmoothedChi2(const genfit::KalmanFitterInfo *kalmanFitterInfo)
Helper function to safely get Chi2 from a KalmanFitterInfo object if available, and if not return nul...
void extractVariables(const RecoTrack &recoTrack)
extract variables from SpacePoints
void setStats(const std::string &identifier, std::vector< float > &values)
calculated statistics and saves them in variable set
void initializeStats(const std::string &identifier, std::vector< Named< float * >> &variables)
initialize statistics subsets of variables from clusters that get combined for SPTC
This class stores additional information to every CDC/SVD/PXD hit stored in a RecoTrack.
RecoHitDetector
The detector this hit comes from (which is of course also visible in the hit type)
This is the Reconstruction Event-Data Model Track.
Definition: RecoTrack.h:76
const genfit::TrackPoint * getCreatedTrackPoint(const RecoHitInformation *recoHitInformation) const
Get a pointer to the TrackPoint that was created from this hit.
Definition: RecoTrack.cc:227
std::vector< RecoHitInformation * > getRecoHitInformations(bool getSorted=false) const
Return a list of all RecoHitInformations associated with the RecoTrack.
Definition: RecoTrack.cc:538
class to extract individual variables
std::unordered_map< std::string, float > m_variables
unordered_map to associate float value with a string name
void addVariable(const std::string &identifier, std::vector< Named< float * >> &variables)
add a variable to the variable set
Collects information needed and produced by a AbsKalmanFitter implementations and is specific to one ...
std::vector< double > getWeights() const
Get weights of measurements.
Object containing AbsMeasurement and AbsFitterInfo objects.
Definition: TrackPoint.h:46
KalmanFitterInfo * getKalmanFitterInfo(const AbsTrackRep *rep=nullptr) const
Helper to avoid casting.
Definition: TrackPoint.cc:180
Abstract base class for different kinds of events.