CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
GsfBetheHeitlerUpdator.cc
Go to the documentation of this file.
2 
6 
7 #include <string>
8 #include <fstream>
9 #include <cmath>
10 
11 #include <cassert>
12 
13 namespace {
15  inline float logisticFunction(const float x) { return 1. / (1. + unsafe_expf<4>(-x)); }
17  inline float BetheHeitlerMean(const float rl) { return unsafe_expf<4>(-rl); }
19  inline float BetheHeitlerVariance(const float rl) {
20 #if defined(__clang__) || defined(__INTEL_COMPILER)
21  const
22 #else
23  constexpr
24 #endif
25  float l3ol2 = std::log(3.) / std::log(2.);
26  float mean = BetheHeitlerMean(rl);
27  return unsafe_expf<4>(-rl * l3ol2) - mean * mean;
28  }
29 } // namespace
30 
31 /*
32 namespace {
34  inline float logisticFunction (const float x) {return 1.f/(1.f+std::exp(-x));}
36  inline float BetheHeitlerMean (const float rl) {
37  return std::exp(-rl);
38  }
40  inline float BetheHeitlerVariance (const float rl)
41  {
42 #if __clang__
43  const
44 #else
45  constexpr
46 #endif
47  float l3ol2 = std::log(3.)/std::log(2.);
48  return std::exp(-rl*l3ol2) - std::exp(-2*rl);
49  }
50 }
51 */
52 
54  : GsfMaterialEffectsUpdator(0.000511, 6), theNrComponents(0), theCorrectionFlag(correctionFlag) {
55  if (theCorrectionFlag == 1)
56  edm::LogInfo("GsfBetheHeitlerUpdator") << "1st moment of mixture will be corrected";
57  if (theCorrectionFlag >= 2)
58  edm::LogInfo("GsfBetheHeitlerUpdator") << "1st and 2nd moments of mixture will be corrected";
59 
60  readParameters(fileName);
61  assert(theNrComponents <= 6);
63 }
64 
66  std::string name = "TrackingTools/GsfTracking/data/";
67  name += fileName;
68 
69  edm::FileInPath parFile(name);
70  edm::LogInfo("GsfBetheHeitlerUpdator") << "Reading GSF parameterization "
71  << "of Bethe-Heitler energy loss from " << parFile.fullPath();
72  std::ifstream ifs(parFile.fullPath().c_str());
73 
74  ifs >> theNrComponents;
75  int orderP;
76  ifs >> orderP;
77  ifs >> theTransformationCode;
78 
79  assert(orderP < MaxOrder);
80 
81  for (int ic = 0; ic != theNrComponents; ++ic) {
82  thePolyWeights[ic] = readPolynomial(ifs, orderP);
83  thePolyMeans[ic] = readPolynomial(ifs, orderP);
84  thePolyVars[ic] = readPolynomial(ifs, orderP);
85  }
86 }
87 
89  const unsigned int order) {
90  float coeffs[order + 1];
91  for (unsigned int i = 0; i < (order + 1); ++i)
92  aStream >> coeffs[i];
93  return Polynomial(coeffs, order + 1);
94 }
95 
97  const PropagationDirection propDir,
98  Effect effects[]) const {
99  //
100  // Get surface and check presence of medium properties
101  //
102  const Surface& surface = TSoS.surface();
103  //
104  // calculate components: first check associated material constants
105  //
106  float rl(0.f);
107  float p(0.f);
108  if (surface.mediumProperties().isValid()) {
109  LocalVector pvec = TSoS.localMomentum();
110  p = pvec.mag();
111  rl = surface.mediumProperties().radLen() / fabs(pvec.z()) * p;
112  }
113  //
114  // produce multi-state only in case of x/X0>0
115  //
116  if (rl > 0.0001f) {
117  //
118  // limit x/x0 to valid range for parametrisation
119  // should be done in a more elegant way ...
120  //
121  if (rl < 0.01f)
122  rl = 0.01f;
123  if (rl > 0.20f)
124  rl = 0.20f;
125 
126  float mixtureData[3][theNrComponents];
127  GSContainer mixture{mixtureData[0], mixtureData[1], mixtureData[2]};
128 
129  getMixtureParameters(rl, mixture);
130  correctWeights(mixture);
131  if (theCorrectionFlag >= 1)
132  mixture.second[0] = correctedFirstMean(rl, mixture);
133  if (theCorrectionFlag >= 2)
134  mixture.third[0] = correctedFirstVar(rl, mixture);
135 
136  for (int i = 0; i < theNrComponents; i++) {
137  float varPinv;
138  effects[i].weight *= mixture.first[i];
139  if (propDir == alongMomentum) {
140  //
141  // for forward propagation: calculate in p (linear in 1/z=p_inside/p_outside),
142  // then convert sig(p) to sig(1/p).
143  //
144  effects[i].deltaP += p * (mixture.second[i] - 1.f);
145  // float f = 1./p/mixture.second[i]/mixture.second[i];
146  // patch to ensure consistency between for- and backward propagation
147  float f = 1.f / (p * mixture.second[i]);
148  varPinv = f * f * mixture.third[i];
149  } else {
150  //
151  // for backward propagation: delta(1/p) is linear in z=p_outside/p_inside
152  // convert to obtain equivalent delta(p)
153  //
154  effects[i].deltaP += p * (1.f / mixture.second[i] - 1.f);
155  varPinv = mixture.third[i] / (p * p);
156  }
157  using namespace materialEffect;
158  effects[i].deltaCov[elos] += varPinv;
159  }
160  }
161 }
162 //
163 // Mixture parameters (in z)
164 //
165 void GsfBetheHeitlerUpdator::getMixtureParameters(const float rl, GSContainer& mixture) const {
167  for (int i = 0; i < theNrComponents; i++) {
168  weight[i] = thePolyWeights[i](rl);
169  z[i] = thePolyMeans[i](rl);
170  vz[i] = thePolyVars[i](rl);
171  }
173  for (int i = 0; i < theNrComponents; i++) {
174  mixture.first[i] = logisticFunction(weight[i]);
175  mixture.second[i] = logisticFunction(z[i]);
176  mixture.third[i] = unsafe_expf<4>(vz[i]);
177  ;
178  }
179  else // theTransformationCode
180  for (int i = 0; i < theNrComponents; i++) {
181  mixture.first[i] = weight[i];
182  mixture.second[i] = z[i];
183  mixture.third[i] = vz[i] * vz[i];
184  }
185 }
186 
187 //
188 // Correct weights
189 //
191  //
192  // get sum of weights
193  //
194  float wsum(0);
195  for (int i = 0; i < theNrComponents; i++)
196  wsum += mixture.first[i];
197  //
198  // rescale to obtain 1
199  //
200  wsum = 1.f / wsum;
201  for (int i = 0; i < theNrComponents; i++)
202  mixture.first[i] *= wsum;
203 }
204 //
205 // Correct means
206 //
207 float GsfBetheHeitlerUpdator::correctedFirstMean(const float rl, const GSContainer& mixture) const {
208  //
209  // calculate difference true mean - weighted sum
210  //
211  float mean = BetheHeitlerMean(rl);
212  for (int i = 1; i < theNrComponents; i++)
213  mean -= mixture.first[i] * mixture.second[i];
214  //
215  // return corrected mean for first component
216  //
217  return std::max(std::min(mean / mixture.first[0], 1.f), 0.f);
218 }
219 //
220 // Correct variances
221 //
222 float GsfBetheHeitlerUpdator::correctedFirstVar(const float rl, const GSContainer& mixture) const {
223  //
224  // calculate difference true variance - weighted sum
225  //
226  float var = BetheHeitlerVariance(rl) + BetheHeitlerMean(rl) * BetheHeitlerMean(rl) -
227  mixture.first[0] * mixture.second[0] * mixture.second[0];
228  for (int i = 1; i < theNrComponents; i++)
229  var -= mixture.first[i] * (mixture.second[i] * mixture.second[i] + mixture.third[i]);
230  //
231  // return corrected variance for first component
232  //
233  return std::max(var / mixture.first[0], 0.f);
234 }
float radLen() const
static std::vector< std::string > checklist log
void correctWeights(GSContainer &) const
Correction for weight of component 1.
PropagationDirection
assert(be >=bs)
Polynomial thePolyWeights[MaxSize]
correction of 1st or 1st&amp;2nd moments
void getMixtureParameters(const float, GSContainer &) const
Filling of mixture (in terms of z=E/E0)
LocalVector localMomentum() const
const SurfaceType & surface() const
T mag() const
Definition: PV3DBase.h:64
list var
if using global norm cols_to_minmax = [&#39;t_delta&#39;, &#39;t_hmaxNearP&#39;,&#39;t_emaxNearP&#39;, &#39;t_hAnnular&#39;, &#39;t_eAnnular&#39;,&#39;t_pt&#39;,&#39;t_nVtx&#39;,&#39;t_ieta&#39;,&#39;t_eHcal10&#39;, &#39;t_eHcal30&#39;,&#39;t_rhoh&#39;,&#39;t_eHcal&#39;] df[cols_to_minmax] = df[cols_to_minmax].apply(lambda x: (x - x.min()) / (x.max() - x.min()) if (x.max() - x.min() &gt; 0) else 1.0/200.0)
T z() const
Definition: PV3DBase.h:61
uint16_t const *__restrict__ x
Definition: gpuClustering.h:39
int theTransformationCode
number of components used for parameterisation
T min(T a, T b)
Definition: MathUtil.h:58
for(Iditer=Id.begin();Iditer!=Id.end();Iditer++)
Log< level::Info, false > LogInfo
void compute(const TrajectoryStateOnSurface &, const PropagationDirection, Effect[]) const override
Computation: generates vectors of weights, means and standard deviations.
Polynomial readPolynomial(std::ifstream &, const unsigned int)
Read coefficients of one polynomial from file.
GsfBetheHeitlerUpdator(const std::string fileName, const int correctionFlag)
constructor with explicit filename and correction flag
int theCorrectionFlag
values to be transformed by logistic / exp. function?
float correctedFirstVar(const float, const GSContainer &) const
Correction for variance of component 1.
Polynomial thePolyVars[MaxSize]
parametrisation of mean for each componentP
std::string fullPath() const
Definition: FileInPath.cc:161
void readParameters(const std::string)
Read parametrization from file.
static constexpr int MaxOrder
Polynomial thePolyMeans[MaxSize]
parametrisation of weight for each component
int weight
Definition: histoStyle.py:51
bool isValid() const
const MediumProperties & mediumProperties() const
Definition: Surface.h:83
float correctedFirstMean(const float, const GSContainer &) const
Correction for mean of component 1.