Go to the documentation of this file.00001 #ifndef _DivisiveClusterizer1D_H_
00002 #define _DivisiveClusterizer1D_H_
00003
00004 #include "CommonTools/Clustering1D/interface/Clusterizer1D.h"
00005
00006
00007 #include "RecoPixelVertexing/PixelVertexFinding/interface/Cluster1DMerger.h"
00008 #include "RecoPixelVertexing/PixelVertexFinding/interface/Cluster1DCleaner.h"
00009 #include "CommonTools/Clustering1D/interface/TrivialWeightEstimator.h"
00010 #include "CommonTools/Clustering1D/interface/Clusterizer1DCommons.h"
00011
00017 namespace pixeltemp {
00018 template < class T>
00019 class DivisiveClusterizer1D : public Clusterizer1D<T>
00020 {
00021 public:
00033 DivisiveClusterizer1D( float zoffset = 5., int ntkmin = 5, bool useError = true,
00034 float zsep = 0.05, bool wei = true );
00035
00036 ~DivisiveClusterizer1D();
00037
00038 std::pair < std::vector < Cluster1D<T> >, std::vector < const T * > > operator()
00039 ( const std::vector < Cluster1D<T> > & ) const;
00040 virtual DivisiveClusterizer1D * clone() const;
00041
00042 void setBeamSpot(const math::XYZPoint & bs) {theMerger->setBeamSpot(bs); }
00043
00044 private:
00045
00046 void findCandidates( const std::vector < Cluster1D<T> >&,
00047 std::vector < Cluster1D<T> >&,
00048 std::vector < Cluster1D<T> >&) const;
00049 std::vector<Cluster1D<T> > makeCluster1Ds( std::vector < Cluster1D<T> > &,
00050 std::vector < Cluster1D<T> >& ) const;
00051 void insertTracks( std::vector < Cluster1D<T> >& ,
00052 std::vector < Cluster1D<T> >& ) const;
00053 std::vector<const T* > takeTracks( const std::vector < Cluster1D<T> >&) const;
00054 Cluster1D<T> mergeCluster1Ds(std::vector < Cluster1D<T> >& ) const;
00055
00056
00057
00058
00059 pixeltemp::Cluster1DMerger<T>* theMerger;
00060 pixeltemp::Cluster1DCleaner<T>* theCleaner;
00061 float theZOffSet;
00062 unsigned int theNTkMin;
00063 bool theUseError;
00064 float theZSeparation;
00065 bool theWei;
00066 };
00067
00068
00069
00070
00071
00072
00073 template <class T>
00074 DivisiveClusterizer1D<T>::DivisiveClusterizer1D(float zoffset,
00075 int ntkmin,
00076 bool useError,
00077 float zsep, bool wei)
00078 :theZOffSet(zoffset), theNTkMin(ntkmin),
00079 theUseError(useError), theZSeparation(zsep), theWei(wei)
00080 {
00081
00082
00083
00084 TrivialWeightEstimator<T> weightEstimator;
00085 theMerger = new pixeltemp::Cluster1DMerger<T>( weightEstimator );
00086 theCleaner = new pixeltemp::Cluster1DCleaner<T>(theZOffSet,theUseError);
00087 }
00088
00089 template <class T>
00090 DivisiveClusterizer1D<T>::~DivisiveClusterizer1D()
00091 {
00092 delete theMerger;
00093 delete theCleaner;
00094 }
00095
00096 template <class T>
00097 std::pair < std::vector < Cluster1D<T> >, std::vector < const T * > >
00098 DivisiveClusterizer1D<T>::operator()
00099 ( const std::vector < Cluster1D<T> > & input ) const
00100 {
00101 std::vector < Cluster1D<T> > discardedCluster1Ds;
00102 std::vector < Cluster1D<T> > output;
00103 findCandidates ( input, output, discardedCluster1Ds );
00104 return std::pair < std::vector < Cluster1D<T> >, std::vector < const T * > >
00105 ( output, takeTracks(discardedCluster1Ds) );
00106 }
00107
00108 template <class T>
00109 DivisiveClusterizer1D<T> * DivisiveClusterizer1D<T>::clone() const
00110 {
00111 return new DivisiveClusterizer1D<T> ( * this );
00112 }
00113
00114 template <class T>
00115 void
00116 DivisiveClusterizer1D<T>::findCandidates ( const std::vector < Cluster1D<T> > & inputo,
00117 std::vector < Cluster1D<T> > & finalCluster1Ds ,
00118 std::vector < Cluster1D<T> > & totDiscardedTracks ) const
00119 {
00120 using namespace Clusterizer1DCommons;
00121
00122 std::vector < Cluster1D<T> > input = inputo;
00123 std::vector < Cluster1D<T> > discardedTracks;
00124 if ( input.size() < (unsigned int)theNTkMin)
00125 {
00126 insertTracks( input, totDiscardedTracks);
00127 return;
00128 }
00129 sort( input.begin(), input.end(), ComparePairs<T>());
00130 int ncount =0;
00131 std::vector < Cluster1D<T> > partOfPTracks;
00132 partOfPTracks.push_back(input.front());
00133 for( typename std::vector < Cluster1D<T> >::const_iterator ic=(input.begin())+1;
00134 ic != input.end(); ic++)
00135 {
00136 ncount++;
00137 if ( fabs( (*ic).position().value()-(*(ic-1)).position().value() )
00138 < (double) theZSeparation )
00139 {
00140 partOfPTracks.push_back((*ic));
00141 }
00142 else
00143 {
00144 if(partOfPTracks.size() >= (unsigned int)theNTkMin)
00145 {
00146 std::vector< Cluster1D<T> > clusters = makeCluster1Ds(partOfPTracks,
00147 discardedTracks);
00148 for (typename std::vector< Cluster1D<T> >::const_iterator iclus=clusters.begin();
00149 iclus != clusters.end(); iclus++)
00150 {
00151 finalCluster1Ds.push_back(*iclus);
00152 }
00153 insertTracks(discardedTracks,totDiscardedTracks);
00154 }
00155 else
00156 {
00157 insertTracks(partOfPTracks,totDiscardedTracks);
00158 }
00159 partOfPTracks.clear();
00160 partOfPTracks.push_back((*ic));
00161 }
00162 }
00163 if (partOfPTracks.size() >= (unsigned int)theNTkMin)
00164 {
00165 std::vector < Cluster1D<T> > clusters = makeCluster1Ds(partOfPTracks,
00166 discardedTracks);
00167 for (typename std::vector< Cluster1D<T> >::const_iterator iclus = clusters.begin();
00168 iclus != clusters.end(); iclus++)
00169 {
00170 finalCluster1Ds.push_back(*iclus);
00171 }
00172 insertTracks(discardedTracks,totDiscardedTracks);
00173 }
00174 else
00175 {
00176 insertTracks(partOfPTracks,totDiscardedTracks);
00177 }
00178
00179 sort(finalCluster1Ds.begin(), finalCluster1Ds.end(),
00180 ComparePairs<T>() );
00181
00182
00183 return;
00184 }
00185
00186 template <class T>
00187 std::vector < Cluster1D<T> >
00188 DivisiveClusterizer1D<T>::makeCluster1Ds( std::vector < Cluster1D<T> >& clusters,
00189 std::vector < Cluster1D<T> >& discardedTracks) const
00190 {
00191
00192 std::vector < Cluster1D<T> > finalCluster1Ds;
00193 discardedTracks.clear();
00194 std::vector<Cluster1D<T> > pvClu0 = clusters;
00195 std::vector<Cluster1D<T> > pvCluNew = pvClu0;
00196 bool stop = false;
00197 while (!stop)
00198 {
00199 int nDiscardedAtIteration = 100;
00200 while ( nDiscardedAtIteration !=0 )
00201 {
00202 pvCluNew = theCleaner->clusters(pvClu0);
00203 std::vector<Cluster1D<T> >
00204 tracksAtIteration = theCleaner->discardedCluster1Ds();
00205 nDiscardedAtIteration = tracksAtIteration.size();
00206 if ( nDiscardedAtIteration!=0 )
00207 {
00208 insertTracks(tracksAtIteration,discardedTracks);
00209 pvClu0 = pvCluNew;
00210 }
00211 }
00212 unsigned ntkclus = pvCluNew.size();
00213 unsigned ndiscard = discardedTracks.size();
00214
00215 if ( ntkclus >= theNTkMin )
00216 {
00217
00218 finalCluster1Ds.push_back( mergeCluster1Ds(pvCluNew) );
00219 if ( ndiscard >= theNTkMin )
00220 {
00221 pvClu0 = discardedTracks;
00222 discardedTracks.clear();
00223 }
00224 else
00225 {
00226 stop = true;
00227 }
00228 }
00229 else
00230 {
00231 insertTracks(pvCluNew, discardedTracks);
00232 stop = true;
00233 }
00234 }
00235 return finalCluster1Ds;
00236 }
00237
00238 template <class T>
00239 void
00240 DivisiveClusterizer1D<T>::insertTracks( std::vector< Cluster1D<T> >& clusou,
00241 std::vector< Cluster1D<T> >& cludest) const
00242 {
00243 if (clusou.size() == 0)
00244 return;
00245 for ( typename std::vector< Cluster1D<T> >::const_iterator iclu = clusou.begin();
00246 iclu != clusou.end(); iclu++)
00247 {
00248 cludest.push_back(*iclu);
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 return;
00261 }
00262
00263 template <class T>
00264 std::vector<const T* >
00265 DivisiveClusterizer1D<T>::takeTracks( const std::vector< Cluster1D<T> > & clu ) const
00266 {
00267 std::vector<const T* > tracks;
00268 for ( typename std::vector< Cluster1D<T> >::const_iterator iclu = clu.begin();
00269 iclu != clu.end(); iclu++)
00270 {
00271 std::vector < const T * > clutks = iclu->tracks();
00272 for ( typename std::vector< const T * >::const_iterator i=clutks.begin();
00273 i!=clutks.end() ; ++i )
00274 {
00275 tracks.push_back ( *i );
00276 }
00277 }
00278 return tracks;
00279 }
00280
00281 template <class T>
00282 Cluster1D<T>
00283 DivisiveClusterizer1D<T>::mergeCluster1Ds( std::vector < Cluster1D<T> >& clusters ) const
00284 {
00285
00286 Cluster1D<T> result = clusters.front();
00287 for ( typename std::vector< Cluster1D<T> >::iterator iclu = (clusters.begin())+1;
00288 iclu != clusters.end(); iclu++)
00289 {
00290 Cluster1D<T> old = result;
00291 result = (*theMerger)( old , *iclu );
00292 }
00293 return result;
00294 }
00295 }
00296 #endif