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
00086
00087
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
00094 for ( std::vector< GlobalPoint >::const_iterator j=data.begin(); j!=data.end() ; ++j )
00095 { D.push_back ( (*j - *i).mag2() ); }
00096
00097 sort( D.begin(), D.end() );
00098 MyPair tmp ( D[nq-1], &(*i) );
00099 pairs.push_back ( tmp );
00100 };
00101
00102
00103 sort( pairs.begin(), pairs.end(), Sorter() );
00104 if ( !(theType & SMS::Interpolate) &&
00105 !(theType & SMS::Iterate) )
00106 {
00107
00108
00109 return *(pairs.begin()->second);
00110 };
00111
00112
00113
00114
00115
00116 if (!(theType & SMS::Iterate) || nq<=2)
00117 return average ( pairs, nq );
00118
00119
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
00150
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
00157 std::vector <MyPairWt> pairs;
00158 for ( i=wdata.begin(); i!=wdata.end() ; ++i )
00159 {
00160 std::vector < FloatPair > D;
00161
00162 for ( j=wdata.begin(); j!=wdata.end() ; ++j )
00163 D.push_back ( FloatPair( (j->first - i->first).mag2() , j->second ) ) ;
00164
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
00172 if (sumw>Sumw*theRatio) break;
00173 }
00174 MyPairWt tmp ( where->first, &(*i) );
00175 pairs.push_back ( tmp );
00176
00177 };
00178
00179
00180 sort( pairs.begin(), pairs.end(), Sorter() );
00181
00182
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
00194
00195 if ( !(theType & SMS::Interpolate) &&
00196 !(theType & SMS::Iterate) )
00197 {
00198
00199
00200 return pairs.begin()->second->first;
00201 };
00202
00203
00204
00205
00206
00207
00208
00209
00210 if (!(theType & SMS::Iterate) || nq<=2) return average ( pairs, nq );
00211
00212
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 }