CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/TrackingTools/GsfTools/src/MultiGaussianStateCombiner1D.cc

Go to the documentation of this file.
00001 #include "TrackingTools/GsfTools/interface/MultiGaussianStateCombiner1D.h"
00002 
00003 #include "FWCore/Utilities/interface/Exception.h"
00004 
00005 #include <cfloat>
00006 
00007 
00008 SingleGaussianState1D
00009 MultiGaussianStateCombiner1D::combine(const MultiGaussianState1D& theState) const
00010 {
00011   return combine(theState.components());
00012 }
00013 
00014 SingleGaussianState1D
00015 MultiGaussianStateCombiner1D::combine(const VSC& theComponents) const
00016 {
00017   if (theComponents.empty()) {
00018     throw cms::Exception("LogicError") 
00019       << "MultiGaussianStateCombiner1D:: state container to collapse is empty";
00020 //     return SingleState(SingleState::Vector(),SingleState::Matrix(),0.);
00021 //     return SingleState(SingleState::Vector(),
00022 //                     SingleState::Matrix(),0.);
00023     return SingleGaussianState1D();
00024   }
00025 
00026   const SingleGaussianState1D firstState(theComponents.front());
00027   if (theComponents.size()==1)  return firstState;
00028 
00029 //   int size = firstState.mean().num_row();
00030   double meanMean(0.);
00031   double weightSum(0.);
00032 //   double weight;
00033   double measCovar1(0.);
00034   double measCovar2(0.);
00035   for ( VSC::const_iterator mixtureIter1 = theComponents.begin();
00036         mixtureIter1 != theComponents.end(); mixtureIter1++ ) {
00037     double weight = mixtureIter1->weight();
00038     weightSum += weight;
00039 
00040     double mean1 = mixtureIter1->mean();
00041     meanMean += weight * mean1;
00042     measCovar1 += weight * mixtureIter1->variance();
00043 
00044     for ( VSC::const_iterator mixtureIter2 = mixtureIter1+1;
00045         mixtureIter2 != theComponents.end(); mixtureIter2++ ) {
00046       double posDiff = mean1 - mixtureIter2->mean();
00047 //       SingleState::Matrix s(1,1); //stupid trick to make CLHEP work decently
00048 //       measCovar2 +=weight * (*mixtureIter2).weight() *
00049 //                                      s.similarity(posDiff.T().T());
00050 //       SingleState::Matrix mat;
00051 //       for ( unsigned int i1=0; i1<N; i1++ ) {
00052 //      for ( unsigned int i2=0; i2<=i1; i2++ )  mat(i1,i2) = posDiff(i1)*posDiff(i2);
00053 //       }
00054 //       measCovar2 += weight * (*mixtureIter2).weight() * mat;
00055       // 
00056       // TensorProd yields a general matrix - need to convert to a symm. matrix
00057       double covGen = posDiff*posDiff;
00058 //       double covSym(covGen.LowerBlock());
00059       measCovar2 += weight * mixtureIter2->weight() * covGen;
00060     }
00061   }
00062 
00063   double measCovar;
00064   if (weightSum<DBL_MIN){
00065     std::cout << "MultiGaussianStateCombiner1D:: New state has total weight of 0."
00066               << std::endl;
00067 //     meanMean = SingleState::Vector(size,0);
00068     meanMean = 0.;
00069     measCovar = 0.;
00070     weightSum = 0.;
00071   } else {
00072     meanMean /= weightSum;
00073     measCovar1 *= (1./weightSum);
00074     measCovar2 *= (1./weightSum/weightSum);
00075     measCovar = measCovar1 + measCovar2;
00076 //     measCovar = measCovar1/weightSum + measCovar2/weightSum/weightSum;
00077   }
00078 
00079   return SingleGaussianState1D(meanMean, measCovar, weightSum);
00080 }