ATLAS Offline Software
Loading...
Searching...
No Matches
ClusterRoadDefiner.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
9
10// --------------------------------------------------------------------------------
11// --------------------------------------------------------------------------------
12
14 const std::string& name,
15 const IInterface* parent):
16 AthAlgTool(type, name, parent)
17{
18}
19
20// --------------------------------------------------------------------------------
21// --------------------------------------------------------------------------------
22
24{
25 ATH_CHECK(m_idHelperSvc.retrieve());
26 ATH_CHECK(m_regionSelector.retrieve());
27 ATH_MSG_DEBUG("Retrieved the RegionSelector tool ");
28
29 return StatusCode::SUCCESS;
30}
31
32// --------------------------------------------------------------------------------
33// --------------------------------------------------------------------------------
34
35StatusCode TrigL2MuonSA::ClusterRoadDefiner::defineRoad(const EventContext& ctx,
36 const xAOD::MuonRoI* p_roi,
37 std::vector<TrigL2MuonSA::MuonRoad>& clusterRoad,
38 TrigL2MuonSA::RpcLayerClusters& rpcLayerClusters,
39 const ToolHandle<ClusterPatFinder>* clusterPatFinder,
40 std::vector<TrigL2MuonSA::RpcFitResult>& clusterFitResults,
41 double roiEtaMinLow,
42 double roiEtaMaxLow,
43 double roiEtaMinHigh,
44 double roiEtaMaxHigh) const
45{
46 const double ZERO_LIMIT = 1e-5;
47 const int N_STATION = 3; //0:inner, 1:middle, 2:outer
48
49 const int N_LAYER = 5; // 0: inner, 1: middle, 2: outer 4: BME 5: BMG
50 const int N_SECTOR = 2; // 0: normal, 1:overlap
51
52 if (m_use_rpc) {
53 std::vector< std::vector< double > > aw, bw;
54 std::vector< double > clearRoad;
55 clearRoad.clear();
56 aw.assign(N_STATION, clearRoad);
57 bw.assign(N_STATION, clearRoad);
58 ATH_MSG_DEBUG("start searching eta pattern");
59 if ( (*clusterPatFinder)->findPatternEta(aw, bw, rpcLayerClusters) ) {
60 for(unsigned int iClus = 0; iClus < aw[1].size(); iClus++){
61 TrigL2MuonSA::RpcFitResult clusFitResult;
62 clusFitResult.Clear();
63 clusFitResult.isSuccess = true;
64 clusFitResult.offset_inner = (bw[0]).at(iClus);
65 clusFitResult.offset_middle = (bw[1]).at(iClus);
66 clusFitResult.offset_outer = (bw[2]).at(iClus);
67 clusFitResult.slope_inner = 1.0/(aw[0]).at(iClus);
68 clusFitResult.slope_middle = 1.0/(aw[1]).at(iClus);
69 clusFitResult.slope_outer = 1.0/(aw[2]).at(iClus);
70 ATH_MSG_DEBUG("==========================================================");
71 ATH_MSG_DEBUG("inner clusterRoad slope/offset = " << clusFitResult.slope_inner << "/" << clusFitResult.offset_inner);
72 ATH_MSG_DEBUG("middle clusterRoad slope/offset = " << clusFitResult.slope_middle << "/" << clusFitResult.offset_middle);
73 ATH_MSG_DEBUG("outer clusterRoad slope/offset = " << clusFitResult.slope_outer << "/" << clusFitResult.offset_outer);
74 for(int i=0;i<N_STATION;i++){
75 if(std::abs(1.0/aw[i].at(iClus)) <= ZERO_LIMIT) clusFitResult.isSuccess = false;
76 }
77 clusterFitResults.push_back(clusFitResult);
78 }
79 ATH_MSG_DEBUG("==========================================================");
80 } else {
81 TrigL2MuonSA::RpcFitResult clusFitResult;
82 clusFitResult.Clear();
83 clusFitResult.isSuccess = false;
84 clusterFitResults.push_back(clusFitResult);
85 }
86
87 ATH_MSG_DEBUG("start searching phi pattern");
88 std::vector<double> phi_middle, phi_outer;
89 phi_middle.clear(); phi_outer.clear();
90 if ( (*clusterPatFinder)->findPatternPhi(phi_middle, phi_outer, rpcLayerClusters) ){
91 double phi_middle_tot = 0;
92 double phi_outer_tot = 0;
93 size_t npatternPhi = phi_middle.size();
94 if(npatternPhi > 0){
95 for(double& phi : phi_middle){
96 phi_middle_tot = phi_middle_tot + phi;
97 }
98 for(double& phi : phi_outer){
99 phi_outer_tot = phi_outer_tot + phi;
100 }
101 double phi_middle_center = phi_middle_tot/npatternPhi;
102 double phi_outer_center = phi_outer_tot/npatternPhi;
103 ATH_MSG_DEBUG("center of phi middle/outer = " << phi_middle_center << "/" << phi_outer_center);
104 for(unsigned int iClus_fit = 0; iClus_fit < clusterFitResults.size(); iClus_fit++){
105 clusterFitResults.at(iClus_fit).phi = phi_middle_center;
106 clusterFitResults.at(iClus_fit).phi_middle = phi_middle_center;
107 clusterFitResults.at(iClus_fit).phi_outer = phi_outer_center;
108 }
109 } else {
110 for(unsigned int iClus_fit = 0; iClus_fit < clusterFitResults.size(); iClus_fit++){
111 clusterFitResults.at(iClus_fit).phi = p_roi->phi();
112 clusterFitResults.at(iClus_fit).phi_middle = p_roi->phi();
113 clusterFitResults.at(iClus_fit).phi_outer = p_roi->phi();
114 }
115 }
116 } else {
117 for(unsigned int iClus_fit = 0; iClus_fit < clusterFitResults.size(); iClus_fit++){
118 clusterFitResults.at(iClus_fit).phi = p_roi->phi();
119 }
120 }
121 }
122 if(clusterFitResults.empty()){
123 TrigL2MuonSA::RpcFitResult clusFitResult;
124 clusFitResult.Clear();
125 clusFitResult.isSuccess = false;
126 clusFitResult.phi = p_roi->phi();
127 clusterFitResults.push_back(clusFitResult);
128 }
129
130 ATH_MSG_DEBUG("stored cluster eta/phi pattern to clusterRoad");
131 for(unsigned int iClus_fit = 0; iClus_fit < clusterFitResults.size(); iClus_fit++){
132 TrigL2MuonSA::MuonRoad muonRoad;
133 muonRoad.Clear();
134 // RPC data is not available -> use RoI
135
136 muonRoad.isEndcap = false;
137 muonRoad.phiMiddle = clusterFitResults.at(iClus_fit).phi;
138 muonRoad.phiRoI = p_roi->phi();
139 muonRoad.side = (p_roi->phi()<0.)? 0 : 1;
140 muonRoad.LargeSmall = ((p_roi->getSectorID() + 1)/2 )%2;
141
142 int PhysicsSector = ((p_roi->getSectorID() + 1)/4 )%8 + 1;
143
144 int special = 0;
145 if (muonRoad.LargeSmall == 0 && (PhysicsSector == 6 || PhysicsSector == 8 ))
146 special = 1;
147 else if (muonRoad.LargeSmall == 1 && (PhysicsSector == 6 || PhysicsSector == 7 ))
148 special = 1;
149 muonRoad.Special = special;
150
151 for (int i_station=0; i_station<6; i_station++) {
152 for (int i_layer=0; i_layer<8; i_layer++) {
153 if(!clusterFitResults.at(iClus_fit).isSuccess) {
154 if (i_station==0) muonRoad.rWidth[i_station][i_layer] = 500;//for inner
155 else if (i_station==1) muonRoad.rWidth[i_station][i_layer] = 650;//for middle
156 else if (i_station==2) muonRoad.rWidth[i_station][i_layer] = 800;//for outer
157 else if (i_station==3) muonRoad.rWidth[i_station][i_layer] = 500;//EndcapInner
158 else if (i_station==4) muonRoad.rWidth[9][i_layer] = 650;//BME
159 else if (i_station==5) muonRoad.rWidth[10][i_layer] = 650;//BMG
160 else muonRoad.rWidth[i_station][i_layer] = m_rWidth_RPC_Failed;
161 }
162 else {
163 if (i_station==0) muonRoad.rWidth[i_station][i_layer] = 400;//for inner
164 else if (i_station==1) muonRoad.rWidth[i_station][i_layer] = 200;//for middle
165 else if (i_station==2) muonRoad.rWidth[i_station][i_layer] = 400;//for outer
166 else if (i_station==3) muonRoad.rWidth[i_station][i_layer] = 400;//EndcapInner
167 else if (i_station==4) muonRoad.rWidth[9][i_layer] = m_rWidth_RPC_Failed;//BME
168 else if (i_station==5) muonRoad.rWidth[10][i_layer] = m_rWidth_RPC_Failed;//BMG
169 else muonRoad.rWidth[i_station][i_layer] = m_rWidth_RPC_Failed;
170 }
171 }
172 }
173 int sector_trigger = 99;
174 int sector_overlap = 99;
175 std::vector<Identifier> stationList;
176 std::vector<IdentifierHash> mdtHashList;
177
178 // get sector_trigger and sector_overlap by using the region selector
179 IdContext context = m_idHelperSvc->mdtIdHelper().module_context();
180
181 double etaMin = p_roi->eta()-.02;
182 double etaMax = p_roi->eta()+.02;
183 double phiMin = muonRoad.phiMiddle-.01;
184 double phiMax = muonRoad.phiMiddle+.01;
185 if(phiMax > M_PI) phiMax -= M_PI*2.;
186 if(phiMin < M_PI*-1) phiMin += M_PI*2.;
187
188 TrigRoiDescriptor* roi = new TrigRoiDescriptor( p_roi->eta(), etaMin, etaMax, p_roi->phi(), phiMin, phiMax );
189
190 const IRoiDescriptor* iroi = static_cast<IRoiDescriptor*> (roi);
191
192 if (iroi) m_regionSelector->lookup(ctx)->HashIDList(*iroi, mdtHashList);
193 else {
194 TrigRoiDescriptor fullscan_roi( true );
195 m_regionSelector->lookup(ctx)->HashIDList(fullscan_roi, mdtHashList);
196 }
197
198 if(roi) delete roi;
199
200 for( const IdentifierHash& hash : mdtHashList){
201
202 Identifier id;
203 const int convert = m_idHelperSvc->mdtIdHelper().get_id(hash, id, &context);
204
205 if(convert!=0) ATH_MSG_ERROR("problem converting hash list to id");
206
207 muonRoad.stationList.push_back(id);
208 const int stationPhi = m_idHelperSvc->mdtIdHelper().stationPhi(id);
209 std::string name = m_idHelperSvc->mdtIdHelper().stationNameString(m_idHelperSvc->mdtIdHelper().stationName(id));
210
211 if ( name[1]=='M' && name[2]=='E' ) continue;//exclude BME
212 else if ( name[1]=='M' && name[2]=='G' ) continue;//exclude BMG
213
214 int LargeSmall = 0;
215 if(name[2]=='S' || name[2]=='F' || name[2]=='G' ) LargeSmall = 1;
216 int sector = (stationPhi-1)*2 + LargeSmall;
217 if(sector_trigger == 99)
218 sector_trigger = sector;
219 else if(sector_trigger != sector)
220 sector_overlap = sector;
221 }
222
223 int MDT_tr = (PhysicsSector - 1)*2 + muonRoad.LargeSmall;
224 if (MDT_tr == sector_overlap) {
225 sector_overlap = sector_trigger;
226 sector_trigger = MDT_tr;
227 }
228
229 muonRoad.MDT_sector_trigger = sector_trigger;
230 muonRoad.MDT_sector_overlap = sector_overlap;
231
232 if (clusterFitResults.at(iClus_fit).isSuccess) {
233 for (int i_sector=0; i_sector<N_SECTOR; i_sector++) {
234 muonRoad.aw[0][i_sector] = clusterFitResults.at(iClus_fit).slope_inner;
235 muonRoad.bw[0][i_sector] = clusterFitResults.at(iClus_fit).offset_inner;
236 muonRoad.aw[1][i_sector] = clusterFitResults.at(iClus_fit).slope_middle;
237 muonRoad.bw[1][i_sector] = clusterFitResults.at(iClus_fit).offset_middle;
238 muonRoad.aw[2][i_sector] = clusterFitResults.at(iClus_fit).slope_outer;
239 muonRoad.bw[2][i_sector] = clusterFitResults.at(iClus_fit).offset_outer;
240 muonRoad.aw[3][i_sector] = clusterFitResults.at(iClus_fit).slope_inner; // Endcap Inner
241 muonRoad.bw[3][i_sector] = clusterFitResults.at(iClus_fit).offset_inner;
242 muonRoad.aw[9][i_sector] = clusterFitResults.at(iClus_fit).slope_middle;//BME
243 muonRoad.bw[9][i_sector] = clusterFitResults.at(iClus_fit).offset_middle;
244 muonRoad.aw[10][i_sector] = clusterFitResults.at(iClus_fit).slope_middle;//BMG
245 muonRoad.bw[10][i_sector] = clusterFitResults.at(iClus_fit).offset_middle;
246 }
247 } else {
248 double roiEtaLow = (roiEtaMinLow + roiEtaMaxLow) * 0.5;
249 double roiEtaHigh = (roiEtaMinHigh + roiEtaMaxHigh) * 0.5;
250 double thetaLow = std::atan(std::exp(-std::abs(roiEtaLow)))*2.;
251 double thetaHigh = std::atan(std::exp(-std::abs(roiEtaHigh)))*2.;
252 double awLow = (std::abs(roiEtaLow) > ZERO_LIMIT)? std::tan(thetaLow)*(std::abs(roiEtaLow)/roiEtaLow): 0.;
253 double awHigh = (std::abs(roiEtaHigh) > ZERO_LIMIT)? std::tan(thetaHigh)*(std::abs(roiEtaHigh)/roiEtaHigh): 0.;
254
255 for (int i_station=0; i_station<N_LAYER; i_station++) {
256 for (int i_sector=0; i_sector<N_SECTOR; i_sector++) {
257 muonRoad.aw[i_station][i_sector] = awLow;
258 muonRoad.bw[i_station][i_sector] = 0;
259 if (i_station==2) muonRoad.aw[i_station][i_sector] = awHigh;
260 else if (i_station==3) muonRoad.aw[i_station][i_sector] = awLow; //EI
261 else if (i_station==4) muonRoad.aw[9][i_sector] = awLow; //BME
262 else if (i_station==5) muonRoad.aw[10][i_sector] = awLow; //BMG
263 }
264 }
265 }
266 clusterRoad.push_back(muonRoad);
267 }
268 ATH_MSG_DEBUG("finished ClusterRoadDefiner algorithm... leave");
269 return StatusCode::SUCCESS;
270}
271
272// --------------------------------------------------------------------------------
273// --------------------------------------------------------------------------------
#define M_PI
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
Athena::TPCnvVers::Current TrigRoiDescriptor
const float ZERO_LIMIT
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Describes the API of the Region of Ineterest geometry.
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
Definition IdContext.h:26
This is a "hash" representation of an Identifier.
StatusCode defineRoad(const EventContext &ctx, const xAOD::MuonRoI *p_roi, std::vector< TrigL2MuonSA::MuonRoad > &clusterRoad, TrigL2MuonSA::RpcLayerClusters &rpcLayerClusters, const ToolHandle< ClusterPatFinder > *clusterPatFinder, std::vector< TrigL2MuonSA::RpcFitResult > &clusterFitResults, double roiEtaMinLow, double roiEtaMaxLow, double roiEtaMinHigh, double roiEtaMaxHigh) const
ToolHandle< IRegSelTool > m_regionSelector
virtual StatusCode initialize() override
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
ClusterRoadDefiner(const std::string &type, const std::string &name, const IInterface *parent)
std::vector< Identifier > stationList
Definition MuonRoad.h:102
double aw[N_STATION][N_SECTOR]
Definition MuonRoad.h:83
double bw[N_STATION][N_SECTOR]
Definition MuonRoad.h:84
double rWidth[N_STATION][N_LAYER]
Definition MuonRoad.h:86
nope - should be used for standalone also, perhaps need to protect the class def bits ifndef XAOD_ANA...
float eta() const
The pseudorapidity ( ) of the muon candidate.
float phi() const
The azimuthal angle ( ) of the muon candidate.
int getSectorID() const
Get the sector ID number.
constexpr int N_STATION
Definition MuonRoad.h:15
constexpr int N_LAYER
Definition MuonRoad.h:17
constexpr int N_SECTOR
Definition MuonRoad.h:16
MuonRoI_v1 MuonRoI
Definition MuonRoI.h:15