CMS 3D CMS Logo

DAClusterizerInZT.cc
Go to the documentation of this file.
6 
7 using namespace std;
8 
9 namespace {
10  constexpr double epsilon = 1.0e-3;
11  constexpr double vertexSizeTime = 0.008;
12  constexpr double dtCutOff = 4.0;
13 
14  bool recTrackLessZ1(const DAClusterizerInZT::track_t & tk1,
15  const DAClusterizerInZT::track_t & tk2)
16  {
17  return tk1.z < tk2.z;
18  }
19 
20  double sqr(double f) { return f*f; }
21 }
22 
23 
24 vector<DAClusterizerInZT::track_t>
25 DAClusterizerInZT::fill( const vector<reco::TransientTrack> & tracks )const{
26  // prepare track data for clustering
27  vector<track_t> tks;
28  tks.reserve(tracks.size());
29  for(vector<reco::TransientTrack>::const_iterator it=tracks.begin(); it!=tracks.end(); it++){
30  track_t t;
31  t.pi = 1.;
32  auto tsPCA = (*it).stateAtBeamLine().trackStateAtPCA();
33  t.z = tsPCA.position().z();
34  t.t = it->timeExt(); // the time
35 
36  if (std::abs(t.z) > 1000.) continue;
37  auto const & t_mom = tsPCA.momentum();
38  // get the beam-spot
39  reco::BeamSpot beamspot = (*it).stateAtBeamLine().beamSpot();
40  t.dz2 =
41  sqr((*it).track().dzError()) // track errror
42  + (sqr(beamspot.BeamWidthX()*t_mom.x())+sqr(beamspot.BeamWidthY()*t_mom.y()))*sqr(t_mom.z())/sqr(t_mom.perp2()) // beam spot width
43  + sqr(vertexSize_); // intrinsic vertex size, safer for outliers and short lived decays
44  //t.dz2 = 1./ t_dz2;
45 
46  t.dtz = 0.;
47  t.dt2 =sqr((*it).dtErrorExt()) + sqr(vertexSizeTime); // the ~injected~ timing error, need to add a small minimum vertex size in time
48 
49  if (d0CutOff_>0){
50  Measurement1D IP = (*it).stateAtBeamLine().transverseImpactParameter();// error constains beamspot
51  t.pi=1./(1.+std::exp(sqr(IP.value()/IP.error()) - sqr(d0CutOff_))); // reduce weight for high ip tracks
52  }else{
53  t.pi=1.;
54  }
55  t.tt=&(*it);
56  t.zi=1.;
58  tks.push_back(t);
59  }
60  }
61 
62  tks.shrink_to_fit();
63  return tks;
64 }
65 
66 
67 
68 
69 
70 double DAClusterizerInZT::e_ik(const track_t & t, const vertex_t &k ) const {
71  return sqr(t.z-k.z)/t.dz2 + sqr(t.t - k.t)/t.dt2;
72 }
73 
74 
75 
76 
77 
78 
80  vector<track_t> & tks,
81  vector<vertex_t> & y,
82  const double rho0 ) const {
83  // MVF style, no more vertex weights, update tracks weights and vertex positions, with noise
84  // returns the squared sum of changes of vertex positions
85 
86  unsigned int nt=tks.size();
87 
88  //initialize sums
89  double sumpi = 0.;
90  for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){
91  k->sw = 0.; k->swz = 0.; k->swt = 0.; k->se = 0.;
92  k->swE = 0.; k->tC=0.;
93  }
94 
95 
96  // loop over tracks
97  for(unsigned int i=0; i<nt; i++){
98 
99  // update pik and Zi and Ti
100  double Zi = rho0*std::exp(-beta*(dzCutOff_*dzCutOff_));// cut-off (eventually add finite size in time)
101  //double Ti = 0.; // dt0*std::exp(-beta*dtCutOff_);
102  for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){
103  k->ei = std::exp(-beta*e_ik(tks[i],*k));// cache exponential for one track at a time
104  Zi += k->pk * k->ei;
105  }
106  tks[i].zi=Zi;
107  sumpi += tks[i].pi;
108 
109  // normalization
110  if (tks[i].zi>0){
111  // accumulate weighted z and weights for vertex update
112  for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){
113  double zratio = k->pk*k->ei/Zi;
114 
115  k->se += tks[i].pi*zratio/k->pk;
116  double w = tks[i].pi * zratio /( tks[i].dz2 + tks[i].dt2 );
117 
118  k->sw += w;
119  k->swz += w * tks[i].z;
120  k->swt += w * tks[i].t;
121  k->swE += w * e_ik(tks[i],*k);
122  }
123  }
124  } // end of track loop
125 
126 
127  // now update z
128  double delta=0;
129  for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){
130  if ( k->sw > 0){
131  const double znew=k->swz/k->sw;
132  const double tnew=k->swt/k->sw;
133  delta += sqr(k->z-znew) + sqr(k->t-tnew);
134  k->z = znew;
135  k->t = tnew;
136  k->tC = 2*k->swE/k->sw;
137  }else{
138  edm::LogInfo("sumw") << "invalid sum of weights in fit: " << k->sw << endl;
139  if(verbose_){cout << " a cluster melted away ? pk=" << k->pk << " sumw=" << k->sw << endl;}
140  k->tC = (rho0 == 0. ? -1 : 0);
141  }
142  if(rho0 == 0.) k->pk = k->pk * k->se / sumpi;
143  }
144 
145  // return how much the prototypes moved
146  return delta;
147 }
148 
149 bool DAClusterizerInZT::merge(vector<vertex_t> & y, int nt)const{
150  // merge clusters that collapsed or never separated, return true if vertices were merged, false otherwise
151 
152  if(y.size()<2) return false;
153 
154  for(vector<vertex_t>::iterator k=y.begin(); (k+1)!=y.end(); k++){
155  if( std::abs( (k+1)->z - k->z ) < epsilon &&
156  std::abs( (k+1)->t - k->t ) < epsilon ){ // with fabs if only called after freeze-out (splitAll() at highter T)
157  double rho = k->pk + (k+1)->pk;
158  if(rho>0){
159  k->z = ( k->pk * k->z + (k+1)->z * (k+1)->pk)/rho;
160  k->t = ( k->pk * k->t + (k+1)->t * (k+1)->pk)/rho;
161  }else{
162  k->z = 0.5*(k->z + (k+1)->z);
163  k->t = 0.5*(k->t + (k+1)->t);
164  }
165  k->pk = rho;
166 
167  y.erase(k+1);
168  return true;
169  }
170  }
171 
172  return false;
173 }
174 
175 bool DAClusterizerInZT::merge(vector<vertex_t> & y, double & beta)const{
176  // merge clusters that collapsed or never separated,
177  // only merge if the estimated critical temperature of the merged vertex is below the current temperature
178  // return true if vertices were merged, false otherwise
179  if(y.size()<2) return false;
180 
181  for(vector<vertex_t>::iterator k=y.begin(); (k+1)!=y.end(); k++){
182  if ( std::abs((k+1)->z - k->z) < 2*epsilon &&
183  std::abs((k+1)->t - k->t) < 2*epsilon ) {
184  double rho=k->pk + (k+1)->pk;
185  double swE=k->swE+(k+1)->swE - k->pk * (k+1)->pk / rho * ( sqr((k+1)->z - k->z) +
186  sqr((k+1)->t - k->t) );
187  double Tc=2*swE/(k->sw+(k+1)->sw);
188 
189  if(Tc*beta<1){
190  if(rho>0){
191  k->z = ( k->pk * k->z + (k+1)->z * (k+1)->pk)/rho;
192  k->t = ( k->pk * k->t + (k+1)->t * (k+1)->pk)/rho;
193  }else{
194  k->z = 0.5*(k->z + (k+1)->z);
195  k->t = 0.5*(k->t + (k+1)->t);
196  }
197  k->pk = rho;
198  k->sw += (k+1)->sw;
199  k->swE = swE;
200  k->tC = Tc;
201  y.erase(k+1);
202  return true;
203  }
204  }
205  }
206 
207  return false;
208 }
209 
210 bool DAClusterizerInZT::purge(vector<vertex_t> & y, vector<track_t> & tks, double & rho0, const double beta)const{
211  // eliminate clusters with only one significant/unique track
212  if(y.size()<2) return false;
213 
214  unsigned int nt=tks.size();
215  double sumpmin=nt;
216  vector<vertex_t>::iterator k0=y.end();
217  for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){
218  int nUnique=0;
219  double sump=0;
220  double pmax=k->pk/(k->pk+rho0*exp(-beta*dzCutOff_*dzCutOff_));
221  for(unsigned int i=0; i<nt; i++){
222  if(tks[i].zi > 0){
223  double p = k->pk * std::exp(-beta*e_ik(tks[i],*k)) / tks[i].zi ;
224  sump+=p;
225  if( (p > 0.9*pmax) && (tks[i].pi>0) ){ nUnique++; }
226  }
227  }
228 
229  if((nUnique<2)&&(sump<sumpmin)){
230  sumpmin=sump;
231  k0=k;
232  }
233  }
234 
235  if(k0!=y.end()){
236  if(verbose_){cout << "eliminating prototype at " << k0->z << "," << k0->t
237  << " with sump=" << sumpmin << endl;}
238  y.erase(k0);
239  return true;
240  }else{
241  return false;
242  }
243 }
244 
245 double DAClusterizerInZT::beta0( double betamax,
246  vector<track_t> & tks,
247  vector<vertex_t> & y ) const {
248 
249  double T0=0; // max Tc for beta=0
250  // estimate critical temperature from beta=0 (T=inf)
251  unsigned int nt=tks.size();
252 
253  for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){
254 
255  // vertex fit at T=inf
256  double sumwz=0.;
257  double sumwt=0.;
258  double sumw=0.;
259  for(unsigned int i=0; i<nt; i++){
260  double w = tks[i].pi/(tks[i].dz2 + tks[i].dt2);
261  sumwz += w*tks[i].z;
262  sumwt += w*tks[i].t;
263  sumw += w;
264  }
265  k->z = sumwz/sumw;
266  k->t = sumwt/sumw;
267 
268  // estimate Tcrit, eventually do this in the same loop
269  double a=0, b=0;
270  for(unsigned int i=0; i<nt; i++){
271  double dx = tks[i].z-(k->z);
272  double dt = tks[i].t-(k->t);
273  double w = tks[i].pi/(tks[i].dz2 + tks[i].dt2);
274  a += w*(sqr(dx)/tks[i].dz2 + sqr(dt)/tks[i].dt2);
275  b += w;
276  }
277  double Tc= 2.*a/b; // the critical temperature of this vertex
278  if(Tc>T0) T0=Tc;
279  }// vertex loop (normally there should be only one vertex at beta=0)
280 
281  if (T0>1./betamax){
282  return betamax/pow(coolingFactor_, int(std::log(T0*betamax)*logCoolingFactor_)-1 );
283  }else{
284  // ensure at least one annealing step
285  return betamax/coolingFactor_;
286  }
287 }
288 
290  vector<track_t> & tks,
291  vector<vertex_t> & y,
292  double threshold ) const {
293  // split only critical vertices (Tc >~ T=1/beta <==> beta*Tc>~1)
294  // an update must have been made just before doing this (same beta, no merging)
295  // returns true if at least one cluster was split
296  bool split=false;
297 
298  // avoid left-right biases by splitting highest Tc first
299 
300  std::vector<std::pair<double, unsigned int> > critical;
301  for(unsigned int ik=0; ik<y.size(); ik++){
302  if (beta*y[ik].tC > 1.){
303  critical.push_back( make_pair(y[ik].tC, ik));
304  }
305  }
306  std::stable_sort(critical.begin(), critical.end(), std::greater<std::pair<double, unsigned int> >() );
307 
308  for(unsigned int ic=0; ic<critical.size(); ic++){
309  unsigned int ik=critical[ic].second;
310  // estimate subcluster positions and weight
311  double p1=0, z1=0, t1=0, w1=0;
312  double p2=0, z2=0, t2=0, w2=0;
313  //double sumpi=0;
314  for(unsigned int i=0; i<tks.size(); i++){
315  if(tks[i].zi>0){
316  //sumpi+=tks[i].pi;
317  double p=y[ik].pk * exp(-beta*e_ik(tks[i],y[ik])) / tks[i].zi*tks[i].pi;
318  double w=p/(tks[i].dz2 + tks[i].dt2);
319  if(tks[i].z < y[ik].z){
320  p1+=p; z1+=w*tks[i].z; t1+=w*tks[i].t; w1+=w;
321  }else{
322  p2+=p; z2+=w*tks[i].z; t2+=w*tks[i].t; w2+=w;
323  }
324  }
325  }
326  if(w1>0){ z1=z1/w1; t1=t1/w1;} else{ z1=y[ik].z-epsilon; t1=y[ik].t-epsilon; }
327  if(w2>0){ z2=z2/w2; t2=t2/w2;} else{ z2=y[ik].z+epsilon; t2=y[ik].t+epsilon;}
328 
329  // reduce split size if there is not enough room
330  if( ( ik > 0 ) && ( y[ik-1].z>=z1 ) ){ z1=0.5*(y[ik].z+y[ik-1].z); t1=0.5*(y[ik].t+y[ik-1].t); }
331  if( ( ik+1 < y.size()) && ( y[ik+1].z<=z2 ) ){ z2=0.5*(y[ik].z+y[ik+1].z); t2=0.5*(y[ik].t+y[ik+1].t); }
332 
333  // split if the new subclusters are significantly separated
334  if( std::abs(z2-z1) > epsilon || std::abs(t2-t1) > epsilon ){
335  split=true;
336  vertex_t vnew;
337  vnew.pk = p1*y[ik].pk/(p1+p2);
338  y[ik].pk= p2*y[ik].pk/(p1+p2);
339  vnew.z = z1;
340  vnew.t = t1;
341  y[ik].z = z2;
342  y[ik].t = t2;
343  y.insert(y.begin()+ik, vnew);
344 
345  // adjust remaining pointers
346  for(unsigned int jc=ic; jc<critical.size(); jc++){
347  if (critical[jc].second>ik) {critical[jc].second++;}
348  }
349  }
350  }
351 
352  // stable_sort(y.begin(), y.end(), clusterLessZ);
353  return split;
354 }
355 
356 
357 
358 
359 
360 void DAClusterizerInZT::splitAll( vector<vertex_t> & y ) const {
361 
362  constexpr double zsep=2*epsilon; // split vertices that are isolated by at least zsep (vertices that haven't collapsed)
363  constexpr double tsep=2*epsilon; // check t as well
364 
365  vector<vertex_t> y1;
366 
367  for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){
368  if ( ( (k==y.begin())|| (k-1)->z < k->z - zsep) && (((k+1)==y.end() )|| (k+1)->z > k->z + zsep)) {
369  // isolated prototype, split
370  vertex_t vnew;
371  vnew.z = k->z - epsilon;
372  vnew.t = k->t - epsilon;
373  (*k).z = k->z + epsilon;
374  (*k).t = k->t + epsilon;
375  vnew.pk= 0.5* (*k).pk;
376  (*k).pk= 0.5* (*k).pk;
377  y1.push_back(vnew);
378  y1.push_back(*k);
379 
380  }else if( y1.empty() || (y1.back().z < k->z -zsep) || (y1.back().t < k->t - tsep) ){
381  y1.push_back(*k);
382  }else{
383  y1.back().z -= epsilon;
384  y1.back().t -= epsilon;
385  k->z += epsilon;
386  k->t += epsilon;
387  y1.push_back(*k);
388  }
389  }// vertex loop
390 
391  y=y1;
392 }
393 
394 
396  verbose_(conf.getUntrackedParameter<bool>("verbose", false)),
397  useTc_(true),
398  vertexSize_(conf.getParameter<double>("vertexSize")),
399  maxIterations_(100),
400  coolingFactor_(std::sqrt(conf.getParameter<double>("coolingFactor"))),
401  betamax_(0.1),
402  betastop_(1.0),
403  dzCutOff_(conf.getParameter<double>("dzCutOff")),
404  d0CutOff_(conf.getParameter<double>("d0CutOff")),
405  dtCutOff_(dtCutOff)
406 {
407 
408  double Tmin = conf.getParameter<double>("Tmin")*std::sqrt(2.0);// scale up by sqrt(D=2)
409  if (Tmin==0){
410  edm::LogWarning("DAClusterizerInZT") << "DAClusterizerInZT: invalid Tmin" << Tmin << " reset do default " << 1./betamax_ << endl;
411  }else{
412  betamax_ = 1./Tmin;
413  }
414 
415  // for testing, negative cooling factor: revert to old splitting scheme
416  if(coolingFactor_<0){
418  }
419 
421 }
422 
423 
424 void DAClusterizerInZT::dump(const double beta, const vector<vertex_t> & y, const vector<track_t> & tks0, int verbosity)const{
425 
426  // copy and sort for nicer printout
427  vector<track_t> tks;
428  for(vector<track_t>::const_iterator t=tks0.begin(); t!=tks0.end(); t++){tks.push_back(*t); }
429  std::stable_sort(tks.begin(), tks.end(), recTrackLessZ1);
430 
431  cout << "-----DAClusterizerInZT::dump ----" << endl;
432  cout << " beta=" << beta << " betamax= " << betamax_ << endl;
433  cout << " z= ";
434  cout.precision(4);
435  for(vector<vertex_t>::const_iterator k=y.begin(); k!=y.end(); k++){
436  cout << setw(8) << fixed << k->z;
437  }
438  cout << endl << " t= ";
439  for(vector<vertex_t>::const_iterator k=y.begin(); k!=y.end(); k++){
440  cout << setw(8) << fixed << k->t;
441  }
442  cout << endl << "T=" << setw(15) << 1./beta <<" Tc= ";
443  for(vector<vertex_t>::const_iterator k=y.begin(); k!=y.end(); k++){
444  cout << setw(8) << fixed << k->tC ;
445  }
446 
447  cout << endl << " pk=";
448  double sumpk=0;
449  for(vector<vertex_t>::const_iterator k=y.begin(); k!=y.end(); k++){
450  cout << setw(8) << setprecision(3) << fixed << k->pk;
451  sumpk+=k->pk;
452  }
453  cout << endl;
454 
455  if(verbosity>0){
456  double E=0, F=0;
457  cout << endl;
458  cout << "---- z +/- dz t +/- dt ip +/-dip pt phi eta weights ----" << endl;
459  cout.precision(4);
460  for(unsigned int i=0; i<tks.size(); i++){
461  if (tks[i].zi>0){ F-=log(tks[i].zi)/beta;}
462  double tz= tks[i].z;
463  double tt= tks[i].t;
464  cout << setw (3)<< i << ")" << setw (8) << fixed << setprecision(4)<< tz << " +/-" << setw (6)<< sqrt(tks[i].dz2)
465  << setw(8) << fixed << setprecision(4) << tt << " +/-" << setw(6) << std::sqrt(tks[i].dt2) ;
466 
467  if(tks[i].tt->track().quality(reco::TrackBase::highPurity)){ cout << " *";}else{cout <<" ";}
468  if(tks[i].tt->track().hitPattern().hasValidHitInPixelLayer(PixelSubdetector::SubDetector::PixelBarrel, 1)){cout <<"+";}else{cout << "-";}
469 
470  cout << setw(1) << tks[i].tt->track().hitPattern().pixelBarrelLayersWithMeasurement(); // see DataFormats/TrackReco/interface/HitPattern.h
471  cout << setw(1) << tks[i].tt->track().hitPattern().pixelEndcapLayersWithMeasurement();
472  cout << setw(1) << hex << tks[i].tt->track().hitPattern().trackerLayersWithMeasurement()-tks[i].tt->track().hitPattern().pixelLayersWithMeasurement() <<dec;
473  cout << "=" << setw(1)<<hex <<tks[i].tt->track().hitPattern().numberOfHits(reco::HitPattern::MISSING_OUTER_HITS) << dec;
474 
475  Measurement1D IP=tks[i].tt->stateAtBeamLine().transverseImpactParameter();
476  cout << setw (8) << IP.value() << "+/-" << setw (6) << IP.error();
477  cout << " " << setw(6) << setprecision(2) << tks[i].tt->track().pt()*tks[i].tt->track().charge();
478  cout << " " << setw(5) << setprecision(2) << tks[i].tt->track().phi()
479  << " " << setw(5) << setprecision(2) << tks[i].tt->track().eta() ;
480 
481  double sump=0.;
482  for(vector<vertex_t>::const_iterator k=y.begin(); k!=y.end(); k++){
483  if((tks[i].pi>0)&&(tks[i].zi>0)){
484  //double p=pik(beta,tks[i],*k);
485  double p=k->pk * std::exp(-beta*e_ik(tks[i],*k)) / tks[i].zi;
486  if( p > 0.0001){
487  cout << setw (8) << setprecision(3) << p;
488  }else{
489  cout << " . ";
490  }
491  E+=p*e_ik(tks[i],*k);
492  sump+=p;
493  }else{
494  cout << " ";
495  }
496  }
497  cout << endl;
498  }
499  cout << endl << "T=" << 1/beta << " E=" << E << " n="<< y.size() << " F= " << F << endl << "----------" << endl;
500  }
501 }
502 
503 
504 
505 
506 
507 vector< TransientVertex >
508 DAClusterizerInZT::vertices(const vector<reco::TransientTrack> & tracks, const int verbosity)
509 const
510 {
511 
512  vector<track_t> tks=fill(tracks);
513  unsigned int nt=tks.size();
514  double rho0=0.0; // start with no outlier rejection
515 
516  vector< TransientVertex > clusters;
517  if (tks.empty()) return clusters;
518 
519  vector<vertex_t> y; // the vertex prototypes
520 
521  // initialize:single vertex at infinite temperature
522  vertex_t vstart;
523  vstart.z=0.;
524  vstart.t=0.;
525  vstart.pk=1.;
526  y.push_back(vstart);
527  int niter=0; // number of iterations
528 
529 
530  // estimate first critical temperature
531  double beta=beta0(betamax_, tks, y);
532  niter=0;
533  while((update(beta, tks,y)>1.e-6) && (niter++ < maxIterations_)){ }
534 
535  // annealing loop, stop when T<Tmin (i.e. beta>1/Tmin)
536  while(beta<betamax_){
537 
538  if(useTc_){
539  update(beta, tks,y);
540  while(merge(y,beta)){update(beta, tks,y);}
541  split(beta, tks,y, 1.);
542  beta=beta/coolingFactor_;
543  }else{
544  beta=beta/coolingFactor_;
545  splitAll(y);
546  }
547 
548 
549  // make sure we are not too far from equilibrium before cooling further
550  niter=0;
551  while((update(beta, tks,y)>1.e-6) && (niter++ < maxIterations_)){ }
552 
553  }
554 
555  if(useTc_){
556  // last round of splitting, make sure no critical clusters are left
557  update(beta, tks,y);
558  while(merge(y,beta)){update(beta, tks,y);}
559  unsigned int ntry=0;
560  while( split(beta, tks,y,1.) && (ntry++<10) ){
561  niter=0;
562  while((update(beta, tks,y)>1.e-6) && (niter++ < maxIterations_)){}
563  merge(y,beta);
564  update(beta, tks,y);
565  }
566  }else{
567  // merge collapsed clusters
568  while(merge(y,beta)){update(beta, tks,y);}
569  if(verbose_ ){ cout << "dump after 1st merging " << endl; dump(beta,y,tks,2);}
570  }
571 
572 
573 
574 
575  // switch on outlier rejection
576  rho0=1./nt;
577  for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){ k->pk =1.; } // democratic
578  niter=0;
579  while( (update(beta, tks,y,rho0) > 1.e-8) && (niter++ < maxIterations_) ){ }
580  if(verbose_ ){ cout << "rho0=" << rho0 << " niter=" << niter << endl; dump(beta,y,tks,2);}
581 
582 
583  // merge again (some cluster split by outliers collapse here)
584  while(merge(y,tks.size())){}
585  if(verbose_ ){ cout << "dump after 2nd merging " << endl; dump(beta,y,tks,2);}
586 
587 
588  // continue from freeze-out to Tstop (=1) without splitting, eliminate insignificant vertices
589  while(beta<=betastop_){
590  while(purge(y,tks,rho0, beta)){
591  niter=0;
592  while((update(beta, tks, y, rho0) > 1.e-6) && (niter++ < maxIterations_)){ }
593  }
594  beta/=coolingFactor_;
595  niter=0;
596  while((update(beta, tks, y, rho0) > 1.e-6) && (niter++ < maxIterations_)){ }
597  }
598 
599  if(verbose_){
600  cout << "Final result, rho0=" << rho0 << endl;
601  dump(beta,y,tks,2);
602  }
603 
604  // ensure correct normalization of probabilities, should make double assginment reasonably impossible
605  for(unsigned int i=0; i<nt; i++){
606  tks[i].zi=rho0*exp(-beta*( dzCutOff_*dzCutOff_));
607  for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){
608  tks[i].zi += k->pk * exp(-beta*e_ik(tks[i],*k));
609  }
610  }
611 
612 
613  for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){
614  GlobalPoint pos(0, 0, k->z);
615  double time = k->t;
616  vector< reco::TransientTrack > vertexTracks;
617  //double max_track_time_err2 = 0;
618  double mean = 0.;
619  double expv_x2 = 0.;
620  double normw = 0.;
621  for(unsigned int i=0; i<nt; i++){
622  const double invdt = 1.0/std::sqrt(tks[i].dt2);
623  if(tks[i].zi>0){
624  double p = k->pk * exp(-beta*e_ik(tks[i],*k)) / tks[i].zi;
625  if( (tks[i].pi>0) && ( p > 0.5 ) ){
626  //std::cout << "pushing back " << i << ' ' << tks[i].tt << std::endl;
627  vertexTracks.push_back(*(tks[i].tt)); tks[i].zi=0;
628  mean += tks[i].t*invdt*p;
629  expv_x2 += tks[i].t*tks[i].t*invdt*p;
630  normw += invdt*p;
631  } // setting Z=0 excludes double assignment
632  }
633  }
634  mean = mean/normw;
635  expv_x2 = expv_x2/normw;
636  const double time_var = expv_x2 - mean*mean;
637  const double crappy_error_guess = std::sqrt(time_var);
638  GlobalError dummyErrorWithTime(0,
639  0,0,
640  0,0,0,
641  0,0,0,crappy_error_guess);
642  TransientVertex v(pos, time, dummyErrorWithTime, vertexTracks, 5);
643  clusters.push_back(v);
644  }
645 
646 
647  return clusters;
648 
649 }
650 
651 
652 
653 
654 
655 vector< vector<reco::TransientTrack> >
656 DAClusterizerInZT::clusterize(const vector<reco::TransientTrack> & tracks)
657  const
658 {
659  if(verbose_) {
660  cout << "###################################################" << endl;
661  cout << "# DAClusterizerInZT::clusterize nt="<<tracks.size() << endl;
662  cout << "###################################################" << endl;
663  }
664 
665  vector< vector<reco::TransientTrack> > clusters;
666  vector< TransientVertex > pv=vertices(tracks);
667 
668  if(verbose_){ cout << "# DAClusterizerInZT::clusterize pv.size="<<pv.size() << endl; }
669  if (pv.size()==0){ return clusters;}
670 
671 
672  // fill into clusters and merge
673  vector< reco::TransientTrack> aCluster=pv.begin()->originalTracks();
674 
675  if( verbose_ ) {
676  std::cout << '\t' << 0;
677  std::cout << ' ' << pv.begin()->position() << ' ' << pv.begin()->time() << std::endl;
678  }
679 
680  for(vector<TransientVertex>::iterator k=pv.begin()+1; k!=pv.end(); k++){
681  if( verbose_ ) {
682  std::cout << '\t' << std::distance(pv.begin(),k);
683  std::cout << ' ' << k->position() << ' ' << k->time() << std::endl;
684  }
685  if ( std::abs(k->position().z() - (k-1)->position().z()) > (2*vertexSize_) ||
686  std::abs(k->time() - (k-1)->time()) > 2*vertexSizeTime ) {
687  // close a cluster
688  clusters.push_back(aCluster);
689  aCluster.clear();
690  }
691  for(unsigned int i=0; i<k->originalTracks().size(); i++){
692  aCluster.push_back( k->originalTracks().at(i));
693  }
694 
695  }
696  clusters.push_back(aCluster);
697 
698  if(verbose_) { std::cout << "# DAClusterizerInZT::clusterize clusters.size="<<clusters.size() << std::endl; }
699 
700  return clusters;
701 
702 }
703 
std::vector< std::vector< reco::TransientTrack > > clusterize(const std::vector< reco::TransientTrack > &tracks) const
const double beta
dbl * delta
Definition: mlp_gen.cc:36
T getParameter(std::string const &) const
float dt
Definition: AMPTWrapper.h:126
common ppss p3p6s2 common epss epspn46 common const1 w2
Definition: inclppp.h:1
const double w
Definition: UKUtility.cc:23
const reco::TransientTrack * tt
double error() const
Definition: Measurement1D.h:30
double update(double beta, std::vector< track_t > &tks, std::vector< vertex_t > &y, const double rho0=0.0) const
std::vector< TransientVertex > vertices(const std::vector< reco::TransientTrack > &tracks, const int verbosity=0) const
double e_ik(const track_t &t, const vertex_t &k) const
#define constexpr
void dump(const double beta, const std::vector< vertex_t > &y, const std::vector< track_t > &tks, const int verbosity=0) const
bool isFinite(T x)
const Double_t pi
U second(std::pair< T, U > const &p)
auto const T2 &decltype(t1.eta()) t2
Definition: deltaR.h:16
T sqrt(T t)
Definition: SSEVec.h:18
void splitAll(std::vector< vertex_t > &y) const
def pv(vc)
Definition: MetAnalyzer.py:6
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool split(double beta, std::vector< track_t > &tks, std::vector< vertex_t > &y, double threshold) const
double f[11][100]
double BeamWidthX() const
beam width X
Definition: BeamSpot.h:86
std::vector< track_t > fill(const std::vector< reco::TransientTrack > &tracks) const
double p2[4]
Definition: TauolaWrapper.h:90
int nt
Definition: AMPTWrapper.h:32
int k[5][pyjets_maxn]
bool merge(std::vector< vertex_t > &, int) const
double BeamWidthY() const
beam width Y
Definition: BeamSpot.h:88
double b
Definition: hdecay.h:120
double value() const
Definition: Measurement1D.h:28
double p1[4]
Definition: TauolaWrapper.h:89
double a
Definition: hdecay.h:121
Square< F >::type sqr(const F &f)
Definition: Square.h:13
static int position[264][3]
Definition: ReadPGInfo.cc:509
DAClusterizerInZT(const edm::ParameterSet &conf)
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:281
double split
Definition: MVATrainer.cc:139
double beta0(const double betamax, std::vector< track_t > &tks, std::vector< vertex_t > &y) const
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
bool purge(std::vector< vertex_t > &, std::vector< track_t > &, double &, const double) const