CMS 3D CMS Logo

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) {
18  return unsafe_expf<4>(-rl);
19  }
21  inline float BetheHeitlerVariance (const float rl)
22  {
23 #if defined(__clang__) || defined(__INTEL_COMPILER)
24  const
25 #else
26  constexpr
27 #endif
28  float l3ol2 = std::log(3.)/std::log(2.);
29  float mean = BetheHeitlerMean(rl);
30  return unsafe_expf<4>(-rl*l3ol2) - mean*mean;
31  }
32 }
33 
34 /*
35 namespace {
37  inline float logisticFunction (const float x) {return 1.f/(1.f+std::exp(-x));}
39  inline float BetheHeitlerMean (const float rl) {
40  return std::exp(-rl);
41  }
43  inline float BetheHeitlerVariance (const float rl)
44  {
45 #if __clang__
46  const
47 #else
48  constexpr
49 #endif
50  float l3ol2 = std::log(3.)/std::log(2.);
51  return std::exp(-rl*l3ol2) - std::exp(-2*rl);
52  }
53 }
54 */
55 
57  const int correctionFlag) :
58  GsfMaterialEffectsUpdator(0.000511,6),
59  theNrComponents(0),
60  theCorrectionFlag(correctionFlag)
61 {
62  if ( theCorrectionFlag==1 )
63  edm::LogInfo("GsfBetheHeitlerUpdator") << "1st moment of mixture will be corrected";
64  if ( theCorrectionFlag>=2 )
65  edm::LogInfo("GsfBetheHeitlerUpdator")
66  << "1st and 2nd moments of mixture will be corrected";
67 
68  readParameters(fileName);
69  assert(theNrComponents<=6);
71 }
72 
74 {
75  std::string name = "TrackingTools/GsfTracking/data/";
76  name += fileName;
77 
78  edm::FileInPath parFile(name);
79  edm::LogInfo("GsfBetheHeitlerUpdator") << "Reading GSF parameterization "
80  << "of Bethe-Heitler energy loss from "
81  << parFile.fullPath();
82  std::ifstream ifs(parFile.fullPath().c_str());
83 
84  ifs >> theNrComponents;
85  int orderP;
86  ifs >> orderP;
87  ifs >> theTransformationCode;
88 
89  assert(orderP<MaxOrder);
90 
91  for ( int ic=0; ic!=theNrComponents; ++ic ) {
92  thePolyWeights[ic]=readPolynomial(ifs,orderP);
93  thePolyMeans[ic]=readPolynomial(ifs,orderP);
94  thePolyVars[ic]=readPolynomial(ifs,orderP);
95  }
96 }
97 
99 GsfBetheHeitlerUpdator::readPolynomial (std::ifstream& aStream,
100  const int order) {
101  float coeffs[order+1];
102  for ( int i=0; i<(order+1); ++i ) aStream >> coeffs[i];
103  return Polynomial(coeffs,order+1);
104 }
105 
106 void
108  const PropagationDirection propDir, Effect effects[]) const
109 {
110  //
111  // Get surface and check presence of medium properties
112  //
113  const Surface& surface = TSoS.surface();
114  //
115  // calculate components: first check associated material constants
116  //
117  float rl(0.f);
118  float p(0.f);
119  if ( surface.mediumProperties().isValid() ) {
120  LocalVector pvec = TSoS.localMomentum();
121  p = pvec.mag();
122  rl = surface.mediumProperties().radLen()/fabs(pvec.z())*p;
123  }
124  //
125  // produce multi-state only in case of x/X0>0
126  //
127  if ( rl>0.0001f ) {
128  //
129  // limit x/x0 to valid range for parametrisation
130  // should be done in a more elegant way ...
131  //
132  if ( rl<0.01f ) rl = 0.01f;
133  if ( rl>0.20f ) rl = 0.20f;
134 
135  float mixtureData[3][theNrComponents];
136  GSContainer mixture{mixtureData[0],mixtureData[1],mixtureData[2]};
137 
138  getMixtureParameters(rl,mixture);
139  correctWeights(mixture);
140  if ( theCorrectionFlag>=1 )
141  mixture.second[0] = correctedFirstMean(rl,mixture);
142  if ( theCorrectionFlag>=2 )
143  mixture.third[0] = correctedFirstVar(rl,mixture);
144 
145  for ( int i=0; i<theNrComponents; i++ ) {
146  float varPinv;
147  effects[i].weight*=mixture.first[i];
148  if ( propDir==alongMomentum ) {
149  //
150  // for forward propagation: calculate in p (linear in 1/z=p_inside/p_outside),
151  // then convert sig(p) to sig(1/p).
152  //
153  effects[i].deltaP += p*(mixture.second[i]-1.f);
154  // float f = 1./p/mixture.second[i]/mixture.second[i];
155  // patch to ensure consistency between for- and backward propagation
156  float f = 1.f/(p*mixture.second[i]);
157  varPinv = f*f*mixture.third[i];
158  }
159  else {
160  //
161  // for backward propagation: delta(1/p) is linear in z=p_outside/p_inside
162  // convert to obtain equivalent delta(p)
163  //
164  effects[i].deltaP += p*(1.f/mixture.second[i]-1.f);
165  varPinv = mixture.third[i]/(p*p);
166  }
167  using namespace materialEffect;
168  effects[i].deltaCov[elos] += varPinv;
169  }
170  }
171 }
172 //
173 // Mixture parameters (in z)
174 //
175 void
177  GSContainer & mixture) const
178 {
179 
181  for ( int i=0; i<theNrComponents; i++ ) {
182  weight[i] = thePolyWeights[i](rl);
183  z[i] = thePolyMeans[i](rl);
184  vz[i] = thePolyVars[i](rl);
185  }
186  if ( theTransformationCode )
187  for ( int i=0; i<theNrComponents; i++ ) {
188  mixture.first[i]=logisticFunction(weight[i]);
189  mixture.second[i]=logisticFunction(z[i]);
190  mixture.third[i]=unsafe_expf<4>(vz[i]);;
191  }
192  else // theTransformationCode
193  for ( int i=0; i<theNrComponents; i++ ) {
194  mixture.first[i]=weight[i];
195  mixture.second[i]=z[i];
196  mixture.third[i]=vz[i]*vz[i];
197  }
198 }
199 
200 //
201 // Correct weights
202 //
203 void
205 {
206  //
207  // get sum of weights
208  //
209  float wsum(0);
210  for ( int i=0; i<theNrComponents; i++ )
211  wsum += mixture.first[i];
212  //
213  // rescale to obtain 1
214  //
215  wsum = 1.f/wsum;
216  for ( int i=0; i<theNrComponents; i++ )
217  mixture.first[i] *= wsum;
218 }
219 //
220 // Correct means
221 //
222 float
224  const GSContainer & mixture) const
225 {
226  //
227  // calculate difference true mean - weighted sum
228  //
229  float mean = BetheHeitlerMean(rl);
230  for ( int i=1; i<theNrComponents; i++ )
231  mean -= mixture.first[i]*mixture.second[i];
232  //
233  // return corrected mean for first component
234  //
235  return std::max(std::min(mean/mixture.first[0],1.f),0.f);
236 }
237 //
238 // Correct variances
239 //
240 float
242  const GSContainer & mixture) const
243 {
244  //
245  // calculate difference true variance - weighted sum
246  //
247  float var = BetheHeitlerVariance(rl) +
248  BetheHeitlerMean(rl)*BetheHeitlerMean(rl) -
249  mixture.first[0]*mixture.second[0]*mixture.second[0];
250  for ( int i=1; i<theNrComponents; i++ )
251  var -= mixture.first[i]*(mixture.second[i]*mixture.second[i]+mixture.third[i]);
252  //
253  // return corrected variance for first component
254  //
255  return std::max(var/mixture.first[0],0.f);
256 }
257 
float radLen() const
Polynomial readPolynomial(std::ifstream &, const int)
Read coefficients of one polynomial from file.
void correctWeights(GSContainer &) const
Correction for weight of component 1.
Definition: weight.py:1
PropagationDirection
Polynomial thePolyWeights[MaxSize]
correction of 1st or 1st&2nd moments
#define constexpr
virtual void compute(const TrajectoryStateOnSurface &, const PropagationDirection, Effect[]) const
Computation: generates vectors of weights, means and standard deviations.
void getMixtureParameters(const float, GSContainer &) const
Filling of mixture (in terms of z=E/E0)
LocalVector localMomentum() const
T x() const
Cartesian x coordinate.
const SurfaceType & surface() const
T mag() const
Definition: PV3DBase.h:67
T z() const
Definition: PV3DBase.h:64
double f[11][100]
int theTransformationCode
number of components used for parameterisation
T min(T a, T b)
Definition: MathUtil.h:58
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
void readParameters(const std::string)
Read parametrization from file.
Polynomial thePolyMeans[MaxSize]
parametrisation of weight for each component
std::string fullPath() const
Definition: FileInPath.cc:184
bool isValid() const
const MediumProperties & mediumProperties() const
Definition: Surface.h:112
float correctedFirstMean(const float, const GSContainer &) const
Correction for mean of component 1.