CMS 3D CMS Logo

SuperclusteringDNNInputs.cc
Go to the documentation of this file.
1 
2 // Author: Theo Cuisset - theo.cuisset@cern.ch
3 // Date: 11/2023
5 
6 #include <algorithm>
7 #include <numeric>
8 #include <cmath>
9 
10 #include <Math/Vector2D.h>
11 #include <Math/Vector3D.h>
12 #include <Math/Rotation3D.h>
13 #include <Math/VectorUtil.h>
14 
17 
18 namespace ticl {
19 
20  std::vector<float> SuperclusteringDNNInputV1::computeVector(Trackster const& ts_base, Trackster const& ts_toCluster) {
21  /* We use the barycenter for most of the variables below as that is what seems to have been used by Alessandro Tarabini,
22  but using PCA might be better.
23  (It would need retraining of the DNN)
24  */
25  return {{
26  std::abs(ts_toCluster.barycenter().Eta()) - std::abs(ts_base.barycenter().Eta()), //DeltaEtaBaryc
27  ts_toCluster.barycenter().Phi() - ts_base.barycenter().phi(), //DeltaPhiBaryc
28  ts_toCluster.raw_energy(), //multi_en
29  ts_toCluster.barycenter().Eta(), //multi_eta
30  (ts_toCluster.raw_energy() * std::sin(ts_toCluster.barycenter().Theta())), //multi_pt
31  ts_base.barycenter().Eta(), //seedEta
32  ts_base.barycenter().Phi(), //seedPhi
33  ts_base.raw_energy(), //seedEn
34  (ts_base.raw_energy() * std::sin(ts_toCluster.barycenter().Theta())), //seedPt
35  }};
36  }
37 
38  // Helper functions for angles. Adapted from ROOT (3D vectors -> 2D vectors)
39  template <class Vector1, class Vector2>
40  float CosTheta2D(const Vector1& v1, const Vector2& v2) {
41  float arg;
42  float v1_r2 = v1.X() * v1.X() + v1.Y() * v1.Y();
43  float v2_r2 = v2.X() * v2.X() + v2.Y() * v2.Y();
44  float ptot2 = v1_r2 * v2_r2;
45  if (ptot2 <= 0) {
46  arg = 0.0;
47  } else {
48  float pdot = v1.X() * v2.X() + v1.Y() * v2.Y();
49  using std::sqrt;
50  arg = pdot / sqrt(ptot2);
51  if (arg > 1.0)
52  arg = 1.0;
53  if (arg < -1.0)
54  arg = -1.0;
55  }
56  return arg;
57  }
58  template <class Vector1, class Vector2>
59  inline float Angle2D(const Vector1& v1, const Vector2& v2) {
60  return static_cast<float>(std::acos(CosTheta2D(v1, v2)));
61  }
62 
63  std::vector<float> SuperclusteringDNNInputV2::computeVector(Trackster const& ts_base, Trackster const& ts_toCluster) {
64  using ROOT::Math::XYVectorF;
66  using ROOT::Math::VectorUtil::Angle;
67  XYZVectorF const& pca_seed_cmsFrame(ts_base.eigenvectors(0));
68  XYZVectorF const& pca_cand_cmsFrame(ts_toCluster.eigenvectors(0));
69  XYZVectorF xs(pca_seed_cmsFrame.Cross(XYZVectorF(0, 0, 1)).Unit());
70  ROOT::Math::Rotation3D rot(xs, xs.Cross(pca_seed_cmsFrame).Unit(), pca_seed_cmsFrame);
71 
72  XYZVectorF pca_cand_seedFrame = rot(pca_cand_cmsFrame); // seed coordinates
73 
74  float explVar_denominator = std::accumulate(
75  std::begin(ts_toCluster.eigenvalues()), std::end(ts_toCluster.eigenvalues()), 0.f, std::plus<float>());
76  float explVarRatio = 0.;
77  if (explVar_denominator != 0.) {
78  explVarRatio = ts_toCluster.eigenvalues()[0] / explVar_denominator;
79  } else {
80  edm::LogWarning("HGCalTICLSuperclustering")
81  << "Sum of eigenvalues was zero for trackster. Could not compute explained variance ratio.";
82  }
83 
84  return {{
85  std::abs(ts_toCluster.barycenter().Eta()) - std::abs(ts_base.barycenter().Eta()), //DeltaEtaBaryc
86  ts_toCluster.barycenter().Phi() - ts_base.barycenter().phi(), //DeltaPhiBaryc
87  ts_toCluster.raw_energy(), //multi_en
88  ts_toCluster.barycenter().Eta(), //multi_eta
89  (ts_toCluster.raw_energy() * std::sin(ts_toCluster.barycenter().Theta())), //multi_pt
90  ts_base.barycenter().Eta(), //seedEta
91  ts_base.barycenter().Phi(), //seedPhi
92  ts_base.raw_energy(), //seedEn
93  (ts_base.raw_energy() * std::sin(ts_toCluster.barycenter().Theta())), //seedPt
94  static_cast<float>(Angle(pca_cand_cmsFrame, pca_seed_cmsFrame)), // theta : angle between seed and candidate
95  Angle2D(XYVectorF(pca_cand_seedFrame.x(), pca_cand_seedFrame.z()), XYVectorF(0, 1)), // theta_xz_seedFrame
96  Angle2D(XYVectorF(pca_cand_seedFrame.y(), pca_cand_seedFrame.z()), XYVectorF(0, 1)), // theta_yz_seedFrame
97  Angle2D(XYVectorF(pca_cand_cmsFrame.x(), pca_cand_cmsFrame.y()),
98  XYVectorF(pca_seed_cmsFrame.x(), pca_seed_cmsFrame.y())), // theta_xy_cmsFrame
99  Angle2D(XYVectorF(pca_cand_cmsFrame.y(), pca_cand_cmsFrame.z()),
100  XYVectorF(pca_seed_cmsFrame.y(), pca_seed_cmsFrame.z())), // theta_yz_cmsFrame
101  Angle2D(XYVectorF(pca_cand_cmsFrame.x(), pca_cand_cmsFrame.z()),
102  XYVectorF(pca_seed_cmsFrame.x(), pca_seed_cmsFrame.z())), // theta_xz_cmsFrame
103  ts_toCluster.eigenvalues()[0], // explVar
104  explVarRatio // explVarRatio
105  }};
106  }
107 
108  std::unique_ptr<AbstractSuperclusteringDNNInput> makeSuperclusteringDNNInputFromString(std::string dnnInputVersion) {
109  if (dnnInputVersion == "v1")
110  return std::make_unique<SuperclusteringDNNInputV1>();
111  else if (dnnInputVersion == "v2")
112  return std::make_unique<SuperclusteringDNNInputV2>();
113  assert(false);
114  }
115 
116 } // namespace ticl
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
const Vector & barycenter() const
Definition: Trackster.h:159
std::vector< float > computeVector(ticl::Trackster const &ts_base, ticl::Trackster const &ts_toCluster) override
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< float > > XYZVectorF
spatial vector with cartesian internal representation
Definition: RntStructs.h:14
assert(be >=bs)
A arg
Definition: Factorize.h:31
const std::array< Vector, 3 > & eigenvectors() const
Definition: Trackster.h:161
const float raw_energy() const
Definition: Trackster.h:154
T sqrt(T t)
Definition: SSEVec.h:23
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
std::unique_ptr< AbstractSuperclusteringDNNInput > makeSuperclusteringDNNInputFromString(std::string dnnVersion)
std::vector< float > computeVector(ticl::Trackster const &ts_base, ticl::Trackster const &ts_toCluster) override
Definition: Common.h:10
Log< level::Warning, false > LogWarning
float CosTheta2D(const Vector1 &v1, const Vector2 &v2)
const std::array< float, 3 > & eigenvalues() const
Definition: Trackster.h:160
float Angle2D(const Vector1 &v1, const Vector2 &v2)