Go to the documentation of this file.00001 #ifndef _FsmwClusterizer1D_H_
00002 #define _FsmwClusterizer1D_H_
00003
00004 #include "CommonTools/Clustering1D/interface/Clusterizer1D.h"
00005 #include "CommonTools/Clustering1D/interface/Clusterizer1DCommons.h"
00006 #include "CommonTools/Clustering1D/interface/TrivialWeightEstimator.h"
00007 #include "CommonTools/Clustering1D/interface/Clustering1DException.h"
00008
00009 #include <vector>
00010 #include <cmath>
00011 #include <algorithm>
00012
00016 template <class T>
00017 class FsmwClusterizer1D : public Clusterizer1D<T>
00018 {
00019 public:
00022 FsmwClusterizer1D ( double fraction = .05, double n_sigma_in = 3.,
00023 const WeightEstimator<T> & est = TrivialWeightEstimator<T>() );
00024 FsmwClusterizer1D ( const FsmwClusterizer1D & );
00025 ~FsmwClusterizer1D();
00026
00027 std::pair < std::vector < Cluster1D<T> >, std::vector < const T * > >
00028 operator() ( const std::vector< Cluster1D<T> > & ) const;
00029
00030 virtual FsmwClusterizer1D * clone() const;
00031
00032 private:
00033 WeightEstimator<T> * theEstimator;
00034 double theFraction;
00035 double theNSigmaIn;
00036 };
00037
00038
00039
00040
00041
00042
00043 namespace FsmwClusterizer1DNameSpace
00044 {
00045
00046
00047
00048
00049
00050 template <class T>
00051 std::pair < typename std::vector< Cluster1D<T> >::const_iterator,
00052 typename std::vector< Cluster1D<T> >::const_iterator >
00053 fsmw ( const std::vector< Cluster1D<T> > & values, double fraction )
00054 {
00055 typedef Cluster1D<T> Cluster1D;
00056 typename std::vector< Cluster1D >::const_iterator begin = values.begin();
00057 typename std::vector< Cluster1D >::const_iterator end = values.end()-1;
00058
00059 while (1)
00060 {
00061 #ifdef FsmwClusterizer1DDebug
00062 cout << "Begin at " << begin->position().value() << endl;
00063 #endif
00064
00065 const int size = (int) (end-begin);
00066 #ifdef FsmwClusterizer1DDebug
00067
00068 cout << "Size " << size << endl;
00069 #endif
00070
00071 int stepsize = (int) floor ( ( 1+ size ) * fraction );
00072 if ( stepsize == 0 )
00073 stepsize=1;
00074 #ifdef FsmwClusterizer1DDebug
00075
00076 cout << "Old end at " << end->position().value() << endl;
00077 #endif
00078
00079 end=begin+stepsize;
00080 typename std::vector< Cluster1D >::const_iterator new_begin = begin;
00081 typename std::vector< Cluster1D >::const_iterator new_end = end;
00082
00083 #ifdef FsmwClusterizer1DDebug
00084
00085 cout << "New end at " << end->position().value() << endl;
00086 cout << "stepsize " << stepsize << endl;
00087 #endif
00088
00089
00090
00091
00092
00093
00094 double totalweight = end->weight();
00095 for ( typename std::vector< Cluster1D >::const_iterator w=begin; w!=end ; ++w )
00096 {
00097 totalweight+=w->weight();
00098 };
00099
00100 double div=fabs ( end->position().value() - begin->position().value() ) /
00101 totalweight;
00102 #ifdef FsmwClusterizer1DDebug
00103
00104 cout << "Div at " << begin->position().value() << ":" << (end)->position().value()
00105 << " = " << div << endl;
00106 #endif
00107
00108 for ( typename std::vector< Cluster1D >::const_iterator i = (begin + 1);
00109 i!=(begin + size - stepsize + 1); ++i )
00110 {
00111
00112
00113
00114
00115
00116 double tmpweight = 0.;
00117 for ( typename std::vector< Cluster1D >::const_iterator wt=i; wt!=(i+stepsize+1); ++wt )
00118 {
00119 tmpweight+=wt->weight();
00120 };
00121
00122 double tmpdiv = fabs( i->position().value() - (i+stepsize)->position().value() )
00123 / tmpweight;
00124 #ifdef FsmwClusterizer1DDebug
00125
00126 cout << "Div at " << i->position().value() << ":" << (i+stepsize)->position().value()
00127 << " = " << tmpdiv << endl;
00128 #endif
00129
00130 if ( tmpdiv < div)
00131 {
00132 new_begin= i;
00133 new_end = i+stepsize;
00134 div= tmpdiv;
00135 };
00136 };
00137 #ifdef FsmwClusterizer1DDebug
00138
00139 cout << "---- new interval: " << new_begin->position().value()
00140 << ":" << new_end->position().value() << endl;
00141 #endif
00142
00143 begin = new_begin;
00144 end = new_end;
00145 if ( size < 4 )
00146 break;
00147 };
00148
00149 std::pair < typename std::vector< Cluster1D >::const_iterator,
00150 typename std::vector< Cluster1D >::const_iterator > ret ( begin, end );
00151 return ret;
00152 }
00153 }
00154
00155 template <class T>
00156 FsmwClusterizer1D<T>::FsmwClusterizer1D( const FsmwClusterizer1D<T> & o )
00157 : theEstimator( o.theEstimator->clone() ), theFraction ( o.theFraction ),
00158 theNSigmaIn ( o.theNSigmaIn )
00159 {}
00160
00161
00162 template <class T>
00163 FsmwClusterizer1D<T>::FsmwClusterizer1D( double fraction, double nsig, const WeightEstimator<T> & est )
00164 : theEstimator ( est.clone() ), theFraction ( fraction ), theNSigmaIn ( nsig )
00165 {}
00166
00167
00168 template <class T>
00169 FsmwClusterizer1D<T>::~FsmwClusterizer1D()
00170 {
00171 delete theEstimator;
00172 }
00173
00174 template <class T>
00175 FsmwClusterizer1D<T> * FsmwClusterizer1D<T>::clone() const
00176 {
00177 return new FsmwClusterizer1D<T>( *this );
00178 }
00179
00180 template <class T>
00181 std::pair < std::vector< Cluster1D<T> >, std::vector< const T * > >
00182 FsmwClusterizer1D<T>::operator() ( const std::vector < Cluster1D<T> > & ov ) const
00183 {
00184 using namespace Clusterizer1DCommons;
00185 using namespace FsmwClusterizer1DNameSpace;
00186 typedef Cluster1D<T> Cluster1D;
00187 std::vector < const T * > unusedtracks;
00188
00189 switch ( ov.size() )
00190 {
00191 case 0:
00192 throw Clustering1DException("[FsmwClusterizer1D] no values given" );
00193 case 1:
00194 std::pair < std::vector < Cluster1D >, std::vector < const T * > > ret ( ov, unusedtracks );
00195 return ret;
00196 };
00197
00198 std::vector < Cluster1D > v = ov;
00199 sort ( v.begin(), v.end(), ComparePairs<T>() );
00200 std::vector < Cluster1D > sols;
00201
00202 std::pair < typename std::vector< Cluster1D >::const_iterator,
00203 typename std::vector< Cluster1D >::const_iterator > estors
00204 = fsmw ( v, theFraction );
00205
00206 double weight = estors.first->weight() + estors.second->weight();
00207 double est = ( estors.first->weight() * estors.first->position().value() +
00208 estors.second->weight() * estors.second->position().value() ) /
00209 weight;
00210 double err=0.;
00211 double sigma = sqrt ( square ( estors.first->position().value() - est ) +
00212 square ( estors.second->position().value() - est ));
00213
00214
00215
00216
00217
00218
00219
00220
00221 std::vector < const T * > trks;
00222 int inliers=0;
00223
00224 for ( typename std::vector< Cluster1D >::iterator i=v.begin();
00225 i!=v.end() ; ++i )
00226 {
00227
00228
00229
00230
00231
00232 if ( fabs ( i->position().value() - est ) < theNSigmaIn * sigma )
00233 {
00234
00235 add ( i->tracks(), trks );
00236 err+= square ( i->position().value() - est );
00237 inliers++;
00238 } else {
00239 add ( i->tracks(), unusedtracks );
00240 };
00241 };
00242 err /= ( inliers - 1 );
00243 err = sqrt ( err );
00244
00245
00246 err=sqrt(err);
00247 sols.push_back ( Cluster1D ( Measurement1D ( est, err ), trks, weight ) );
00248
00249 std::pair < std::vector < Cluster1D >, std::vector < const T * > > ret ( sols, unusedtracks );
00250 return ret;
00251 }
00252
00253 #endif