CMS 3D CMS Logo

ClusterShapeAlgo.cc
Go to the documentation of this file.
1 #include <iostream>
2 
10 
15 
16 #include "CLHEP/Geometry/Transform3D.h"
17 #include "CLHEP/Units/GlobalSystemOfUnits.h"
18 
19 ClusterShapeAlgo::ClusterShapeAlgo(const edm::ParameterSet& par) : parameterSet_(par) {}
20 
24  const CaloSubdetectorTopology* topology) {
25  Calculate_TopEnergy(passedCluster, hits);
26  Calculate_2ndEnergy(passedCluster, hits);
27  Create_Map(hits, topology);
37  Calculate_Covariances(passedCluster, hits, geometry);
40  Calculate_EnergyDepTopology(passedCluster, hits, geometry, true);
41  Calculate_lat(passedCluster);
42  Calculate_ComplexZernikeMoments(passedCluster);
43 
45  covEtaPhi_,
46  covPhiPhi_,
47  eMax_,
48  eMaxId_,
49  e2nd_,
50  e2ndId_,
51  e2x2_,
52  e3x2_,
53  e3x3_,
54  e4x4_,
55  e5x5_,
56  e2x5Right_,
57  e2x5Left_,
58  e2x5Top_,
60  e3x2Ratio_,
61  lat_,
62  etaLat_,
63  phiLat_,
64  A20_,
65  A42_,
68 }
69 
71  double eMax = 0;
72  DetId eMaxId(0);
73 
74  const std::vector<std::pair<DetId, float> >& clusterDetIds = passedCluster.hitsAndFractions();
75 
76  EcalRecHit testEcalRecHit;
77 
78  for (auto const& posCurrent : clusterDetIds) {
79  if ((posCurrent.first != DetId(0)) && (hits->find(posCurrent.first) != hits->end())) {
80  EcalRecHitCollection::const_iterator itt = hits->find(posCurrent.first);
81  testEcalRecHit = *itt;
82 
83  if (testEcalRecHit.energy() * posCurrent.second > eMax) {
84  eMax = testEcalRecHit.energy() * posCurrent.second;
85  eMaxId = testEcalRecHit.id();
86  }
87  }
88  }
89 
90  eMax_ = eMax;
91  eMaxId_ = eMaxId;
92 }
93 
95  double e2nd = 0;
96  DetId e2ndId(0);
97 
98  const std::vector<std::pair<DetId, float> >& clusterDetIds = passedCluster.hitsAndFractions();
99 
100  EcalRecHit testEcalRecHit;
101 
102  for (auto const& posCurrent : clusterDetIds) {
103  if ((posCurrent.first != DetId(0)) && (hits->find(posCurrent.first) != hits->end())) {
104  EcalRecHitCollection::const_iterator itt = hits->find(posCurrent.first);
105  testEcalRecHit = *itt;
106 
107  if (testEcalRecHit.energy() * posCurrent.second > e2nd && testEcalRecHit.id() != eMaxId_) {
108  e2nd = testEcalRecHit.energy() * posCurrent.second;
109  e2ndId = testEcalRecHit.id();
110  }
111  }
112  }
113 
114  e2nd_ = e2nd;
115  e2ndId_ = e2ndId;
116 }
117 
119  EcalRecHit tempEcalRecHit;
120  CaloNavigator<DetId> posCurrent = CaloNavigator<DetId>(eMaxId_, topology);
121 
122  for (int x = 0; x < 5; x++)
123  for (int y = 0; y < 5; y++) {
124  posCurrent.home();
125  posCurrent.offsetBy(-2 + x, -2 + y);
126 
127  if ((*posCurrent != DetId(0)) && (hits->find(*posCurrent) != hits->end())) {
128  EcalRecHitCollection::const_iterator itt = hits->find(*posCurrent);
129  tempEcalRecHit = *itt;
130  energyMap_[y][x] = std::make_pair(tempEcalRecHit.id(), tempEcalRecHit.energy());
131  } else
132  energyMap_[y][x] = std::make_pair(DetId(0), 0);
133  }
134 }
135 
137  double e2x2Max = 0;
138  double e2x2Test = 0;
139 
140  int deltaX = 0, deltaY = 0;
141 
142  for (int corner = 0; corner < 4; corner++) {
143  switch (corner) {
144  case 0:
145  deltaX = -1;
146  deltaY = -1;
147  break;
148  case 1:
149  deltaX = -1;
150  deltaY = 1;
151  break;
152  case 2:
153  deltaX = 1;
154  deltaY = -1;
155  break;
156  case 3:
157  deltaX = 1;
158  deltaY = 1;
159  break;
160  }
161 
162  e2x2Test = energyMap_[2][2].second;
163  e2x2Test += energyMap_[2 + deltaY][2].second;
164  e2x2Test += energyMap_[2][2 + deltaX].second;
165  e2x2Test += energyMap_[2 + deltaY][2 + deltaX].second;
166 
167  if (e2x2Test > e2x2Max) {
168  e2x2Max = e2x2Test;
169  e2x2_Diagonal_X_ = 2 + deltaX;
170  e2x2_Diagonal_Y_ = 2 + deltaY;
171  }
172  }
173 
174  e2x2_ = e2x2Max;
175 }
176 
178  double e3x2 = 0.0;
179  double e3x2Ratio = 0.0, e3x2RatioNumerator = 0.0, e3x2RatioDenominator = 0.0;
180 
181  int e2ndX = 2, e2ndY = 2;
182  int deltaY = 0, deltaX = 0;
183 
184  double nextEnergy = -999;
185  int nextEneryDirection = -1;
186 
187  for (int cardinalDirection = 0; cardinalDirection < 4; cardinalDirection++) {
188  switch (cardinalDirection) {
189  case 0:
190  deltaX = -1;
191  deltaY = 0;
192  break;
193  case 1:
194  deltaX = 1;
195  deltaY = 0;
196  break;
197  case 2:
198  deltaX = 0;
199  deltaY = -1;
200  break;
201  case 3:
202  deltaX = 0;
203  deltaY = 1;
204  break;
205  }
206 
207  if (energyMap_[2 + deltaY][2 + deltaX].second >= nextEnergy) {
208  nextEnergy = energyMap_[2 + deltaY][2 + deltaX].second;
209  nextEneryDirection = cardinalDirection;
210 
211  e2ndX = 2 + deltaX;
212  e2ndY = 2 + deltaY;
213  }
214  }
215 
216  switch (nextEneryDirection) {
217  case 0:;
218  case 1:
219  deltaX = 0;
220  deltaY = 1;
221  break;
222  case 2:;
223  case 3:
224  deltaX = 1;
225  deltaY = 0;
226  break;
227  }
228 
229  for (int sign = -1; sign <= 1; sign++)
230  e3x2 += (energyMap_[2 + deltaY * sign][2 + deltaX * sign].second +
231  energyMap_[e2ndY + deltaY * sign][e2ndX + deltaX * sign].second);
232 
233  e3x2RatioNumerator =
234  energyMap_[e2ndY + deltaY][e2ndX + deltaX].second + energyMap_[e2ndY - deltaY][e2ndX - deltaX].second;
235  e3x2RatioDenominator = 0.5 + energyMap_[2 + deltaY][2 + deltaX].second + energyMap_[2 - deltaY][2 - deltaX].second;
236  e3x2Ratio = e3x2RatioNumerator / e3x2RatioDenominator;
237 
238  e3x2_ = e3x2;
239  e3x2Ratio_ = e3x2Ratio;
240 }
241 
243  double e3x3 = 0;
244 
245  for (int i = 1; i <= 3; i++)
246  for (int j = 1; j <= 3; j++)
247  e3x3 += energyMap_[j][i].second;
248 
249  e3x3_ = e3x3;
250 }
251 
253  double e4x4 = 0;
254 
255  int startX = -1, startY = -1;
256 
257  switch (e2x2_Diagonal_X_) {
258  case 1:
259  startX = 0;
260  break;
261  case 3:
262  startX = 1;
263  break;
264  }
265 
266  switch (e2x2_Diagonal_Y_) {
267  case 1:
268  startY = 0;
269  break;
270  case 3:
271  startY = 1;
272  break;
273  }
274 
275  for (int i = startX; i <= startX + 3; i++)
276  for (int j = startY; j <= startY + 3; j++)
277  e4x4 += energyMap_[j][i].second;
278 
279  e4x4_ = e4x4;
280 }
281 
283  double e5x5 = 0;
284 
285  for (int i = 0; i <= 4; i++)
286  for (int j = 0; j <= 4; j++)
287  e5x5 += energyMap_[j][i].second;
288 
289  e5x5_ = e5x5;
290 }
291 
293  double e2x5R = 0.0;
294  for (int i = 0; i <= 4; i++) {
295  for (int j = 0; j <= 4; j++) {
296  if (j > 2) {
297  e2x5R += energyMap_[i][j].second;
298  }
299  }
300  }
301  e2x5Right_ = e2x5R;
302 }
303 
305  double e2x5L = 0.0;
306  for (int i = 0; i <= 4; i++) {
307  for (int j = 0; j <= 4; j++) {
308  if (j < 2) {
309  e2x5L += energyMap_[i][j].second;
310  }
311  }
312  }
313  e2x5Left_ = e2x5L;
314 }
315 
317  double e2x5B = 0.0;
318  for (int i = 0; i <= 4; i++) {
319  for (int j = 0; j <= 4; j++) {
320  if (i > 2) {
321  e2x5B += energyMap_[i][j].second;
322  }
323  }
324  }
325  e2x5Bottom_ = e2x5B;
326 }
327 
329  double e2x5T = 0.0;
330  for (int i = 0; i <= 4; i++) {
331  for (int j = 0; j <= 4; j++) {
332  if (i < 2) {
333  e2x5T += energyMap_[i][j].second;
334  }
335  }
336  }
337  e2x5Top_ = e2x5T;
338 }
339 
341  const EcalRecHitCollection* hits,
343  if (e5x5_ > 0.) {
344  double w0_ = parameterSet_.getParameter<double>("W0");
345 
346  // first find energy-weighted mean position - doing it when filling the energy map might save time
347  math::XYZVector meanPosition(0.0, 0.0, 0.0);
348  for (int i = 0; i < 5; ++i) {
349  for (int j = 0; j < 5; ++j) {
350  DetId id = energyMap_[i][j].first;
351  if (id != DetId(0)) {
352  GlobalPoint positionGP = geometry->getGeometry(id)->getPosition();
353  math::XYZVector position(positionGP.x(), positionGP.y(), positionGP.z());
354  meanPosition = meanPosition + energyMap_[i][j].second * position;
355  }
356  }
357  }
358 
359  meanPosition /= e5x5_;
360 
361  // now we can calculate the covariances
362  double numeratorEtaEta = 0;
363  double numeratorEtaPhi = 0;
364  double numeratorPhiPhi = 0;
365  double denominator = 0;
366 
367  for (int i = 0; i < 5; ++i) {
368  for (int j = 0; j < 5; ++j) {
369  DetId id = energyMap_[i][j].first;
370  if (id != DetId(0)) {
371  GlobalPoint position = geometry->getGeometry(id)->getPosition();
372 
373  double dPhi = position.phi() - meanPosition.phi();
374  if (dPhi > +Geom::pi()) {
375  dPhi = Geom::twoPi() - dPhi;
376  }
377  if (dPhi < -Geom::pi()) {
378  dPhi = Geom::twoPi() + dPhi;
379  }
380 
381  double dEta = position.eta() - meanPosition.eta();
382  double w = 0.;
383  if (energyMap_[i][j].second > 0.)
384  w = std::max(0.0, w0_ + log(energyMap_[i][j].second / e5x5_));
385 
386  denominator += w;
387  numeratorEtaEta += w * dEta * dEta;
388  numeratorEtaPhi += w * dEta * dPhi;
389  numeratorPhiPhi += w * dPhi * dPhi;
390  }
391  }
392  }
393 
394  covEtaEta_ = numeratorEtaEta / denominator;
395  covEtaPhi_ = numeratorEtaPhi / denominator;
396  covPhiPhi_ = numeratorPhiPhi / denominator;
397  } else {
398  // Warn the user if there was no energy in the cells and return zeroes.
399  // std::cout << "\ClusterShapeAlgo::Calculate_Covariances: no energy in supplied cells.\n";
400  covEtaEta_ = 0;
401  covEtaPhi_ = 0;
402  covPhiPhi_ = 0;
403  }
404 }
405 
407  const EcalRecHitCollection* hits,
408  const int EtaPhi,
410  if ((hits == nullptr) || (((*hits)[0]).id().subdetId() != EcalBarrel)) {
411  //std::cout << "No basket correction if no hits or for endacap!" << std::endl;
412  return;
413  }
414 
415  std::map<int, double> indexedBasketEnergy;
416  const std::vector<std::pair<DetId, float> >& clusterDetIds = passedCluster.hitsAndFractions();
417  const EcalBarrelGeometry* subDetGeometry = dynamic_cast<const EcalBarrelGeometry*>(geometry);
418 
419  for (auto const& posCurrent : clusterDetIds) {
420  int basketIndex = 999;
421 
422  if (EtaPhi == Eta) {
423  int unsignedIEta = abs(EBDetId(posCurrent.first).ieta());
424  std::vector<int> etaBasketSize = subDetGeometry->getEtaBaskets();
425 
426  for (unsigned int i = 0; i < etaBasketSize.size(); i++) {
427  unsignedIEta -= etaBasketSize[i];
428  if (unsignedIEta - 1 < 0) {
429  basketIndex = i;
430  break;
431  }
432  }
433  basketIndex = (basketIndex + 1) * (EBDetId(posCurrent.first).ieta() > 0 ? 1 : -1);
434 
435  } else if (EtaPhi == Phi) {
436  int halfNumBasketInPhi = (EBDetId::MAX_IPHI - EBDetId::MIN_IPHI + 1) / subDetGeometry->getBasketSizeInPhi() / 2;
437 
438  basketIndex = (EBDetId(posCurrent.first).iphi() - 1) / subDetGeometry->getBasketSizeInPhi() -
439  (EBDetId((clusterDetIds[0]).first).iphi() - 1) / subDetGeometry->getBasketSizeInPhi();
440 
441  if (basketIndex >= halfNumBasketInPhi)
442  basketIndex -= 2 * halfNumBasketInPhi;
443  else if (basketIndex < -1 * halfNumBasketInPhi)
444  basketIndex += 2 * halfNumBasketInPhi;
445 
446  } else
447  throw(std::runtime_error("\n\nOh No! Calculate_BarrelBasketEnergyFraction called on invalid index.\n\n"));
448 
449  indexedBasketEnergy[basketIndex] += (hits->find(posCurrent.first))->energy();
450  }
451 
452  std::vector<double> energyFraction;
453  for (std::map<int, double>::iterator posCurrent = indexedBasketEnergy.begin();
454  posCurrent != indexedBasketEnergy.end();
455  posCurrent++) {
456  energyFraction.push_back(indexedBasketEnergy[posCurrent->first] / passedCluster.energy());
457  }
458 
459  switch (EtaPhi) {
460  case Eta:
461  energyBasketFractionEta_ = energyFraction;
462  break;
463  case Phi:
464  energyBasketFractionPhi_ = energyFraction;
465  break;
466  }
467 }
468 
470  double r, redmoment = 0;
471  double phiRedmoment = 0;
472  double etaRedmoment = 0;
473  int n, n1, n2, tmp;
474  int clusterSize = energyDistribution_.size();
475  if (clusterSize < 3) {
476  etaLat_ = 0.0;
477  lat_ = 0.0;
478  return;
479  }
480 
481  n1 = 0;
482  n2 = 1;
483  if (energyDistribution_[1].deposited_energy > energyDistribution_[0].deposited_energy) {
484  tmp = n2;
485  n2 = n1;
486  n1 = tmp;
487  }
488  for (int i = 2; i < clusterSize; i++) {
489  n = i;
490  if (energyDistribution_[i].deposited_energy > energyDistribution_[n1].deposited_energy) {
491  tmp = n2;
492  n2 = n1;
493  n1 = i;
494  n = tmp;
495  } else {
496  if (energyDistribution_[i].deposited_energy > energyDistribution_[n2].deposited_energy) {
497  tmp = n2;
498  n2 = i;
499  n = tmp;
500  }
501  }
502 
503  r = energyDistribution_[n].r;
504  redmoment += r * r * energyDistribution_[n].deposited_energy;
505  double rphi = r * cos(energyDistribution_[n].phi);
506  phiRedmoment += rphi * rphi * energyDistribution_[n].deposited_energy;
507  double reta = r * sin(energyDistribution_[n].phi);
508  etaRedmoment += reta * reta * energyDistribution_[n].deposited_energy;
509  }
510  double e1 = energyDistribution_[n1].deposited_energy;
511  double e2 = energyDistribution_[n2].deposited_energy;
512 
513  lat_ = redmoment / (redmoment + 2.19 * 2.19 * (e1 + e2));
514  phiLat_ = phiRedmoment / (phiRedmoment + 2.19 * 2.19 * (e1 + e2));
515  etaLat_ = etaRedmoment / (etaRedmoment + 2.19 * 2.19 * (e1 + e2));
516 }
517 
519  // Calculate only the moments which go into the default cluster shape
520  // (moments with m>=2 are the only sensitive to azimuthal shape)
521  A20_ = absZernikeMoment(passedCluster, 2, 0);
522  A42_ = absZernikeMoment(passedCluster, 4, 2);
523 }
524 
525 double ClusterShapeAlgo::absZernikeMoment(const reco::BasicCluster& passedCluster, int n, int m, double R0) {
526  // 1. Check if n,m are correctly
527  if ((m > n) || ((n - m) % 2 != 0) || (n < 0) || (m < 0))
528  return -1;
529 
530  // 2. Check if n,R0 are within validity Range :
531  // n>20 or R0<2.19cm just makes no sense !
532  if ((n > 20) || (R0 <= 2.19))
533  return -1;
534  if (n <= 5)
535  return fast_AbsZernikeMoment(passedCluster, n, m, R0);
536  else
537  return calc_AbsZernikeMoment(passedCluster, n, m, R0);
538 }
539 
540 double ClusterShapeAlgo::f00(double r) { return 1; }
541 
542 double ClusterShapeAlgo::f11(double r) { return r; }
543 
544 double ClusterShapeAlgo::f20(double r) { return 2.0 * r * r - 1.0; }
545 
546 double ClusterShapeAlgo::f22(double r) { return r * r; }
547 
548 double ClusterShapeAlgo::f31(double r) { return 3.0 * r * r * r - 2.0 * r; }
549 
550 double ClusterShapeAlgo::f33(double r) { return r * r * r; }
551 
552 double ClusterShapeAlgo::f40(double r) { return 6.0 * r * r * r * r - 6.0 * r * r + 1.0; }
553 
554 double ClusterShapeAlgo::f42(double r) { return 4.0 * r * r * r * r - 3.0 * r * r; }
555 
556 double ClusterShapeAlgo::f44(double r) { return r * r * r * r; }
557 
558 double ClusterShapeAlgo::f51(double r) { return 10.0 * pow(r, 5) - 12.0 * pow(r, 3) + 3.0 * r; }
559 
560 double ClusterShapeAlgo::f53(double r) { return 5.0 * pow(r, 5) - 4.0 * pow(r, 3); }
561 
562 double ClusterShapeAlgo::f55(double r) { return pow(r, 5); }
563 
564 double ClusterShapeAlgo::fast_AbsZernikeMoment(const reco::BasicCluster& passedCluster, int n, int m, double R0) {
565  double r, ph, e, Re = 0, Im = 0, result;
566  double TotalEnergy = passedCluster.energy();
567  int index = (n / 2) * (n / 2) + (n / 2) + m;
568  int clusterSize = energyDistribution_.size();
569  if (clusterSize < 3)
570  return 0.0;
571 
572  for (int i = 0; i < clusterSize; i++) {
573  r = energyDistribution_[i].r / R0;
574  if (r < 1) {
575  fcn_.clear();
578  e = energyDistribution_[i].deposited_energy;
579  Re = Re + e / TotalEnergy * fcn_[index] * cos((double)m * ph);
580  Im = Im - e / TotalEnergy * fcn_[index] * sin((double)m * ph);
581  }
582  }
583  result = sqrt(Re * Re + Im * Im);
584 
585  return result;
586 }
587 
588 double ClusterShapeAlgo::calc_AbsZernikeMoment(const reco::BasicCluster& passedCluster, int n, int m, double R0) {
589  double r, ph, e, Re = 0, Im = 0, f_nm, result;
590  double TotalEnergy = passedCluster.energy();
591  int clusterSize = energyDistribution_.size();
592  if (clusterSize < 3)
593  return 0.0;
594 
595  for (int i = 0; i < clusterSize; i++) {
596  r = energyDistribution_[i].r / R0;
597  if (r < 1) {
599  e = energyDistribution_[i].deposited_energy;
600  f_nm = 0;
601  for (int s = 0; s <= (n - m) / 2; s++) {
602  if (s % 2 == 0) {
603  f_nm = f_nm + factorial(n - s) * pow(r, (double)(n - 2 * s)) /
604  (factorial(s) * factorial((n + m) / 2 - s) * factorial((n - m) / 2 - s));
605  } else {
606  f_nm = f_nm - factorial(n - s) * pow(r, (double)(n - 2 * s)) /
607  (factorial(s) * factorial((n + m) / 2 - s) * factorial((n - m) / 2 - s));
608  }
609  }
610  Re = Re + e / TotalEnergy * f_nm * cos((double)m * ph);
611  Im = Im - e / TotalEnergy * f_nm * sin((double)m * ph);
612  }
613  }
614  result = sqrt(Re * Re + Im * Im);
615 
616  return result;
617 }
618 
620  const EcalRecHitCollection* hits,
622  bool logW) {
623  // resets the energy distribution
624  energyDistribution_.clear();
625 
626  // init a map of the energy deposition centered on the
627  // cluster centroid. This is for momenta calculation only.
628  CLHEP::Hep3Vector clVect(passedCluster.position().x(), passedCluster.position().y(), passedCluster.position().z());
629  CLHEP::Hep3Vector clDir(clVect);
630  clDir *= 1.0 / clDir.mag();
631  // in the transverse plane, axis perpendicular to clusterDir
632  CLHEP::Hep3Vector theta_axis(clDir.y(), -clDir.x(), 0.0);
633  theta_axis *= 1.0 / theta_axis.mag();
634  CLHEP::Hep3Vector phi_axis = theta_axis.cross(clDir);
635 
636  const std::vector<std::pair<DetId, float> >& clusterDetIds = passedCluster.hitsAndFractions();
637 
639  EcalRecHit testEcalRecHit;
640  // loop over crystals
641  for (auto const& posCurrent : clusterDetIds) {
642  EcalRecHitCollection::const_iterator itt = hits->find(posCurrent.first);
643  testEcalRecHit = *itt;
644 
645  if ((posCurrent.first != DetId(0)) && (hits->find(posCurrent.first) != hits->end())) {
646  clEdep.deposited_energy = testEcalRecHit.energy();
647 
648  // if logarithmic weight is requested, apply cut on minimum energy of the recHit
649  if (logW) {
650  double w0_ = parameterSet_.getParameter<double>("W0");
651 
652  if (clEdep.deposited_energy == 0) {
653  LogDebug("ClusterShapeAlgo") << "Crystal has zero energy; skipping... ";
654  continue;
655  }
656  double weight = std::max(0.0, w0_ + log(fabs(clEdep.deposited_energy) / passedCluster.energy()));
657  if (weight == 0) {
658  LogDebug("ClusterShapeAlgo") << "Crystal has insufficient energy: E = " << clEdep.deposited_energy
659  << " GeV; skipping... ";
660  continue;
661  } else
662  LogDebug("ClusterShapeAlgo") << "===> got crystal. Energy = " << clEdep.deposited_energy << " GeV. ";
663  }
664  DetId id_ = posCurrent.first;
665  auto this_cell = geometry->getGeometry(id_);
666  const GlobalPoint& cellPos = this_cell->getPosition();
667  CLHEP::Hep3Vector gblPos(cellPos.x(), cellPos.y(), cellPos.z()); //surface position?
668  // Evaluate the distance from the cluster centroid
669  CLHEP::Hep3Vector diff = gblPos - clVect;
670  // Important: for the moment calculation, only the "lateral distance" is important
671  // "lateral distance" r_i = distance of the digi position from the axis Origin-Cluster Center
672  // ---> subtract the projection on clDir
673  CLHEP::Hep3Vector DigiVect = diff - diff.dot(clDir) * clDir;
674  clEdep.r = DigiVect.mag();
675  LogDebug("ClusterShapeAlgo") << "E = " << clEdep.deposited_energy << "\tdiff = " << diff.mag()
676  << "\tr = " << clEdep.r;
677  clEdep.phi = DigiVect.angle(theta_axis);
678  if (DigiVect.dot(phi_axis) < 0)
679  clEdep.phi = 2 * M_PI - clEdep.phi;
680  energyDistribution_.push_back(clEdep);
681  }
682  }
683 }
684 
686  fcn_.push_back(f00(rho));
687  fcn_.push_back(f11(rho));
688  fcn_.push_back(f20(rho));
689  fcn_.push_back(f31(rho));
690  fcn_.push_back(f22(rho));
691  fcn_.push_back(f33(rho));
692  fcn_.push_back(f40(rho));
693  fcn_.push_back(f51(rho));
694  fcn_.push_back(f42(rho));
695  fcn_.push_back(f53(rho));
696  fcn_.push_back(f44(rho));
697  fcn_.push_back(f55(rho));
698 }
699 
700 double ClusterShapeAlgo::factorial(int n) const {
701  double res = 1.0;
702  for (int i = 2; i <= n; i++)
703  res *= (double)i;
704  return res;
705 }
const math::XYZPoint & position() const
cluster centroid position
Definition: CaloCluster.h:153
int getBasketSizeInPhi() const
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
void home() const
move the navigator back to the starting point
Definition: CaloNavigator.h:96
static const int MIN_IPHI
Definition: EBDetId.h:135
const std::vector< std::pair< DetId, float > > & hitsAndFractions() const
Definition: CaloCluster.h:209
double f20(double r)
void Create_Map(const EcalRecHitCollection *hits, const CaloSubdetectorTopology *topology)
double fast_AbsZernikeMoment(const reco::BasicCluster &passedCluster, int n, int m, double R0)
std::vector< double > fcn_
std::vector< EcalClusterEnergyDeposition > energyDistribution_
T w() const
T z() const
Definition: PV3DBase.h:61
int iphi() const
get the crystal iphi
Definition: EBDetId.h:51
edm::ParameterSet parameterSet_
double f00(double r)
double f44(double r)
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
void Calculate_BarrelBasketEnergyFraction(const reco::BasicCluster &passedCluster, const EcalRecHitCollection *hits, const int EtaPhi, const CaloSubdetectorGeometry *geometry)
std::vector< EcalRecHit >::const_iterator const_iterator
double calc_AbsZernikeMoment(const reco::BasicCluster &passedCluster, int n, int m, double R0)
double factorial(int n) const
Definition: weight.py:1
constexpr int pow(int x)
Definition: conifer.h:24
std::pair< DetId, double > energyMap_[5][5]
double f31(double r)
double absZernikeMoment(const reco::BasicCluster &passedCluster, int n, int m, double R0=6.6)
double f55(double r)
Definition: Electron.h:6
int ieta() const
get the crystal ieta
Definition: EBDetId.h:49
U second(std::pair< T, U > const &p)
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
reco::ClusterShape Calculate(const reco::BasicCluster &passedCluster, const EcalRecHitCollection *hits, const CaloSubdetectorGeometry *geometry, const CaloSubdetectorTopology *topology)
void Calculate_Covariances(const reco::BasicCluster &passedCluster, const EcalRecHitCollection *hits, const CaloSubdetectorGeometry *geometry)
double f42(double r)
T sqrt(T t)
Definition: SSEVec.h:19
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
void Calculate_EnergyDepTopology(const reco::BasicCluster &passedCluster, const EcalRecHitCollection *hits, const CaloSubdetectorGeometry *geometry, bool logW=true)
double f40(double r)
double f33(double r)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void Calculate_TopEnergy(const reco::BasicCluster &passedCluster, const EcalRecHitCollection *hits)
#define M_PI
double energy() const
cluster energy
Definition: CaloCluster.h:148
void Calculate_Polynomials(double rho)
double f11(double r)
Definition: DetId.h:17
double f51(double r)
static const int MAX_IPHI
Definition: EBDetId.h:137
std::vector< double > energyBasketFractionPhi_
void Calculate_ComplexZernikeMoments(const reco::BasicCluster &passedCluster)
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
T offsetBy(int deltaX, int deltaY) const
Free movement of arbitray steps.
Definition: CaloNavigator.h:66
double f22(double r)
DetId id() const
get the id
Definition: EcalRecHit.h:78
void Calculate_lat(const reco::BasicCluster &passedCluster)
static int position[264][3]
Definition: ReadPGInfo.cc:289
std::vector< double > energyBasketFractionEta_
const std::vector< int > & getEtaBaskets() const
constexpr double pi()
Definition: Pi.h:31
float energy() const
Definition: EcalRecHit.h:69
tmp
align.sh
Definition: createJobs.py:716
constexpr double twoPi()
Definition: Pi.h:32
double f53(double r)
void Calculate_2ndEnergy(const reco::BasicCluster &passedCluster, const EcalRecHitCollection *hits)
#define LogDebug(id)