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>
18 {
19 public:
22  FsmwClusterizer1D ( double fraction = .05, double n_sigma_in = 3.,
25  ~FsmwClusterizer1D() override;
26 
27  std::pair < std::vector < Cluster1D<T> >, std::vector < const T * > >
28  operator() ( 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 /*
46  * Function that computes the 'fraction-of sample mode with weights'.
47  * The modefinder, that is.
48  * Warning, values have to be sorted in this method!!
49  */
50 template <class T>
51 std::pair < typename std::vector< Cluster1D<T> >::const_iterator,
52 typename std::vector< Cluster1D<T> >::const_iterator >
53 fsmw ( const std::vector< Cluster1D<T> > & values, double fraction )
54 {
55  typedef Cluster1D<T> Cluster1D;
56  typename std::vector< Cluster1D >::const_iterator begin = values.begin();
57  typename std::vector< Cluster1D >::const_iterator end = values.end()-1;
58 
59  while (true)
60  {
61 #ifdef FsmwClusterizer1DDebug
62  cout << "Begin at " << begin->position().value() << endl;
63 #endif
64 
65  const int size = (int) (end-begin);
66 #ifdef FsmwClusterizer1DDebug
67 
68  cout << "Size " << size << endl;
69 #endif
70 
71  int stepsize = (int) floor ( ( 1+ size ) * fraction );
72  if ( stepsize == 0 )
73  stepsize=1;
74 #ifdef FsmwClusterizer1DDebug
75 
76  cout << "Old end at " << end->position().value() << endl;
77 #endif
78 
79  end=begin+stepsize;
80  typename std::vector< Cluster1D >::const_iterator new_begin = begin;
81  typename std::vector< Cluster1D >::const_iterator new_end = end;
82 
83 #ifdef FsmwClusterizer1DDebug
84 
85  cout << "New end at " << end->position().value() << endl;
86  cout << "stepsize " << stepsize << endl;
87 #endif
88 
89  // Old version: used the weights of just the end points
90  // double totalweight = begin->weight() + end->weight();
91 
92  // new version: sums up the weights of all points involved
93  // _including_ the "end" point
94  double totalweight = end->weight();
95  for ( typename std::vector< Cluster1D >::const_iterator w=begin; w!=end ; ++w )
96  {
97  totalweight+=w->weight();
98  };
99 
100  double div=fabs ( end->position().value() - begin->position().value() ) /
101  totalweight;
102 #ifdef FsmwClusterizer1DDebug
103 
104  cout << "Div at " << begin->position().value() << ":" << (end)->position().value()
105  << " = " << div << endl;
106 #endif
107 
108  for ( typename std::vector< Cluster1D >::const_iterator i = (begin + 1);
109  i!=(begin + size - stepsize + 1); ++i )
110  {
111  // FIXME wrong
112  // double tmpweight = i->weight() + (i+stepsize)->weight();
113  //
114  // new version: sums up the weights of all points in the interval
115  // _including_ the end point (i+stepsize)
116  double tmpweight = 0.;
117  for ( typename std::vector< Cluster1D >::const_iterator wt=i; wt!=(i+stepsize+1); ++wt )
118  {
119  tmpweight+=wt->weight();
120  };
121 
122  double tmpdiv = fabs( i->position().value() - (i+stepsize)->position().value() )
123  / tmpweight;
124 #ifdef FsmwClusterizer1DDebug
125 
126  cout << "Div at " << i->position().value() << ":" << (i+stepsize)->position().value()
127  << " = " << tmpdiv << endl;
128 #endif
129 
130  if ( tmpdiv < div)
131  {
132  new_begin= i;
133  new_end = i+stepsize;
134  div= tmpdiv;
135  };
136  };
137 #ifdef FsmwClusterizer1DDebug
138 
139  cout << "---- new interval: " << new_begin->position().value()
140  << ":" << new_end->position().value() << endl;
141 #endif
142 
143  begin = new_begin;
144  end = new_end;
145  if ( size < 4 )
146  break;
147  };
148 
149  std::pair < typename std::vector< Cluster1D >::const_iterator,
150  typename std::vector< Cluster1D >::const_iterator > ret ( begin, end );
151  return ret;
152 }
153 }
154 
155 template <class T>
157  : theEstimator( o.theEstimator->clone() ), theFraction ( o.theFraction ),
159 {}
160 
161 
162 template <class T>
164  : theEstimator ( est.clone() ), theFraction ( fraction ), theNSigmaIn ( nsig )
165 {}
166 
167 
168 template <class T>
170 {
171  delete theEstimator;
172 }
173 
174 template <class T>
176 {
177  return new FsmwClusterizer1D<T>( *this );
178 }
179 
180 template <class T>
181 std::pair < std::vector< Cluster1D<T> >, std::vector< const T * > >
182 FsmwClusterizer1D<T>::operator() ( const std::vector < Cluster1D<T> > & ov ) const
183 {
184  using namespace Clusterizer1DCommons;
185  using namespace FsmwClusterizer1DNameSpace;
186  typedef Cluster1D<T> Cluster1D;
187  std::vector < const T * > unusedtracks;
188 
189  switch ( ov.size() )
190  {
191  case 0:
192  throw Clustering1DException("[FsmwClusterizer1D] no values given" );
193  case 1:
194  std::pair < std::vector < Cluster1D >, std::vector < const T * > > ret ( ov, unusedtracks );
195  return ret;
196  };
197 
198  std::vector < Cluster1D > v = ov;
199  sort ( v.begin(), v.end(), ComparePairs<T>() );
200  std::vector < Cluster1D > sols;
201 
202  std::pair < typename std::vector< Cluster1D >::const_iterator,
203  typename std::vector< Cluster1D >::const_iterator > estors
204  = fsmw ( v, theFraction );
205 
206  double weight = estors.first->weight() + estors.second->weight();
207  double est = ( estors.first->weight() * estors.first->position().value() +
208  estors.second->weight() * estors.second->position().value() ) /
209  weight;
210  double err=0.;
211  double sigma = sqrt ( square ( estors.first->position().value() - est ) +
212  square ( estors.second->position().value() - est ));
213  /*
214  std::cout << "[FsmwClusterizer1D] first=" << estors.first->position().value()
215  << " second=" << estors.second->position().value()
216  << " est=" << est << std::endl;
217  double sigma = sqrt ( square ( estors.first->position().error() ) +
218  square ( estors.second->position().error() ) );
219  double sigma = estors.first->position().error();
220  */
221  std::vector < const T * > trks;
222  int inliers=0;
223 
224  for ( typename std::vector< Cluster1D >::iterator i=v.begin();
225  i!=v.end() ; ++i )
226  {
227  /*
228  std::cout << "[FsmwClusterizer1D] see if they're in: delta="
229  << 10000 * fabs ( i->position().value() - est )
230  << " sigma=" << 10000 * sigma << std::endl;
231  */
232  if ( fabs ( i->position().value() - est ) < theNSigmaIn * sigma )
233  {
234  // all within theNSigmaIn sigma are 'in'
235  add ( i->tracks(), trks );
236  err+= square ( i->position().value() - est );
237  inliers++;
238  } else {
239  add ( i->tracks(), unusedtracks );
240  };
241  };
242  err /= ( inliers - 1 ); // the algo definitely produces 2 or more inliers
243  err = sqrt ( err );
244 
245 
246  err=sqrt(err);
247  sols.push_back ( Cluster1D ( Measurement1D ( est, err ), trks, weight ) );
248 
249  std::pair < std::vector < Cluster1D >, std::vector < const T * > > ret ( sols, unusedtracks );
250  return ret;
251 }
252 
253 #endif
size
Write out results.
WeightEstimator< T > * theEstimator
const double w
Definition: UKUtility.cc:23
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)
Definition: weight.py:1
FsmwClusterizer1D(double fraction=.05, double n_sigma_in=3., const WeightEstimator< T > &est=TrivialWeightEstimator< T >())
T sqrt(T t)
Definition: SSEVec.h:18
FsmwClusterizer1D * clone() const override
#define end
Definition: vmac.h:39
std::pair< std::vector< Cluster1D< T > >, std::vector< const T * > > operator()(const std::vector< Cluster1D< T > > &) const override
void add(std::map< std::string, TH1 * > &h, TH1 *hist)
static double square(double x)
#define begin
Definition: vmac.h:32
static int position[264][3]
Definition: ReadPGInfo.cc:509
~FsmwClusterizer1D() override