CMS 3D CMS Logo

TrackstersPCA.cc
Go to the documentation of this file.
4 #include "TrackstersPCA.h"
5 
6 #include <iostream>
7 #include <set>
8 
9 #include <Eigen/Core>
10 #include <Eigen/Dense>
11 
12 void ticl::assignPCAtoTracksters(std::vector<Trackster> &tracksters,
13  const std::vector<reco::CaloCluster> &layerClusters,
14  const edm::ValueMap<std::pair<float, float>> &layerClustersTime,
15  double z_limit_em,
16  bool energyWeight) {
17  LogDebug("TrackstersPCA_Eigen") << "------- Eigen -------" << std::endl;
18 
19  for (auto &trackster : tracksters) {
21  point << 0., 0., 0.;
22  Eigen::Vector3d barycenter;
23  barycenter << 0., 0., 0.;
24 
25  auto fillPoint = [&](const reco::CaloCluster &c, const float weight = 1.f) {
26  point[0] = weight * c.x();
27  point[1] = weight * c.y();
28  point[2] = weight * c.z();
29  };
30 
31  // Initialize this trackster with default, dummy values
32  trackster.setRawEnergy(0.f);
33  trackster.setRawEmEnergy(0.f);
34  trackster.setRawPt(0.f);
35  trackster.setRawEmPt(0.f);
36 
37  size_t N = trackster.vertices().size();
38  float weight = 1.f / N;
39  float weights2_sum = 0.f;
40  Eigen::Vector3d sigmas;
41  sigmas << 0., 0., 0.;
42  Eigen::Vector3d sigmasEigen;
43  sigmasEigen << 0., 0., 0.;
44  Eigen::Matrix3d covM = Eigen::Matrix3d::Zero();
45 
46  std::vector<float> times;
47  std::vector<float> timeErrors;
48  std::set<uint32_t> usedLC;
49 
50  for (size_t i = 0; i < N; ++i) {
51  auto fraction = 1.f / trackster.vertex_multiplicity(i);
52  trackster.addToRawEnergy(layerClusters[trackster.vertices(i)].energy() * fraction);
53  if (std::abs(layerClusters[trackster.vertices(i)].z()) <= z_limit_em)
54  trackster.addToRawEmEnergy(layerClusters[trackster.vertices(i)].energy() * fraction);
55 
56  // Compute the weighted barycenter.
57  if (energyWeight)
58  weight = layerClusters[trackster.vertices(i)].energy() * fraction;
59  fillPoint(layerClusters[trackster.vertices(i)], weight);
60  for (size_t j = 0; j < 3; ++j)
61  barycenter[j] += point[j];
62 
63  // Add timing from layerClusters not already used
64  if ((usedLC.insert(trackster.vertices(i))).second) {
65  float timeE = layerClustersTime.get(trackster.vertices(i)).second;
66  if (timeE > 0.f) {
67  times.push_back(layerClustersTime.get(trackster.vertices(i)).first);
68  timeErrors.push_back(1. / pow(timeE, 2));
69  }
70  }
71  }
72  if (energyWeight && trackster.raw_energy())
73  barycenter /= trackster.raw_energy();
74 
76  std::pair<float, float> timeTrackster = timeEstimator.fixSizeHighestDensity(times, timeErrors);
77 
78  // Compute the Covariance Matrix and the sum of the squared weights, used
79  // to compute the correct normalization.
80  // The barycenter has to be known.
81  for (size_t i = 0; i < N; ++i) {
82  fillPoint(layerClusters[trackster.vertices(i)]);
83  if (energyWeight && trackster.raw_energy())
84  weight =
85  (layerClusters[trackster.vertices(i)].energy() / trackster.vertex_multiplicity(i)) / trackster.raw_energy();
86  weights2_sum += weight * weight;
87  for (size_t x = 0; x < 3; ++x)
88  for (size_t y = 0; y <= x; ++y) {
89  covM(x, y) += weight * (point[x] - barycenter[x]) * (point[y] - barycenter[y]);
90  covM(y, x) = covM(x, y);
91  }
92  }
93  covM *= 1. / (1. - weights2_sum);
94 
95  // Perform the actual decomposition
96  Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d>::RealVectorType eigenvalues_fromEigen;
97  Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d>::EigenvectorsType eigenvectors_fromEigen;
98  Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigensolver(covM);
99  if (eigensolver.info() != Eigen::Success) {
100  eigenvalues_fromEigen = eigenvalues_fromEigen.Zero();
101  eigenvectors_fromEigen = eigenvectors_fromEigen.Zero();
102  } else {
103  eigenvalues_fromEigen = eigensolver.eigenvalues();
104  eigenvectors_fromEigen = eigensolver.eigenvectors();
105  }
106 
107  // Compute the spread in the both spaces.
108  for (size_t i = 0; i < N; ++i) {
109  fillPoint(layerClusters[trackster.vertices(i)]);
110  sigmas += weight * (point - barycenter).cwiseAbs2();
111  Eigen::Vector3d point_transformed = eigenvectors_fromEigen * (point - barycenter);
112  if (energyWeight && trackster.raw_energy())
113  weight =
114  (layerClusters[trackster.vertices(i)].energy() / trackster.vertex_multiplicity(i)) / trackster.raw_energy();
115  sigmasEigen += weight * (point_transformed.cwiseAbs2());
116  }
117  sigmas /= (1. - weights2_sum);
118  sigmasEigen /= (1. - weights2_sum);
119 
120  // Add trackster attributes
121  trackster.setBarycenter(ticl::Trackster::Vector(barycenter));
122  trackster.setTimeAndError(timeTrackster.first, timeTrackster.second);
123  trackster.fillPCAVariables(
124  eigenvalues_fromEigen, eigenvectors_fromEigen, sigmas, sigmasEigen, 3, ticl::Trackster::PCAOrdering::ascending);
125 
126  LogDebug("TrackstersPCA") << "Use energy weighting: " << energyWeight << std::endl;
127  LogDebug("TrackstersPCA") << "\nTrackster characteristics: " << std::endl;
128  LogDebug("TrackstersPCA") << "Size: " << N << std::endl;
129  LogDebug("TrackstersPCA") << "Energy: " << trackster.raw_energy() << std::endl;
130  LogDebug("TrackstersPCA") << "raw_pt: " << trackster.raw_pt() << std::endl;
131  LogDebug("TrackstersPCA") << "Means: " << barycenter[0] << ", " << barycenter[1] << ", " << barycenter[2]
132  << std::endl;
133  LogDebug("TrackstersPCA") << "Time: " << trackster.time() << " +/- " << trackster.timeError() << std::endl;
134  LogDebug("TrackstersPCA") << "EigenValues from Eigen/Tr(cov): " << eigenvalues_fromEigen[2] / covM.trace() << ", "
135  << eigenvalues_fromEigen[1] / covM.trace() << ", "
136  << eigenvalues_fromEigen[0] / covM.trace() << std::endl;
137  LogDebug("TrackstersPCA") << "EigenValues from Eigen: " << eigenvalues_fromEigen[2] << ", "
138  << eigenvalues_fromEigen[1] << ", " << eigenvalues_fromEigen[0] << std::endl;
139  LogDebug("TrackstersPCA") << "EigenVector 3 from Eigen: " << eigenvectors_fromEigen(0, 2) << ", "
140  << eigenvectors_fromEigen(1, 2) << ", " << eigenvectors_fromEigen(2, 2) << std::endl;
141  LogDebug("TrackstersPCA") << "EigenVector 2 from Eigen: " << eigenvectors_fromEigen(0, 1) << ", "
142  << eigenvectors_fromEigen(1, 1) << ", " << eigenvectors_fromEigen(2, 1) << std::endl;
143  LogDebug("TrackstersPCA") << "EigenVector 1 from Eigen: " << eigenvectors_fromEigen(0, 0) << ", "
144  << eigenvectors_fromEigen(1, 0) << ", " << eigenvectors_fromEigen(2, 0) << std::endl;
145  LogDebug("TrackstersPCA") << "Original sigmas: " << sigmas[0] << ", " << sigmas[1] << ", " << sigmas[2]
146  << std::endl;
147  LogDebug("TrackstersPCA") << "SigmasEigen in PCA space: " << sigmasEigen[2] << ", " << sigmasEigen[1] << ", "
148  << sigmasEigen[0] << std::endl;
149  LogDebug("TrackstersPCA") << "covM: \n" << covM << std::endl;
150  }
151 }
math::XYZVectorF Vector
Definition: Trackster.h:21
Definition: weight.py:1
U second(std::pair< T, U > const &p)
void assignPCAtoTracksters(std::vector< Trackster > &, const std::vector< reco::CaloCluster > &, const edm::ValueMap< std::pair< float, float >> &, double, bool energyWeight=true)
std::pair< float, float > fixSizeHighestDensity(std::vector< float > &time, std::vector< float > weight=std::vector< float >(), unsigned int minNhits=3, float deltaT=0.210, float timeWidthBy=0.5)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
#define N
Definition: blowfish.cc:9
float x
Eigen::Matrix3d Matrix3d
Definition: FitResult.h:18
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5
Eigen::Vector3d Vector3d
Definition: FitResult.h:14
#define LogDebug(id)