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 
46 GsfBetheHeitlerUpdator::GsfBetheHeitlerUpdator(const std::string fileName,
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);
59  assert(theNrComponents<=6);
60  resize(theNrComponents);
61 }
62 
63 void GsfBetheHeitlerUpdator::readParameters (const std::string fileName)
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 
88 GsfBetheHeitlerUpdator::Polynomial
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  GSContainer mixture[theNrComponents];
126  getMixtureParameters(rl,mixture);
127  correctWeights(mixture);
128  if ( theCorrectionFlag>=1 )
129  mixture[0].second = correctedFirstMean(rl,mixture);
130  if ( theCorrectionFlag>=2 )
131  mixture[0].third = correctedFirstVar(rl,mixture);
132 
133  for ( int i=0; i<theNrComponents; i++ ) {
134  float varPinv;
135  effects[i].weight*=mixture[i].first;
136  if ( propDir==alongMomentum ) {
137  //
138  // for forward propagation: calculate in p (linear in 1/z=p_inside/p_outside),
139  // then convert sig(p) to sig(1/p).
140  //
141  effects[i].deltaP += p*(mixture[i].second-1);
142  // float f = 1./p/mixture[i].second/mixture[i].second;
143  // patch to ensure consistency between for- and backward propagation
144  float f = 1./p/mixture[i].second;
145  varPinv = f*f*mixture[i].third;
146  }
147  else {
148  //
149  // for backward propagation: delta(1/p) is linear in z=p_outside/p_inside
150  // convert to obtain equivalent delta(p)
151  //
152  effects[i].deltaP += p*(1/mixture[i].second-1);
153  varPinv = mixture[i].third/p/p;
154  }
155  using namespace materialEffect;
156  effects[i].deltaCov[elos] += varPinv;
157  }
158  }
159 }
160 //
161 // Mixture parameters (in z)
162 //
163 void
164 GsfBetheHeitlerUpdator::getMixtureParameters (const float rl,
165  GSContainer mixture[]) const
166 {
167 
168  for ( int i=0; i<theNrComponents; i++ ) {
169 
170  float weight = thePolyWeights[i](rl);
171  if ( theTransformationCode ) weight = logisticFunction(weight);
172 
173  float z = thePolyMeans[i](rl);
174  if ( theTransformationCode ) z = logisticFunction(z);
175 
176  float vz = thePolyVars[i](rl);
177  if ( theTransformationCode )
178  vz = unsafe_expf<4>(vz);
179  else vz = vz*vz;
180 
181  mixture[i]=Triplet<float,float,float>(weight,z,vz);
182  }
183 }
184 
185 //
186 // Correct weights
187 //
188 void
189 GsfBetheHeitlerUpdator::correctWeights (GSContainer mixture[]) const
190 {
191  //
192  // get sum of weights
193  //
194  float wsum(0);
195  for ( int i=0; i<theNrComponents; i++ )
196  wsum += mixture[i].first;
197  //
198  // rescale to obtain 1
199  //
200  for ( int i=0; i<theNrComponents; i++ )
201  mixture[i].first /= wsum;
202 }
203 //
204 // Correct means
205 //
206 float
207 GsfBetheHeitlerUpdator::correctedFirstMean (const float rl,
208  const GSContainer mixture[]) const
209 {
210  //
211  // calculate difference true mean - weighted sum
212  //
213  float mean = BetheHeitlerMean(rl);
214  for ( int i=1; i<theNrComponents; i++ )
215  mean -= mixture[i].first*mixture[i].second;
216  //
217  // return corrected mean for first component
218  //
219  return std::max(std::min(mean/mixture[0].first,1.f),0.f);
220 }
221 //
222 // Correct variances
223 //
224 float
225 GsfBetheHeitlerUpdator::correctedFirstVar (const float rl,
226  const GSContainer mixture[]) const
227 {
228  //
229  // calculate difference true variance - weighted sum
230  //
231  float var = BetheHeitlerVariance(rl) +
232  BetheHeitlerMean(rl)*BetheHeitlerMean(rl) -
233  mixture[0].first*mixture[0].second*mixture[0].second;
234  for ( int i=1; i<theNrComponents; i++ )
235  var -= mixture[i].first*(mixture[i].second*mixture[i].second+mixture[i].third);
236  //
237  // return corrected variance for first component
238  //
239  return std::max(var/mixture[0].first,0.f);
240 }
241 
int i
Definition: DBlmapReader.cc:9
float radLen() const
PropagationDirection
Definition: Triplet.h:9
float float float z
LocalVector localMomentum() const
U second(std::pair< T, U > const &p)
const SurfaceType & surface() const
T mag() const
Definition: PV3DBase.h:67
const T & max(const T &a, const T &b)
T z() const
Definition: PV3DBase.h:64
double f[11][100]
bool first
Definition: L1TdeRCT.cc:79
Definition: DDAxes.h:10
int weight
Definition: histoStyle.py:50
bool isValid() const
const MediumProperties & mediumProperties() const
Definition: Surface.h:120