ATLAS Offline Software
RpcHitClustering.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 namespace Muon {
8 
9  bool RpcHitClusteringObj::cluster( const std::vector<const RpcPrepData*>& col ){
10 
11  if( col.empty() ) return false;
12  std::vector<const RpcPrepData*>::const_iterator cit_begin = col.begin();
13  std::vector<const RpcPrepData*>::const_iterator cit_end = col.end();
14  if( cit_begin == cit_end ) return false;
15  std::vector<const RpcPrepData*>::const_iterator cit = cit_begin;
16  const Muon::RpcPrepData* prd_first = *cit;
17  if( !prd_first ) return false;
18  clustersEta.clear();
19  clustersPhi.clear();
20 
21  std::set<Identifier> subModuleIds;
22  for( ; cit!=cit_end;++cit ) {
23  const Muon::RpcPrepData* prd = *cit;
24  const Identifier& id = prd->identify();
25  Identifier elId = m_rpcIdHelper->elementID(id);
26  int doubZ = m_rpcIdHelper->doubletZ(id);
27  int doubPhi = m_rpcIdHelper->doubletPhi(id);
28  Identifier detElId = m_rpcIdHelper->channelID(elId,doubZ,doubPhi,1,0,1);
29  subModuleIds.insert(detElId);
30  }
31  if( debug ) {
32  std::cout << " RPC performing clustering " << col.size() << " sub modules " << subModuleIds.size() << std::endl;
33  std::set<Identifier>::iterator it = subModuleIds.begin();
34  std::set<Identifier>::iterator it_end = subModuleIds.end();
35  for( ;it!=it_end;++it ){
36  std::cout << " sub module " << m_rpcIdHelper->print_to_string(*it) << std::endl;
37  }
38  }
39  std::set<Identifier>::iterator it = subModuleIds.begin();
40  std::set<Identifier>::iterator it_end = subModuleIds.end();
41  for( ;it!=it_end;++it ){
42  if( !cluster(col,*it) ) return false;
43  }
44 
45  findBest();
46  if( debug ) dump();
47  return true;
48  }
49 
50 
51  bool RpcHitClusteringObj::cluster( const std::vector<const RpcPrepData*>& col, const Identifier& subid ){
52 
69  // check if there was an input
70  if( col.empty() ) return false;
71  std::vector<const RpcPrepData*>::const_iterator cit_begin = col.begin();
72  std::vector<const RpcPrepData*>::const_iterator cit_end = col.end();
73  if( cit_begin == cit_end ) return false;
74  if( debug ) std::cout << " RPC performing clustering: " << col.size() << " " << m_rpcIdHelper->print_to_string(subid) << std::endl;
75 
76  // find the first PRD matching the subid
77  int doubZ = m_rpcIdHelper->doubletZ(subid);
78  int doubPhi = m_rpcIdHelper->doubletPhi(subid);
79  std::vector<const RpcPrepData*>::const_iterator cit = cit_begin;
80  const Muon::RpcPrepData* prd_first = nullptr;
81  for( ; cit!=cit_end;++cit ) {
82  const Muon::RpcPrepData* prd = *cit;
83  const Identifier& id = prd->identify();
84  if( doubZ != m_rpcIdHelper->doubletZ(id) ) continue;
85  if( doubPhi != m_rpcIdHelper->doubletPhi(id) ) continue;
86  prd_first = prd;
87  break;
88  }
89 
90  // exit if none found
91  if( !prd_first ) return false;
92 
93  // setup arrays
94  clustersEtaTmp.clear();
95  clustersPhiTmp.clear();
96  channelsEta.clear();
97  channelsPhi.clear();
98  channelsEta.resize(prd_first->detectorElement()->NetaStrips());
99  channelsPhi.resize(prd_first->detectorElement()->NphiStrips());
100 
101  // loop over hits
102  std::vector<Doublet>* channelsPtr = nullptr;
103  cit = cit_begin;
104  for( ; cit!=cit_end;++cit ) {
105 
106  // drop hits in other subid's
107  const Muon::RpcPrepData* prd = *cit;
108  const Identifier& id = prd->identify();
109  if( doubZ != m_rpcIdHelper->doubletZ(id) ) continue;
110  if( doubPhi != m_rpcIdHelper->doubletPhi(id) ) continue;
111  if( debug ) std::cout << " adding prd " << m_rpcIdHelper->print_to_string(id) << std::endl;
112 
113  // decode identifier
114  bool measuresPhi = m_rpcIdHelper->measuresPhi(id);
115  int gasgap = m_rpcIdHelper->gasGap(id);
116  int channel = m_rpcIdHelper->strip(id)-1;
117  if(measuresPhi) channelsPtr = &channelsPhi;
118  else channelsPtr = &channelsEta;
119  if( channel >= (int)channelsPtr->size() ){
120  std::cout << "index channels out of range: " << channel << " max " << channelsPtr->size() << std::endl;
121  continue;
122  }
123 
124  //
125  std::vector<RpcClusterObj>& clusters = measuresPhi ? clustersPhiTmp : clustersEtaTmp;
126 
127  Doublet& doublet = (*channelsPtr)[channel];
128 
129  // first treat the case of a second hit in the same tube
130  int channelClusterNumber = gasgap==1 ? doublet.first : doublet.second;
131  if( channelClusterNumber != -1 ){
132  if( debug ){
133  std::cout << " secondary hit " << channel << " " << gasgap;
134  if( measuresPhi ) std::cout << " phi " << channelClusterNumber << std::endl;
135  else std::cout << " eta " << channelClusterNumber << std::endl;
136  }
137  RpcClusterObj& cluster = clusters[channelClusterNumber];
138  if( !cluster.addSecond(prd,gasgap) ){
139  }
140  }else{
141 
142  std::vector<Id> neighbours;
143  if( combinedGasGaps ){
144  if( gasgap == 1 ) {
145  neighbours.emplace_back(2,channel );
146  if( channel != 0 ) neighbours.emplace_back(2,channel-1 );
147  if( channel < (int)channelsPtr->size()-1 ) neighbours.emplace_back(2,channel+1 );
148  }else if( gasgap == 2 ){
149  neighbours.emplace_back(1,channel );
150  if( channel != 0 ) neighbours.emplace_back(1,channel-1 );
151  if( channel < (int)channelsPtr->size()-1 ) neighbours.emplace_back(1,channel+1 );
152  }
153  }
154  if( channel != 0 ) neighbours.emplace_back(gasgap,channel-1 );
155  if( channel < (int)channelsPtr->size()-1 ) neighbours.emplace_back(gasgap,channel+1 );
156 
157  if( debug ) {
158  std::cout << " adding new channel " << channel << " " << gasgap;
159  if( measuresPhi ) std::cout << " phi " << " neighbours " << neighbours.size() << std::endl;
160  else std::cout << " eta " << " neighbours " << neighbours.size() << std::endl;
161  }
162  std::vector<Id>::iterator nit = neighbours.begin();
163  std::vector<Id>::iterator nit_end = neighbours.end();
164  RpcClusterObj* currentCluster = nullptr;
165  int currentClusterId = -1;
166  for( ;nit!=nit_end;++nit ){
167 
168  Doublet& doub = (*channelsPtr)[nit->ch];
169 
170  int clusterNumber = nit->gp==1 ? doub.first : doub.second;
171  if( clusterNumber == -1 ) continue;
172  if( debug ) std::cout << " new neighbour " << nit->gp << " " << nit->ch << " clusterid " << clusterNumber;
173 
174  RpcClusterObj& cluster = clusters[clusterNumber];
175 
176  // if the hit is unassigned add it to the cluster
177  if( currentCluster == nullptr ){
178  cluster.add(prd,gasgap);
179  currentCluster = &cluster;
180  if( gasgap==1 ) doublet.first = clusterNumber;
181  else doublet.second = clusterNumber;
182  currentClusterId = clusterNumber;
183  if( debug ) std::cout << " adding hit to neighbour cluster with ID " << clusterNumber << std::endl;
184  }else if( clusterNumber != currentClusterId ){
185  // the hit is already assigned to a cluster, merge the two clusters
186  // first update hitPattern
187  RpcClusterObj::HitIt h = cluster.hitList.begin();
188  RpcClusterObj::HitIt h_end = cluster.hitList.end();
189  for( ;h!=h_end;++h ) {
190  const Identifier& cid = (*h)->identify();
191  int ch = m_rpcIdHelper->strip(cid)-1;
192  int gp = m_rpcIdHelper->gasGap(cid);
193  Doublet& doub = (*channelsPtr)[ch];
194  if( gp==1 ) doub.first = currentClusterId;
195  else doub.second = currentClusterId;
196  }
197  if( debug ) std::cout << " found cluster overlap, merging clusters " << std::endl;
198  currentCluster->merge(cluster);
199  }else{
200  if( debug ) std::cout << " cluster overlap, same cluster " << std::endl;
201  }
202  }
203  // now check whether the hit was already assigned to a cluster, if not create a new cluster
204  if( currentCluster == nullptr ){
205  if( debug ) std::cout << " no neighbouring hits, creating new cluster " << clusters.size() << std::endl;
207  cl.add(prd,gasgap);
208  Doublet& doub = (*channelsPtr)[channel];
209  if( gasgap==1 ) doub.first = clusters.size();
210  else doub.second = clusters.size();
211  clusters.push_back(cl);
212  }
213  }
214  }
215 
216  if( debug ) {
217  std::cout << " finished clustering: eta clusters " << clustersEtaTmp.size() << " phi clusters " << clustersPhiTmp.size() << std::endl;
218  for( auto& cl : clustersEtaTmp ){
219  std::cout << " cluster " << cl.ngasgap1 << " " << cl.ngasgap2 << " hits " << cl.hitList.size() << std::endl;
220  for( const auto *hit : cl.hitList ){
221  std::cout << " " << m_rpcIdHelper->print_to_string(hit->identify()) << std::endl;
222  }
223  }
224  }
225  // add all active clusters
226  for( auto& cl : clustersEtaTmp ){
227  if( cl.active() ) clustersEta.push_back(cl);
228  }
229  for( auto& cl : clustersPhiTmp ){
230  if( cl.active() ) clustersPhi.push_back(cl);
231  }
232 
233  return true;
234  }
235 
236 
238  int clid = -1;
239  std::vector<RpcClusterObj>::const_iterator cit = clustersEta.begin();
240  std::vector<RpcClusterObj>::const_iterator cit_end = clustersEta.end();
241  for( ;cit!=cit_end;++cit ){
242  ++clid;
243  if( !cit->active() ) continue;
244  std::cout << " new cluster " << clid << " size " << cit->hitList.size() << std::endl;
245  RpcClusterObj::HitCit hit = cit->hitList.begin();
246  RpcClusterObj::HitCit hit_end = cit->hitList.end();
247  for( ;hit!=hit_end;++hit ){
248  const Muon::RpcPrepData& prd = **hit;
249  const Identifier& id = prd.identify();
250  std::cout << " hit " << m_rpcIdHelper->gasGap(id) << " " << m_rpcIdHelper->strip(id)-1;
251  bool measuresPhi = m_rpcIdHelper->measuresPhi(id);
252  if(measuresPhi) std::cout << " phi" << std::endl;
253  else std::cout << " eta" << std::endl;
254  }
255  }
256  }
257 
261  std::stable_sort(it,it_end,SortRpcClusterObjs());
262  it = clustersPhi.begin();
263  it_end = clustersPhi.end();
264  std::stable_sort(it,it_end,SortRpcClusterObjs());
265  }
266 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
Muon::RpcHitClusteringObj::clustersPhi
std::vector< RpcClusterObj > clustersPhi
Definition: RpcHitClustering.h:117
sendEI_SPB.ch
ch
Definition: sendEI_SPB.py:35
Muon::RpcHitClusteringObj::findBest
void findBest()
Definition: RpcHitClustering.cxx:258
plotting.yearwise_efficiency.channel
channel
Definition: yearwise_efficiency.py:28
RpcIdHelper::elementID
Identifier elementID(int stationName, int stationEta, int stationPhi, int doubletR) const
Definition: RpcIdHelper.cxx:802
RpcIdHelper::doubletZ
int doubletZ(const Identifier &id) const
Definition: RpcIdHelper.cxx:1062
Muon::RpcHitClusteringObj::clustersEtaTmp
std::vector< RpcClusterObj > clustersEtaTmp
Definition: RpcHitClustering.h:118
skel.it
it
Definition: skel.GENtoEVGEN.py:423
RpcIdHelper::measuresPhi
bool measuresPhi(const Identifier &id) const override
Definition: RpcIdHelper.cxx:1068
RpcHitClustering.h
Muon::RpcClusterObj::merge
void merge(RpcClusterObj &cluster)
Definition: RpcHitClustering.h:46
RpcIdHelper::channelID
Identifier channelID(int stationName, int stationEta, int stationPhi, int doubletR, int doubletZ, int doubletPhi, int gasGap, int measuresPhi, int strip) const
Definition: RpcIdHelper.cxx:940
Muon
This class provides conversion from CSC RDO data to CSC Digits.
Definition: TrackSystemController.h:49
Muon::RpcHitClusteringObj::dump
void dump() const
Definition: RpcHitClustering.cxx:237
Muon::RpcClusterObj::HitIt
HitList::iterator HitIt
Definition: RpcHitClustering.h:21
RpcIdHelper::gasGap
int gasGap(const Identifier &id) const override
get the hashes
Definition: RpcIdHelper.cxx:1066
Muon::RpcPrepData
Class to represent RPC measurements.
Definition: RpcPrepData.h:35
Muon::RpcPrepData::detectorElement
virtual const MuonGM::RpcReadoutElement * detectorElement() const override final
Returns the detector element corresponding to this PRD.
Definition: RpcPrepData.h:202
Muon::RpcHitClusteringObj::cluster
bool cluster(const std::vector< const RpcPrepData * > &col)
Definition: RpcHitClustering.cxx:9
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
extractSporadic.h
list h
Definition: extractSporadic.py:97
Muon::SortRpcClusterObjs
Definition: RpcHitClustering.h:68
MuonGM::RpcReadoutElement::NphiStrips
int NphiStrips() const
returns the number of phi strips
Muon::RpcHitClusteringObj::Doublet::second
int second
Definition: RpcHitClustering.h:87
RpcIdHelper::strip
int strip(const Identifier &id) const
Definition: RpcIdHelper.cxx:1070
Muon::RpcHitClusteringObj::channelsEta
std::vector< Doublet > channelsEta
Definition: RpcHitClustering.h:114
Muon::RpcHitClusteringObj::clustersPhiTmp
std::vector< RpcClusterObj > clustersPhiTmp
Definition: RpcHitClustering.h:119
MuonGM::RpcReadoutElement::NetaStrips
int NetaStrips() const
returns the number of eta strips
Trk::PrepRawData::identify
Identifier identify() const
return the identifier
AtlasDetectorID::print_to_string
std::string print_to_string(Identifier id, const IdContext *context=0) const
or provide the printout in string form
Definition: AtlasDetectorID.cxx:655
Muon::RpcClusterObj::HitCit
HitList::const_iterator HitCit
Definition: RpcHitClustering.h:22
Muon::RpcHitClusteringObj::combinedGasGaps
bool combinedGasGaps
Definition: RpcHitClustering.h:121
query_example.col
col
Definition: query_example.py:7
Muon::RpcHitClusteringObj::clustersEta
std::vector< RpcClusterObj > clustersEta
Definition: RpcHitClustering.h:116
Muon::RpcClusterObj
Definition: RpcHitClustering.h:18
h
RunTileMonitoring.clusters
clusters
Definition: RunTileMonitoring.py:133
Muon::RpcHitClusteringObj::Doublet::first
int first
Definition: RpcHitClustering.h:86
Muon::RpcHitClusteringObj::m_rpcIdHelper
const RpcIdHelper * m_rpcIdHelper
Definition: RpcHitClustering.h:113
Muon::RpcHitClusteringObj::channelsPhi
std::vector< Doublet > channelsPhi
Definition: RpcHitClustering.h:115
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:26
Muon::RpcHitClusteringObj::Doublet
Definition: RpcHitClustering.h:84
Muon::RpcHitClusteringObj::debug
bool debug
Definition: RpcHitClustering.h:120
RpcIdHelper::doubletPhi
int doubletPhi(const Identifier &id) const
Definition: RpcIdHelper.cxx:1064