CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
PFClusterWidthAlgo.cc
Go to the documentation of this file.
7 #include "TMath.h"
8 #include <algorithm>
9 using namespace std;
10 using namespace reco;
11 
12 PFClusterWidthAlgo::PFClusterWidthAlgo(const std::vector<const reco::PFCluster*>& pfclust) {
13  double numeratorEtaWidth = 0.;
14  double numeratorPhiWidth = 0.;
15  double sclusterE = 0.;
16  double posX = 0.;
17  double posY = 0.;
18  double posZ = 0.;
19  sigmaEtaEta_ = 0.;
20 
21  unsigned int nclust = pfclust.size();
22  if (nclust == 0) {
23  etaWidth_ = 0.;
24  phiWidth_ = 0.;
25  sigmaEtaEta_ = 0.;
26  } else {
27  //first loop, compute supercluster position at ecal face, and energy sum from rechit loop
28  //in order to be consistent with variance calculation
29  for (unsigned int icl = 0; icl < nclust; ++icl) {
30  const std::vector<reco::PFRecHitFraction>& PFRecHits = pfclust[icl]->recHitFractions();
31 
32  for (std::vector<reco::PFRecHitFraction>::const_iterator it = PFRecHits.begin(); it != PFRecHits.end(); ++it) {
33  const PFRecHitRef& RefPFRecHit = it->recHitRef();
34  //compute rechit energy taking into account fractions
35  double energyHit = RefPFRecHit->energy() * it->fraction();
36 
37  sclusterE += energyHit;
38  posX += energyHit * RefPFRecHit->position().x();
39  posY += energyHit * RefPFRecHit->position().y();
40  posZ += energyHit * RefPFRecHit->position().z();
41  }
42  } // end for ncluster
43 
44  double denominator = sclusterE;
45 
46  posX /= sclusterE;
47  posY /= sclusterE;
48  posZ /= sclusterE;
49 
50  math::XYZPoint pflowSCPos(posX, posY, posZ);
51 
52  double scEta = pflowSCPos.eta();
53  double scPhi = pflowSCPos.phi();
54 
55  double SeedClusEnergy = -1.;
56  unsigned int SeedDetID = 0;
57  double SeedEta = -1.;
58 
59  //second loop, compute variances
60  for (unsigned int icl = 0; icl < nclust; ++icl) {
61  const auto& PFRecHits = pfclust[icl]->recHitFractions();
62 
63  for (auto it = PFRecHits.begin(); it != PFRecHits.end(); ++it) {
64  const PFRecHitRef& RefPFRecHit = it->recHitRef();
65  //compute rechit energy taking into account fractions
66  double energyHit = RefPFRecHit->energy() * it->fraction();
67 
68  //only for the first cluster (from GSF) find the seed
69  if (icl == 0) {
70  if (energyHit > SeedClusEnergy) {
71  SeedClusEnergy = energyHit;
72  SeedEta = RefPFRecHit->position().eta();
73  SeedDetID = RefPFRecHit->detId();
74  }
75  }
76 
77  double dPhi = reco::deltaPhi(RefPFRecHit->positionREP().phi(), scPhi);
78  double dEta = RefPFRecHit->positionREP().eta() - scEta;
79  numeratorEtaWidth += energyHit * dEta * dEta;
80  numeratorPhiWidth += energyHit * dPhi * dPhi;
81  }
82  } // end for ncluster
83 
84  //for the first cluster (from GSF) computed sigmaEtaEta
85  const auto& PFRecHits = pfclust[0]->recHitFractions();
86  for (auto it = PFRecHits.begin(); it != PFRecHits.end(); ++it) {
87  const auto& RefPFRecHit = it->recHitRef();
88  if (!RefPFRecHit.isAvailable())
89  return;
90  double energyHit = RefPFRecHit->energy();
91  if (RefPFRecHit->detId() != SeedDetID) {
92  float diffEta = RefPFRecHit->positionREP().eta() - SeedEta;
93  sigmaEtaEta_ += (diffEta * diffEta) * (energyHit / SeedClusEnergy);
94  }
95  }
96  if (sigmaEtaEta_ == 0.)
97  sigmaEtaEta_ = 0.00000001;
98 
99  etaWidth_ = std::sqrt(numeratorEtaWidth / denominator);
100  phiWidth_ = std::sqrt(numeratorPhiWidth / denominator);
101 
102  } // endif ncluster > 0
103 }
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
list denominator
Definition: cuy.py:485
T sqrt(T t)
Definition: SSEVec.h:19
PFClusterWidthAlgo(const std::vector< const reco::PFCluster * > &pfclust)
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12