CMS 3D CMS Logo

LikelihoodFitDeDxEstimator.h
Go to the documentation of this file.
1 #ifndef RecoTracker_DeDx_LikelihoodFitDeDxEstimator_h
2 #define RecoTracker_DeDx_LikelihoodFitDeDxEstimator_h
3 
6 
8 public:
10 
11  std::pair<float, float> dedx(const reco::DeDxHitCollection& Hits) override {
12  if (Hits.empty())
13  return {0., 0.};
14  // compute original
15  std::array<double, 2> value;
16  const auto& chi2 = estimate(Hits, value);
17  // try to remove lowest dE/dx measurement
18  const auto& n = Hits.size();
19  if (n >= 3 && (chi2 > 1.3 * n + 4 * std::sqrt(1.3 * n))) {
20  auto hs = Hits;
21  hs.erase(std::min_element(hs.begin(), hs.end()));
22  // if got better, accept
23  std::array<double, 2> v;
24  if (estimate(hs, v) < chi2 - 12)
25  value = v;
26  }
27  return {value[0], std::sqrt(value[1])};
28  }
29 
30 private:
31  void calculate_wrt_epsilon(const reco::DeDxHit&, const double&, std::array<double, 3>&);
32  void functionEpsilon(const reco::DeDxHitCollection&, const double&, std::array<double, 3>&);
33  double minimizeAllSaturated(const reco::DeDxHitCollection&, std::array<double, 2>&);
34  double newtonMethodEpsilon(const reco::DeDxHitCollection&, std::array<double, 2>&);
35  double estimate(const reco::DeDxHitCollection&, std::array<double, 2>&);
36 };
37 
38 /*****************************************************************************/
40  const double& epsilon,
41  std::array<double, 3>& value) {
42  const auto& ls = h.pathLength();
43  const auto& sn = h.error(); // energy sigma
44  const auto y = h.charge() * ls; // = g * y
45  const auto sD = 2.E-3 + 0.095 * y;
46  const auto ss = sD * sD + sn * sn;
47  const auto s = std::sqrt(ss);
48  const auto delta = epsilon * ls;
49  const auto dy = delta - y;
50  constexpr double nu(0.65);
51 
52  // calculate derivatives with respect to delta
53  std::array<double, 3> val{{0.}};
54  if (h.rawDetId() == 0) { // normal
55  if (dy < -nu * s) {
56  val[0] = -2. * nu * dy / s - nu * nu;
57  val[1] = -2. * nu / s;
58  val[2] = 0.;
59  } else {
60  val[0] = dy * dy / ss;
61  val[1] = 2. * dy / ss;
62  val[2] = 2. / ss;
63  }
64  } else { // saturated
65  if (dy < s) {
66  val[0] = -dy / s + 1.;
67  val[1] = -1. / s;
68  val[2] = 0.;
69  } else {
70  val[0] = 0.;
71  val[1] = 0.;
72  val[2] = 0.;
73  }
74  }
75 
76  // d/d delta -> d/d epsilon
77  val[1] *= ls;
78  val[2] *= ls * ls;
79 
80  // sum
81  for (size_t k = 0; k < value.size(); k++)
82  value[k] += val[k];
83 }
84 
85 /*****************************************************************************/
87  const double& epsilon,
88  std::array<double, 3>& val) {
89  val = {{0, 0, 0}};
90  for (const auto& h : Hits)
92 }
93 
94 /*****************************************************************************/
96  std::array<double, 2>& value) {
97  int nStep(0);
98  double par(3.0); // input MeV/cm
99 
100  std::array<double, 3> val{{0}};
101  do {
102  functionEpsilon(Hits, par, val);
103  if (val[1] != 0)
104  par += -val[0] / val[1];
105  nStep++;
106  } while (val[0] > 1e-3 && val[1] != 0 && nStep < 10);
107 
108  value[0] = par * 1.1;
109  value[1] = par * par * 0.01;
110 
111  return val[0];
112 }
113 
114 /*****************************************************************************/
116  std::array<double, 2>& value) {
117  int nStep(0);
118  double par(3.0); // input MeV/cm
119  double dpar(0);
120 
121  std::array<double, 3> val{{0}};
122  do {
123  functionEpsilon(Hits, par, val);
124  if (val[2] != 0.)
125  dpar = -val[1] / std::abs(val[2]);
126  else
127  dpar = 1.; // step up, for epsilon
128  if (par + dpar > 0)
129  par += dpar; // ok
130  else
131  par /= 2.; // half
132  nStep++;
133  } while (std::abs(dpar) > 1e-3 && nStep < 50);
134 
135  value[0] = par;
136  value[1] = 2. / val[2];
137 
138  return val[0];
139 }
140 
141 /*****************************************************************************/
142 double LikelihoodFitDeDxEstimator::estimate(const reco::DeDxHitCollection& Hits, std::array<double, 2>& value) {
143  // use newton method if at least one hit is not saturated
144  for (const auto& h : Hits)
145  if (h.rawDetId() == 0)
146  return newtonMethodEpsilon(Hits, value);
147  // else use minimize all saturated
148  return minimizeAllSaturated(Hits, value);
149 }
150 
151 #endif
std::vector< DeDxHit > DeDxHitCollection
Definition: DeDxHit.h:45
std::pair< float, float > dedx(const reco::DeDxHitCollection &Hits) override
void functionEpsilon(const reco::DeDxHitCollection &, const double &, std::array< double, 3 > &)
double estimate(const reco::DeDxHitCollection &, std::array< double, 2 > &)
T sqrt(T t)
Definition: SSEVec.h:23
void calculate_wrt_epsilon(const reco::DeDxHit &, const double &, std::array< double, 3 > &)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
Definition: value.py:1
LikelihoodFitDeDxEstimator(const edm::ParameterSet &iConfig)
double minimizeAllSaturated(const reco::DeDxHitCollection &, std::array< double, 2 > &)
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
double newtonMethodEpsilon(const reco::DeDxHitCollection &, std::array< double, 2 > &)