ATLAS Offline Software
Loading...
Searching...
No Matches
Muon::RpcHitClusteringObj Struct Reference

#include <RpcHitClustering.h>

Collaboration diagram for Muon::RpcHitClusteringObj:

Classes

struct  Doublet
struct  Id

Public Types

typedef std::vector< DoubletHitClustering

Public Member Functions

 RpcHitClusteringObj (const RpcIdHelper *rpcIdHelper)
bool cluster (const std::vector< const RpcPrepData * > &col)
bool cluster (const std::vector< const RpcPrepData * > &col, const Identifier &subid)
void dump () const
const RpcClusterObjbestEtaCluster () const
const RpcClusterObjbestPhiCluster () const
void findBest ()

Public Attributes

const RpcIdHelperm_rpcIdHelper
std::vector< DoubletchannelsEta
std::vector< DoubletchannelsPhi
std::vector< RpcClusterObjclustersEta
std::vector< RpcClusterObjclustersPhi
std::vector< RpcClusterObjclustersEtaTmp
std::vector< RpcClusterObjclustersPhiTmp
bool debug
bool combinedGasGaps

Detailed Description

Definition at line 76 of file RpcHitClustering.h.

Member Typedef Documentation

◆ HitClustering

Definition at line 90 of file RpcHitClustering.h.

Constructor & Destructor Documentation

◆ RpcHitClusteringObj()

Muon::RpcHitClusteringObj::RpcHitClusteringObj ( const RpcIdHelper * rpcIdHelper)
inline

Definition at line 92 of file RpcHitClustering.h.

92 :
93 m_rpcIdHelper(rpcIdHelper),debug(false),combinedGasGaps(true)
94 {}
const RpcIdHelper * m_rpcIdHelper

Member Function Documentation

◆ bestEtaCluster()

const RpcClusterObj * Muon::RpcHitClusteringObj::bestEtaCluster ( ) const
inline

Definition at line 101 of file RpcHitClustering.h.

101 {
102 if( clustersEta.empty() ) return 0;
103 return &clustersEta.front();
104 }
std::vector< RpcClusterObj > clustersEta

◆ bestPhiCluster()

const RpcClusterObj * Muon::RpcHitClusteringObj::bestPhiCluster ( ) const
inline

Definition at line 106 of file RpcHitClustering.h.

106 {
107 if( clustersPhi.empty() ) return 0;
108 return &clustersPhi.front();
109 }
std::vector< RpcClusterObj > clustersPhi

◆ cluster() [1/2]

bool Muon::RpcHitClusteringObj::cluster ( const std::vector< const RpcPrepData * > & col)

Definition at line 9 of file RpcHitClustering.cxx.

9 {
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 }
Identifier identify() const
return the identifier
bool cluster(const std::vector< const RpcPrepData * > &col)

◆ cluster() [2/2]

bool Muon::RpcHitClusteringObj::cluster ( const std::vector< const RpcPrepData * > & col,
const Identifier & subid )

Core clustering routine that runs on a single RPC module (two gas-gaps) Strategy:

  • create a hash vector with the channel number as index and store a Doublet object in it. The Doublet contains two integers, one for each gasgap. The integers are used to store the cluster number the hit in that channel is associated with.
  • loop over the input hits, filtering out all those in different modules
    • calculate the channel number and look-up the cluster number, if any, for the channel nummber
      • if there is already a cluster associated with the channel (meaning this is a duplicate hit), add the hit as secondary hit
    • calculate all potential neightbours of the channel number
    • loop over the neighbour channels and check if any of them is already assigned to a cluster
      • if one of the neighbours already is assigned to a cluster, add the hit to that cluster
      • if another neighbouring channel is assigned to a different cluster, the hit connects the two clusters -> merge the two clusters
  • add the clusters to the final cluster list

Definition at line 51 of file RpcHitClustering.cxx.

51 {
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 }
int NphiStrips() const
returns the number of phi strips
int NetaStrips() const
returns the number of eta strips
virtual const MuonGM::RpcReadoutElement * detectorElement() const override final
Returns the detector element corresponding to this PRD.
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
HitList::iterator HitIt
std::vector< RpcClusterObj > clustersPhiTmp
std::vector< Doublet > channelsEta
std::vector< Doublet > channelsPhi
std::vector< RpcClusterObj > clustersEtaTmp

◆ dump()

void Muon::RpcHitClusteringObj::dump ( ) const

Definition at line 237 of file RpcHitClustering.cxx.

237 {
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 }
HitList::const_iterator HitCit

◆ findBest()

void Muon::RpcHitClusteringObj::findBest ( )

Definition at line 258 of file RpcHitClustering.cxx.

258 {
259 std::vector<RpcClusterObj>::iterator it = clustersEta.begin();
260 std::vector<RpcClusterObj>::iterator it_end = clustersEta.end();
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 }
void stable_sort(DataModel_detail::iterator< DVL > beg, DataModel_detail::iterator< DVL > end)
Specialization of stable_sort for DataVector/List.

Member Data Documentation

◆ channelsEta

std::vector<Doublet> Muon::RpcHitClusteringObj::channelsEta

Definition at line 114 of file RpcHitClustering.h.

◆ channelsPhi

std::vector<Doublet> Muon::RpcHitClusteringObj::channelsPhi

Definition at line 115 of file RpcHitClustering.h.

◆ clustersEta

std::vector<RpcClusterObj> Muon::RpcHitClusteringObj::clustersEta

Definition at line 116 of file RpcHitClustering.h.

◆ clustersEtaTmp

std::vector<RpcClusterObj> Muon::RpcHitClusteringObj::clustersEtaTmp

Definition at line 118 of file RpcHitClustering.h.

◆ clustersPhi

std::vector<RpcClusterObj> Muon::RpcHitClusteringObj::clustersPhi

Definition at line 117 of file RpcHitClustering.h.

◆ clustersPhiTmp

std::vector<RpcClusterObj> Muon::RpcHitClusteringObj::clustersPhiTmp

Definition at line 119 of file RpcHitClustering.h.

◆ combinedGasGaps

bool Muon::RpcHitClusteringObj::combinedGasGaps

Definition at line 121 of file RpcHitClustering.h.

◆ debug

bool Muon::RpcHitClusteringObj::debug

Definition at line 120 of file RpcHitClustering.h.

◆ m_rpcIdHelper

const RpcIdHelper* Muon::RpcHitClusteringObj::m_rpcIdHelper

Definition at line 113 of file RpcHitClustering.h.


The documentation for this struct was generated from the following files: