File indexing completed on 2024-04-06 12:25:53
0001 #include "RecoLocalCalo/HGCalRecAlgos/interface/HGCal3DClustering.h"
0002 #include "DataFormats/Math/interface/deltaR.h"
0003
0004 namespace {
0005 std::vector<size_t> sorted_indices(const reco::HGCalMultiCluster::ClusterCollection &v) {
0006
0007 std::vector<size_t> idx(v.size());
0008 std::iota(std::begin(idx), std::end(idx), 0);
0009
0010
0011 std::sort(idx.begin(), idx.end(), [&v](size_t i1, size_t i2) { return (*v[i1]) > (*v[i2]); });
0012
0013 return idx;
0014 }
0015
0016 float distReal2(const edm::Ptr<reco::BasicCluster> &a, const std::array<double, 3> &to) {
0017 return (a->x() - to[0]) * (a->x() - to[0]) + (a->y() - to[1]) * (a->y() - to[1]);
0018 }
0019 }
0020
0021 void HGCal3DClustering::organizeByLayer(const reco::HGCalMultiCluster::ClusterCollection &thecls) {
0022 es = sorted_indices(thecls);
0023 unsigned int es_size = es.size();
0024 for (unsigned int i = 0; i < es_size; ++i) {
0025 int layer = rhtools_.getLayerWithOffset(thecls[es[i]]->hitsAndFractions()[0].first);
0026 layer += int(thecls[es[i]]->z() > 0) * (maxlayer + 1);
0027 float x = thecls[es[i]]->x();
0028 float y = thecls[es[i]]->y();
0029 float z = thecls[es[i]]->z();
0030 points[layer].emplace_back(ClusterRef(i, z), x, y);
0031 if (zees[layer] == 0.) {
0032
0033 zees[layer] = z;
0034 }
0035 if (points[layer].empty()) {
0036 minpos[layer][0] = x;
0037 minpos[layer][1] = y;
0038 maxpos[layer][0] = x;
0039 maxpos[layer][1] = y;
0040 } else {
0041 minpos[layer][0] = std::min(x, minpos[layer][0]);
0042 minpos[layer][1] = std::min(y, minpos[layer][1]);
0043 maxpos[layer][0] = std::max(x, maxpos[layer][0]);
0044 maxpos[layer][1] = std::max(y, maxpos[layer][1]);
0045 }
0046 }
0047 }
0048 std::vector<reco::HGCalMultiCluster> HGCal3DClustering::makeClusters(
0049 const reco::HGCalMultiCluster::ClusterCollection &thecls) {
0050 reset();
0051 organizeByLayer(thecls);
0052 std::vector<reco::HGCalMultiCluster> thePreClusters;
0053
0054 std::vector<KDTree> hit_kdtree(2 * (maxlayer + 1));
0055 for (unsigned int i = 0; i <= 2 * maxlayer + 1; ++i) {
0056 KDTreeBox bounds(minpos[i][0], maxpos[i][0], minpos[i][1], maxpos[i][1]);
0057 hit_kdtree[i].build(points[i], bounds);
0058 }
0059 std::vector<int> vused(es.size(), 0);
0060
0061 unsigned int es_size = es.size();
0062 for (unsigned int i = 0; i < es_size; ++i) {
0063 if (vused[i] == 0) {
0064 reco::HGCalMultiCluster temp;
0065 temp.push_back(thecls[es[i]]);
0066 vused[i] = (thecls[es[i]]->z() > 0) ? 1 : -1;
0067
0068 std::array<double, 3> from{{thecls[es[i]]->x(), thecls[es[i]]->y(), thecls[es[i]]->z()}};
0069 unsigned int firstlayer = int(thecls[es[i]]->z() > 0) * (maxlayer + 1);
0070 unsigned int lastlayer = firstlayer + maxlayer + 1;
0071 for (unsigned int j = firstlayer; j < lastlayer; ++j) {
0072 if (zees[j] == 0.) {
0073
0074 continue;
0075 }
0076 std::array<double, 3> to{{0., 0., zees[j]}};
0077 layerIntersection(to, from);
0078 unsigned int layer =
0079 j > maxlayer ? (j - (maxlayer + 1)) : j;
0080 float radius = radii[2];
0081 if (layer <= rhtools_.lastLayerEE())
0082 radius = radii[0];
0083 else if (layer < rhtools_.firstLayerBH())
0084 radius = radii[1];
0085 float radius2 = radius * radius;
0086 KDTreeBox search_box(
0087 float(to[0]) - radius, float(to[0]) + radius, float(to[1]) - radius, float(to[1]) + radius);
0088 std::vector<ClusterRef> found;
0089
0090 hit_kdtree[j].search(search_box, found);
0091
0092 for (unsigned int k = 0; k < found.size(); k++) {
0093 if (vused[found[k].ind] == 0 && distReal2(thecls[es[found[k].ind]], to) < radius2) {
0094 temp.push_back(thecls[es[found[k].ind]]);
0095 vused[found[k].ind] = vused[i];
0096 }
0097 }
0098 }
0099 if (temp.size() > minClusters) {
0100 math::XYZPoint position = clusterTools->getMultiClusterPosition(temp);
0101 if (std::abs(position.z()) <= 0.)
0102 continue;
0103
0104
0105 thePreClusters.push_back(temp);
0106 auto &back = thePreClusters.back();
0107 back.setPosition(position);
0108 back.setEnergy(clusterTools->getMultiClusterEnergy(back));
0109 }
0110 }
0111 }
0112
0113 return thePreClusters;
0114 }
0115
0116 void HGCal3DClustering::layerIntersection(std::array<double, 3> &to, const std::array<double, 3> &from) const {
0117 if (from[2] != 0) {
0118 to[0] = from[0] / from[2] * to[2];
0119 to[1] = from[1] / from[2] * to[2];
0120 } else {
0121 to[0] = 0;
0122 to[1] = 0;
0123 }
0124 }