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