CMS 3D CMS Logo

FsmwClusterizer1D.h
Go to the documentation of this file.
1 #ifndef _FsmwClusterizer1D_H_
2 #define _FsmwClusterizer1D_H_
3 
8 
9 #include <vector>
10 #include <cmath>
11 #include <algorithm>
12 
16 template <class T>
17 class FsmwClusterizer1D : public Clusterizer1D<T> {
18 public:
21  FsmwClusterizer1D(double fraction = .05,
22  double n_sigma_in = 3.,
25  ~FsmwClusterizer1D() override;
26 
27  std::pair<std::vector<Cluster1D<T> >, std::vector<const T*> > operator()(
28  const std::vector<Cluster1D<T> >&) const override;
29 
30  FsmwClusterizer1D* clone() const override;
31 
32 private:
34  double theFraction;
35  double theNSigmaIn;
36 };
37 
38 /*
39  * --- implementation ---
40  *
41  */
42 
44  /*
45  * Function that computes the 'fraction-of sample mode with weights'.
46  * The modefinder, that is.
47  * Warning, values have to be sorted in this method!!
48  */
49  template <class T>
50  std::pair<typename std::vector<Cluster1D<T> >::const_iterator, typename std::vector<Cluster1D<T> >::const_iterator>
52  typedef Cluster1D<T> Cluster1D;
53  typename std::vector<Cluster1D>::const_iterator begin = values.begin();
54  typename std::vector<Cluster1D>::const_iterator end = values.end() - 1;
55 
56  while (true) {
57 #ifdef FsmwClusterizer1DDebug
58  cout << "Begin at " << begin->position().value() << endl;
59 #endif
60 
61  const int size = (int)(end - begin);
62 #ifdef FsmwClusterizer1DDebug
63 
64  cout << "Size " << size << endl;
65 #endif
66 
67  int stepsize = (int)floor((1 + size) * fraction);
68  if (stepsize == 0)
69  stepsize = 1;
70 #ifdef FsmwClusterizer1DDebug
71 
72  cout << "Old end at " << end->position().value() << endl;
73 #endif
74 
75  end = begin + stepsize;
76  typename std::vector<Cluster1D>::const_iterator new_begin = begin;
77  typename std::vector<Cluster1D>::const_iterator new_end = end;
78 
79 #ifdef FsmwClusterizer1DDebug
80 
81  cout << "New end at " << end->position().value() << endl;
82  cout << "stepsize " << stepsize << endl;
83 #endif
84 
85  // Old version: used the weights of just the end points
86  // double totalweight = begin->weight() + end->weight();
87 
88  // new version: sums up the weights of all points involved
89  // _including_ the "end" point
90  double totalweight = end->weight();
91  for (typename std::vector<Cluster1D>::const_iterator w = begin; w != end; ++w) {
92  totalweight += w->weight();
93  };
94 
95  double div = fabs(end->position().value() - begin->position().value()) / totalweight;
96 #ifdef FsmwClusterizer1DDebug
97 
98  cout << "Div at " << begin->position().value() << ":" << (end)->position().value() << " = " << div << endl;
99 #endif
100 
101  for (typename std::vector<Cluster1D>::const_iterator i = (begin + 1); i != (begin + size - stepsize + 1); ++i) {
102  // FIXME wrong
103  // double tmpweight = i->weight() + (i+stepsize)->weight();
104  //
105  // new version: sums up the weights of all points in the interval
106  // _including_ the end point (i+stepsize)
107  double tmpweight = 0.;
108  for (typename std::vector<Cluster1D>::const_iterator wt = i; wt != (i + stepsize + 1); ++wt) {
109  tmpweight += wt->weight();
110  };
111 
112  double tmpdiv = fabs(i->position().value() - (i + stepsize)->position().value()) / tmpweight;
113 #ifdef FsmwClusterizer1DDebug
114 
115  cout << "Div at " << i->position().value() << ":" << (i + stepsize)->position().value() << " = " << tmpdiv
116  << endl;
117 #endif
118 
119  if (tmpdiv < div) {
120  new_begin = i;
121  new_end = i + stepsize;
122  div = tmpdiv;
123  };
124  };
125 #ifdef FsmwClusterizer1DDebug
126 
127  cout << "---- new interval: " << new_begin->position().value() << ":" << new_end->position().value() << endl;
128 #endif
129 
130  begin = new_begin;
131  end = new_end;
132  if (size < 4)
133  break;
134  };
135 
136  std::pair<typename std::vector<Cluster1D>::const_iterator, typename std::vector<Cluster1D>::const_iterator> ret(
137  begin, end);
138  return ret;
139  }
140 } // namespace FsmwClusterizer1DNameSpace
141 
142 template <class T>
144  : theEstimator(o.theEstimator->clone()), theFraction(o.theFraction), theNSigmaIn(o.theNSigmaIn) {}
145 
146 template <class T>
148  : theEstimator(est.clone()), theFraction(fraction), theNSigmaIn(nsig) {}
149 
150 template <class T>
152  delete theEstimator;
153 }
154 
155 template <class T>
157  return new FsmwClusterizer1D<T>(*this);
158 }
159 
160 template <class T>
161 std::pair<std::vector<Cluster1D<T> >, std::vector<const T*> > FsmwClusterizer1D<T>::operator()(
162  const std::vector<Cluster1D<T> >& ov) const {
163  using namespace Clusterizer1DCommons;
164  using namespace FsmwClusterizer1DNameSpace;
165  typedef Cluster1D<T> Cluster1D;
166  std::vector<const T*> unusedtracks;
167 
168  switch (ov.size()) {
169  case 0:
170  throw Clustering1DException("[FsmwClusterizer1D] no values given");
171  case 1:
172  std::pair<std::vector<Cluster1D>, std::vector<const T*> > ret(ov, unusedtracks);
173  return ret;
174  };
175 
176  std::vector<Cluster1D> v = ov;
177  sort(v.begin(), v.end(), ComparePairs<T>());
178  std::vector<Cluster1D> sols;
179 
180  std::pair<typename std::vector<Cluster1D>::const_iterator, typename std::vector<Cluster1D>::const_iterator> estors =
181  fsmw(v, theFraction);
182 
183  double weight = estors.first->weight() + estors.second->weight();
184  double est = (estors.first->weight() * estors.first->position().value() +
185  estors.second->weight() * estors.second->position().value()) /
186  weight;
187  double err = 0.;
188  double sigma = sqrt(square(estors.first->position().value() - est) + square(estors.second->position().value() - est));
189  /*
190  std::cout << "[FsmwClusterizer1D] first=" << estors.first->position().value()
191  << " second=" << estors.second->position().value()
192  << " est=" << est << std::endl;
193  double sigma = sqrt ( square ( estors.first->position().error() ) +
194  square ( estors.second->position().error() ) );
195  double sigma = estors.first->position().error();
196  */
197  std::vector<const T*> trks;
198  int inliers = 0;
199 
200  for (typename std::vector<Cluster1D>::iterator i = v.begin(); i != v.end(); ++i) {
201  /*
202  std::cout << "[FsmwClusterizer1D] see if they're in: delta="
203  << 10000 * fabs ( i->position().value() - est )
204  << " sigma=" << 10000 * sigma << std::endl;
205  */
206  if (fabs(i->position().value() - est) < theNSigmaIn * sigma) {
207  // all within theNSigmaIn sigma are 'in'
208  add(i->tracks(), trks);
209  err += square(i->position().value() - est);
210  inliers++;
211  } else {
212  add(i->tracks(), unusedtracks);
213  };
214  };
215  err /= (inliers - 1); // the algo definitely produces 2 or more inliers
216  err = sqrt(err);
217 
218  err = sqrt(err);
219  sols.push_back(Cluster1D(Measurement1D(est, err), trks, weight));
220 
221  std::pair<std::vector<Cluster1D>, std::vector<const T*> > ret(sols, unusedtracks);
222  return ret;
223 }
224 
225 #endif
WeightEstimator< T > * theEstimator
T w() const
ret
prodAgent to be discontinued
FsmwClusterizer1D * clone() const override
Definition: weight.py:1
std::pair< std::vector< Cluster1D< T > >, std::vector< const T * > > operator()(const std::vector< Cluster1D< T > > &) const override
FsmwClusterizer1D(double fraction=.05, double n_sigma_in=3., const WeightEstimator< T > &est=TrivialWeightEstimator< T >())
T sqrt(T t)
Definition: SSEVec.h:23
void add(const std::vector< const T *> &source, std::vector< const T *> &dest)
std::pair< typename std::vector< Cluster1D< T > >::const_iterator, typename std::vector< Cluster1D< T > >::const_iterator > fsmw(const std::vector< Cluster1D< T > > &values, double fraction)
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
Definition: eve_macros.cc:135
static int position[264][3]
Definition: ReadPGInfo.cc:289
double square(const double a)
~FsmwClusterizer1D() override