00001 #include "TrackingTools/GsfTracking/interface/GsfMultipleScatteringUpdator.h" 00002 00003 #include "DataFormats/GeometrySurface/interface/MediumProperties.h" 00004 00005 // #include "CommonDet/DetUtilities/interface/DetExceptions.h" 00006 00007 // #include "Utilities/Notification/interface/Verbose.h" 00008 00009 void 00010 GsfMultipleScatteringUpdator::compute (const TrajectoryStateOnSurface& TSoS, 00011 const PropagationDirection propDir) const 00012 { 00013 // 00014 // clear cache 00015 // 00016 theWeights.clear(); 00017 theDeltaPs.clear(); 00018 theDeltaCovs.clear(); 00019 // 00020 // Get surface and check presence of medium properties 00021 // 00022 const Surface& surface = TSoS.surface(); 00023 // 00024 // calculate components 00025 // 00026 if ( surface.mediumProperties() ) { 00027 LocalVector pvec = TSoS.localMomentum(); 00028 double p = TSoS.localMomentum().mag(); 00029 pvec *= 1./p; 00030 // thickness in radiation lengths 00031 double rl = surface.mediumProperties()->radLen()/fabs(pvec.z()); 00032 // auxiliary variables for modified X0 00033 const double z = 14; // atomic number of silicon 00034 const double logz = log(z); 00035 const double h = (z+1)/z*log(287*sqrt(z))/log(159*pow(z,-1./3.)); 00036 double beta2 = 1./(1.+mass()*mass()/p/p); 00037 // reduced thickness 00038 double dp1 = rl/beta2/h; 00039 double logdp1 = log(dp1); 00040 double logdp2 = 2./3.*logz + logdp1; 00041 // means are always 0 00042 theDeltaPs.push_back(0.); 00043 theDeltaPs.push_back(0.); 00044 // weights 00045 double w2; 00046 if ( logdp2<log(0.5) ) 00047 w2 = 0.05283+0.0077*logdp2+0.00069*logdp2*logdp2; 00048 else 00049 w2 =-0.01517+0.1151*logdp2-0.00653*logdp2*logdp2; 00050 double w1 = 1.-w2; 00051 theWeights.push_back(w1); 00052 theWeights.push_back(w2); 00053 // reduced variances 00054 double var1 = 0.8510+0.03314*logdp1-0.001825*logdp1*logdp1; 00055 double var2 = (1.-w1*var1)/w2; 00056 for ( int ic=0; ic<2; ic++ ) { 00057 // choose component and multiply with total variance 00058 double var = ic==0 ? var1 : var2; 00059 var *= 225.e-6*dp1/p/p; 00060 AlgebraicSymMatrix55 cov; 00061 // transform from orthogonal planes containing the 00062 // momentum vector to local parameters 00063 double sl = pvec.perp(); 00064 double cl = pvec.z(); 00065 double cf = pvec.x()/sl; 00066 double sf = pvec.y()/sl; 00067 cov(1,1) = var*(sf*sf*cl*cl + cf*cf)/(cl*cl*cl*cl); 00068 cov(1,2) = var*(cf*sf*sl*sl )/(cl*cl*cl*cl); 00069 cov(2,2) = var*(cf*cf*cl*cl + sf*sf)/(cl*cl*cl*cl); 00070 theDeltaCovs.push_back(cov); 00071 } 00072 } 00073 else { 00074 theWeights.push_back(1.); 00075 theDeltaPs.push_back(0.); 00076 theDeltaCovs.push_back(AlgebraicSymMatrix55()); 00077 } 00078 // 00079 // Save arguments to avoid duplication of computation 00080 // 00081 storeArguments(TSoS,propDir); 00082 } 00083 00084 // 00085 // Compare arguments with the ones of the previous call 00086 // 00087 bool 00088 GsfMultipleScatteringUpdator::newArguments (const TrajectoryStateOnSurface& TSoS, 00089 const PropagationDirection propDir) const { 00090 return TSoS.localMomentum().unit().z()!=theLastDz || 00091 TSoS.localMomentum().mag()!=theLastP || propDir!=theLastPropDir || 00092 TSoS.surface().mediumProperties()->radLen()!=theLastRadLength; 00093 } 00094 // 00095 // Save arguments 00096 // 00097 void GsfMultipleScatteringUpdator::storeArguments (const TrajectoryStateOnSurface& TSoS, 00098 const PropagationDirection propDir) const { 00099 theLastDz = TSoS.localMomentum().unit().z(); 00100 theLastP = TSoS.localMomentum().mag(); 00101 theLastPropDir = propDir; 00102 theLastRadLength = TSoS.surface().mediumProperties()->radLen(); 00103 }