CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/RecoVertex/VertexTools/src/SMS.cc

Go to the documentation of this file.
00001 #ifdef PROJECT_NAME
00002 #include "RecoVertex/VertexTools/interface/SMS.h"
00003 #else
00004 #include <vector>
00005 #include <algorithm>
00006 #include "RecoVertex/VertexTools/interface/SMS.h"
00007 using namespace std;
00008 #endif
00009 
00010 namespace {
00011 
00012 
00013   typedef std::pair < float, const GlobalPoint * > MyPair;
00014   typedef std::pair < float, float > FloatPair;
00015   typedef std::pair < GlobalPoint, float > GlPtWt;
00016   typedef std::pair < float, const GlPtWt * > MyPairWt;
00017 
00018   struct Sorter
00019   {
00020     bool operator() ( const MyPair & pair1, const MyPair & pair2 )
00021     {
00022       return ( pair1.first < pair2.first );
00023     };
00024 
00025     bool operator() ( const FloatPair & pair1, const FloatPair & pair2 )
00026     {
00027       return ( pair1.first < pair2.first );
00028     };
00029 
00030     bool operator() ( const MyPairWt & pair1, const MyPairWt & pair2 )
00031     {
00032       return ( pair1.first < pair2.first );
00033     };
00034   };
00035 
00036   bool debug()
00037   {
00038     return false;
00039   }
00040 
00041   inline GlobalPoint & operator += ( GlobalPoint & a, const GlobalPoint & b )
00042   {
00043     a = GlobalPoint ( a.x() + b.x(), a.y() + b.y(), a.z() + b.z() );
00044     return a;
00045   }
00046   inline GlobalPoint & operator /= ( GlobalPoint & a, float b )
00047   {
00048     a = GlobalPoint ( a.x() / b, a.y() / b, a.z() / b );
00049     return a;
00050   }
00051 
00052   GlobalPoint average ( const std::vector < MyPair > & pairs, int nq )
00053   {
00054     GlobalPoint location(0,0,0);
00055     for ( std::vector< MyPair >::const_iterator i=pairs.begin(); i!=( pairs.begin() + nq ); ++i )
00056       location+=*( i->second );
00057     location/=nq;
00058     return location;
00059   }
00060 
00061   GlobalPoint average ( const std::vector < MyPairWt > & pairs, int nq )
00062   {
00063     GlobalPoint location(0,0,0);
00064     for ( std::vector< MyPairWt >::const_iterator i=pairs.begin(); i!=( pairs.begin() + nq ); ++i )
00065       location+=(i->second)->first;
00066     location/=nq;
00067     return location;
00068   }
00069 
00070   typedef SMS::SMSType SMSType;
00071 }
00072 
00073 SMS::SMS ( SMSType tp , float q ) : theType(tp) , theRatio(q) {}
00074 
00075 
00076 GlobalPoint SMS::location ( const std::vector<GlobalPoint> & data ) const
00077 {
00078   if ( theType & Weighted )
00079   {
00080     std::cout << "[SMS] warning: Weighted SMS was asked for, but data are "
00081               << "weightless!" << std::endl;
00082   };
00083   int nobs=data.size();
00084   int nq=(int) ceil( theRatio*nobs);
00085   // cout << "nobs= " << nobs << "  nq= " << nq << endl;
00086 
00087   // Compute distances
00088   std::vector<MyPair> pairs;
00089 
00090   for ( std::vector< GlobalPoint >::const_iterator i=data.begin(); i!=data.end() ; ++i )
00091   {
00092     std::vector < float > D;
00093     // Compute squared distances to all points
00094     for ( std::vector< GlobalPoint >::const_iterator j=data.begin(); j!=data.end() ; ++j )
00095     { D.push_back ( (*j - *i).mag2() ); }
00096     // Find q-quantile in each row of the distance matrix
00097     sort( D.begin(), D.end() );
00098     MyPair tmp (  D[nq-1], &(*i) );
00099     pairs.push_back ( tmp );
00100   };
00101 
00102   // Sort pairs by first element
00103   sort( pairs.begin(), pairs.end(), Sorter() );
00104   if ( !(theType & SMS::Interpolate) &&
00105        !(theType & SMS::Iterate) )
00106   {
00107     // we dont interpolate, we dont iterate, so we can stop right here.
00108     // cout << "No interpolation, no iteration" << endl;
00109     return *(pairs.begin()->second);
00110   };
00111 
00112   // we dont iterate, or we dont have anything to iterate (anymore?)
00113   // so we stop here
00114 
00115   // cout << "nobs= " << nobs << "  nq= " << nq << endl;
00116   if (!(theType & SMS::Iterate) || nq<=2)
00117     return average ( pairs, nq );
00118 
00119   // we iterate (recursively)
00120 
00121   std::vector < GlobalPoint > data1;
00122   std::vector<MyPair>::iterator j;
00123 
00124   for ( j=pairs.begin(); j-pairs.begin()<nq; ++j)
00125      data1.push_back(*(j->second));
00126 
00127   return this->location( data1 );
00128 
00129 }
00130 
00131 
00132 GlobalPoint SMS::location (  const std::vector < GlPtWt > & wdata ) const
00133 {
00134   if ( !(theType & Weighted) )
00135   {
00136     std::vector < GlobalPoint > points;
00137     for ( std::vector< GlPtWt >::const_iterator i=wdata.begin(); 
00138           i!=wdata.end() ; ++i )
00139     {
00140       points.push_back ( i->first );
00141     };
00142     if ( debug() )
00143     {
00144       std::cout << "[SMS] Unweighted SMS was asked for; ignoring the weights."
00145                 << std::endl;
00146     };
00147     return location ( points );
00148   };
00149   // int nobs=wdata.size();
00150   // Sum of weights
00151   float Sumw=0;
00152   std::vector< GlPtWt >::const_iterator i,j;
00153   for ( i=wdata.begin() ; i!=wdata.end() ; ++i)
00154     Sumw+=i->second;
00155 
00156   // Compute pairwise distances
00157   std::vector <MyPairWt> pairs;
00158   for ( i=wdata.begin(); i!=wdata.end() ; ++i )
00159   {
00160     std::vector < FloatPair > D;
00161     // Compute squared distances to all points
00162     for ( j=wdata.begin(); j!=wdata.end() ; ++j )
00163       D.push_back ( FloatPair( (j->first - i->first).mag2() , j->second ) ) ;
00164     // Find weighted q-quantile in the distance vector
00165     sort( D.begin(), D.end() );
00166     float sumw=0;
00167     std::vector< FloatPair >::const_iterator where;
00168     for ( where=D.begin(); where!=D.end(); ++where )
00169     {
00170       sumw+=where->second;
00171       // cout << sumw << endl;
00172       if (sumw>Sumw*theRatio) break;
00173     }
00174     MyPairWt tmp ( where->first, &(*i) );
00175     pairs.push_back ( tmp );
00176     // cout << where->first << endl;
00177   };
00178 
00179   // Sort pairs by first element
00180   sort( pairs.begin(), pairs.end(), Sorter() );
00181 
00182   // Find weighted q-quantile in the list of pairs
00183   float sumw=0;
00184   int nq=0;
00185   std::vector < MyPairWt >::const_iterator k;
00186   for (k=pairs.begin(); k!=pairs.end(); ++k )
00187   {
00188     sumw+=k->second->second;
00189     ++nq;
00190     if (sumw>Sumw*theRatio) break;
00191   }
00192 
00193   // cout << "nobs= " << nobs << "  nq= " << nq << endl;
00194 
00195   if ( !(theType & SMS::Interpolate) &&
00196        !(theType & SMS::Iterate) )
00197   {
00198     // we dont interpolate, we dont iterate, so we can stop right here.
00199     // cout << "No interpolation, no iteration" << endl;
00200     return pairs.begin()->second->first;
00201   };
00202 
00203 
00204 
00205 
00206   // we dont iterate, or we dont have anything to iterate (anymore?)
00207   // so we stop here
00208 
00209   // cout << "nobs= " << nobs << "  nq= " << nq << endl;
00210   if (!(theType & SMS::Iterate) || nq<=2) return average ( pairs, nq );
00211 
00212   // we iterate (recursively)
00213 
00214   std::vector<GlPtWt> wdata1;
00215 
00216   for ( k=pairs.begin(); k-pairs.begin()<nq; ++k)
00217     wdata1.push_back(*(k->second));
00218 
00219   return this->location( wdata1 );
00220 
00221 }