ATLAS Offline Software
RpcClusterPreparator.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include <iostream>
6 #include <cmath>
7 
8 #include "RpcClusterPreparator.h"
9 
11 #include "CxxUtils/phihelper.h"
12 
14  const std::string& name,
15  const IInterface* parent):
17 {
18 }
19 
20 // --------------------------------------------------------------------------------
21 // --------------------------------------------------------------------------------
22 
24 {
25  ATH_CHECK(m_idHelperSvc.retrieve());
26  ATH_MSG_DEBUG("Retrieved " << m_idHelperSvc);
27  ATH_CHECK( m_recRPCRoiTool.retrieve() );
28 
29 
30  return StatusCode::SUCCESS;
31 }
32 // --------------------------------------------------------------------------------
33 // --------------------------------------------------------------------------------
34 
36  const std::vector<const Muon::RpcPrepDataCollection*>& rpcCols,
37  const TrigRoiDescriptor* p_roids,
38  const ToolHandle<ClusterPatFinder>* clusterPatFinder,
39  TrigL2MuonSA::RpcLayerClusters& rpcLayerClusters) const
40 {
41 
42  // pattern : map<int, Muon::RpcPrepData*, less<int>>
43  std::map<Identifier,pattern> digits;
44  digits.clear();
45 
46  for( const Muon::RpcPrepDataCollection* theCollection : rpcCols ){
47 
48  if(theCollection->size()>0){
49  // build the patterns
50  if(buildPatterns(doMultiMuon, p_roids, theCollection, digits)){
51  buildClusters(clusterPatFinder, digits, rpcLayerClusters);
52  }
53  }
54  //clear map at each collection
55  digits.clear();
56  }
57  return StatusCode::SUCCESS;
58 }
59 
60 // --------------------------------------------------------------------------------
61 // --------------------------------------------------------------------------------
62 
64  const TrigRoiDescriptor* p_roids,
65  const Muon::RpcPrepDataCollection* rpcCollection,
66  std::map<Identifier, pattern>& digits) const
67 {
68  ATH_MSG_DEBUG("start building patterns of RPC hits for clustering");
69  float deta_thr = 0.1;
70  float dphi_thr = 0.1;
71  float dynamic_add = 0.02;
72  if(doMultiMuon){
73  ATH_MSG_DEBUG("# dynamic search window of RPC");
74  double RoiPhiMin(0);
75  double RoiPhiMax(0);
76  double RoiEtaMin(0);
77  double RoiEtaMax(0);
78  if( !m_recRPCRoiTool->RoIsize(p_roids->roiWord(), RoiEtaMin, RoiEtaMax, RoiPhiMin, RoiPhiMax).isSuccess() ){
79  ATH_MSG_WARNING( "Problem in roiWord decording" );
80  }
81  ATH_MSG_DEBUG( " ... RoI Phi min = " << RoiPhiMin << " RoI Phi max = " << RoiPhiMax << " RoI Eta min = " << RoiEtaMin << " RoI Eta max = " << RoiEtaMax );
82  deta_thr = std::abs( RoiEtaMax - RoiEtaMin )/2. + dynamic_add;
83  dphi_thr = std::abs( std::acos( std::cos( RoiPhiMax - RoiPhiMin ) ) )/2. + dynamic_add;
84  ATH_MSG_DEBUG( "## deta/dphi threshold = " << deta_thr << "/" << dphi_thr);
85  }
86 
87  // here we loop over the digits in the collection and fill the patterns
88  Identifier eleId=rpcCollection->identify();
89  // loop over digits in collection
90  ATH_MSG_DEBUG("# select RPC hits around RoI");
91  for( const Muon::RpcPrepData* rpcDigit : *rpcCollection ){
92  const Identifier id=rpcDigit->identify();
93  const int nstrip = m_idHelperSvc->rpcIdHelper().strip(id);
94  const int doubletZ = m_idHelperSvc->rpcIdHelper().doubletZ(id);
95  const int doubletPhi = m_idHelperSvc->rpcIdHelper().doubletPhi(id);
96  const int gasGap = m_idHelperSvc->rpcIdHelper().gasGap(id);
97  const bool measPhi = m_idHelperSvc->rpcIdHelper().measuresPhi(id);
98 
99  //select RPC hits around RoI
100  const Amg::Vector3D globalpos = rpcDigit->globalPosition();
101  const double hitx=globalpos.x();
102  const double hity=globalpos.y();
103  const double hitz=globalpos.z();
104 
105  const float r2 = hitx*hitx+hity*hity;
106  float phi = std::atan2(hity,hitx);
107  const float l = std::sqrt(hitz*hitz+r2);
108  const float tan = std::sqrt( (l-hitz)/(l+hitz) );
109  const float eta = -std::log(tan);
110  const float deta = std::abs(p_roids->eta() - eta);
111  const float dphi = std::abs(CxxUtils::wrapToPi(p_roids->phi() - phi));
112 
113  ATH_MSG_DEBUG( " ... RPC hit deta/dphi frm RoI = " << deta << "/" << dphi << ", x/y/z = " << hitx << "/" << hity << "/" << hitz);
114 
115  // use Id of first strip to identify a panel.
116  Identifier panelId=m_idHelperSvc->rpcIdHelper().channelID(eleId,doubletZ,doubletPhi,gasGap,measPhi,1);
117 
118  if ( deta<deta_thr && dphi<dphi_thr){
119  if(digits.find(panelId)==digits.end()){ // first hit on this panel
120  pattern newPatt;
121  newPatt[nstrip]=rpcDigit;
122  digits[panelId]=newPatt;
123 
124  } else { // use existing pattern
125 
126  if(digits[panelId].find(nstrip)==digits[panelId].end()){ // no hits on this strip before
127  digits[panelId][nstrip]=rpcDigit;
128  } else if(digits[panelId][nstrip]->time()> rpcDigit->time()){
129  digits[panelId][nstrip]=rpcDigit; // if more than one digit, keep only the one with lowest time
130  }
131  }
132  }
133  }
134 
135  return digits.size();
136 }
137 
138 // --------------------------------------------------------------------------------
139 // --------------------------------------------------------------------------------
140 
141 void TrigL2MuonSA::RpcClusterPreparator::buildClusters(const ToolHandle<ClusterPatFinder>* clusterPatFinder,
142  std::map<Identifier, pattern>& digits,
143  TrigL2MuonSA::RpcLayerClusters& rpcLayerClusters) const
144 {
145  // loop over existing patterns
146 
147  std::map<Identifier, pattern >::iterator patt_it=digits.begin();
148 
149  for(;patt_it!=digits.end();++patt_it){
150 
151  Identifier panelId=(*patt_it).first; // this is the panel id
152 
153  const bool measphi = m_idHelperSvc->rpcIdHelper().measuresPhi(panelId);
154  std::map<int, const Muon::RpcPrepData*, std::less<int> >::iterator dig_it=digits[panelId].begin();
155 
156  std::vector<Identifier> theIDs;
157  int lastStrip=-999;
158  Amg::Vector3D globalPosition(0,0,0);
159  unsigned int count=0;
160 
161  // get the ID from the first digit in collection
162  for(;dig_it!=digits[panelId].end();++dig_it){ // loop over patterns
163 
164  const MuonGM::RpcReadoutElement* descriptor = (*dig_it).second->detectorElement();
165 
166  const int doubletR = m_idHelperSvc->rpcIdHelper().doubletR((*dig_it).second->identify());
167  const int gasGap = m_idHelperSvc->rpcIdHelper().gasGap((*dig_it).second->identify());
168  const int stationEta = m_idHelperSvc->rpcIdHelper().stationEta((*dig_it).second->identify());
169  std::string stationName = m_idHelperSvc->rpcIdHelper().stationNameString(m_idHelperSvc->rpcIdHelper().stationName((*dig_it).second->identify()));
170 
171  if(lastStrip==-999){ // first hit of a cluster..
172  lastStrip=(*dig_it).first;
173  theIDs.push_back((*dig_it).second->identify());
174  globalPosition+=descriptor->stripPos((*dig_it).second->identify());
175  ATH_MSG_DEBUG( ">> first hit of a cluster, id = " << lastStrip << ", RPChit x/y/z/ = " << descriptor->stripPos((*dig_it).second->identify()).x() << "/" << descriptor->stripPos((*dig_it).second->identify()).y() << "/" << descriptor->stripPos((*dig_it).second->identify()).z());
176 
177  } else if(std::abs(lastStrip-(*dig_it).first)==1){ // still on the same cluster
178 
179  lastStrip=(*dig_it).first;
180  theIDs.push_back((*dig_it).second->identify());
181  globalPosition+=descriptor->stripPos((*dig_it).second->identify());
182  ATH_MSG_DEBUG( " ... still on the same cluster, id = " << lastStrip << ", RPChit x/y/z/ = " << descriptor->stripPos((*dig_it).second->identify()).x() << "/" << descriptor->stripPos((*dig_it).second->identify()).y() << "/" << descriptor->stripPos((*dig_it).second->identify()).z());
183 
184  } else { // close the cluster
185 
186  globalPosition=globalPosition*(1/(float)theIDs.size());
187 
188  ATH_MSG_DEBUG(" ... close the cluster ---> cluster at " << stationName << ", x/y/z = " << globalPosition.x() << "/" << globalPosition.y() << "/" << globalPosition.z());
189  (*clusterPatFinder)->addCluster(stationName, stationEta, measphi, gasGap, doubletR, globalPosition.x(), globalPosition.y(), globalPosition.z(), rpcLayerClusters);
190 
191  // clear all the numbers and restart a new cluster
192  lastStrip=(*dig_it).first;
193  theIDs.clear();
194 
195  theIDs.push_back((*dig_it).second->identify());
196  globalPosition=descriptor->stripPos((*dig_it).second->identify());
197  }
198 
199 
200  // if we are at the end, close the custer anyway and fill it with what we have found
201 
202  if(count==digits[panelId].size()-1&&theIDs.size()>0){
203  globalPosition=globalPosition*(1/(float)theIDs.size());
204 
205  //addCluster to PatFinder
206  ATH_MSG_DEBUG(" ... close the cluster ---> cluster at " << stationName << ", x/y/z = " << globalPosition.x() << "/" << globalPosition.y() << "/" << globalPosition.z());
207 
208  (*clusterPatFinder)->addCluster(stationName, stationEta, measphi, gasGap, doubletR, globalPosition.x(), globalPosition.y(), globalPosition.z(), rpcLayerClusters);
209  }
210  count++;
211  }
212  }
213 
214 }
215 
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
dumpTgcDigiDeadChambers.gasGap
list gasGap
Definition: dumpTgcDigiDeadChambers.py:33
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:64
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
dumpTgcDigiDeadChambers.stationName
dictionary stationName
Definition: dumpTgcDigiDeadChambers.py:30
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
CxxUtils::wrapToPi
T wrapToPi(T phi)
Wrap angle in radians to [-pi, pi].
Definition: phihelper.h:24
createCablingJSON.doubletR
int doubletR
Definition: createCablingJSON.py:10
TrigRoiDescriptor::roiWord
virtual unsigned int roiWord() const override final
Definition: TrigRoiDescriptor.h:135
MuonGM::RpcReadoutElement
An RpcReadoutElement corresponds to a single RPC module; therefore typicaly a barrel muon station con...
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/RpcReadoutElement.h:54
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
TrigRoiDescriptor
nope - should be used for standalone also, perhaps need to protect the class def bits #ifndef XAOD_AN...
Definition: TrigRoiDescriptor.h:56
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
TrigL2MuonSA::RpcClusterPreparator::buildClusters
void buildClusters(const ToolHandle< ClusterPatFinder > *clusterPatFinder, std::map< Identifier, pattern > &digits, TrigL2MuonSA::RpcLayerClusters &rpcLayerClusters) const
Definition: RpcClusterPreparator.cxx:141
TrigL2MuonSA::RpcClusterPreparator::pattern
std::map< int, const Muon::RpcPrepData *, std::less< int > > pattern
Definition: RpcClusterPreparator.h:46
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
SCT_CalibAlgs::lastStrip
@ lastStrip
Definition: SCT_CalibNumbers.h:10
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
TrigL2MuonSA::RpcClusterPreparator::clusteringRPCs
StatusCode clusteringRPCs(const bool doMultiMuon, const std::vector< const Muon::RpcPrepDataCollection * > &rpcCols, const TrigRoiDescriptor *p_roids, const ToolHandle< ClusterPatFinder > *clusterPatFinder, TrigL2MuonSA::RpcLayerClusters &rpcLayerClusters) const
Definition: RpcClusterPreparator.cxx:35
Muon::RpcPrepData
Class to represent RPC measurements.
Definition: RpcPrepData.h:35
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
RpcClusterPreparator.h
TrigL2MuonSA::RpcClusterPreparator::initialize
virtual StatusCode initialize() override
Definition: RpcClusterPreparator.cxx:23
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Muon::MuonPrepDataCollection::identify
virtual Identifier identify() const override final
test_pyathena.parent
parent
Definition: test_pyathena.py:15
TrigL2MuonSA::RpcLayerClusters
Definition: ClusterPatFinder.h:58
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
TrigL2MuonSA::RpcClusterPreparator::RpcClusterPreparator
RpcClusterPreparator(const std::string &type, const std::string &name, const IInterface *parent)
Definition: RpcClusterPreparator.cxx:13
TrigL2MuonSA::RpcClusterPreparator::buildPatterns
int buildPatterns(const bool doMultiMuon, const TrigRoiDescriptor *p_roids, const Muon::RpcPrepDataCollection *rpcCollection, std::map< Identifier, pattern > &digits) const
Definition: RpcClusterPreparator.cxx:63
Muon::MuonPrepDataCollection
Template to hold collections of MuonPrepRawData objects.
Definition: MuonPrepDataCollection.h:46
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
MuonGM::RpcReadoutElement::stripPos
Amg::Vector3D stripPos(const Identifier &id) const
Definition: MuonDetDescr/MuonReadoutGeometry/src/RpcReadoutElement.cxx:177
phihelper.h
Helper for azimuthal angle calculations.
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
CaloSwCorrections.time
def time(flags, cells_name, *args, **kw)
Definition: CaloSwCorrections.py:242
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
RoiDescriptor::phi
virtual double phi() const override final
Methods to retrieve data members.
Definition: RoiDescriptor.h:100
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
RoiDescriptor::eta
virtual double eta() const override final
Definition: RoiDescriptor.h:101
createCablingJSON.doubletPhi
int doubletPhi
Definition: createCablingJSON.py:11
AthAlgTool
Definition: AthAlgTool.h:26
readCCLHist.float
float
Definition: readCCLHist.py:83
RpcReadoutElement.h