File indexing completed on 2024-04-06 12:01:04
0001 #ifndef _DivisiveClusterizer1D_H_
0002 #define _DivisiveClusterizer1D_H_
0003
0004 #include "CommonTools/Clustering1D/interface/Clusterizer1D.h"
0005 #include "CommonTools/Clustering1D/interface/Cluster1DMerger.h"
0006 #include "CommonTools/Clustering1D/interface/Cluster1DCleaner.h"
0007 #include "CommonTools/Clustering1D/interface/TrivialWeightEstimator.h"
0008 #include "CommonTools/Clustering1D/interface/Clusterizer1DCommons.h"
0009
0010
0011
0012
0013 template <class T>
0014 class DivisiveClusterizer1D : public Clusterizer1D<T> {
0015 public:
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 DivisiveClusterizer1D(float zoffset = 5., int ntkmin = 5, bool useError = true, float zsep = 0.05, bool wei = true);
0028
0029 ~DivisiveClusterizer1D();
0030
0031 std::pair<std::vector<Cluster1D<T> >, std::vector<const T*> > operator()(const std::vector<Cluster1D<T> >&) const;
0032 virtual DivisiveClusterizer1D* clone() const;
0033
0034 private:
0035
0036 void findCandidates(const std::vector<Cluster1D<T> >&,
0037 std::vector<Cluster1D<T> >&,
0038 std::vector<Cluster1D<T> >&) const;
0039 std::vector<Cluster1D<T> > makeCluster1Ds(std::vector<Cluster1D<T> >&, std::vector<Cluster1D<T> >&) const;
0040 void insertTracks(std::vector<Cluster1D<T> >&, std::vector<Cluster1D<T> >&) const;
0041 std::vector<const T*> takeTracks(const std::vector<Cluster1D<T> >&) const;
0042 Cluster1D<T> mergeCluster1Ds(std::vector<Cluster1D<T> >&) const;
0043
0044
0045
0046
0047 Cluster1DMerger<T>* theMerger;
0048 Cluster1DCleaner<T>* theCleaner;
0049 float theZOffSet;
0050 float theZSeparation;
0051 unsigned theNTkMin;
0052 bool theWei;
0053 bool theUseError;
0054 };
0055
0056
0057
0058
0059
0060
0061 template <class T>
0062 DivisiveClusterizer1D<T>::DivisiveClusterizer1D(float zoffset, int ntkmin, bool useError, float zsep, bool wei)
0063 : theZOffSet(zoffset), theZSeparation(zsep), theNTkMin(ntkmin), theWei(wei), theUseError(useError) {
0064
0065
0066
0067 TrivialWeightEstimator<T> weightEstimator;
0068 theMerger = new Cluster1DMerger<T>(weightEstimator);
0069 theCleaner = new Cluster1DCleaner<T>(theZOffSet, theUseError);
0070 }
0071
0072 template <class T>
0073 DivisiveClusterizer1D<T>::~DivisiveClusterizer1D() {
0074 delete theMerger;
0075 delete theCleaner;
0076 }
0077
0078 template <class T>
0079 std::pair<std::vector<Cluster1D<T> >, std::vector<const T*> > DivisiveClusterizer1D<T>::operator()(
0080 const std::vector<Cluster1D<T> >& input) const {
0081 std::vector<Cluster1D<T> > discardedCluster1Ds;
0082 std::vector<Cluster1D<T> > output;
0083 findCandidates(input, output, discardedCluster1Ds);
0084 return std::pair<std::vector<Cluster1D<T> >, std::vector<const T*> >(output, takeTracks(discardedCluster1Ds));
0085 }
0086
0087 template <class T>
0088 DivisiveClusterizer1D<T>* DivisiveClusterizer1D<T>::clone() const {
0089 return new DivisiveClusterizer1D<T>(*this);
0090 }
0091
0092 template <class T>
0093 void DivisiveClusterizer1D<T>::findCandidates(const std::vector<Cluster1D<T> >& inputo,
0094 std::vector<Cluster1D<T> >& finalCluster1Ds,
0095 std::vector<Cluster1D<T> >& totDiscardedTracks) const {
0096 using namespace Clusterizer1DCommons;
0097
0098 std::vector<Cluster1D<T> > input = inputo;
0099 std::vector<Cluster1D<T> > discardedTracks;
0100 if (input.size() < theNTkMin) {
0101 insertTracks(input, totDiscardedTracks);
0102 return;
0103 }
0104 sort(input.begin(), input.end(), ComparePairs<T>());
0105 std::vector<Cluster1D<T> > partOfPTracks;
0106 partOfPTracks.push_back(input.front());
0107 for (typename std::vector<Cluster1D<T> >::const_iterator ic = (input.begin()) + 1; ic != input.end(); ic++) {
0108 if (fabs((*ic).position().value() - (*(ic - 1)).position().value()) < (double)theZSeparation) {
0109 partOfPTracks.push_back((*ic));
0110 } else {
0111 if (partOfPTracks.size() >= theNTkMin) {
0112 std::vector<Cluster1D<T> > clusters = makeCluster1Ds(partOfPTracks, discardedTracks);
0113 for (typename std::vector<Cluster1D<T> >::const_iterator iclus = clusters.begin(); iclus != clusters.end();
0114 iclus++) {
0115 finalCluster1Ds.push_back(*iclus);
0116 }
0117 insertTracks(discardedTracks, totDiscardedTracks);
0118 } else {
0119 insertTracks(partOfPTracks, totDiscardedTracks);
0120 }
0121 partOfPTracks.clear();
0122 partOfPTracks.push_back((*ic));
0123 }
0124 }
0125 if (partOfPTracks.size() >= theNTkMin) {
0126 std::vector<Cluster1D<T> > clusters = makeCluster1Ds(partOfPTracks, discardedTracks);
0127 for (typename std::vector<Cluster1D<T> >::const_iterator iclus = clusters.begin(); iclus != clusters.end();
0128 iclus++) {
0129 finalCluster1Ds.push_back(*iclus);
0130 }
0131 insertTracks(discardedTracks, totDiscardedTracks);
0132 } else {
0133 insertTracks(partOfPTracks, totDiscardedTracks);
0134 }
0135
0136 sort(finalCluster1Ds.begin(), finalCluster1Ds.end(), ComparePairs<T>());
0137
0138
0139 return;
0140 }
0141
0142 template <class T>
0143 std::vector<Cluster1D<T> > DivisiveClusterizer1D<T>::makeCluster1Ds(std::vector<Cluster1D<T> >& clusters,
0144 std::vector<Cluster1D<T> >& discardedTracks) const {
0145 std::vector<Cluster1D<T> > finalCluster1Ds;
0146 discardedTracks.clear();
0147 std::vector<Cluster1D<T> > pvClu0 = clusters;
0148 std::vector<Cluster1D<T> > pvCluNew = pvClu0;
0149 bool stop = false;
0150 while (!stop) {
0151 int nDiscardedAtIteration = 100;
0152 while (nDiscardedAtIteration != 0) {
0153 pvCluNew = theCleaner->clusters(pvClu0);
0154 std::vector<Cluster1D<T> > tracksAtIteration = theCleaner->discardedCluster1Ds();
0155 nDiscardedAtIteration = tracksAtIteration.size();
0156 if (nDiscardedAtIteration != 0) {
0157 insertTracks(tracksAtIteration, discardedTracks);
0158 pvClu0 = pvCluNew;
0159 }
0160 }
0161 unsigned ntkclus = pvCluNew.size();
0162 unsigned ndiscard = discardedTracks.size();
0163
0164 if (ntkclus >= theNTkMin) {
0165
0166 finalCluster1Ds.push_back(mergeCluster1Ds(pvCluNew));
0167 if (ndiscard >= theNTkMin) {
0168 pvClu0 = discardedTracks;
0169 discardedTracks.clear();
0170 } else {
0171 stop = true;
0172 }
0173 } else {
0174 insertTracks(pvCluNew, discardedTracks);
0175 stop = true;
0176 }
0177 }
0178 return finalCluster1Ds;
0179 }
0180
0181 template <class T>
0182 void DivisiveClusterizer1D<T>::insertTracks(std::vector<Cluster1D<T> >& clusou,
0183 std::vector<Cluster1D<T> >& cludest) const {
0184 if (clusou.empty())
0185 return;
0186 for (typename std::vector<Cluster1D<T> >::const_iterator iclu = clusou.begin(); iclu != clusou.end(); iclu++) {
0187 cludest.push_back(*iclu);
0188 }
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199 return;
0200 }
0201
0202 template <class T>
0203 std::vector<const T*> DivisiveClusterizer1D<T>::takeTracks(const std::vector<Cluster1D<T> >& clu) const {
0204 std::vector<const T*> tracks;
0205 for (typename std::vector<Cluster1D<T> >::const_iterator iclu = clu.begin(); iclu != clu.end(); iclu++) {
0206 std::vector<const T*> clutks = iclu->tracks();
0207 for (typename std::vector<const T*>::const_iterator i = clutks.begin(); i != clutks.end(); ++i) {
0208 tracks.push_back(*i);
0209 }
0210 }
0211 return tracks;
0212 }
0213
0214 template <class T>
0215 Cluster1D<T> DivisiveClusterizer1D<T>::mergeCluster1Ds(std::vector<Cluster1D<T> >& clusters) const {
0216 Cluster1D<T> result = clusters.front();
0217 for (typename std::vector<Cluster1D<T> >::iterator iclu = (clusters.begin()) + 1; iclu != clusters.end(); iclu++) {
0218 Cluster1D<T> old = result;
0219 result = (*theMerger)(old, *iclu);
0220 }
0221 return result;
0222 }
0223
0224 #endif