00001 #include "TrackingTools/GsfTracking/interface/PosteriorWeightsCalculator.h" 00002 00003 #include "TrackingTools/PatternTools/interface/MeasurementExtractor.h" 00004 #include "FWCore/MessageLogger/interface/MessageLogger.h" 00005 00006 #include <cfloat> 00007 00008 std::vector<double> PosteriorWeightsCalculator::weights(const TransientTrackingRecHit& recHit) const { 00009 switch (recHit.dimension()) { 00010 case 1: return weights<1>(recHit); 00011 case 2: return weights<2>(recHit); 00012 case 3: return weights<3>(recHit); 00013 case 4: return weights<4>(recHit); 00014 case 5: return weights<5>(recHit); 00015 } 00016 throw cms::Exception("Error: rechit of size not 1,2,3,4,5"); 00017 } 00018 00019 template<unsigned int D> 00020 std::vector<double> PosteriorWeightsCalculator::weights(const TransientTrackingRecHit& recHit) const { 00021 typedef typename AlgebraicROOTObject<D,5>::Matrix MatD5; 00022 typedef typename AlgebraicROOTObject<5,D>::Matrix Mat5D; 00023 typedef typename AlgebraicROOTObject<D,D>::SymMatrix SMatDD; 00024 typedef typename AlgebraicROOTObject<D>::Vector VecD; 00025 00026 std::vector<double> weights; 00027 if ( predictedComponents.empty() ) return weights; 00028 weights.reserve(predictedComponents.size()); 00029 00030 std::vector<double> detRs; 00031 detRs.reserve(predictedComponents.size()); 00032 std::vector<double> chi2s; 00033 chi2s.reserve(predictedComponents.size()); 00034 // 00035 // calculate chi2 and determinant / component and find 00036 // minimum / maximum of chi2 00037 // 00038 double chi2Min(DBL_MAX); 00039 for ( unsigned int i=0; i<predictedComponents.size(); i++ ) { 00040 MeasurementExtractor me(predictedComponents[i]); 00041 // Residuals of aPredictedState w.r.t. aRecHit, 00043 VecD r = asSVector<D>(recHit.parameters()) - me.measuredParameters<D>(recHit); 00044 // and covariance matrix of residuals 00046 SMatDD V = asSMatrix<D>(recHit.parametersError()); 00047 SMatDD R = V + me.measuredError<D>(recHit); 00048 double detR; 00049 if (! R.Det2(detR) ) { 00050 edm::LogError("PosteriorWeightsCalculator") << "PosteriorWeightsCalculator: determinant failed"; 00051 return std::vector<double>(); 00052 } 00053 detRs.push_back(detR); 00054 00055 int ierr = ! R.Invert(); // if (ierr != 0) throw exception; 00056 if ( ierr!=0 ) { 00057 edm::LogError("PosteriorWeightsCalculator") 00058 << "PosteriorWeightsCalculator: inversion failed, ierr = " << ierr; 00059 return std::vector<double>(); 00060 } 00061 double chi2 = ROOT::Math::Similarity(r,R); 00062 chi2s.push_back(chi2); 00063 if ( chi2<chi2Min ) chi2Min = chi2; 00064 } 00065 if ( detRs.size()!=predictedComponents.size() || 00066 chi2s.size()!=predictedComponents.size() ) { 00067 edm::LogError("PosteriorWeightsCalculator") << "Problem in vector sizes"; 00068 return std::vector<double>(); 00069 } 00070 // 00071 // calculate weights (extracting a common factor 00072 // exp(-0.5*chi2Min) to avoid numerical problems 00073 // during exponentation 00074 // 00075 double sumWeights(0.); 00076 for ( unsigned int i=0; i<predictedComponents.size(); i++ ) { 00077 double priorWeight = predictedComponents[i].weight(); 00078 00079 double chi2 = chi2s[i] - chi2Min; 00080 00081 double tempWeight(0.); 00082 if ( detRs[i]>FLT_MIN ) { 00083 // 00084 // Calculation of (non-normalised) weight. Common factors exp(-chi2Norm/2.) and 00085 // 1./sqrt(2*pi*recHit.dimension()) have been omitted 00086 // 00087 tempWeight = priorWeight * sqrt(1./detRs[i]) * exp(-0.5 * chi2); 00088 } 00089 // else { 00090 // edm::LogInfo("PosteriorWeightsCalculator") << "PosteriorWeightsCalculator: detR < FLT_MIN !!"; 00091 // } 00092 weights.push_back(tempWeight); 00093 sumWeights += tempWeight; 00094 } 00095 if ( sumWeights<DBL_MIN ) { 00096 edm::LogInfo("PosteriorWeightsCalculator") << "PosteriorWeightsCalculator: sumWeight < DBL_MIN"; 00097 return std::vector<double>(); 00098 } 00099 00100 if ( weights.size()!=predictedComponents.size() ) { 00101 edm::LogError("PosteriorWeightsCalculator") << "Problem in vector sizes (2)"; 00102 return std::vector<double>(); 00103 } 00104 for (std::vector<double>::iterator iter = weights.begin(); 00105 iter != weights.end(); iter++) { 00106 (*iter) /= sumWeights; 00107 } 00108 00109 return weights; 00110 }