CMS 3D CMS Logo

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