Go to the documentation of this file.00001 #include "TrackingTools/GsfTracking/interface/GsfBetheHeitlerUpdator.h"
00002
00003 #include "DataFormats/GeometrySurface/interface/MediumProperties.h"
00004 #include "FWCore/ParameterSet/interface/FileInPath.h"
00005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00006
00007 #include <string>
00008 #include <fstream>
00009 #include <cmath>
00010
00011 GsfBetheHeitlerUpdator::GsfBetheHeitlerUpdator(const std::string fileName,
00012 const int correctionFlag) :
00013
00014 GsfMaterialEffectsUpdator(0.000511),
00015 theNrComponents(0),
00016 theCorrectionFlag(correctionFlag),
00017 theLastDz(0.),
00018 theLastP(-1.),
00019 theLastPropDir(alongMomentum),
00020 theLastRadLength(-1.)
00021 {
00022 if ( theCorrectionFlag==1 )
00023 edm::LogInfo("GsfBetheHeitlerUpdator") << "1st moment of mixture will be corrected";
00024 if ( theCorrectionFlag>=2 )
00025 edm::LogInfo("GsfBetheHeitlerUpdator")
00026 << "1st and 2nd moments of mixture will be corrected";
00027
00028 readParameters(fileName);
00029 }
00030
00031 void GsfBetheHeitlerUpdator::readParameters (const std::string fileName)
00032 {
00033 std::string name = "TrackingTools/GsfTracking/data/";
00034 name += fileName;
00035
00036 edm::FileInPath parFile(name);
00037 edm::LogInfo("GsfBetheHeitlerUpdator") << "Reading GSF parameterization "
00038 << "of Bethe-Heitler energy loss from "
00039 << parFile.fullPath();
00040 std::ifstream ifs(parFile.fullPath().c_str());
00041
00042 ifs >> theNrComponents;
00043 int orderP;
00044 ifs >> orderP;
00045 ifs >> theTransformationCode;
00046 for ( int ic=0; ic<theNrComponents; ic++ ) {
00047 thePolyWeights.push_back(readPolynomial(ifs,orderP));
00048 thePolyMeans.push_back(readPolynomial(ifs,orderP));
00049 thePolyVars.push_back(readPolynomial(ifs,orderP));
00050 }
00051 }
00052
00053 GsfBetheHeitlerUpdator::Polynomial
00054 GsfBetheHeitlerUpdator::readPolynomial (std::ifstream& aStream,
00055 const int order) {
00056 std::vector<double> coeffs(order+1);
00057 for ( int i=0; i<(order+1); i++ ) aStream >> coeffs[i];
00058 return Polynomial(coeffs);
00059 }
00060
00061 void
00062 GsfBetheHeitlerUpdator::compute (const TrajectoryStateOnSurface& TSoS,
00063 const PropagationDirection propDir) const
00064 {
00065
00066
00067
00068 theWeights.clear();
00069 theDeltaPs.clear();
00070 theDeltaCovs.clear();
00071
00072
00073
00074 const Surface& surface = TSoS.surface();
00075
00076
00077
00078 double rl(0.);
00079 double p(0.);
00080 if ( surface.mediumProperties() ) {
00081 LocalVector pvec = TSoS.localMomentum();
00082 p = pvec.mag();
00083 rl = surface.mediumProperties()->radLen()/fabs(pvec.z())*p;
00084 }
00085
00086
00087
00088 if ( rl>0.0001 ) {
00089
00090
00091
00092
00093 if ( rl<0.01 ) rl = 0.01;
00094 if ( rl>0.20 ) rl = 0.20;
00095
00096 GSContainer mixture;
00097 getMixtureParameters(rl,mixture);
00098 correctWeights(mixture);
00099 if ( theCorrectionFlag>=1 )
00100 mixture[0].second = correctedFirstMean(rl,mixture);
00101 if ( theCorrectionFlag>=2 )
00102 mixture[0].third = correctedFirstVar(rl,mixture);
00103
00104 for ( int i=0; i<theNrComponents; i++ ) {
00105 double varPinv;
00106 theWeights.push_back(mixture[i].first);
00107 if ( propDir==alongMomentum ) {
00108
00109
00110
00111
00112 theDeltaPs.push_back(p*(mixture[i].second-1));
00113
00114
00115 double f = 1./p/mixture[i].second;
00116 varPinv = f*f*mixture[i].third;
00117 }
00118 else {
00119
00120
00121
00122
00123 theDeltaPs.push_back(p*(1/mixture[i].second-1));
00124 varPinv = mixture[i].third/p/p;
00125 }
00126 AlgebraicSymMatrix55 errors;
00127 errors(0,0) = varPinv;
00128 theDeltaCovs.push_back(errors);
00129 }
00130 }
00131 else {
00132 theWeights.push_back(1.);
00133 theDeltaPs.push_back(0.);
00134 theDeltaCovs.push_back(AlgebraicSymMatrix55());
00135 }
00136
00137
00138
00139 storeArguments(TSoS,propDir);
00140 }
00141
00142
00143
00144 void
00145 GsfBetheHeitlerUpdator::getMixtureParameters (const double rl,
00146 GSContainer& mixture) const
00147 {
00148 mixture.clear();
00149 mixture.reserve(theNrComponents);
00150
00151 for ( int i=0; i<theNrComponents; i++ ) {
00152
00153 double weight = thePolyWeights[i](rl);
00154 if ( theTransformationCode ) weight = logisticFunction(weight);
00155
00156 double z = thePolyMeans[i](rl);
00157 if ( theTransformationCode ) z = logisticFunction(z);
00158
00159 double vz = thePolyVars[i](rl);
00160 if ( theTransformationCode ) vz = exp(vz);
00161 else vz = vz*vz;
00162
00163 mixture.push_back(Triplet<double,double,double>(weight,z,vz));
00164 }
00165 }
00166
00167
00168
00169
00170 void
00171 GsfBetheHeitlerUpdator::correctWeights (GSContainer& mixture) const
00172 {
00173 if ( mixture.empty() ) return;
00174
00175
00176
00177 double wsum(0);
00178 for ( GSContainer::const_iterator i=mixture.begin();
00179 i!=mixture.end(); i++ ) wsum += (*i).first;
00180
00181
00182
00183 for ( GSContainer::iterator i=mixture.begin();
00184 i!=mixture.end(); i++ ) (*i).first /= wsum;
00185 }
00186
00187
00188
00189 double
00190 GsfBetheHeitlerUpdator::correctedFirstMean (const double rl,
00191 const GSContainer& mixture) const
00192 {
00193 if ( mixture.empty() ) return 0.;
00194
00195
00196
00197 double mean = BetheHeitlerMean(rl);
00198 for ( GSContainer::const_iterator i=mixture.begin()+1;
00199 i!=mixture.end(); i++ ) mean -= (*i).first*(*i).second;
00200
00201
00202
00203 return std::max(std::min(mean/mixture[0].first,1.),0.);
00204 }
00205
00206
00207
00208 double
00209 GsfBetheHeitlerUpdator::correctedFirstVar (const double rl,
00210 const GSContainer& mixture) const
00211 {
00212 if ( mixture.empty() ) return 0.;
00213
00214
00215
00216 double var = BetheHeitlerVariance(rl) +
00217 BetheHeitlerMean(rl)*BetheHeitlerMean(rl) -
00218 mixture[0].first*mixture[0].second*mixture[0].second;
00219 for ( GSContainer::const_iterator i=mixture.begin()+1;
00220 i!=mixture.end(); i++ )
00221 var -= (*i).first*((*i).second*(*i).second+(*i).third);
00222
00223
00224
00225 return std::max(var/mixture[0].first,0.);
00226 }
00227
00228
00229
00230
00231 bool
00232 GsfBetheHeitlerUpdator::newArguments (const TrajectoryStateOnSurface& TSoS,
00233 const PropagationDirection propDir) const {
00234 return TSoS.localMomentum().unit().z()!=theLastDz ||
00235 TSoS.localMomentum().mag()!=theLastP || propDir!=theLastPropDir ||
00236 TSoS.surface().mediumProperties()->radLen()!=theLastRadLength;
00237 }
00238
00239
00240
00241 void GsfBetheHeitlerUpdator::storeArguments (const TrajectoryStateOnSurface& TSoS,
00242 const PropagationDirection propDir) const {
00243 theLastDz = TSoS.localMomentum().unit().z();
00244 theLastP = TSoS.localMomentum().mag();
00245 theLastPropDir = propDir;
00246 theLastRadLength = TSoS.surface().mediumProperties()->radLen();
00247 }