CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PFClusterAlgo.cc
Go to the documentation of this file.
4 #include "Math/GenVector/VectorUtil.h"
5 #include "TFile.h"
6 #include "TH2F.h"
7 #include "TROOT.h"
8 
10 
11 #include <stdexcept>
12 #include <string>
13 #include <sstream>
14 
15 using namespace std;
16 
17 unsigned PFClusterAlgo::prodNum_ = 1;
18 
19 //for debug only
20 //#define PFLOW_DEBUG
21 
23  pfClusters_( new vector<reco::PFCluster> ),
24  pfRecHitsCleaned_( new vector<reco::PFRecHit> ),
25  threshBarrel_(0.),
26  threshPtBarrel_(0.),
27  threshSeedBarrel_(0.2),
28  threshPtSeedBarrel_(0.),
29  threshEndcap_(0.),
30  threshPtEndcap_(0.),
31  threshSeedEndcap_(0.6),
32  threshPtSeedEndcap_(0.),
33  threshCleanBarrel_(1E5),
34  minS4S1Barrel_(0.),
35  threshDoubleSpikeBarrel_(1E9),
36  minS6S2DoubleSpikeBarrel_(-1.),
37  threshCleanEndcap_(1E5),
38  minS4S1Endcap_(0.),
39  threshDoubleSpikeEndcap_(1E9),
40  minS6S2DoubleSpikeEndcap_(-1.),
41  nNeighbours_(4),
42  posCalcNCrystal_(-1),
43  posCalcP1_(-1),
44  showerSigma_(5),
45  useCornerCells_(false),
46  cleanRBXandHPDs_(false),
47  debug_(false)
48 {
49  file_ = 0;
50  hBNeighbour = 0;
51  hENeighbour = 0;
52 }
53 
54 void
56 
57  if ( file_ ) {
58  file_->Write();
59  cout << "Benchmark output written to file " << file_->GetName() << endl;
60  file_->Close();
61  }
62 
63 }
64 
65 
66 void PFClusterAlgo::doClustering( const PFRecHitHandle& rechitsHandle ) {
67  const reco::PFRecHitCollection& rechits = * rechitsHandle;
68 
69  // cache the Handle to the rechits
70  rechitsHandle_ = rechitsHandle;
71 
72  // clear rechits mask
73  mask_.clear();
74  mask_.resize( rechits.size(), true );
75 
76  // perform clustering
77  doClusteringWorker( rechits );
78 }
79 
80 void PFClusterAlgo::doClustering( const PFRecHitHandle& rechitsHandle, const std::vector<bool> & mask ) {
81 
82  const reco::PFRecHitCollection& rechits = * rechitsHandle;
83 
84  // cache the Handle to the rechits
85  rechitsHandle_ = rechitsHandle;
86 
87  // use the specified mask, unless it doesn't match with the rechits
88  mask_.clear();
89  if (mask.size() == rechits.size()) {
90  mask_.insert( mask_.end(), mask.begin(), mask.end() );
91  } else {
92  edm::LogError("PClusterAlgo::doClustering") << "map size should be " << rechits.size() << ". Will be reinitialized.";
93  mask_.resize( rechits.size(), true );
94  }
95 
96  // perform clustering
97 
98  doClusteringWorker( rechits );
99 
100 }
101 
103 
104  // using rechits without a Handle, clear to avoid a stale member
106 
107  // clear rechits mask
108  mask_.clear();
109  mask_.resize( rechits.size(), true );
110 
111  // perform clustering
112  doClusteringWorker( rechits );
113 
114 }
115 
116 void PFClusterAlgo::doClustering( const reco::PFRecHitCollection& rechits, const std::vector<bool> & mask ) {
117  // using rechits without a Handle, clear to avoid a stale member
118 
120 
121  // use the specified mask, unless it doesn't match with the rechits
122  mask_.clear();
123 
124  if (mask.size() == rechits.size()) {
125  mask_.insert( mask_.end(), mask.begin(), mask.end() );
126  } else {
127  edm::LogError("PClusterAlgo::doClustering") << "map size should be " << rechits.size() << ". Will be reinitialized.";
128  mask_.resize( rechits.size(), true );
129  }
130 
131  // perform clustering
132  doClusteringWorker( rechits );
133 
134 }
135 
136 
138 
139 
140  if ( pfClusters_.get() )
141  pfClusters_->clear();
142  else
143  pfClusters_.reset( new std::vector<reco::PFCluster> );
144 
145 
146  if ( pfRecHitsCleaned_.get() )
147  pfRecHitsCleaned_->clear();
148  else
149  pfRecHitsCleaned_.reset( new std::vector<reco::PFRecHit> );
150 
151 
152  eRecHits_.clear();
153 
154  for ( unsigned i = 0; i < rechits.size(); i++ ){
155 
156  eRecHits_.insert( make_pair( rechit(i, rechits).energy(), i) );
157  }
158 
159  color_.clear();
160  color_.resize( rechits.size(), 0 );
161 
162  seedStates_.clear();
163  seedStates_.resize( rechits.size(), UNKNOWN );
164 
165  usedInTopo_.clear();
166  usedInTopo_.resize( rechits.size(), false );
167 
168  if ( cleanRBXandHPDs_ ) cleanRBXAndHPD( rechits);
169 
170  // look for seeds.
171 
172  findSeeds( rechits );
173 
174  // build topological clusters around seeds
175  buildTopoClusters( rechits );
176 
177  // look for PFClusters inside each topological cluster (one per seed)
178 
179 
180  // int ix=0;
181  // for (reco::PFRecHitCollection::const_iterator cand =rechits.begin(); cand<rechits.end(); cand++){
182  // cout <<ix++<<" "<< cand->layer()<<endl;
183  // }
184 
185 
186  for(unsigned i=0; i<topoClusters_.size(); i++) {
187 
188  const std::vector< unsigned >& topocluster = topoClusters_[i];
189 
190  buildPFClusters( topocluster, rechits );
191 
192  }
193 
194 }
195 
196 
198  PFLayer::Layer layer,
199  unsigned iCoeff, int iring ) const {
200 
201 
202  double value = 0;
203 
204  switch( layer ) {
205 
208  case PFLayer::HCAL_BARREL2: // HO.
209 
210  switch(paramtype) {
211  case THRESH:
212  value = (iring==0) ? threshBarrel_ : threshEndcap_; //For HO Ring0 and others
213  break;
214  case SEED_THRESH:
215  value = (iring==0) ? threshSeedBarrel_ : threshSeedEndcap_;
216  break;
217  case PT_THRESH:
218  value = (iring==0) ? threshPtBarrel_ : threshPtEndcap_;
219  break;
220  case SEED_PT_THRESH:
221  value = (iring==0) ? threshPtSeedBarrel_ : threshPtSeedEndcap_;
222  break;
223  case CLEAN_THRESH:
224  value = threshCleanBarrel_;
225  break;
226  case CLEAN_S4S1:
227  value = minS4S1Barrel_[iCoeff];
228  break;
229  case DOUBLESPIKE_THRESH:
230  value = threshDoubleSpikeBarrel_;
231  break;
232  case DOUBLESPIKE_S6S2:
234  break;
235  default:
236  cerr<<"PFClusterAlgo::parameter : unknown parameter type "
237  <<paramtype<<endl;
238  assert(0);
239  }
240  break;
243  case PFLayer::PS1:
244  case PFLayer::PS2:
245  case PFLayer::HF_EM:
246  case PFLayer::HF_HAD:
247  // and no particle flow in VFCAL
248  switch(paramtype) {
249  case THRESH:
250  value = threshEndcap_;
251  break;
252  case SEED_THRESH:
253  value = threshSeedEndcap_;
254  break;
255  case PT_THRESH:
256  value = threshPtEndcap_;
257  break;
258  case SEED_PT_THRESH:
259  value = threshPtSeedEndcap_;
260  break;
261  case CLEAN_THRESH:
262  value = threshCleanEndcap_;
263  break;
264  case CLEAN_S4S1:
265  value = minS4S1Endcap_[iCoeff];
266  break;
267  case DOUBLESPIKE_THRESH:
268  value = threshDoubleSpikeEndcap_;
269  break;
270  case DOUBLESPIKE_S6S2:
272  break;
273  default:
274  cerr<<"PFClusterAlgo::parameter : unknown parameter type "
275  <<paramtype<<endl;
276  assert(0);
277  }
278  break;
279  default:
280  cerr<<"PFClusterAlgo::parameter : unknown layer "<<layer<<endl;
281  assert(0);
282  break;
283  }
284 
285  return value;
286 }
287 
288 
289 void
291 
292  std::map< int, std::vector<unsigned> > hpds;
293  std::map< int, std::vector<unsigned> > rbxs;
294 
295  for(EH ih = eRecHits_.begin(); ih != eRecHits_.end(); ih++ ) {
296 
297  unsigned rhi = ih->second;
298 
299  if(! masked(rhi) ) continue;
300  // rechit was asked to be processed
301  const reco::PFRecHit& rhit = rechit( rhi, rechits);
302  //double energy = rhit.energy();
303  int layer = rhit.layer();
304  if ( layer != PFLayer::HCAL_BARREL1 &&
305  layer != PFLayer::HCAL_ENDCAP ) break;
306  // layer != PFLayer::HCAL_BARREL2) break; //BARREL2 for HO : need specific cleaning
307  HcalDetId theHcalDetId = HcalDetId(rhit.detId());
308  int ieta = theHcalDetId.ieta();
309  int iphi = theHcalDetId.iphi();
310  int ihpd = ieta < 0 ?
311  ( layer == PFLayer::HCAL_ENDCAP ? -(iphi+1)/2-100 : -iphi ) :
312  ( layer == PFLayer::HCAL_ENDCAP ? (iphi+1)/2+100 : iphi ) ;
313  hpds[ihpd].push_back(rhi);
314  int irbx = ieta < 0 ?
315  ( layer == PFLayer::HCAL_ENDCAP ? -(iphi+5)/4 - 20 : -(iphi+5)/4 ) :
316  ( layer == PFLayer::HCAL_ENDCAP ? (iphi+5)/4 + 20 : (iphi+5)/4 ) ;
317  if ( irbx == 19 ) irbx = 1;
318  else if ( irbx == -19 ) irbx = -1;
319  else if ( irbx == 39 ) irbx = 21;
320  else if ( irbx == -39 ) irbx = -21;
321  rbxs[irbx].push_back(rhi);
322  }
323 
324  // Loop on readout boxes
325  for ( std::map<int, std::vector<unsigned> >::iterator itrbx = rbxs.begin();
326  itrbx != rbxs.end(); ++itrbx ) {
327  if ( ( abs(itrbx->first)<20 && itrbx->second.size() > 30 ) ||
328  ( abs(itrbx->first)>20 && itrbx->second.size() > 30 ) ) {
329  const std::vector<unsigned>& rhits = itrbx->second;
330  double totalEta = 0.;
331  double totalEtaW = 0.;
332  double totalPhi = 0.;
333  double totalPhiW = 0.;
334  double totalEta2 = 1E-9;
335  double totalEta2W = 1E-9;
336  double totalPhi2 = 1E-9;
337  double totalPhi2W = 1E-9;
338  double totalEnergy = 0.;
339  double totalEnergy2 = 1E-9;
340  unsigned nSeeds = rhits.size();
341  unsigned nSeeds0 = rhits.size();
342  std::map< int,std::vector<unsigned> > theHPDs;
343  std::multimap< double,unsigned > theEnergies;
344  for ( unsigned jh=0; jh < rhits.size(); ++jh ) {
345  const reco::PFRecHit& hit = rechit(rhits[jh], rechits);
346  // Check if the hit is a seed
347  unsigned nN = 0;
348  bool isASeed = true;
349  const vector<unsigned>& neighbours4 = *(& hit.neighbours4());
350  for(unsigned in=0; in<neighbours4.size(); in++) {
351  const reco::PFRecHit& neighbour = rechit( neighbours4[in], rechits );
352  // one neighbour has a higher energy -> the tested rechit is not a seed
353  if( neighbour.energy() > hit.energy() ) {
354  --nSeeds;
355  --nSeeds0;
356  isASeed = false;
357  break;
358  } else {
359  if ( neighbour.energy() > 0.4 ) ++nN;
360  }
361  }
362  if ( isASeed && !nN ) --nSeeds0;
363 
364  HcalDetId theHcalDetId = HcalDetId(hit.detId());
365  // int ieta = theHcalDetId.ieta();
366  int iphi = theHcalDetId.iphi();
367  // std::cout << "Hit : " << hit.energy() << " " << ieta << " " << iphi << std::endl;
368  if ( hit.layer() == PFLayer::HCAL_BARREL1 )
369  theHPDs[iphi].push_back(rhits[jh]);
370  else
371  theHPDs[(iphi-1)/2].push_back(rhits[jh]);
372  theEnergies.insert(std::pair<double,unsigned>(hit.energy(),rhits[jh]));
373  totalEnergy += hit.energy();
374  totalPhi += fabs(hit.position().phi());
375  totalPhiW += hit.energy()*fabs(hit.position().phi());
376  totalEta += hit.position().eta();
377  totalEtaW += hit.energy()*hit.position().eta();
378  totalEnergy2 += hit.energy()*hit.energy();
379  totalPhi2 += hit.position().phi()*hit.position().phi();
380  totalPhi2W += hit.energy()*hit.position().phi()*hit.position().phi();
381  totalEta2 += hit.position().eta()*hit.position().eta();
382  totalEta2W += hit.energy()*hit.position().eta()*hit.position().eta();
383  }
384  // totalPhi /= totalEnergy;
385  totalPhi /= rhits.size();
386  totalEta /= rhits.size();
387  totalPhiW /= totalEnergy;
388  totalEtaW /= totalEnergy;
389  totalPhi2 /= rhits.size();
390  totalEta2 /= rhits.size();
391  totalPhi2W /= totalEnergy;
392  totalEta2W /= totalEnergy;
393  totalPhi2 = std::sqrt(totalPhi2 - totalPhi*totalPhi);
394  totalEta2 = std::sqrt(totalEta2 - totalEta*totalEta);
395  totalPhi2W = std::sqrt(totalPhi2W - totalPhiW*totalPhiW);
396  totalEta2W = std::sqrt(totalEta2W - totalEtaW*totalEtaW);
397  totalEnergy /= rhits.size();
398  totalEnergy2 /= rhits.size();
399  totalEnergy2 = std::sqrt(totalEnergy2 - totalEnergy*totalEnergy);
400  //if ( totalPhi2W/totalEta2W < 0.18 ) {
401  if ( nSeeds0 > 6 ) {
402  unsigned nHPD15 = 0;
403  for ( std::map<int, std::vector<unsigned> >::iterator itHPD = theHPDs.begin();
404  itHPD != theHPDs.end(); ++itHPD ) {
405  int hpdN = itHPD->first;
406  const std::vector<unsigned>& hpdHits = itHPD->second;
407  if ( ( abs(hpdN) < 100 && hpdHits.size() > 14 ) ||
408  ( abs(hpdN) > 100 && hpdHits.size() > 14 ) ) ++nHPD15;
409  }
410  if ( nHPD15 > 1 ) {
411  /*
412  std::cout << "Read out box numero " << itrbx->first
413  << " has " << itrbx->second.size() << " hits in it !"
414  << std::endl << "sigma Eta/Phi = " << totalEta2 << " " << totalPhi2 << " " << totalPhi2/totalEta2
415  << std::endl << "sigma EtaW/PhiW = " << totalEta2W << " " << totalPhi2W << " " << totalPhi2W/totalEta2W
416  << std::endl << "E = " << totalEnergy << " +/- " << totalEnergy2
417  << std::endl << "nSeeds = " << nSeeds << " " << nSeeds0
418  << std::endl;
419  for ( std::map<int, std::vector<unsigned> >::iterator itHPD = theHPDs.begin();
420  itHPD != theHPDs.end(); ++itHPD ) {
421  unsigned hpdN = itHPD->first;
422  const std::vector<unsigned>& hpdHits = itHPD->second;
423  std::cout << "HPD number " << hpdN << " contains " << hpdHits.size() << " hits" << std::endl;
424  }
425  */
426  std::multimap<double, unsigned >::iterator ntEn = theEnergies.end();
427  --ntEn;
428  unsigned nn = 0;
429  double threshold = 1.;
430  for ( std::multimap<double, unsigned >::iterator itEn = theEnergies.begin();
431  itEn != theEnergies.end(); ++itEn ) {
432  ++nn;
433  if ( nn < 5 ) {
434  mask_[itEn->second] = false;
435  } else if ( nn == 5 ) {
436  threshold = itEn->first * 5.;
437  mask_[itEn->second] = false;
438  } else {
439  if ( itEn->first < threshold ) mask_[itEn->second] = false;
440  }
441  if ( !masked(itEn->second) ) {
442  reco::PFRecHit theCleanedHit(rechit(itEn->second, rechits));
443  //theCleanedHit.setRescale(0.);
444  pfRecHitsCleaned_->push_back(theCleanedHit);
445  }
446  /*
447  if ( !masked(itEn->second) )
448  std::cout << "Hit Energies = " << itEn->first
449  << " " << ntEn->first/itEn->first << " masked " << std::endl;
450  else
451  std::cout << "Hit Energies = " << itEn->first
452  << " " << ntEn->first/itEn->first << " kept for clustering " << std::endl;
453  */
454  }
455  }
456  }
457  }
458  }
459 
460  // Loop on hpd's
461  std::map<int, std::vector<unsigned> >::iterator neighbour1;
462  std::map<int, std::vector<unsigned> >::iterator neighbour2;
463  std::map<int, std::vector<unsigned> >::iterator neighbour0;
464  std::map<int, std::vector<unsigned> >::iterator neighbour3;
465  unsigned size1 = 0;
466  unsigned size2 = 0;
467  for ( std::map<int, std::vector<unsigned> >::iterator ithpd = hpds.begin();
468  ithpd != hpds.end(); ++ithpd ) {
469 
470  const std::vector<unsigned>& rhits = ithpd->second;
471  std::multimap< double,unsigned > theEnergies;
472  double totalEnergy = 0.;
473  double totalEnergy2 = 1E-9;
474  for ( unsigned jh=0; jh < rhits.size(); ++jh ) {
475  const reco::PFRecHit& hit = rechit(rhits[jh], rechits);
476  totalEnergy += hit.energy();
477  totalEnergy2 += hit.energy()*hit.energy();
478  theEnergies.insert(std::pair<double,unsigned>(hit.energy(),rhits[jh]));
479  }
480  totalEnergy /= rhits.size();
481  totalEnergy2 /= rhits.size();
482  totalEnergy2 = std::sqrt(totalEnergy2 - totalEnergy*totalEnergy);
483 
484  if ( ithpd->first == 1 ) neighbour1 = hpds.find(72);
485  else if ( ithpd->first == -1 ) neighbour1 = hpds.find(-72);
486  else if ( ithpd->first == 101 ) neighbour1 = hpds.find(136);
487  else if ( ithpd->first == -101 ) neighbour1 = hpds.find(-136);
488  else neighbour1 = ithpd->first > 0 ? hpds.find(ithpd->first-1) : hpds.find(ithpd->first+1) ;
489 
490  if ( ithpd->first == 72 ) neighbour2 = hpds.find(1);
491  else if ( ithpd->first == -72 ) neighbour2 = hpds.find(-1);
492  else if ( ithpd->first == 136 ) neighbour2 = hpds.find(101);
493  else if ( ithpd->first == -136 ) neighbour2 = hpds.find(-101);
494  else neighbour2 = ithpd->first > 0 ? hpds.find(ithpd->first+1) : hpds.find(ithpd->first-1) ;
495 
496  if ( neighbour1 != hpds.end() ) {
497  if ( neighbour1->first == 1 ) neighbour0 = hpds.find(72);
498  else if ( neighbour1->first == -1 ) neighbour0 = hpds.find(-72);
499  else if ( neighbour1->first == 101 ) neighbour0 = hpds.find(136);
500  else if ( neighbour1->first == -101 ) neighbour0 = hpds.find(-136);
501  else neighbour0 = neighbour1->first > 0 ? hpds.find(neighbour1->first-1) : hpds.find(neighbour1->first+1) ;
502  }
503 
504  if ( neighbour2 != hpds.end() ) {
505  if ( neighbour2->first == 72 ) neighbour3 = hpds.find(1);
506  else if ( neighbour2->first == -72 ) neighbour3 = hpds.find(-1);
507  else if ( neighbour2->first == 136 ) neighbour3 = hpds.find(101);
508  else if ( neighbour2->first == -136 ) neighbour3 = hpds.find(-101);
509  else neighbour3 = neighbour2->first > 0 ? hpds.find(neighbour2->first+1) : hpds.find(neighbour2->first-1) ;
510  }
511 
512  size1 = neighbour1 != hpds.end() ? neighbour1->second.size() : 0;
513  size2 = neighbour2 != hpds.end() ? neighbour2->second.size() : 0;
514 
515  // Also treat the case of two neighbouring HPD's not in the same RBX
516  if ( size1 > 10 ) {
517  if ( ( abs(neighbour1->first) > 100 && neighbour1->second.size() > 15 ) ||
518  ( abs(neighbour1->first) < 100 && neighbour1->second.size() > 12 ) )
519  size1 = neighbour0 != hpds.end() ? neighbour0->second.size() : 0;
520  }
521  if ( size2 > 10 ) {
522  if ( ( abs(neighbour2->first) > 100 && neighbour2->second.size() > 15 ) ||
523  ( abs(neighbour2->first) < 100 && neighbour2->second.size() > 12 ) )
524  size2 = neighbour3 != hpds.end() ? neighbour3->second.size() : 0;
525  }
526 
527  if ( ( abs(ithpd->first) > 100 && ithpd->second.size() > 15 ) ||
528  ( abs(ithpd->first) < 100 && ithpd->second.size() > 12 ) )
529  if ( (float)(size1 + size2)/(float)ithpd->second.size() < 1.0 ) {
530  /*
531  std::cout << "HPD numero " << ithpd->first
532  << " has " << ithpd->second.size() << " hits in it !" << std::endl
533  << "Neighbours : " << size1 << " " << size2
534  << std::endl;
535  */
536  std::multimap<double, unsigned >::iterator ntEn = theEnergies.end();
537  --ntEn;
538  unsigned nn = 0;
539  double threshold = 1.;
540  for ( std::multimap<double, unsigned >::iterator itEn = theEnergies.begin();
541  itEn != theEnergies.end(); ++itEn ) {
542  ++nn;
543  if ( nn < 5 ) {
544  mask_[itEn->second] = false;
545  } else if ( nn == 5 ) {
546  threshold = itEn->first * 2.5;
547  mask_[itEn->second] = false;
548  } else {
549  if ( itEn->first < threshold ) mask_[itEn->second] = false;
550  }
551  if ( !masked(itEn->second) ) {
552  reco::PFRecHit theCleanedHit(rechit(itEn->second, rechits));
553  //theCleanedHit.setRescale(0.);
554  pfRecHitsCleaned_->push_back(theCleanedHit);
555  }
556  /*
557  if ( !masked(itEn->second) )
558  std::cout << "Hit Energies = " << itEn->first
559  << " " << ntEn->first/itEn->first << " masked " << std::endl;
560  else
561  std::cout << "Hit Energies = " << itEn->first
562  << " " << ntEn->first/itEn->first << " kept for clustering " << std::endl;
563  */
564  }
565  }
566  }
567 
568 }
569 
570 
572 
573  seeds_.clear();
574 
575  // should replace this by the message logger.
576 #ifdef PFLOW_DEBUG
577  if(debug_)
578  cout<<"PFClusterAlgo::findSeeds : start"<<endl;
579 #endif
580 
581 
582  // An empty list of neighbours
583  const vector<unsigned> noNeighbours(0, static_cast<unsigned>(0));
584 
585  // loop on rechits (sorted by decreasing energy - not E_T)
586 
587  for(EH ih = eRecHits_.begin(); ih != eRecHits_.end(); ih++ ) {
588 
589  unsigned rhi = ih->second;
590 
591  if(! masked(rhi) ) continue;
592  // rechit was asked to be processed
593 
594  double rhenergy = ih->first;
595  const reco::PFRecHit& wannaBeSeed = rechit(rhi, rechits);
596 
597  if( seedStates_[rhi] == NO ) continue;
598  // this hit was already tested, and is not a seed
599 
600  // determine seed energy threshold depending on the detector
601  int layer = wannaBeSeed.layer();
602  //for HO Ring0 and 1/2 boundary
603 
604  int iring = 0;
605  if (layer==PFLayer::HCAL_BARREL2 && abs(wannaBeSeed.positionREP().Eta())>0.34) iring= 1;
606 
607  double seedThresh = parameter( SEED_THRESH,
608  static_cast<PFLayer::Layer>(layer), 0, iring );
609 
610  double seedPtThresh = parameter( SEED_PT_THRESH,
611  static_cast<PFLayer::Layer>(layer), 0., iring );
612 
613  double cleanThresh = parameter( CLEAN_THRESH,
614  static_cast<PFLayer::Layer>(layer), 0, iring );
615 
616  double minS4S1_a = parameter( CLEAN_S4S1,
617  static_cast<PFLayer::Layer>(layer), 0, iring );
618 
619  double minS4S1_b = parameter( CLEAN_S4S1,
620  static_cast<PFLayer::Layer>(layer), 1, iring );
621 
622  double doubleSpikeThresh = parameter( DOUBLESPIKE_THRESH,
623  static_cast<PFLayer::Layer>(layer), 0, iring );
624 
625  double doubleSpikeS6S2 = parameter( DOUBLESPIKE_S6S2,
626  static_cast<PFLayer::Layer>(layer), 0, iring );
627 
628 #ifdef PFLOW_DEBUG
629  if(debug_)
630  cout<<"layer:"<<layer<<" seedThresh:"<<seedThresh<<endl;
631 #endif
632 
633 
634  if( rhenergy < seedThresh || (seedPtThresh>0. && wannaBeSeed.pt2() < seedPtThresh*seedPtThresh )) {
635  seedStates_[rhi] = NO;
636  continue;
637  }
638 
639  // Find the cell unused neighbours
640  const vector<unsigned>* nbp;
641  double tighterE = 1.0;
642  double tighterF = 1.0;
643 
644  switch ( layer ) {
645  case PFLayer::ECAL_BARREL:
646  case PFLayer::ECAL_ENDCAP:
650  tighterE = 2.0;
651  tighterF = 3.0;
652  case PFLayer::HF_EM:
653  case PFLayer::HF_HAD:
654  if( nNeighbours_ == 4 ) {
655  nbp = & wannaBeSeed.neighbours4();
656  }
657  else if( nNeighbours_ == 8 ) {
658  nbp = & wannaBeSeed.neighbours8();
659  }
660  else if( nNeighbours_ == 0 ) {
661  nbp = & noNeighbours;
662  // Allows for no clustering at all: all rechits are clusters.
663  // Useful for HF
664  }
665  else {
666  cerr<<"you're not allowed to set n neighbours to "
667  <<nNeighbours_<<endl;
668  assert(0);
669  }
670  break;
671  case PFLayer::PS1:
672  case PFLayer::PS2:
673  nbp = & wannaBeSeed.neighbours4();
674  break;
675 
676  default:
677  cerr<<"CellsEF::PhotonSeeds : unknown layer "<<layer<<endl;
678  assert(0);
679  }
680 
681  const vector<unsigned>& neighbours = *nbp;
682 
683 
684  // Select as a seed if all neighbours have a smaller energy
685 
686  seedStates_[rhi] = YES;
687  for(unsigned in=0; in<neighbours.size(); in++) {
688 
689  unsigned rhj = neighbours[in];
690  // Ignore neighbours already masked
691  if ( !masked(rhj) ) continue;
692  const reco::PFRecHit& neighbour = rechit( rhj, rechits );
693 
694  // one neighbour has a higher energy -> the tested rechit is not a seed
695  if( neighbour.energy() > wannaBeSeed.energy() ) {
696  seedStates_[rhi] = NO;
697  break;
698  }
699  }
700 
701  // Cleaning : check energetic, isolated seeds, likely to come from erratic noise.
702  if ( file_ || wannaBeSeed.energy() > cleanThresh ) {
703 
704  const vector<unsigned>& neighbours4 = *(& wannaBeSeed.neighbours4());
705  // Determine the fraction of surrounding energy
706  double surroundingEnergy = wannaBeSeed.energyUp();
707  double neighbourEnergy = 0.;
708  double layerEnergy = 0.;
709  for(unsigned in4=0; in4<neighbours4.size(); in4++) {
710  unsigned rhj = neighbours4[in4];
711  // Ignore neighbours already masked
712  if ( !masked(rhj) ) continue;
713  const reco::PFRecHit& neighbour = rechit( rhj, rechits );
714  surroundingEnergy += neighbour.energy() + neighbour.energyUp();
715  neighbourEnergy += neighbour.energy() + neighbour.energyUp();
716  layerEnergy += neighbour.energy();
717  }
718  // Fraction 0 is the balance between EM and HAD layer for this tower
719  // double fraction0 = layer == PFLayer::HF_EM || layer == PFLayer::HF_HAD ?
720  // wannaBeSeed.energyUp()/wannaBeSeed.energy() : 1.;
721  // Fraction 1 is the balance between the hit and its neighbours from both layers
722  double fraction1 = surroundingEnergy/wannaBeSeed.energy();
723  // Fraction 2 is the balance between the tower and the tower neighbours
724  // double fraction2 = neighbourEnergy/(wannaBeSeed.energy()+wannaBeSeed.energyUp());
725  // Fraction 3 is the balance between the hits and the hits neighbours in the same layer.
726  // double fraction3 = layerEnergy/(wannaBeSeed.energy());
727  // Mask the seed and the hit if energetic/isolated rechit
728  // if ( fraction0 < minS4S1 || fraction1 < minS4S1 || fraction2 < minS4S1 || fraction3 < minS4S1 ) {
729  // if ( fraction1 < minS4S1 || ( wannaBeSeed.energy() > 1.5*cleanThresh && fraction0 + fraction3 < minS4S1 ) ) {
730 
731  if ( file_ ) {
732  if ( layer == PFLayer::ECAL_BARREL || layer == PFLayer::HCAL_BARREL1 || layer == PFLayer::HCAL_BARREL2) { //BARREL2 for HO
733  /*
734  double eta = wannaBeSeed.position().eta();
735  double phi = wannaBeSeed.position().phi();
736  std::pair<double,double> dcr = dCrack(phi,eta);
737  double dcrmin = std::min(dcr.first, dcr.second);
738  if ( dcrmin > 1. )
739  */
740  hBNeighbour->Fill(1./wannaBeSeed.energy(), fraction1);
741  } else if ( fabs(wannaBeSeed.position().eta()) < 5.0 ) {
742  if ( layer == PFLayer::ECAL_ENDCAP || layer == PFLayer::HCAL_ENDCAP ) {
743  if ( wannaBeSeed.energy() > 1000 ) {
744  if ( fabs(wannaBeSeed.position().eta()) < 2.8 )
745  hENeighbour->Fill(1./wannaBeSeed.energy(), fraction1);
746  }
747  } else {
748  hENeighbour->Fill(1./wannaBeSeed.energy(), fraction1);
749  }
750  }
751  }
752 
753  if ( wannaBeSeed.energy() > cleanThresh ) {
754  double f1Cut = minS4S1_a * log10(wannaBeSeed.energy()) + minS4S1_b;
755  if ( fraction1 < f1Cut ) {
756  // Double the energy cleaning threshold when close to the ECAL/HCAL - HF transition
757  double eta = wannaBeSeed.position().eta();
758  double phi = wannaBeSeed.position().phi();
759  std::pair<double,double> dcr = dCrack(phi,eta);
760  double dcrmin = layer == PFLayer::ECAL_BARREL ? std::min(dcr.first, dcr.second) : dcr.second;
761  eta = fabs(eta);
762  if ( eta < 5.0 && // No cleaning for the HF border
763  ( ( eta < 2.85 && dcrmin > 1. ) ||
764  ( rhenergy > tighterE*cleanThresh &&
765  fraction1 < f1Cut/tighterF ) ) // Tighter cleaning for various cracks
766  ) {
767  seedStates_[rhi] = CLEAN;
768  mask_[rhi] = false;
769  reco::PFRecHit theCleanedHit(wannaBeSeed);
770  //theCleanedHit.setRescale(0.);
771  pfRecHitsCleaned_->push_back(theCleanedHit);
772  /*
773  std::cout << "A seed with E/pT/eta/phi = " << wannaBeSeed.energy() << " " << wannaBeSeed.energyUp()
774  << " " << sqrt(wannaBeSeed.pt2()) << " " << wannaBeSeed.position().eta() << " " << phi
775  << " and with surrounding fractions = " << fraction0 << " " << fraction1
776  << " " << fraction2 << " " << fraction3
777  << " in layer " << layer
778  << " had been cleaned " << std::endl
779  << " Distances to cracks : " << dcr.first << " " << dcr.second << std::endl
780  << "(Cuts were : " << cleanThresh << " and " << f1Cut << ")" << std::endl;
781  */
782  }
783  }
784  }
785  }
786 
787  // Clean double spikes
788  if ( mask_[rhi] && wannaBeSeed.energy() > doubleSpikeThresh ) {
789  // Determine energy surrounding the seed and the most energetic neighbour
790  double surroundingEnergyi = 0.;
791  double enmax = -999.;
792  unsigned mostEnergeticNeighbour = 0;
793  const vector<unsigned>& neighbours4i = *(& wannaBeSeed.neighbours4());
794  for(unsigned in4=0; in4<neighbours4i.size(); in4++) {
795  unsigned rhj = neighbours4i[in4];
796  if ( !masked(rhj) ) continue;
797  const reco::PFRecHit& neighbouri = rechit( rhj, rechits );
798  surroundingEnergyi += neighbouri.energy();
799  if ( neighbouri.energy() > enmax ) {
800  enmax = neighbouri.energy();
801  mostEnergeticNeighbour = rhj;
802  }
803  }
804  // Is there an energetic neighbour ?
805  if ( enmax > 0. ) {
806  unsigned rhj = mostEnergeticNeighbour;
807  const reco::PFRecHit& neighbouri = rechit( rhj, rechits );
808  double surroundingEnergyj = 0.;
809  //if ( mask_[rhj] && neighbouri.energy() > doubleSpikeThresh ) {
810  // Determine energy surrounding the energetic neighbour
811  const vector<unsigned>& neighbours4j = *(& neighbouri.neighbours4());
812  for(unsigned jn4=0; jn4<neighbours4j.size(); jn4++) {
813  unsigned rhk = neighbours4j[jn4];
814  const reco::PFRecHit& neighbourj = rechit( rhk, rechits );
815  surroundingEnergyj += neighbourj.energy();
816  }
817  // The energy surrounding the double spike candidate
818  double surroundingEnergyFraction =
819  (surroundingEnergyi+surroundingEnergyj) / (wannaBeSeed.energy()+neighbouri.energy()) - 1.;
820  if ( surroundingEnergyFraction < doubleSpikeS6S2 ) {
821  double eta = wannaBeSeed.position().eta();
822  double phi = wannaBeSeed.position().phi();
823  std::pair<double,double> dcr = dCrack(phi,eta);
824  double dcrmin = layer == PFLayer::ECAL_BARREL ? std::min(dcr.first, dcr.second) : dcr.second;
825  eta = fabs(eta);
826  if ( ( eta < 5.0 && dcrmin > 1. ) ||
827  ( wannaBeSeed.energy() > tighterE*doubleSpikeThresh &&
828  surroundingEnergyFraction < doubleSpikeS6S2/tighterF ) ) {
829  /*
830  std::cout << "Double spike cleaned : Energies = " << wannaBeSeed.energy()
831  << " " << neighbouri.energy()
832  << " surrounded by only " << surroundingEnergyFraction*100.
833  << "% of the two spike energies at eta/phi/distance to closest crack = "
834  << eta << " " << phi << " " << dcrmin
835  << std::endl;
836  */
837  // mask the seed
838  seedStates_[rhi] = CLEAN;
839  mask_[rhi] = false;
840  reco::PFRecHit theCleanedSeed(wannaBeSeed);
841  pfRecHitsCleaned_->push_back(theCleanedSeed);
842  // mask the neighbour
843  seedStates_[rhj] = CLEAN;
844  mask_[rhj] = false;
845  reco::PFRecHit theCleanedNeighbour(wannaBeSeed);
846  pfRecHitsCleaned_->push_back(neighbouri);
847  }
848  }
849  } else {
850  /*
851  std::cout << "PFClusterAlgo : Double spike search : An isolated cell should have been killed " << std::endl
852  << "but is going through the double spike search!" << std::endl;
853  */
854  }
855  }
856 
857  if ( seedStates_[rhi] == YES ) {
858 
859  // seeds_ contains the indices of all seeds.
860  seeds_.push_back( rhi );
861 
862  // marking the rechit
863  paint(rhi, SEED);
864 
865  // then all neighbours cannot be seeds and are flagged as such
866  for(unsigned in=0; in<neighbours.size(); in++) {
867  seedStates_[ neighbours[in] ] = NO;
868  }
869  }
870 
871  }
872 
873 #ifdef PFLOW_DEBUG
874  if(debug_)
875  cout<<"PFClusterAlgo::findSeeds : done"<<endl;
876 #endif
877 }
878 
879 
880 
881 
883 
884  topoClusters_.clear();
885 
886 #ifdef PFLOW_DEBUG
887  if(debug_)
888  cout<<"PFClusterAlgo::buildTopoClusters start"<<endl;
889 #endif
890 
891  for(unsigned is = 0; is<seeds_.size(); is++) {
892 
893  unsigned rhi = seeds_[is];
894 
895  if( !masked(rhi) ) continue;
896  // rechit was masked to be processed
897 
898  // already used in a topological cluster
899  if( usedInTopo_[rhi] ) {
900 #ifdef PFLOW_DEBUG
901  if(debug_)
902  cout<<rhi<<" used"<<endl;
903 #endif
904  continue;
905  }
906 
907  vector< unsigned > topocluster;
908  buildTopoCluster( topocluster, rhi, rechits );
909 
910  if(topocluster.empty() ) continue;
911 
912  topoClusters_.push_back( topocluster );
913 
914  }
915 
916 #ifdef PFLOW_DEBUG
917  if(debug_)
918  cout<<"PFClusterAlgo::buildTopoClusters done"<<endl;
919 #endif
920 
921  return;
922 }
923 
924 
925 void
926 PFClusterAlgo::buildTopoCluster( vector< unsigned >& cluster,
927  unsigned rhi,
929 
930 
931 #ifdef PFLOW_DEBUG
932  if(debug_)
933  cout<<"PFClusterAlgo::buildTopoCluster in"<<endl;
934 #endif
935 
936  const reco::PFRecHit& rh = rechit( rhi, rechits);
937 
938  double e = rh.energy();
939  int layer = rh.layer();
940 
941 
942  int iring = 0;
943  if (layer==PFLayer::HCAL_BARREL2 && abs(rh.positionREP().Eta())>0.34) iring= 1;
944 
945  double thresh = parameter( THRESH,
946  static_cast<PFLayer::Layer>(layer), 0, iring );
947  double ptThresh = parameter( PT_THRESH,
948  static_cast<PFLayer::Layer>(layer), 0, iring );
949 
950 
951  if( e < thresh || (ptThresh > 0. && rh.pt2() < ptThresh*ptThresh) ) {
952 #ifdef PFLOW_DEBUG
953  if(debug_)
954  cout<<"return : "<<e<<"<"<<thresh<<endl;
955 #endif
956  return;
957  }
958 
959  // add hit to cluster
960 
961  cluster.push_back( rhi );
962  // idUsedRecHits_.insert( rh.detId() );
963 
964  usedInTopo_[ rhi ] = true;
965 
966  // cout<<" hit ptr "<<hit<<endl;
967 
968  // get neighbours, either with one side in common,
969  // or with one corner in common (if useCornerCells_)
970  const std::vector< unsigned >& nbs
971  = useCornerCells_ ? rh.neighbours8() : rh.neighbours4();
972 
973  for(unsigned i=0; i<nbs.size(); i++) {
974 
975 // const reco::PFRecHit& neighbour = rechit( nbs[i], rechits );
976 
977 // set<unsigned>::iterator used
978 // = idUsedRecHits_.find( neighbour.detId() );
979 // if(used != idUsedRecHits_.end() ) continue;
980 
981  // already used
982  if( usedInTopo_[ nbs[i] ] ) {
983 #ifdef PFLOW_DEBUG
984  if(debug_)
985  cout<<rhi<<" used"<<endl;
986 #endif
987  continue;
988  }
989 
990  if( !masked(nbs[i]) ) continue;
991  buildTopoCluster( cluster, nbs[i], rechits );
992  }
993 #ifdef PFLOW_DEBUG
994  if(debug_)
995  cout<<"PFClusterAlgo::buildTopoCluster out"<<endl;
996 #endif
997 
998 }
999 
1000 
1001 void
1002 PFClusterAlgo::buildPFClusters( const std::vector< unsigned >& topocluster,
1004 {
1005 
1006 
1007  // bool debug = false;
1008 
1009 
1010  // several rechits may be seeds. initialize PFClusters on these seeds.
1011 
1012  vector<reco::PFCluster> curpfclusters;
1013  vector<reco::PFCluster> curpfclusterswodepthcor;
1014  vector< unsigned > seedsintopocluster;
1015 
1016 
1017  for(unsigned i=0; i<topocluster.size(); i++ ) {
1018 
1019  unsigned rhi = topocluster[i];
1020 
1021  if( seedStates_[rhi] == YES ) {
1022 
1023  reco::PFCluster cluster;
1024  reco::PFCluster clusterwodepthcor;
1025 
1026  double fraction = 1.0;
1027 
1028  reco::PFRecHitRef recHitRef = createRecHitRef( rechits, rhi );
1029 
1030  cluster.addRecHitFraction( reco::PFRecHitFraction( recHitRef,
1031  fraction ) );
1032 
1033  // cluster.addRecHit( rhi, fraction );
1034 
1035  calculateClusterPosition( cluster,
1036  clusterwodepthcor,
1037  true );
1038 
1039 
1040 // cout<<"PFClusterAlgo: 2"<<endl;
1041  curpfclusters.push_back( cluster );
1042  curpfclusterswodepthcor.push_back( clusterwodepthcor );
1043 #ifdef PFLOW_DEBUG
1044  if(debug_) {
1045  cout << "PFClusterAlgo::buildPFClusters: seed "
1046  << rechit( rhi, rechits) <<endl;
1047  cout << "PFClusterAlgo::buildPFClusters: pfcluster initialized : "
1048  << cluster <<endl;
1049  }
1050 #endif
1051 
1052  // keep track of the seed of each topocluster
1053  seedsintopocluster.push_back( rhi );
1054  }
1055  }
1056 
1057  // if only one seed in the topocluster, use all crystals
1058  // in the position calculation (posCalcNCrystal = -1)
1059  // otherwise, use the user specified value
1060  int posCalcNCrystal = seedsintopocluster.size()>1 ? posCalcNCrystal_:-1;
1061  double ns2 = std::max(1.,(double)(seedsintopocluster.size())-1.);
1062  ns2 *= ns2;
1063 
1064  // Find iteratively the energy and position
1065  // of each pfcluster in the topological cluster
1066  unsigned iter = 0;
1067  unsigned niter = 50;
1068  double diff = ns2;
1069 
1070  // if(debug_) niter=2;
1071  vector<double> ener;
1072  vector<double> dist;
1073  vector<double> frac;
1074  vector<math::XYZVector> tmp;
1075 
1076  while ( iter++ < niter && diff > 1E-8*ns2 ) {
1077 
1078  // Store previous iteration's result and reset pfclusters
1079  ener.clear();
1080  tmp.clear();
1081 
1082  for ( unsigned ic=0; ic<curpfclusters.size(); ic++ ) {
1083  ener.push_back( curpfclusters[ic].energy() );
1084 
1086  v = curpfclusters[ic].position();
1087 
1088  tmp.push_back( v );
1089 
1090 #ifdef PFLOW_DEBUG
1091  if(debug_) {
1092  cout<<"saving photon pos "<<ic<<" "<<curpfclusters[ic]<<endl;
1093  cout<<tmp[ic].X()<<" "<<tmp[ic].Y()<<" "<<tmp[ic].Z()<<endl;
1094  }
1095 #endif
1096 
1097  curpfclusters[ic].reset();
1098  }
1099 
1100  // Loop over topocluster cells
1101  for( unsigned irh=0; irh<topocluster.size(); irh++ ) {
1102  unsigned rhindex = topocluster[irh];
1103 
1104  const reco::PFRecHit& rh = rechit( rhindex, rechits);
1105 
1106  // int layer = rh.layer();
1107 
1108  dist.clear();
1109  frac.clear();
1110  double fractot = 0.;
1111 
1112  bool isaseed = isSeed(rhindex);
1113 
1114  math::XYZVector cposxyzcell;
1115  cposxyzcell = rh.position();
1116 
1117 #ifdef PFLOW_DEBUG
1118  if(debug_) {
1119  cout<<rh<<endl;
1120  cout<<"start loop on curpfclusters"<<endl;
1121  }
1122 #endif
1123 
1124  // Loop over pfclusters
1125  for ( unsigned ic=0; ic<tmp.size(); ic++) {
1126 
1127 #ifdef PFLOW_DEBUG
1128  if(debug_) cout<<"pfcluster "<<ic<<endl;
1129 #endif
1130 
1131  double frc=0.;
1132  bool seedexclusion=true;
1133 
1134  // convert cluster coordinates to xyz
1135  //math::XYZVector cposxyzclust( tmp[ic].X(), tmp[ic].Y(), tmp[ic].Z() );
1136  // cluster position used to compute distance with cell
1137  math::XYZVector cposxyzclust;
1138  cposxyzclust = curpfclusterswodepthcor[ic].position();
1139 
1140 #ifdef PFLOW_DEBUG
1141  if(debug_) {
1142 
1143  cout<<"CLUSTER "<<cposxyzclust.X()<<","
1144  <<cposxyzclust.Y()<<","
1145  <<cposxyzclust.Z()<<"\t\t"
1146  <<"CELL "<<cposxyzcell.X()<<","
1147  <<cposxyzcell.Y()<<","
1148  <<cposxyzcell.Z()<<endl;
1149  }
1150 #endif
1151 
1152  // Compute the distance between the current cell
1153  // and the current PF cluster, normalized to a
1154  // number of "sigma"
1155  math::XYZVector deltav = cposxyzclust;
1156  deltav -= cposxyzcell;
1157  double d = deltav.R() / showerSigma_;
1158 
1159  // if distance cell-cluster is too large, it means that
1160  // we're right on the junction between 2 subdetectors (HCAL/VFCAL...)
1161  // in this case, distance is calculated in the xy plane
1162  // could also be a large supercluster...
1163 #ifdef PFLOW_DEBUG
1164  if( d > 10. && debug_ ) {
1165  paint(rhindex, SPECIAL);
1166  cout<<"PFClusterAlgo Warning: distance too large"<<d<<endl;
1167  }
1168 #endif
1169  dist.push_back( d );
1170 
1171  // the current cell is the seed from the current photon.
1172  if( rhindex == seedsintopocluster[ic] && seedexclusion ) {
1173  frc = 1.;
1174 #ifdef PFLOW_DEBUG
1175  if(debug_) cout<<"this cell is a seed for the current photon"<<endl;
1176 #endif
1177  }
1178  else if( isaseed && seedexclusion ) {
1179  frc = 0.;
1180 #ifdef PFLOW_DEBUG
1181  if(debug_) cout<<"this cell is a seed for another photon"<<endl;
1182 #endif
1183  }
1184  else {
1185  // Compute the fractions of the cell energy to be assigned to
1186  // each curpfclusters in the cluster.
1187  frc = ener[ic] * exp ( - dist[ic]*dist[ic] / 2. );
1188 
1189 #ifdef PFLOW_DEBUG
1190  if(debug_) {
1191  cout<<"dist["<<ic<<"] "<<dist[ic]
1192  // <<", sigma="<<sigma
1193  <<", frc="<<frc<<endl;
1194  }
1195 #endif
1196 
1197  }
1198  fractot += frc;
1199  frac.push_back(frc);
1200  }
1201 
1202  // Add the relevant fraction of the cell to the curpfclusters
1203 #ifdef PFLOW_DEBUG
1204  if(debug_) cout<<"start add cell"<<endl;
1205 #endif
1206  for ( unsigned ic=0; ic<tmp.size(); ++ic ) {
1207 #ifdef PFLOW_DEBUG
1208  if(debug_)
1209  cout<<" frac["<<ic<<"] "<<frac[ic]<<" "<<fractot<<" "<<rh<<endl;
1210 #endif
1211 
1212  if( fractot )
1213  frac[ic] /= fractot;
1214  else {
1215 #ifdef PFLOW_DEBUG
1216  if( debug_ ) {
1217  int layer = rh.layer();
1218  cerr<<"fractot = 0 ! "<<layer<<endl;
1219 
1220  for( unsigned trh=0; trh<topocluster.size(); trh++ ) {
1221  unsigned tindex = topocluster[trh];
1222  const reco::PFRecHit& rh = rechit( tindex, rechits);
1223  cout<<rh<<endl;
1224  }
1225 
1226  // assert(0)
1227  }
1228 #endif
1229 
1230  continue;
1231  }
1232 
1233  // if the fraction has been set to 0, the cell
1234  // is now added to the cluster - careful ! (PJ, 19/07/08)
1235  // BUT KEEP ONLY CLOSE CELLS OTHERWISE MEMORY JUST EXPLOSES
1236  // (PJ, 15/09/08 <- similar to what existed before the
1237  // previous bug fix, but keeps the close seeds inside,
1238  // even if their fraction was set to zero.)
1239  // Also add a protection to keep the seed in the cluster
1240  // when the latter gets far from the former. These cases
1241  // (about 1% of the clusters) need to be studied, as
1242  // they create fake photons, in general.
1243  // (PJ, 16/09/08)
1244  if ( dist[ic] < 10. || frac[ic] > 0.99999 ) {
1245  // if ( dist[ic] > 6. ) cout << "Warning : PCluster is getting very far from its seeding cell" << endl;
1246  reco::PFRecHitRef recHitRef = createRecHitRef( rechits, rhindex );
1247  reco::PFRecHitFraction rhf( recHitRef,frac[ic] );
1248  curpfclusters[ic].addRecHitFraction( rhf );
1249  }
1250  }
1251  // if(debug_) cout<<" end add cell"<<endl;
1252  }
1253 
1254  // Determine the new cluster position and check
1255  // the distance with the previous iteration
1256  diff = 0.;
1257  for ( unsigned ic=0; ic<tmp.size(); ++ic ) {
1258 
1259  calculateClusterPosition( curpfclusters[ic], curpfclusterswodepthcor[ic],
1260  true, posCalcNCrystal );
1261 #ifdef PFLOW_DEBUG
1262  if(debug_) cout<<"new iter "<<ic<<endl;
1263  if(debug_) cout<<curpfclusters[ic]<<endl;
1264 #endif
1265 
1266  double delta = ROOT::Math::VectorUtil::DeltaR(curpfclusters[ic].position(),tmp[ic]);
1267  if ( delta > diff ) diff = delta;
1268  }
1269  }
1270 
1271  // Issue a warning message if the number of iterations
1272  // exceeds 50
1273 #ifdef PFLOW_DEBUG
1274  if ( iter >= 50 && debug_ )
1275  cout << "PFClusterAlgo Warning: "
1276  << "more than "<<niter<<" iterations in pfcluster finding: "
1277  << setprecision(10) << diff << endl;
1278 #endif
1279 
1280  // There we go
1281  // add all clusters to the list of pfClusters.
1282  for(unsigned ic=0; ic<curpfclusters.size(); ic++) {
1283 
1284  calculateClusterPosition(curpfclusters[ic], curpfclusterswodepthcor[ic],
1285  true, posCalcNCrystal);
1286 
1287  pfClusters_->push_back(curpfclusters[ic]);
1288  }
1289 }
1290 
1291 
1292 
1293 void
1295  reco::PFCluster& clusterwodepthcor,
1296  bool depcor,
1297  int posCalcNCrystal) {
1298 
1299  if( posCalcNCrystal_ != -1 &&
1300  posCalcNCrystal_ != 5 &&
1301  posCalcNCrystal_ != 9 ) {
1302  throw "PFCluster::calculatePosition : posCalcNCrystal_ must be -1, 5, or 9.";
1303  }
1304 
1305 
1306  if(!posCalcNCrystal) posCalcNCrystal = posCalcNCrystal_;
1307 
1308  cluster.position_.SetXYZ(0,0,0);
1309 
1310  cluster.energy_ = 0;
1311 
1312  double normalize = 0;
1313 
1314  // calculate total energy, average layer, and look for seed ---------- //
1315 
1316 
1317  // double layer = 0;
1318  map <PFLayer::Layer, double> layers;
1319 
1320  unsigned seedIndex = 0;
1321  bool seedIndexFound = false;
1322 
1323  //Colin: the following can be simplified!
1324 
1325  // loop on rechit fractions
1326  for (unsigned ic=0; ic<cluster.rechits_.size(); ic++ ) {
1327 
1328  unsigned rhi = cluster.rechits_[ic].recHitRef().index();
1329  // const reco::PFRecHit& rh = rechit( rhi, rechits );
1330 
1331  const reco::PFRecHit& rh = *(cluster.rechits_[ic].recHitRef());
1332  double fraction = cluster.rechits_[ic].fraction();
1333 
1334  // Find the seed of this sub-cluster (excluding other seeds found in the topological
1335  // cluster, the energy fraction of which were set to 0 fpr the position determination.
1336  if( isSeed(rhi) && fraction > 1e-9 ) {
1337  seedIndex = rhi;
1338  seedIndexFound = true;
1339  }
1340 
1341  double recHitEnergy = rh.energy() * fraction;
1342 
1343  // is nan ?
1344  if( recHitEnergy!=recHitEnergy ) {
1345  ostringstream ostr;
1346  edm::LogError("PFClusterAlgo")<<"rechit "<<rh.detId()<<" has a NaN energy... The input of the particle flow clustering seems to be corrupted.";
1347  }
1348 
1349  cluster.energy_ += recHitEnergy;
1350 
1351  // sum energy in each layer
1352  PFLayer::Layer layer = rh.layer();
1353 
1354  map <PFLayer::Layer, double>:: iterator it = layers.find(layer);
1355 
1356  if (it != layers.end()) {
1357  it->second += recHitEnergy;
1358  } else {
1359 
1360  layers.insert(make_pair(layer, recHitEnergy));
1361 
1362  }
1363 
1364  }
1365 
1366  assert(seedIndexFound);
1367 
1368  // loop over pairs to find layer with max energy
1369  double Emax = 0.;
1370  PFLayer::Layer layer = PFLayer::NONE;
1371  for (map<PFLayer::Layer, double>::iterator it = layers.begin();
1372  it != layers.end(); ++it) {
1373  double e = it->second;
1374  if(e > Emax){
1375  Emax = e;
1376  layer = it->first;
1377  }
1378  }
1379 
1380 
1381  //setlayer here
1382  cluster.setLayer( layer ); // take layer with max energy
1383 
1384  // layer /= cluster.energy_;
1385  // cluster.layer_ = lrintf(layer); // nearest integer
1386 
1387 
1388 
1389  double p1 = posCalcP1_;
1390  if( p1 < 0 ) {
1391  // automatic (and hopefully best !) determination of the parameter
1392  // for position determination.
1393 
1394  // Remove the ad-hoc determination of p1, and set it to the
1395  // seed threshold.
1396  switch(cluster.layer() ) {
1397  case PFLayer::ECAL_BARREL:
1398  case PFLayer::HCAL_BARREL1:
1399  case PFLayer::HCAL_BARREL2:
1400  // case PFLayer::HCAL_HO:
1401  p1 = threshBarrel_;
1402  break;
1403  case PFLayer::ECAL_ENDCAP:
1404  case PFLayer::HCAL_ENDCAP:
1405  case PFLayer::HF_EM:
1406  case PFLayer::HF_HAD:
1407  case PFLayer::PS1:
1408  case PFLayer::PS2:
1409  p1 = threshEndcap_;
1410  break;
1411 
1412  /*
1413  switch(cluster.layer() ) {
1414  case PFLayer::ECAL_BARREL:
1415  p1 = 0.004 + 0.022*cluster.energy_; // 27 feb 2006
1416  break;
1417  case PFLayer::ECAL_ENDCAP:
1418  p1 = 0.014 + 0.009*cluster.energy_; // 27 feb 2006
1419  break;
1420  case PFLayer::HCAL_BARREL1:
1421  case PFLayer::HCAL_BARREL2:
1422  case PFLayer::HCAL_ENDCAP:
1423  case PFLayer::HCAL_HF:
1424  p1 = 5.41215e-01 * log( cluster.energy_ / 1.29803e+01 );
1425  if(p1<0.01) p1 = 0.01;
1426  break;
1427  */
1428 
1429  default:
1430  cerr<<"Clusters weight_p1 -1 not yet allowed for layer "<<layer
1431  <<". Chose a better value in the opt file"<<endl;
1432  assert(0);
1433  break;
1434  }
1435  }
1436  else if( p1< 1e-9 ) { // will divide by p1 later on
1437  p1 = 1e-9;
1438  }
1439  // calculate uncorrected cluster position --------------------------------
1440 
1441  reco::PFCluster::REPPoint clusterpos; // uncorrected cluster pos
1442  math::XYZPoint clusterposxyz; // idem, xyz coord
1443  math::XYZPoint firstrechitposxyz; // pos of the rechit with highest E
1444 
1445  double maxe = -9999;
1446  double x = 0;
1447  double y = 0;
1448  double z = 0;
1449 
1450  for (unsigned ic=0; ic<cluster.rechits_.size(); ic++ ) {
1451 
1452  unsigned rhi = cluster.rechits_[ic].recHitRef().index();
1453 // const reco::PFRecHit& rh = rechit( rhi, rechits );
1454 
1455  const reco::PFRecHit& rh = *(cluster.rechits_[ic].recHitRef());
1456 
1457  if(rhi != seedIndex) { // not the seed
1458  if( posCalcNCrystal == 5 ) { // pos calculated from the 5 neighbours only
1459  if(!rh.isNeighbour4(seedIndex) ) {
1460  continue;
1461  }
1462  }
1463  if( posCalcNCrystal == 9 ) { // pos calculated from the 9 neighbours only
1464  if(!rh.isNeighbour8(seedIndex) ) {
1465  continue;
1466  }
1467  }
1468  }
1469  double fraction = cluster.rechits_[ic].fraction();
1470  double recHitEnergy = rh.energy() * fraction;
1471 
1472  double norm = fraction < 1E-9 ? 0. : max(0., log(recHitEnergy/p1 ));
1473 
1474  const math::XYZPoint& rechitposxyz = rh.position();
1475 
1476  if( recHitEnergy > maxe ) {
1477  firstrechitposxyz = rechitposxyz;
1478  maxe = recHitEnergy;
1479  }
1480 
1481  x += rechitposxyz.X() * norm;
1482  y += rechitposxyz.Y() * norm;
1483  z += rechitposxyz.Z() * norm;
1484 
1485  // clusterposxyz += rechitposxyz * norm;
1486  normalize += norm;
1487  }
1488 
1489  // normalize uncorrected position
1490  // assert(normalize);
1491  if( normalize < 1e-9 ) {
1492  // cerr<<"--------------------"<<endl;
1493  // cerr<<(*this)<<endl;
1494  cout << "Watch out : cluster too far from its seeding cell, set to 0,0,0" << endl;
1495  clusterposxyz.SetXYZ(0,0,0);
1496  clusterpos.SetCoordinates(0,0,0);
1497  return;
1498  }
1499  else {
1500  x /= normalize;
1501  y /= normalize;
1502  z /= normalize;
1503 
1504  clusterposxyz.SetCoordinates( x, y, z);
1505 
1506  clusterpos.SetCoordinates( clusterposxyz.Rho(), clusterposxyz.Eta(), clusterposxyz.Phi() );
1507 
1508  }
1509 
1510  cluster.posrep_ = clusterpos;
1511 
1512  cluster.position_ = clusterposxyz;
1513 
1514  clusterwodepthcor = cluster;
1515 
1516 
1517  // correctio of the rechit position,
1518  // according to the depth, only for ECAL
1519 
1520 
1521  if( depcor && // correction requested and ECAL
1522  ( cluster.layer() == PFLayer::ECAL_BARREL ||
1523  cluster.layer() == PFLayer::ECAL_ENDCAP ) ) {
1524 
1525 
1526  double corra = reco::PFCluster::depthCorA_;
1527  double corrb = reco::PFCluster::depthCorB_;
1528  if( abs(clusterpos.Eta() ) < 2.6 &&
1529  abs(clusterpos.Eta() ) > 1.65 ) {
1530  // if crystals under preshower, correction is not the same
1531  // (shower depth smaller)
1534  }
1535 
1536  double depth = 0;
1537 
1538  switch( reco::PFCluster::depthCorMode_ ) {
1539  case 1: // for e/gamma
1540  depth = corra * ( corrb + log(cluster.energy_) );
1541  break;
1542  case 2: // for hadrons
1543  depth = corra;
1544  break;
1545  default:
1546  cerr<<"PFClusterAlgo::calculateClusterPosition : unknown function for depth correction! "<<endl;
1547  assert(0);
1548  }
1549 
1550 
1551  // calculate depth vector:
1552  // its mag is depth
1553  // its direction is the cluster direction (uncorrected)
1554 
1555 // double xdepthv = clusterposxyz.X();
1556 // double ydepthv = clusterposxyz.Y();
1557 // double zdepthv = clusterposxyz.Z();
1558 // double mag = sqrt( xdepthv*xdepthv +
1559 // ydepthv*ydepthv +
1560 // zdepthv*zdepthv );
1561 
1562 
1563 // math::XYZPoint depthv(clusterposxyz);
1564 // depthv.SetMag(depth);
1565 
1566 
1567  math::XYZVector depthv( clusterposxyz.X(),
1568  clusterposxyz.Y(),
1569  clusterposxyz.Z() );
1570  depthv /= sqrt(depthv.Mag2() );
1571  depthv *= depth;
1572 
1573 
1574  // now calculate corrected cluster position:
1575  math::XYZPoint clusterposxyzcor;
1576 
1577  maxe = -9999;
1578  x = 0;
1579  y = 0;
1580  z = 0;
1581  cluster.posrep_.SetXYZ(0,0,0);
1582  normalize = 0;
1583  for (unsigned ic=0; ic<cluster.rechits_.size(); ic++ ) {
1584 
1585  unsigned rhi = cluster.rechits_[ic].recHitRef().index();
1586 // const reco::PFRecHit& rh = rechit( rhi, rechits );
1587 
1588  const reco::PFRecHit& rh = *(cluster.rechits_[ic].recHitRef());
1589 
1590  if(rhi != seedIndex) {
1591  if( posCalcNCrystal == 5 ) {
1592  if(!rh.isNeighbour4(seedIndex) ) {
1593  continue;
1594  }
1595  }
1596  if( posCalcNCrystal == 9 ) {
1597  if(!rh.isNeighbour8(seedIndex) ) {
1598  continue;
1599  }
1600  }
1601  }
1602 
1603  double fraction = cluster.rechits_[ic].fraction();
1604  double recHitEnergy = rh.energy() * fraction;
1605 
1606  const math::XYZPoint& rechitposxyz = rh.position();
1607 
1608  // rechit axis not correct !
1609  math::XYZVector rechitaxis = rh.getAxisXYZ();
1610  // rechitaxis -= math::XYZVector( rechitposxyz.X(), rechitposxyz.Y(), rechitposxyz.Z() );
1611 
1612  math::XYZVector rechitaxisu( rechitaxis );
1613  rechitaxisu /= sqrt( rechitaxis.Mag2() );
1614 
1615  math::XYZVector displacement( rechitaxisu );
1616  // displacement /= sqrt( displacement.Mag2() );
1617  displacement *= rechitaxisu.Dot( depthv );
1618 
1619  math::XYZPoint rechitposxyzcor( rechitposxyz );
1620  rechitposxyzcor += displacement;
1621 
1622  if( recHitEnergy > maxe ) {
1623  firstrechitposxyz = rechitposxyzcor;
1624  maxe = recHitEnergy;
1625  }
1626 
1627  double norm = fraction < 1E-9 ? 0. : max(0., log(recHitEnergy/p1 ));
1628 
1629  x += rechitposxyzcor.X() * norm;
1630  y += rechitposxyzcor.Y() * norm;
1631  z += rechitposxyzcor.Z() * norm;
1632 
1633  // clusterposxyzcor += rechitposxyzcor * norm;
1634  normalize += norm;
1635  }
1636 
1637  // normalize
1638  if(normalize < 1e-9) {
1639  cerr<<"--------------------"<<endl;
1640  cerr<< cluster <<endl;
1641  assert(0);
1642  }
1643  else {
1644  x /= normalize;
1645  y /= normalize;
1646  z /= normalize;
1647 
1648 
1649  clusterposxyzcor.SetCoordinates(x,y,z);
1650  cluster.posrep_.SetCoordinates( clusterposxyzcor.Rho(),
1651  clusterposxyzcor.Eta(),
1652  clusterposxyzcor.Phi() );
1653  cluster.position_ = clusterposxyzcor;
1654  clusterposxyz = clusterposxyzcor;
1655  }
1656 
1657  }
1658 }
1659 
1660 
1661 
1662 const reco::PFRecHit&
1665 
1666  if(i >= rechits.size() ) { // i >= 0, since i is unsigned
1667  string err = "PFClusterAlgo::rechit : out of range";
1668  throw std::out_of_range(err);
1669  }
1670 
1671  return rechits[i];
1672 }
1673 
1674 
1675 
1676 bool PFClusterAlgo::masked(unsigned rhi) const {
1677 
1678  if(rhi>=mask_.size() ) { // rhi >= 0, since rhi is unsigned
1679  string err = "PFClusterAlgo::masked : out of range";
1680  throw std::out_of_range(err);
1681  }
1682 
1683  return mask_[rhi];
1684 }
1685 
1686 
1687 unsigned PFClusterAlgo::color(unsigned rhi) const {
1688 
1689  if(rhi>=color_.size() ) { // rhi >= 0, since rhi is unsigned
1690  string err = "PFClusterAlgo::color : out of range";
1691  throw std::out_of_range(err);
1692  }
1693 
1694  return color_[rhi];
1695 }
1696 
1697 
1698 
1699 bool PFClusterAlgo::isSeed(unsigned rhi) const {
1700 
1701  if(rhi>=seedStates_.size() ) { // rhi >= 0, since rhi is unsigned
1702  string err = "PFClusterAlgo::isSeed : out of range";
1703  throw std::out_of_range(err);
1704  }
1705 
1706  return seedStates_[rhi]>0 ? true : false;
1707 }
1708 
1709 
1710 void PFClusterAlgo::paint(unsigned rhi, unsigned color ) {
1711 
1712  if(rhi>=color_.size() ) { // rhi >= 0, since rhi is unsigned
1713  string err = "PFClusterAlgo::color : out of range";
1714  throw std::out_of_range(err);
1715  }
1716 
1717  color_[rhi] = color;
1718 }
1719 
1720 
1723  unsigned rhi ) {
1724 
1725  if( rechitsHandle_.isValid() ) {
1726  return reco::PFRecHitRef( rechitsHandle_, rhi );
1727  }
1728  else {
1729  return reco::PFRecHitRef( &rechits, rhi );
1730  }
1731 }
1732 
1733 
1734 ostream& operator<<(ostream& out,const PFClusterAlgo& algo) {
1735  if(!out) return out;
1736  out<<"PFClusterAlgo parameters : "<<endl;
1737  out<<"-----------------------------------------------------"<<endl;
1738  out<<"threshBarrel : "<<algo.threshBarrel_ <<endl;
1739  out<<"threshSeedBarrel : "<<algo.threshSeedBarrel_ <<endl;
1740  out<<"threshPtBarrel : "<<algo.threshPtBarrel_ <<endl;
1741  out<<"threshPtSeedBarrel : "<<algo.threshPtSeedBarrel_ <<endl;
1742  out<<"threshCleanBarrel : "<<algo.threshCleanBarrel_ <<endl;
1743  out<<"minS4S1Barrel : "<<algo.minS4S1Barrel_[0]<<" x log10(E) + "<<algo.minS4S1Barrel_[1]<<endl;
1744  out<<"threshEndcap : "<<algo.threshEndcap_ <<endl;
1745  out<<"threshSeedEndcap : "<<algo.threshSeedEndcap_ <<endl;
1746  out<<"threshPtEndcap : "<<algo.threshPtEndcap_ <<endl;
1747  out<<"threshPtSeedEndcap : "<<algo.threshPtSeedEndcap_ <<endl;
1748  out<<"threshEndcap : "<<algo.threshEndcap_ <<endl;
1749  out<<"threshCleanEndcap : "<<algo.threshCleanEndcap_ <<endl;
1750  out<<"minS4S1Endcap : "<<algo.minS4S1Endcap_[0]<<" x log10(E) + "<<algo.minS4S1Endcap_[1]<<endl;
1751  out<<"nNeighbours : "<<algo.nNeighbours_ <<endl;
1752  out<<"posCalcNCrystal : "<<algo.posCalcNCrystal_ <<endl;
1753  out<<"posCalcP1 : "<<algo.posCalcP1_ <<endl;
1754  out<<"showerSigma : "<<algo.showerSigma_ <<endl;
1755  out<<"useCornerCells : "<<algo.useCornerCells_ <<endl;
1756 
1757  out<<endl;
1758  out<<algo.pfClusters_->size()<<" clusters:"<<endl;
1759 
1760  for(unsigned i=0; i<algo.pfClusters_->size(); i++) {
1761  out<<(*algo.pfClusters_)[i]<<endl;
1762 
1763  if(!out) return out;
1764  }
1765 
1766  return out;
1767 }
1768 
1769 
1770 //compute the unsigned distance to the closest phi-crack in the barrel
1771 std::pair<double,double>
1773 
1774  static double pi= M_PI;// 3.14159265358979323846;
1775 
1776  //Location of the 18 phi-cracks
1777  static std::vector<double> cPhi;
1778  if(cPhi.size()==0)
1779  {
1780  cPhi.resize(18,0);
1781  cPhi[0]=2.97025;
1782  for(unsigned i=1;i<=17;++i) cPhi[i]=cPhi[0]-2*i*pi/18;
1783  }
1784 
1785  //Shift of this location if eta<0
1786  static double delta_cPhi=0.00638;
1787 
1788  double defi; //the result
1789 
1790  //the location is shifted
1791  if(eta<0) phi +=delta_cPhi;
1792 
1793  if (phi>=-pi && phi<=pi){
1794 
1795  //the problem of the extrema
1796  if (phi<cPhi[17] || phi>=cPhi[0]){
1797  if (phi<0) phi+= 2*pi;
1798  defi = std::min(fabs(phi -cPhi[0]),fabs(phi-cPhi[17]-2*pi));
1799  }
1800 
1801  //between these extrema...
1802  else{
1803  bool OK = false;
1804  unsigned i=16;
1805  while(!OK){
1806  if (phi<cPhi[i]){
1807  defi=std::min(fabs(phi-cPhi[i+1]),fabs(phi-cPhi[i]));
1808  OK=true;
1809  }
1810  else i-=1;
1811  }
1812  }
1813  }
1814  else{
1815  defi=0.; //if there is a problem, we assum that we are in a crack
1816  std::cout<<"Problem in dminphi"<<std::endl;
1817  }
1818  //if(eta<0) defi=-defi; //because of the disymetry
1819 
1820  static std::vector<double> cEta;
1821  if ( cEta.size() == 0 ) {
1822  cEta.push_back(0.0);
1823  cEta.push_back(4.44747e-01) ; cEta.push_back(-4.44747e-01) ;
1824  cEta.push_back(7.92824e-01) ; cEta.push_back(-7.92824e-01) ;
1825  cEta.push_back(1.14090e+00) ; cEta.push_back(-1.14090e+00) ;
1826  cEta.push_back(1.47464e+00) ; cEta.push_back(-1.47464e+00) ;
1827  }
1828  double deta = 999.; // the other result
1829 
1830  for ( unsigned ieta=0; ieta<cEta.size(); ++ieta ) {
1831  deta = std::min(deta,fabs(eta-cEta[ieta]));
1832  }
1833 
1834  defi /= 0.0175;
1835  deta /= 0.0175;
1836  return std::pair<double,double>(defi,deta);
1837 
1838 }
PFLayer::Layer layer() const
cluster layer, see PFLayer.h in this directory
Definition: PFCluster.cc:81
dbl * delta
Definition: mlp_gen.cc:36
void cleanRBXAndHPD(const reco::PFRecHitCollection &rechits)
Clean HCAL readout box noise and HPD discharge.
void setLayer(PFLayer::Layer layer)
set layer
Definition: PFCluster.cc:74
int i
Definition: DBlmapReader.cc:9
math::XYZPoint position_
cluster centroid position
Definition: CaloCluster.h:207
std::multimap< double, unsigned >::iterator EH
int posCalcNCrystal_
number of crystals for position calculation
double threshEndcap_
endcap threshold
tuple nN
people filling error matrix uses the naive 1/sqrt(N) errors
double threshDoubleSpikeBarrel_
Barrel double-spike cleaning.
double energy_
cluster energy
Definition: CaloCluster.h:204
double pt2() const
rechit momentum transverse to the beam, squared.
Definition: PFRecHit.h:117
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:42
void doClustering(const reco::PFRecHitCollection &rechits)
perform clustering
std::vector< unsigned > color_
color, for all rechits
PFRecHitHandle rechitsHandle_
unsigned detId() const
rechit detId
Definition: PFRecHit.h:99
std::vector< reco::PFRecHitFraction > rechits_
vector of rechit fractions (transient)
Definition: PFCluster.h:144
ROOT::Math::PositionVector3D< ROOT::Math::CylindricalEta3D< Double32_t > > REPPoint
Definition: PFCluster.h:46
std::pair< double, double > dCrack(double phi, double eta)
distance to a crack in the ECAL barrel in eta and phi direction
bool isSeed(unsigned rhi) const
const reco::PFRecHit & rechit(unsigned i, const reco::PFRecHitCollection &rechits)
double threshDoubleSpikeEndcap_
Endcap double-spike cleaning.
double threshPtEndcap_
#define abs(x)
Definition: mlp_lapack.h:159
Fraction of a PFRecHit (rechits can be shared between several PFCluster&#39;s)
TH2F * hENeighbour
#define min(a, b)
Definition: mlp_lapack.h:161
std::vector< PFRecHit > PFRecHitCollection
collection of PFRecHit objects
Definition: PFRecHitFwd.h:9
std::multimap< double, unsigned, std::greater< double > > eRecHits_
indices to rechits, sorted by decreasing E (not E_T)
std::vector< double > minS4S1Barrel_
double threshPtSeedEndcap_
double threshPtSeedBarrel_
T eta() const
std::ostream & operator<<(std::ostream &out, const ALILine &li)
Definition: ALILine.cc:187
std::vector< SeedState > seedStates_
seed state, for all rechits
std::vector< std::vector< unsigned > > topoClusters_
sets of cells having one common side, and energy over threshold
std::auto_ptr< std::vector< reco::PFRecHit > > pfRecHitsCleaned_
particle flow rechits cleaned
std::vector< bool > usedInTopo_
used in topo cluster? for all rechits
double energyUp() const
For HF hits: rechit energy (and neighbour&#39;s) in the other HF layer.
Definition: PFRecHit.h:114
double double double z
static int position[TOTALCHAMBERS][3]
Definition: ReadPGInfo.cc:509
dictionary map
Definition: Association.py:205
double threshSeedBarrel_
barrel seed threshold
PFLayer::Layer layer() const
rechit layer
Definition: PFRecHit.h:102
Algorithm for particle flow clustering.
Definition: PFClusterAlgo.h:31
bool masked(unsigned rhi) const
std::vector< unsigned > seeds_
vector of indices for seeds.
void doClusteringWorker(const reco::PFRecHitCollection &rechits)
perform clustering
TH2F * hBNeighbour
int posCalcNCrystal() const
get number of crystals for position calculation (-1 all,5, or 9)
Particle flow rechit (rechit + geometry and topology information). See clustering algorithm in PFClus...
Definition: PFRecHit.h:31
const T & max(const T &a, const T &b)
const std::vector< unsigned > & neighbours8() const
Definition: PFRecHit.h:154
T sqrt(T t)
Definition: SSEVec.h:46
const math::XYZVector & getAxisXYZ() const
rechit cell axis x, y, z
Definition: PFRecHit.h:141
std::vector< bool > mask_
static double depthCorAp_
Definition: PFCluster.h:160
bool cleanRBXandHPDs_
option to clean HCAL RBX&#39;s and HPD&#39;s
int ieta() const
get the cell ieta
Definition: HcalDetId.h:38
void buildTopoClusters(const reco::PFRecHitCollection &rechits)
build topoclusters around seeds
edm::Ref< PFRecHitCollection > PFRecHitRef
persistent reference to PFRecHit objects
Definition: PFRecHitFwd.h:15
bool isValid() const
Definition: HandleBase.h:76
static double depthCorB_
Definition: PFCluster.h:157
std::vector< double > minS4S1Endcap_
static double depthCorBp_
Definition: PFCluster.h:163
void findSeeds(const reco::PFRecHitCollection &rechits)
look for seeds
PFClusterAlgo()
constructor
tuple out
Definition: dbtoconf.py:99
Layer
layer definition
Definition: PFLayer.h:31
static int depthCorMode_
Definition: PFCluster.h:151
double threshCleanBarrel_
Barrel cleaning threshold and S4/S1 smallest fractiom.
int iphi() const
get the cell iphi
Definition: HcalDetId.h:40
const math::XYZPoint & position() const
is seed ?
Definition: PFRecHit.h:135
bool debug_
debugging on/off
int nNeighbours_
number of neighbours
reco::PFRecHitRef createRecHitRef(const reco::PFRecHitCollection &rechits, unsigned rhi)
#define M_PI
Definition: BFit3D.cc:3
REPPoint posrep_
cluster position: rho, eta, phi (transient)
Definition: PFCluster.h:147
void buildTopoCluster(std::vector< unsigned > &cluster, unsigned rhi, const reco::PFRecHitCollection &rechits)
build a topocluster (recursive)
double minS6S2DoubleSpikeEndcap_
void write()
write histos
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
bool isNeighbour4(unsigned id) const
Definition: PFRecHit.cc:248
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:13
double showerSigma_
sigma of shower (cm)
void paint(unsigned rhi, unsigned color=1)
paint a rechit with a color.
double parameter(Parameter paramtype, PFLayer::Layer layer, unsigned iCoeff=0, int iring0=0) const
void addRecHitFraction(const reco::PFRecHitFraction &frac)
add a given fraction of the rechit
Definition: PFCluster.cc:40
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
double energy() const
rechit energy
Definition: PFRecHit.h:105
double p1[4]
Definition: TauolaWrapper.h:89
double threshBarrel_
barrel threshold
bool useCornerCells_
option to use cells with a common corner to build topo-clusters
static unsigned prodNum_
product number
bool isNeighbour8(unsigned id) const
Definition: PFRecHit.cc:257
void calculateClusterPosition(reco::PFCluster &cluster, reco::PFCluster &clusterwodepthcor, bool depcor=true, int posCalcNCrystal=0)
calculate position of a cluster
tuple cout
Definition: gather_cfg.py:121
double threshSeedEndcap_
endcap seed threshold
std::auto_ptr< std::vector< reco::PFCluster > > pfClusters_
all clusters
static double depthCorA_
Definition: PFCluster.h:154
LimitAlgo * algo
Definition: Combine.cc:60
double pi
Definition: DDAxes.h:10
double threshPtBarrel_
void buildPFClusters(const std::vector< unsigned > &cluster, const reco::PFRecHitCollection &rechits)
build PFClusters from a topocluster
unsigned color(unsigned rhi) const
const std::vector< unsigned > & neighbours4() const
Definition: PFRecHit.h:151
mathSSE::Vec4< T > v
double minS6S2DoubleSpikeBarrel_
double threshCleanEndcap_
Endcap cleaning threshold and S4/S1 smallest fractiom.
double posCalcP1_
parameter for position calculation
const REPPoint & positionREP() const
rechit cell centre rho, eta, phi. call calculatePositionREP before !
Definition: PFRecHit.cc:121
Definition: DDAxes.h:10