CMS 3D CMS Logo

HGCal3DClustering.cc
Go to the documentation of this file.
3 
4 namespace {
6  // initialize original index locations
7  std::vector<size_t> idx(v.size());
8  std::iota(std::begin(idx), std::end(idx), 0);
9 
10  // sort indices based on comparing values in v
11  std::sort(idx.begin(), idx.end(), [&v](size_t i1, size_t i2) { return (*v[i1]) > (*v[i2]); });
12 
13  return idx;
14  }
15 
16  float distReal2(const edm::Ptr<reco::BasicCluster> &a, const std::array<double, 3> &to) {
17  return (a->x() - to[0]) * (a->x() - to[0]) + (a->y() - to[1]) * (a->y() - to[1]);
18  }
19 } // namespace
20 
22  es = sorted_indices(thecls);
23  unsigned int es_size = es.size();
24  for (unsigned int i = 0; i < es_size; ++i) {
25  int layer = rhtools_.getLayerWithOffset(thecls[es[i]]->hitsAndFractions()[0].first);
26  layer += int(thecls[es[i]]->z() > 0) * (maxlayer + 1);
27  float x = thecls[es[i]]->x();
28  float y = thecls[es[i]]->y();
29  float z = thecls[es[i]]->z();
30  points[layer].emplace_back(ClusterRef(i, z), x, y);
31  if (zees[layer] == 0.) {
32  // At least one cluster for layer at z
33  zees[layer] = z;
34  }
35  if (points[layer].empty()) {
36  minpos[layer][0] = x;
37  minpos[layer][1] = y;
38  maxpos[layer][0] = x;
39  maxpos[layer][1] = y;
40  } else {
41  minpos[layer][0] = std::min(x, minpos[layer][0]);
42  minpos[layer][1] = std::min(y, minpos[layer][1]);
43  maxpos[layer][0] = std::max(x, maxpos[layer][0]);
44  maxpos[layer][1] = std::max(y, maxpos[layer][1]);
45  }
46  }
47 }
48 std::vector<reco::HGCalMultiCluster> HGCal3DClustering::makeClusters(
50  reset();
51  organizeByLayer(thecls);
52  std::vector<reco::HGCalMultiCluster> thePreClusters;
53 
54  std::vector<KDTree> hit_kdtree(2 * (maxlayer + 1));
55  for (unsigned int i = 0; i <= 2 * maxlayer + 1; ++i) {
56  KDTreeBox bounds(minpos[i][0], maxpos[i][0], minpos[i][1], maxpos[i][1]);
57  hit_kdtree[i].build(points[i], bounds);
58  }
59  std::vector<int> vused(es.size(), 0);
60  unsigned int used = 0;
61 
62  unsigned int es_size = es.size();
63  for (unsigned int i = 0; i < es_size; ++i) {
64  if (vused[i] == 0) {
66  temp.push_back(thecls[es[i]]);
67  vused[i] = (thecls[es[i]]->z() > 0) ? 1 : -1;
68  ++used;
69  // Starting from cluster es[i] at from[0] - from[1] - from[2]
70  std::array<double, 3> from{{thecls[es[i]]->x(), thecls[es[i]]->y(), thecls[es[i]]->z()}};
71  unsigned int firstlayer = int(thecls[es[i]]->z() > 0) * (maxlayer + 1);
72  unsigned int lastlayer = firstlayer + maxlayer + 1;
73  for (unsigned int j = firstlayer; j < lastlayer; ++j) {
74  if (zees[j] == 0.) {
75  // layer j not yet ever reached?
76  continue;
77  }
78  std::array<double, 3> to{{0., 0., zees[j]}};
79  layerIntersection(to, from);
80  unsigned int layer =
81  j > maxlayer ? (j - (maxlayer + 1)) : j; //maps back from index used for KD trees to actual layer
82  float radius = radii[2];
83  if (layer <= rhtools_.lastLayerEE())
84  radius = radii[0];
85  else if (layer < rhtools_.firstLayerBH())
86  radius = radii[1];
87  float radius2 = radius * radius;
88  KDTreeBox search_box(
89  float(to[0]) - radius, float(to[0]) + radius, float(to[1]) - radius, float(to[1]) + radius);
90  std::vector<ClusterRef> found;
91  // at layer j in box float(to[0])+/-radius - float(to[1])+/-radius
92  hit_kdtree[j].search(search_box, found);
93  // found found.size() clusters within box
94  for (unsigned int k = 0; k < found.size(); k++) {
95  if (vused[found[k].ind] == 0 && distReal2(thecls[es[found[k].ind]], to) < radius2) {
96  temp.push_back(thecls[es[found[k].ind]]);
97  vused[found[k].ind] = vused[i];
98  ++used;
99  }
100  }
101  }
102  if (temp.size() > minClusters) {
103  math::XYZPoint position = clusterTools->getMultiClusterPosition(temp);
104  if (std::abs(position.z()) <= 0.)
105  continue;
106  // only store multiclusters that pass the energy threshold in getMultiClusterPosition
107  // giving them a position inside the HGCal
108  thePreClusters.push_back(temp);
109  auto &back = thePreClusters.back();
110  back.setPosition(position);
111  back.setEnergy(clusterTools->getMultiClusterEnergy(back));
112  }
113  }
114  }
115 
116  return thePreClusters;
117 }
118 
119 void HGCal3DClustering::layerIntersection(std::array<double, 3> &to, const std::array<double, 3> &from) const {
120  if (from[2] != 0) {
121  to[0] = from[0] / from[2] * to[2];
122  to[1] = from[1] / from[2] * to[2];
123  } else {
124  to[0] = 0;
125  to[1] = 0;
126  }
127 }
std::vector< std::vector< KDNode > > points
std::vector< double > radii
unsigned int firstLayerBH() const
Definition: RecHitTools.h:77
void organizeByLayer(const reco::HGCalMultiCluster::ClusterCollection &)
constexpr std::array< uint8_t, layerIndexSize > layer
std::vector< float > zees
std::vector< size_t > sorted_indices(const std::vector< T > &v)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::vector< std::array< float, 2 > > maxpos
std::vector< std::array< float, 2 > > minpos
void layerIntersection(std::array< double, 3 > &to, const std::array< double, 3 > &from) const
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
std::unique_ptr< hgcal::ClusterTools > clusterTools
hgcal::RecHitTools rhtools_
unsigned int maxlayer
double a
Definition: hdecay.h:119
static int position[264][3]
Definition: ReadPGInfo.cc:289
std::vector< size_t > es
std::vector< reco::HGCalMultiCluster > makeClusters(const reco::HGCalMultiCluster::ClusterCollection &)
unsigned int lastLayerEE(bool nose=false) const
Definition: RecHitTools.h:75
unsigned int getLayerWithOffset(const DetId &) const
Definition: RecHitTools.cc:365