ATLAS Offline Software
Loading...
Searching...
No Matches
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
7namespace 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
68
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;
206 RpcClusterObj cl;
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
259 std::vector<RpcClusterObj>::iterator it = clustersEta.begin();
260 std::vector<RpcClusterObj>::iterator it_end = clustersEta.end();
262 it = clustersPhi.begin();
263 it_end = clustersPhi.end();
265 }
266}
Header file for AthHistogramAlgorithm.
int NphiStrips() const
returns the number of phi strips
int NetaStrips() const
returns the number of eta strips
Class to represent RPC measurements.
Definition RpcPrepData.h:35
virtual const MuonGM::RpcReadoutElement * detectorElement() const override final
Returns the detector element corresponding to this PRD.
Identifier identify() const
return the identifier
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
void stable_sort(DataModel_detail::iterator< DVL > beg, DataModel_detail::iterator< DVL > end)
Specialization of stable_sort for DataVector/List.
HitList::const_iterator HitCit
void merge(RpcClusterObj &cluster)
HitList::iterator HitIt
std::vector< RpcClusterObj > clustersPhiTmp
std::vector< Doublet > channelsEta
std::vector< RpcClusterObj > clustersEta
const RpcIdHelper * m_rpcIdHelper
std::vector< Doublet > channelsPhi
bool cluster(const std::vector< const RpcPrepData * > &col)
std::vector< RpcClusterObj > clustersEtaTmp
std::vector< RpcClusterObj > clustersPhi