CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
GsfBetheHeitlerUpdator.cc
Go to the documentation of this file.
2 
6 
7 #include <string>
8 #include <fstream>
9 #include <cmath>
10 #include<cassert>
11 
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  const float l3ol2 = std::log(3.)/std::log(2.);
24  float mean = BetheHeitlerMean(rl);
25  return unsafe_expf<4>(-rl*l3ol2) - mean*mean;
26  }
27 }
28 
29 /*
30 namespace {
32  inline float logisticFunction (const float x) {return 1.f/(1.f+std::exp(-x));}
34  inline float BetheHeitlerMean (const float rl) {
35  return std::exp(-rl);
36  }
38  inline float BetheHeitlerVariance (const float rl)
39  {
40  constexpr float l3ol2 = std::log(3.)/std::log(2.);
41  return std::exp(-rl*l3ol2) - std::exp(-2*rl);
42  }
43 }
44 */
45 
47  const int correctionFlag) :
48  GsfMaterialEffectsUpdator(0.000511,6),
49  theNrComponents(0),
50  theCorrectionFlag(correctionFlag)
51 {
52  if ( theCorrectionFlag==1 )
53  edm::LogInfo("GsfBetheHeitlerUpdator") << "1st moment of mixture will be corrected";
54  if ( theCorrectionFlag>=2 )
55  edm::LogInfo("GsfBetheHeitlerUpdator")
56  << "1st and 2nd moments of mixture will be corrected";
57 
58  readParameters(fileName);
61 }
62 
64 {
65  std::string name = "TrackingTools/GsfTracking/data/";
66  name += fileName;
67 
68  edm::FileInPath parFile(name);
69  edm::LogInfo("GsfBetheHeitlerUpdator") << "Reading GSF parameterization "
70  << "of Bethe-Heitler energy loss from "
71  << 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 GsfBetheHeitlerUpdator::readPolynomial (std::ifstream& aStream,
90  const int order) {
91  float coeffs[order+1];
92  for ( int i=0; i<(order+1); ++i ) aStream >> coeffs[i];
93  return Polynomial(coeffs,order+1);
94 }
95 
96 void
98  const PropagationDirection propDir, Effect effects[]) const
99 {
100  //
101  // Get surface and check presence of medium properties
102  //
103  const Surface& surface = TSoS.surface();
104  //
105  // calculate components: first check associated material constants
106  //
107  float rl(0.f);
108  float p(0.f);
109  if ( surface.mediumProperties().isValid() ) {
110  LocalVector pvec = TSoS.localMomentum();
111  p = pvec.mag();
112  rl = surface.mediumProperties().radLen()/fabs(pvec.z())*p;
113  }
114  //
115  // produce multi-state only in case of x/X0>0
116  //
117  if ( rl>0.0001f ) {
118  //
119  // limit x/x0 to valid range for parametrisation
120  // should be done in a more elegant way ...
121  //
122  if ( rl<0.01f ) rl = 0.01f;
123  if ( rl>0.20f ) rl = 0.20f;
124 
125  #if __clang__
126  std::vector<GSContainer> mixtureHolder(theNrComponents);
127  GSContainer *mixture = mixtureHolder.data();
128  #else
129  GSContainer mixture[theNrComponents];
130  #endif
131  getMixtureParameters(rl,mixture);
132  correctWeights(mixture);
133  if ( theCorrectionFlag>=1 )
134  mixture[0].second = correctedFirstMean(rl,mixture);
135  if ( theCorrectionFlag>=2 )
136  mixture[0].third = correctedFirstVar(rl,mixture);
137 
138  for ( int i=0; i<theNrComponents; i++ ) {
139  float varPinv;
140  effects[i].weight*=mixture[i].first;
141  if ( propDir==alongMomentum ) {
142  //
143  // for forward propagation: calculate in p (linear in 1/z=p_inside/p_outside),
144  // then convert sig(p) to sig(1/p).
145  //
146  effects[i].deltaP += p*(mixture[i].second-1);
147  // float f = 1./p/mixture[i].second/mixture[i].second;
148  // patch to ensure consistency between for- and backward propagation
149  float f = 1./p/mixture[i].second;
150  varPinv = f*f*mixture[i].third;
151  }
152  else {
153  //
154  // for backward propagation: delta(1/p) is linear in z=p_outside/p_inside
155  // convert to obtain equivalent delta(p)
156  //
157  effects[i].deltaP += p*(1/mixture[i].second-1);
158  varPinv = mixture[i].third/p/p;
159  }
160  using namespace materialEffect;
161  effects[i].deltaCov[elos] += varPinv;
162  }
163  }
164 }
165 //
166 // Mixture parameters (in z)
167 //
168 void
170  GSContainer mixture[]) const
171 {
172 
173  for ( int i=0; i<theNrComponents; i++ ) {
174 
175  float weight = thePolyWeights[i](rl);
176  if ( theTransformationCode ) weight = logisticFunction(weight);
177 
178  float z = thePolyMeans[i](rl);
179  if ( theTransformationCode ) z = logisticFunction(z);
180 
181  float vz = thePolyVars[i](rl);
182  if ( theTransformationCode )
183  vz = unsafe_expf<4>(vz);
184  else vz = vz*vz;
185 
186  mixture[i]=Triplet<float,float,float>(weight,z,vz);
187  }
188 }
189 
190 //
191 // Correct weights
192 //
193 void
195 {
196  //
197  // get sum of weights
198  //
199  float wsum(0);
200  for ( int i=0; i<theNrComponents; i++ )
201  wsum += mixture[i].first;
202  //
203  // rescale to obtain 1
204  //
205  for ( int i=0; i<theNrComponents; i++ )
206  mixture[i].first /= wsum;
207 }
208 //
209 // Correct means
210 //
211 float
213  const GSContainer mixture[]) const
214 {
215  //
216  // calculate difference true mean - weighted sum
217  //
218  float mean = BetheHeitlerMean(rl);
219  for ( int i=1; i<theNrComponents; i++ )
220  mean -= mixture[i].first*mixture[i].second;
221  //
222  // return corrected mean for first component
223  //
224  return std::max(std::min(mean/mixture[0].first,1.f),0.f);
225 }
226 //
227 // Correct variances
228 //
229 float
231  const GSContainer mixture[]) const
232 {
233  //
234  // calculate difference true variance - weighted sum
235  //
236  float var = BetheHeitlerVariance(rl) +
237  BetheHeitlerMean(rl)*BetheHeitlerMean(rl) -
238  mixture[0].first*mixture[0].second*mixture[0].second;
239  for ( int i=1; i<theNrComponents; i++ )
240  var -= mixture[i].first*(mixture[i].second*mixture[i].second+mixture[i].third);
241  //
242  // return corrected variance for first component
243  //
244  return std::max(var/mixture[0].first,0.f);
245 }
246 
int i
Definition: DBlmapReader.cc:9
float radLen() const
Polynomial readPolynomial(std::ifstream &, const int)
Read coefficients of one polynomial from file.
assert(m_qm.get())
PropagationDirection
Definition: Triplet.h:9
Polynomial thePolyWeights[MaxSize]
correction of 1st or 1st&amp;2nd moments
virtual void compute(const TrajectoryStateOnSurface &, const PropagationDirection, Effect[]) const
Computation: generates vectors of weights, means and standard deviations.
LocalVector localMomentum() const
U second(std::pair< T, U > const &p)
void getMixtureParameters(const float, GSContainer[]) const
Filling of mixture (in terms of z=E/E0)
T x() const
Cartesian x coordinate.
const SurfaceType & surface() const
T mag() const
Definition: PV3DBase.h:67
T z() const
Definition: PV3DBase.h:64
void correctWeights(GSContainer[]) const
Correction for weight of component 1.
T2 second
Definition: Triplet.h:15
T3 third
Definition: Triplet.h:16
double f[11][100]
float correctedFirstVar(const float, const GSContainer[]) const
Correction for variance of component 1.
int theTransformationCode
number of components used for parameterisation
T min(T a, T b)
Definition: MathUtil.h:58
T1 first
Definition: Triplet.h:14
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?
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
int weight
Definition: histoStyle.py:50
bool isValid() const
const MediumProperties & mediumProperties() const
Definition: Surface.h:112
float correctedFirstMean(const float, const GSContainer[]) const
Correction for mean of component 1.