CMS 3D CMS Logo

HGCalClusteringImpl.cc
Go to the documentation of this file.
1 #include <unordered_set>
2 #include <unordered_map>
6 
7 //class constructor
9  seedThreshold_(conf.getParameter<double>("seeding_threshold")),
10  triggerCellThreshold_(conf.getParameter<double>("clustering_threshold")),
11  dr_(conf.getParameter<double>("dR_cluster")),
12  clusteringAlgorithmType_(conf.getParameter<string>("clusterType"))
13 {
14  edm::LogInfo("HGCalClusterParameters") << "C2d Clustering Algorithm selected : " << clusteringAlgorithmType_ ;
15  edm::LogInfo("HGCalClusterParameters") << "C2d seeding Thr: " << seedThreshold_ ;
16  edm::LogInfo("HGCalClusterParameters") << "C2d clustering Thr: " << triggerCellThreshold_ ;
17 
18 }
19 
20 
21 /* dR-algorithms */
23  const l1t::HGCalCluster & clu,
24  double distXY ) const
25 {
26 
27  HGCalDetId tcDetId( tc.detId() );
28  HGCalDetId cluDetId( clu.detId() );
29  if( (tcDetId.layer() != cluDetId.layer()) ||
30  (tcDetId.subdetId() != cluDetId.subdetId()) ||
31  (tcDetId.zside() != cluDetId.zside()) ){
32  return false;
33  }
34  if ( clu.distance((tc)) < distXY ){
35  return true;
36  }
37  return false;
38 
39 }
40 
41 
44  ){
45 
46  bool isSeed[triggerCellsPtrs.size()];
47 
48  /* search for cluster seeds */
49  int itc(0);
50  for( edm::PtrVector<l1t::HGCalTriggerCell>::const_iterator tc = triggerCellsPtrs.begin(); tc != triggerCellsPtrs.end(); ++tc,++itc ){
51  isSeed[itc] = ( (*tc)->mipPt() > seedThreshold_) ? true : false;
52  }
53 
54  /* clustering the TCs */
55  std::vector<l1t::HGCalCluster> clustersTmp;
56 
57  itc=0;
58  for( edm::PtrVector<l1t::HGCalTriggerCell>::const_iterator tc = triggerCellsPtrs.begin(); tc != triggerCellsPtrs.end(); ++tc,++itc ){
59 
60  if( (*tc)->mipPt() < triggerCellThreshold_ ){
61  continue;
62  }
63 
64  /* searching for TC near the center of the cluster */
65  int iclu=0;
66  vector<int> tcPertinentClusters;
67  for( const auto& clu : clustersTmp){
68  if( this->isPertinent(**tc, clu, dr_) ){
69  tcPertinentClusters.push_back(iclu);
70  }
71  ++iclu;
72  }
73  if( tcPertinentClusters.size() == 0 && isSeed[itc] ){
74  clustersTmp.emplace_back( *tc );
75  }
76  else if ( tcPertinentClusters.size() > 0 ){
77 
78  unsigned minDist(300);
79  unsigned targetClu(0);
80 
81  for( int iclu : tcPertinentClusters){
82  double d = clustersTmp.at(iclu).distance(**tc);
83  if( d < minDist ){
84  minDist = d;
85  targetClu = iclu;
86  }
87  }
88 
89  clustersTmp.at(targetClu).addConstituent( *tc );
90 
91  }
92  }
93 
94  /* store clusters in the persistent collection */
95  clusters.resize(0, clustersTmp.size());
96  for( unsigned i(0); i<clustersTmp.size(); ++i ){
97  clusters.set( 0, i, clustersTmp.at(i) );
98  }
99 
100 }
101 
102 
103 
104 /* NN-algorithms */
105 
106 /* storing trigger cells into vector per layer and per endcap */
108  std::array< std::array<std::vector<edm::Ptr<l1t::HGCalTriggerCell>>, kLayers_>,kNSides_> & reshuffledTriggerCells
109  ){
110 
111  for( const auto& tc : triggerCellsPtrs ){
112  int endcap = tc->zside() == -1 ? 0 : 1 ;
113  HGCalDetId tcDetId( tc->detId() );
114  int subdet = tcDetId.subdetId();
115  int layer = -1;
116 
117  if( subdet == HGCEE ){
118  layer = tc->layer();
119  }
120  else if( subdet == HGCHEF ){
121  layer = tc->layer() + kLayersEE_;
122  }
123  else if( subdet == HGCHEB ){
124  edm::LogWarning("DataNotFound") << "WARNING: the BH trgCells are not yet implemented";
125  }
126 
127  reshuffledTriggerCells[endcap][layer-1].emplace_back(tc);
128 
129  }
130 
131 }
132 
133 
134 /* merge clusters that have common neighbors */
136  const l1t::HGCalCluster & secondary_cluster ) const
137 {
138 
139  const edm::PtrVector<l1t::HGCalTriggerCell>& pertinentTC = secondary_cluster.constituents();
140 
141  for( edm::PtrVector<l1t::HGCalTriggerCell>::iterator tc = pertinentTC.begin(); tc != pertinentTC.end(); ++tc ){
142  main_cluster.addConstituent(*tc);
143  }
144 
145 }
146 
147 
148 void HGCalClusteringImpl::NNKernel( const std::vector<edm::Ptr<l1t::HGCalTriggerCell>> & reshuffledTriggerCells,
150  const HGCalTriggerGeometryBase & triggerGeometry
151  ){
152 
153  /* declaring the clusters vector */
154  std::vector<l1t::HGCalCluster> clustersTmp;
155 
156  // map TC id -> cluster index in clustersTmp
157  std::unordered_map<uint32_t, unsigned> cluNNmap;
158 
159  /* loop over the trigger-cells */
160  for( const auto& tc_ptr : reshuffledTriggerCells ){
161 
162  if( tc_ptr->mipPt() < triggerCellThreshold_ ){
163  continue;
164  }
165 
166  // Check if the neighbors of that TC are already included in a cluster
167  // If this is the case, add the TC to the first (arbitrary) neighbor cluster
168  // Otherwise create a new cluster
169  bool createNewC2d(true);
170  const auto neighbors = triggerGeometry.getNeighborsFromTriggerCell(tc_ptr->detId());
171  for( const auto neighbor : neighbors ){
172  auto tc_cluster_itr = cluNNmap.find(neighbor);
173  if(tc_cluster_itr!=cluNNmap.end()){
174  createNewC2d = false;
175  if( tc_cluster_itr->second < clustersTmp.size()){
176  clustersTmp.at(tc_cluster_itr->second).addConstituent(tc_ptr);
177  // map TC id to the existing cluster
178  cluNNmap.emplace(tc_ptr->detId(), tc_cluster_itr->second);
179  }
180  else{
181  throw cms::Exception("HGCTriggerUnexpected")
182  << "Trying to access a non-existing cluster. But it should exist...\n";
183  }
184  break;
185  }
186  }
187  if(createNewC2d){
188  clustersTmp.emplace_back(tc_ptr);
189  clustersTmp.back().setValid(true);
190  // map TC id to the cluster index (size - 1)
191  cluNNmap.emplace(tc_ptr->detId(), clustersTmp.size()-1);
192  }
193  }
194 
195  /* declaring the vector with possible clusters merged */
196  // Merge neighbor clusters together
197  for( auto& cluster1 : clustersTmp){
198  // If the cluster has been merged into another one, skip it
199  if( !cluster1.valid() ) continue;
200  // Fill a set containing all TC included in the clusters
201  // as well as all neighbor TC
202  std::unordered_set<uint32_t> cluTcSet;
203  for(const auto& tc_clu1 : cluster1.constituents()){
204  cluTcSet.insert( tc_clu1->detId() );
205  const auto neighbors = triggerGeometry.getNeighborsFromTriggerCell( tc_clu1->detId() );
206  for(const auto neighbor : neighbors){
207  cluTcSet.insert( neighbor );
208  }
209  }
210 
211  for( auto& cluster2 : clustersTmp ){
212  // If the cluster has been merged into another one, skip it
213  if( cluster1.detId()==cluster2.detId() ) continue;
214  if( !cluster2.valid() ) continue;
215  // Check if the TC in clu2 are in clu1 or its neighbors
216  // If yes, merge the second cluster into the first one
217  for(const auto& tc_clu2 : cluster2.constituents()){
218  if( cluTcSet.find(tc_clu2->detId())!=cluTcSet.end() ){
219  mergeClusters( cluster1, cluster2 );
220  cluTcSet.insert( tc_clu2->detId() );
221  const auto neighbors = triggerGeometry.getNeighborsFromTriggerCell( tc_clu2->detId() );
222  for(const auto neighbor : neighbors){
223  cluTcSet.insert( neighbor );
224  }
225  cluster2.setValid(false);
226  break;
227  }
228  }
229  }
230  }
231 
232  /* store clusters in the persistent collection */
233  // only if the cluster contain a TC above the seed threshold
234  for( auto& cluster : clustersTmp ){
235  if( !cluster.valid() ) continue;
236  bool saveInCollection(false);
237  for( const auto& tc_ptr : cluster.constituents() ){
238  /* threshold in transverse-mip */
239  if( tc_ptr->mipPt() > seedThreshold_ ){
240  saveInCollection = true;
241  break;
242  }
243  }
244  if(saveInCollection){
245  clusters.push_back( 0, cluster );
246  }
247  }
248 }
249 
250 
253  const HGCalTriggerGeometryBase & triggerGeometry
254  ){
255 
256  std::array< std::array< std::vector<edm::Ptr<l1t::HGCalTriggerCell> >,kLayers_>,kNSides_> reshuffledTriggerCells;
257  triggerCellReshuffling( triggerCellsPtrs, reshuffledTriggerCells );
258 
259  for(unsigned iec=0; iec<kNSides_; ++iec){
260  for(unsigned il=0; il<kLayers_; ++il){
261  NNKernel( reshuffledTriggerCells[iec][il], clusters, triggerGeometry );
262  }
263  }
264 
265 }
266 
double distance(const l1t::HGCalTriggerCell &tc) const
Definition: HGCalClusterT.h:99
size_type size() const
Size of the RefVector.
Definition: PtrVectorBase.h:74
void clusterizeDR(const edm::PtrVector< l1t::HGCalTriggerCell > &triggerCellsPtrs, l1t::HGCalClusterBxCollection &clusters)
virtual geom_set getNeighborsFromTriggerCell(const unsigned trigger_cell_det_id) const =0
void mergeClusters(l1t::HGCalCluster &main_cluster, const l1t::HGCalCluster &secondary_cluster) const
bool neighbor(int endcap, int sector, int SectIndex, int id, int sub, int station)
void clusterizeNN(const edm::PtrVector< l1t::HGCalTriggerCell > &triggerCellsPtrs, l1t::HGCalClusterBxCollection &clusters, const HGCalTriggerGeometryBase &triggerGeometry)
const_iterator begin() const
Definition: PtrVector.h:130
uint32_t detId() const
bool isPertinent(const l1t::HGCalTriggerCell &tc, const l1t::HGCalCluster &clu, double distXY) const
void triggerCellReshuffling(const edm::PtrVector< l1t::HGCalTriggerCell > &triggerCellsPtrs, std::array< std::array< std::vector< edm::Ptr< l1t::HGCalTriggerCell >>, kLayers_ >, kNSides_ > &reshuffledTriggerCells)
static const unsigned kLayersEE_
std::string clusteringAlgorithmType_
const_iterator end() const
Definition: PtrVector.h:135
uint32_t detId() const
Definition: HGCalClusterT.h:96
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
void set(int bx, unsigned i, const T &object)
static const unsigned kNSides_
void addConstituent(const edm::Ptr< C > &c)
Definition: HGCalClusterT.h:54
HGCalClusteringImpl(const edm::ParameterSet &conf)
void resize(int bx, unsigned size)
const edm::PtrVector< C > & constituents() const
Definition: HGCalClusterT.h:49
void NNKernel(const std::vector< edm::Ptr< l1t::HGCalTriggerCell >> &reshuffledTriggerCells, l1t::HGCalClusterBxCollection &clusters, const HGCalTriggerGeometryBase &triggerGeometry)
static const unsigned kLayers_
void push_back(int bx, T object)