ATLAS Offline Software
Loading...
Searching...
No Matches
ClusterPatFinder.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "ClusterPatFinder.h"
6
7#include <math.h>
8#include <bitset>
9#include <iostream>
10
12
13// --------------------------------------------------------------------------------
14// --------------------------------------------------------------------------------
15
17 const std::string& name,
18 const IInterface* parent):
19 AthAlgTool(type, name, parent)
20{
21}
22
23// --------------------------------------------------------------------------------
24// --------------------------------------------------------------------------------
25
26void TrigL2MuonSA::ClusterPatFinder::addCluster(const std::string& stationName,
27 int stationEta,
28 bool measuresPhi,
29 unsigned int gasGap,
30 unsigned int doubletR,
31 double gPosX,
32 double gPosY,
33 double gPosZ,
34 TrigL2MuonSA::RpcLayerClusters& rpcLayerClusters) const
35{
36
37 int ilay=0;
38 // BO
39 if (stationName.substr(0,2)=="BO") ilay=4;
40 // doubletR
41 ilay+=2*(doubletR-1);
42 // BML7 special chamber with 1 RPC doublet (doubletR=1 but RPC2) :
43 if (stationName.substr(0,3)=="BML" && stationEta==7) ilay+=2;
44 // gasGap
45 ilay+=gasGap-1;
46
47 double R=std::sqrt(gPosX*gPosX+gPosY*gPosY);
48 double Phi=std::atan2(gPosY,gPosX);
49
50 if (!measuresPhi){
51 // if eta measurement then save Z/R
52 R = calibR(stationName,R, Phi);
53 double x=gPosZ/R;
54 rpcLayerClusters.clusters_in_layer_eta.at(ilay).push_back(x);
55 rpcLayerClusters.clusters_in_layer_R.at(ilay).push_back(R);//mod!
56 rpcLayerClusters.clusters_in_layer_Z.at(ilay).push_back(gPosZ);//mod!
57 }else{
58 // if phi measurement then save phi
59 rpcLayerClusters.clusters_in_layer_phi.at(ilay).push_back(Phi);
60 }
61}
62
63
64// --------------------------------------------------------------------------------
65// --------------------------------------------------------------------------------
66bool TrigL2MuonSA::ClusterPatFinder::findPatternPhi(std::vector<double>& phi_middle,
67 std::vector<double>& phi_outer,
68 TrigL2MuonSA::RpcLayerClusters& rpcLayerClusters) const
69{
70 std::vector<TrigL2MuonSA::ClusterPattern> crPatterns;
71
72 if( !patfinder(crPatterns, rpcLayerClusters) ) return false;
73 removeSimilarRoad(crPatterns);
74 for(TrigL2MuonSA::ClusterPattern& crPat : crPatterns){
75 if( !crPat.isGoodFit ) continue;
76 phi_middle.push_back(crPat.phi_middle);
77 phi_outer.push_back(crPat.phi_outer);
78 ATH_MSG_DEBUG("phi_middle/phi_outer = " << crPat.phi_middle << "/" << crPat.phi_outer);
79 }
80 return true;
81}
82
83// --------------------------------------------------------------------------------
84// --------------------------------------------------------------------------------
85bool TrigL2MuonSA::ClusterPatFinder::patfinder(std::vector<TrigL2MuonSA::ClusterPattern>& crPatterns,
86 TrigL2MuonSA::RpcLayerClusters& rpcLayerClusters) const
87{
88 const int N_layers=8;
89 bool iphi = true;
90
91 std::vector<std::list<double>> * rpc_x;
92 rpc_x = &rpcLayerClusters.clusters_in_layer_phi;
93
94 int l_start_max=2; //max layer of first hit
95 if (rpc_x->at(6).size()+rpc_x->at(7).size()>0) l_start_max=5; // special "feet" towers
96
97 for (int l_start=0; l_start<=l_start_max; l_start++){
98 size_t index[8] = {};
99 for(int i=0; i<8; i++) index[i]=-1;
100 // Loop on hits of start layer, for each hit try a new pattern
101 for (std::list<double>::iterator i_start=rpc_x->at(l_start).begin(); i_start!=rpc_x->at(l_start).end(); ++i_start){
103 crPat.Clear();
104 int n_hits=1;
105 unsigned int pat=(1<<l_start); // bit pattern of hit layers
106 double dMO=9999; // disstance middle-outer station
107 double dMM=9999; // distance RPC1-RPC2 on middle stations
108 double current_x =*i_start; // set current_x to the starting hit
109 int l_current = l_start;
110
111 index[l_start] = std::distance(rpc_x->at(l_start).begin(), i_start);//mod!
112 ATH_MSG_DEBUG("patfinder_cluster: l_start = "<< l_start << " x= " << current_x
113 << " pat= " << (std::bitset<8>) pat);
114
115 // ----- add compatible hits in other layers ----//
116 // loop on test layers:
117 bool skipLayer = false;
118 for (int l_test=l_start+1; l_test<N_layers; l_test++){
119 ATH_MSG_DEBUG("start searching the clusters in RPC plane, l_test = " << l_test);
120 if(l_test % 2 == 0){
121 int n_layer=0; //number of found clusters in sets
122 int n_layer_upper=0;
123 double x_layer=0; // position of the best cluster at test layer
124 double delta_layer=999; //minimum d(Z/R)
125 int layerID = 0;
126 for(int ilayer = 0; ilayer < 2; ilayer++){
127 for (std::list<double>::iterator i_test=rpc_x->at(l_test + ilayer).begin(); i_test!=rpc_x->at(l_test + ilayer).end(); ++i_test){
128 double delta=-1;
129 // check if within the road
130 if (!deltaOK( l_current,l_test + ilayer,current_x,*i_test,iphi,delta)) continue;
131 if(ilayer == 0)n_layer++; //in the layer,if there is the cluster which pass th deltaOK
132 else if(ilayer == 1)n_layer_upper++;
133 // if closest hit update x_layer
134 if (delta<delta_layer) {
135 delta_layer=delta;
136 x_layer=*i_test;
137 layerID = ilayer;
138 index[l_test+ilayer] = std::distance(rpc_x->at(l_test+ilayer).begin(), i_test);//mod!
139 //"index" is the ID of the best matched cluster in "l_test" layer
140 if(ilayer == 1){
141 ATH_MSG_DEBUG("the minimum delta was found in upper layer, update info");
142 index[l_test] = 0;
143 skipLayer = true;
144 }
145 }
146 }//for i_test
147 }//for ilayer
148 if (n_layer>0 || n_layer_upper>0) {// compatible hit found in this layer increase n_hits
149 int l_result = l_test + layerID;
150 n_hits+=1;
151 current_x=x_layer;
152 pat+=(1<<l_result);
153 l_current=l_result;
154 if (l_start<4&&l_result>=4&&delta_layer<dMO){
155 dMO=delta_layer;
156 }else if (l_start<2&&l_result>=2&&l_result<4&&delta_layer<dMM) {
157 dMM=delta_layer;
158 } else if (l_start>=4&&l_start<5&&l_result>=6&&delta_layer<dMM) {
159 dMM=delta_layer;
160 }
161 }// if (n_layer)
162 if(layerID == 0){
163 ATH_MSG_DEBUG(" l_test = "<< l_test+layerID << " n_layer= "<< n_layer
164 << " x= " << current_x << " pat= " << (std::bitset<8>)pat);
165 }
166 else if(layerID == 1){
167 ATH_MSG_DEBUG(" l_test = "<< l_test+layerID << " n_layer_upper= "<< n_layer_upper
168 << " x= " << current_x << " pat= " << (std::bitset<8>)pat);
169 }
170 }//test layer is 2 || 4 || 6
171 else if(l_test % 2 == 1){
172 int n_layer=0; //number of found clusters in sets
173 double x_layer=0; // position of the best cluster at test layer
174 double delta_layer=999; //minimum d(Z/R)
175 // loop on hits of test layer and picks the one with smaller distance from current_x
176 for (std::list<double>::iterator i_test=rpc_x->at(l_test).begin(); i_test!=rpc_x->at(l_test).end(); ++i_test){
177 double delta=-1;
178 // check if within the road
179 if (!deltaOK( l_current,l_test,current_x,*i_test,iphi,delta)) continue;
180 n_layer++; //in the layer,if there is the cluster which pass th deltaOK
181 // if closest hit update x_layer
182 if (delta<delta_layer) {
183 delta_layer=delta;
184 x_layer=*i_test;
185 index[l_test] = std::distance(rpc_x->at(l_test).begin(), i_test);//mod!
186 //"index" is the ID of the best matched cluster in "l_test" layer
187 }
188 }//for i_test
189 if (n_layer>0) {// compatible hit found in this layer increase n_hits
190 n_hits+=1;
191 current_x=x_layer;
192 pat+=(1<<l_test);
193 l_current=l_test;
194 if (l_start<4&&l_test>=4&&delta_layer<dMO){
195 dMO=delta_layer;
196 }else if (l_start<2&&l_test>=2&&l_test<4&&delta_layer<dMM) {
197 dMM=delta_layer;
198 } else if (l_start>=4&&l_start<5&&l_test>=6&&delta_layer<dMM) {
199 dMM=delta_layer;
200 }
201 }// if (n_layer)
202
203 ATH_MSG_DEBUG(" l_test = "<< l_test << " n_layer= "<< n_layer
204 << " x= " << current_x << " pat= " << (std::bitset<8>)pat);
205 ATH_MSG_DEBUG(" dMM/dMO = " << dMM << "/" << dMO);
206 }
207 if(skipLayer){
208 l_test++;
209 skipLayer = false;
210 }
211
212
213 }//for l_test
215 if(n_hits >= 2){
216 crPat.phi_middle = *i_start;
217 crPat.phi_outer = current_x;
218 crPat.dMM = dMM;
219 crPat.dMO = dMO;
220 for(int i = 0; i < 8; i++){
221 crPat.clustersID[i] = index[i];
222 }
223 crPatterns.push_back(std::move(crPat));
224 }
225 }//for i_start
226 }//for l_start
227 return crPatterns.size() > 0;
228}
229// --------------------------------------------------------------------------------
230// --------------------------------------------------------------------------------
231
232bool TrigL2MuonSA::ClusterPatFinder::findPatternEta(std::vector<std::vector<double>>& aw,
233 std::vector<std::vector<double>>& bw,
234 TrigL2MuonSA::RpcLayerClusters& rpcLayerClusters) const
235{
236 std::vector<TrigL2MuonSA::ClusterPattern> crPatterns;
237
238 if( !patfinder_forEta(crPatterns, rpcLayerClusters) ) return false;
239 removeSimilarRoad(crPatterns);
240 for(TrigL2MuonSA::ClusterPattern& crPat : crPatterns){
241 if( !crPat.isGoodFit ) continue;
242 for(int i=0; i<3; i++){
243 aw[i].push_back(crPat.aw[i]);
244 bw[i].push_back(crPat.bw[i]);
245
246 ATH_MSG_DEBUG("aw[" << i << "]/bw[" << i << "] = " << crPat.aw[i] << "/" << crPat.bw[i]);
247 }
248 }
249 return true;
250}
251
252// --------------------------------------------------------------------------------
253// --------------------------------------------------------------------------------
254
255bool TrigL2MuonSA::ClusterPatFinder::patfinder_forEta(std::vector<TrigL2MuonSA::ClusterPattern>& crPatterns,
256 TrigL2MuonSA::RpcLayerClusters& rpcLayerClusters) const
257{
258 bool iphi = false;
259 std::vector<std::list<double>> * rpc_x;
260 rpc_x = &rpcLayerClusters.clusters_in_layer_eta;
261 int layer_end;
262 if(rpc_x->at(6).size()+rpc_x->at(7).size() >0) layer_end = 7;//special "feet" towers
263 else layer_end = 5;
264
265 // Loop on start layer
266 ATH_MSG_DEBUG("=== start to find rpc clusters pattern ===");
267 for (int l_start=0; l_start<layer_end; l_start++){
268 size_t index[8]={};
269 for(int i=0; i<8; i++) index[i]=-1;
271 crPat.Clear();
272
273 // Loop on hits of start layer, for each hit try a new pattern
274 for (std::list<double>::iterator i_start=rpc_x->at(l_start).begin(); i_start!=rpc_x->at(l_start).end(); ++i_start){
275 int n_hits=1;
276 unsigned int pat=(1<<l_start); // bit pattern of hit layers
277 double dMO=9999; // disstance middle-outer station
278 double dMM=9999; // distance RPC1-RPC2 on middle stations
279 double aw[3] = {0., 0., 0. };
280 double bw[3] = {0., 0., 0. };
281 double current_x =*i_start; // set current_x to the starting hit
282 int l_current = l_start;
283 index[l_start] = std::distance(rpc_x->at(l_start).begin(), i_start);//mod!
284
285 ATH_MSG_DEBUG("l_start = "<< l_start << " x= " << current_x
286 << " pat= " << (std::bitset<8>) pat);
287
288 // ----- add compatible hits in other layers ----//
289 // loop on test layers:
290 bool skipLayer = false;
291 for (int l_test=l_start+1; l_test<=layer_end; l_test++){
292 ATH_MSG_DEBUG("start searching the clusters in RPC plane, l_test = " << l_test);
293 if(l_test % 2 == 0){
294 int n_layer=0; //number of found clusters in sets
295 int n_layer_upper=0;
296 double x_layer=0; // position of the best cluster at test layer
297 double delta_layer=999; //minimum d(Z/R)
298 int layerID = 0;
299 for(int ilayer = 0; ilayer < 2; ilayer++){
300 for (std::list<double>::iterator i_test=rpc_x->at(l_test + ilayer).begin(); i_test!=rpc_x->at(l_test + ilayer).end(); ++i_test){
301 double delta=-1;
302 // check if within the road
303 if (!deltaOK( l_current,l_test + ilayer,current_x,*i_test,iphi,delta)) continue;
304 if(ilayer == 0) n_layer++; //in the layer,if there is the cluster which pass th deltaOK
305 else if(ilayer == 1) n_layer_upper++;
306 // if closest hit update x_layer
307 if (delta<delta_layer) {
308 delta_layer=delta;
309 x_layer=*i_test;
310 layerID = ilayer;
311 index[l_test+ilayer] = std::distance(rpc_x->at(l_test+ilayer).begin(), i_test);//mod!
312 //"index" is the ID of the best matched cluster in "l_test" layer
313 if(ilayer == 1){
314 ATH_MSG_DEBUG("the minimum delta was found in upper layer, update info");
315 index[l_test] = 0;
316 skipLayer = true;
317 }
318 }
319 }//for i_test
320 }//for ilayer
321 if (n_layer>0 || n_layer_upper>0) {// compatible hit found in this layer increase n_hits
322 int l_result = l_test + layerID;
323 n_hits+=1;
324 current_x=x_layer;
325 pat+=(1<<l_result);
326 l_current=l_result;
327 if (l_start<4&&l_result>=4&&delta_layer<dMO){
328 dMO=delta_layer;
329 }else if (l_start<2&&l_result>=2&&l_result<4&&delta_layer<dMM) {
330 dMM=delta_layer;
331 } else if (l_start>=4&&l_start<5&&l_result>=6&&delta_layer<dMM) {
332 dMM=delta_layer;
333 }
334 }// if (n_layer)
335 if(layerID == 0){
336 ATH_MSG_DEBUG(" l_test = "<< l_test+layerID << " n_layer= "<< n_layer
337 << " x= " << current_x << " pat= " << (std::bitset<8>)pat);
338 }
339 else if(layerID == 1){
340 ATH_MSG_DEBUG(" l_test = "<< l_test+layerID << " n_layer_upper= "<< n_layer_upper
341 << " x= " << current_x << " pat= " << (std::bitset<8>)pat);
342 }
343 }//test layer is 2 || 4 || 6
344 else if(l_test % 2 == 1){
345 int n_layer=0; //number of found clusters in sets
346 double x_layer=0; // position of the best cluster at test layer
347 double delta_layer=999; //minimum d(Z/R)
348 // loop on hits of test layer and picks the one with smaller distance from current_x
349 for (std::list<double>::iterator i_test=rpc_x->at(l_test).begin(); i_test!=rpc_x->at(l_test).end(); ++i_test){
350 double delta=-1;
351 // check if within the road
352 if (!deltaOK( l_current,l_test,current_x,*i_test,iphi,delta)) continue;
353 n_layer++; //in the layer,if there is the cluster which pass th deltaOK
354 // if closest hit update x_layer
355 if (delta<delta_layer) {
356 delta_layer=delta;
357 x_layer=*i_test;
358 index[l_test] = std::distance(rpc_x->at(l_test).begin(), i_test);//mod!
359 //"index" is the ID of the best matched cluster in "l_test" layer
360 }
361 }//for i_test
362 if (n_layer>0) {// compatible hit found in this layer increase n_hits
363 n_hits+=1;
364 current_x=x_layer;
365 pat+=(1<<l_test);
366 l_current=l_test;
367 if (l_start<4&&l_test>=4&&delta_layer<dMO){
368 dMO=delta_layer;
369 }else if (l_start<2&&l_test>=2&&l_test<4&&delta_layer<dMM) {
370 dMM=delta_layer;
371 }else if(l_start>=4&&l_start<5&&l_test>=6&&delta_layer<dMM) {
372 dMM=delta_layer;
373 }
374 }// if (n_layer)
375
376 ATH_MSG_DEBUG(" l_test = "<< l_test << " n_layer= "<< n_layer
377 << " x= " << current_x << " pat= " << (std::bitset<8>)pat);
378 ATH_MSG_DEBUG(" dMM/dMO = " << dMM << "/" << dMO);
379 }
380 if(skipLayer){
381 l_test++;
382 skipLayer = false;
383 }
384 }//for l_test
385
387 if (n_hits>=2) {
388 crPat.dMM = dMM;
389 crPat.dMO = dMO;
390 abcal(pat, index, aw, bw, rpcLayerClusters);
391 for(int i = 0; i < 3; i++){
392 crPat.aw[i] = aw[i];
393 crPat.bw[i] = bw[i];
394 }
395 for(int i = 0; i < 8; i++){
396 crPat.clustersID[i] = index[i];
397 }
398 crPatterns.push_back(crPat);
399 }
400 }//for i_start
401 }//for l_start
402 return crPatterns.size() > 0;
403}
404
405// --------------------------------------------------------------------------------
406// --------------------------------------------------------------------------------
407
408bool TrigL2MuonSA::ClusterPatFinder::deltaOK(int l1, int l2, double x1, double x2, int isphi, double &delta) const
409{
410
411
412 // ROAD tuned for ~20 GeV
413 /*
414 double delta_gasgap_eta = 0.004;
415 double delta_lowpt_eta = 0.005;
416 double delta_highpt_eta = 0.012;
417 double delta_feet_eta = 0.02;
418
419 double delta_gasgap_phi = 0.004;
420 double delta_lowpt_phi = 0.005;
421 double delta_highpt_phi = 0.008;
422 double delta_feet_phi = 0.02;
423 */
424
425 //OPEN road
426
427 const double delta_gasgap_eta = 0.01;
428 const double delta_lowpt_eta = 0.05;
429 const double delta_highpt_eta = 0.1;
430 const double delta_feet_eta = 0.05;
431
432 const double delta_gasgap_phi = 0.01;
433 const double delta_lowpt_phi = 0.03;
434 const double delta_highpt_phi = 0.04;
435 const double delta_feet_phi = 0.03;
436
437 // calculate delta-eta or delta-phi
438 if(isphi) delta=std::abs(std::acos(std::cos(x2-x1)));
439 else delta=std::abs(x2-x1);
440
441 double delta_max=0;
442 if (l1>l2) {
443 int tmp=l2;
444 l2=l1;
445 l1=tmp;
446 }
447 // calculate delta_max
448 if (isphi){
449 if (l2-l1==1&&(l1==0||l1==2||l1==4||l1==6)){
450 delta_max=delta_gasgap_phi;
451 } else if (l1<2&&l2<4) {
452 delta_max=delta_lowpt_phi;
453 }else if (l1<4&&l2>=4) {
454 delta_max=delta_highpt_phi;
455 }else if (l1<6&&l1>=4&&l2>=6) {
456 delta_max=delta_feet_phi;
457 }
458 } else {
459 if (l2-l1==1&&(l1==0||l1==2||l1==4||l1==6)){
460 delta_max=delta_gasgap_eta;
461 } else if (l1<2&&l2>=2&&l2<4) {
462 delta_max=delta_lowpt_eta;
463 }else if (l1<4&&l2>=4) {
464 delta_max=delta_highpt_eta;
465 }else if (l1<6&&l1>=4&&l2>=6) {
466 delta_max=delta_feet_eta;
467 }
468 }
469
470 // evaluate the result
471 return delta<delta_max;
472
473}
474
475// --------------------------------------------------------------------------------
476// --------------------------------------------------------------------------------
477
478double TrigL2MuonSA::ClusterPatFinder::calibR(const std::string& stationName, double R, double Phi) const
479{
480 double DeltaPhi, temp_phi;
481 double calibPhi = std::acos(std::cos(Phi)); // 0 < Phi < 2PI
482
483 if(std::string::npos != stationName.rfind('L')){//For Large , SP
484 DeltaPhi= 999; temp_phi=9999;
485 for(int inum=0;inum < 8;inum++){
486 temp_phi = std::abs((inum * M_PI/4.0 )- calibPhi);
487 DeltaPhi = std::min(temp_phi, DeltaPhi);
488 }
489 }else if(std::string::npos != stationName.rfind('S') ||
490 std::string::npos != stationName.rfind('F') ||
491 std::string::npos != stationName.rfind('G') ){
492 DeltaPhi= 999; temp_phi=9999;
493
494 for(int inum=0;inum < 8;inum++){
495 temp_phi = std::abs(inum *(M_PI/4.0 )+(M_PI/8.0) - calibPhi);
496 DeltaPhi = std::min(temp_phi, DeltaPhi);
497 }//for end
498 }else return R;
499
500 return R *std::cos(DeltaPhi);
501}//calbR()
502
503// --------------------------------------------------------------------------------
504// --------------------------------------------------------------------------------
505
506void TrigL2MuonSA::ClusterPatFinder::abcal(unsigned int result_pat, size_t index[], double aw[], double bw[], TrigL2MuonSA::RpcLayerClusters& rpcLayerClusters) const
507{
508 const float ZERO_LIMIT = 1.e-5;
509
510 std::vector<std::vector<double> > * rpc_R;
511 std::vector<std::vector<double> > * rpc_Z;
512 rpc_R = &rpcLayerClusters.clusters_in_layer_R;
513 rpc_Z = &rpcLayerClusters.clusters_in_layer_Z;
514 double R[8]={0,0,0,0,0,0,0,0};
515 double Z[8]={0,0,0,0,0,0,0,0};
516 unsigned int bit=1;
517
518 int hot_min[3]={999,999,999};
519 int hot_max[3]={-999,-999,-999};
520
521 int out_counter=0;
522
523 for(int i=0; i<8; i++){
524 if(i != 0) bit = bit << 1;
525 if((result_pat & bit)==false) continue;
526 R[i] = rpc_R->at(i).at(index[i]);
527 Z[i] = rpc_Z->at(i).at(index[i]);
528
529 if(i < hot_min[0]) hot_min[0] = i;
530 if(i < hot_min[1]) hot_min[1] = i;
531 if(1 < i && out_counter <1) hot_min[2] = i;
532
533 if(i < 4){
534 hot_max[0] = i;
535 hot_max[1] = i;
536 }
537 if(hot_max[2] < i ) hot_max[2] = i;
538
539 if(1 < i) out_counter++;
540 }//for i
541 //
542 double R_refit = 0;
543 double Z_refit = 0;
544 bool refitFlag = false;
545 if((hot_max[1]-hot_min[1] == 1) && (hot_min[1] == 0 || hot_min[1] == 2)){
546 refitFlag = true;
547 R_refit = (R[hot_max[1]]+R[hot_min[1]])/2;
548 Z_refit = (Z[hot_max[1]]+Z[hot_min[1]])/2;
549 }
550
551 unsigned int inn_bit;
552 inn_bit=0x3;//00000011
553 if((result_pat & inn_bit)==inn_bit){
554 R[hot_min[0]] = (R[0]+R[1])/2.0;
555 Z[hot_min[0]] = (Z[0]+Z[1])/2.0;
556 }
557 inn_bit=0xC;//00001100
558 if((result_pat & inn_bit)==inn_bit){
559 R[hot_max[0]] = (R[2]+R[3])/2.0;
560 Z[hot_max[0]] = (Z[2]+Z[3])/2.0;
561 }
562
563 unsigned int mid_bit;
564 mid_bit=0x3;//00000011
565 if((result_pat & mid_bit)==mid_bit){
566 R[hot_min[1]] = (R[0]+R[1])/2.0;
567 Z[hot_min[1]] = (Z[0]+Z[1])/2.0;
568 }
569 mid_bit=0xC;//00001100
570 if((result_pat & mid_bit)==mid_bit){
571 R[hot_max[1]] = (R[2]+R[3])/2.0;
572 Z[hot_max[1]] = (Z[2]+Z[3])/2.0;
573 }
574
575 unsigned int out_bit;
576 out_bit=0xC;//00001100
577 if((result_pat & out_bit)==out_bit){
578 R[hot_min[2]] = (R[2]+R[3])/2.0;
579 Z[hot_min[2]] = (Z[2]+Z[3])/2.0;
580 }
581
582 out_bit=0x30;//00110000
583 if((result_pat & out_bit)==out_bit){
584 R[hot_max[2]] = (R[4]+R[5])/2.0;
585 Z[hot_max[2]] = (Z[4]+Z[5])/2.0;
586 }
587
588 out_bit=0xC0;//11000000
589 if((result_pat & out_bit)==out_bit){
590 R[hot_max[2]] = (R[6]+R[7])/2.0;
591 Z[hot_max[2]] = (Z[6]+Z[7])/2.0;
592 }
593
594 inn_bit=0xF;//00001111
595 double theta_m,theta_t, theta_f;
596 if((result_pat & inn_bit)==inn_bit){
597 theta_m = std::atan2(R[hot_min[0]],Z[hot_min[0]]);
598 theta_t = std::atan2(R[hot_max[0]]-R[hot_min[0]],Z[hot_max[0]]-Z[hot_min[0]]);
599 theta_f = (theta_m+theta_t)/2.0;
600
601 aw[0] = std::tan(theta_f);
602 bw[0] = R[hot_min[0]] - Z[hot_min[0]]*aw[0];
603 aw[0] = 1.0/aw[0];
604 }else{
605 if(hot_min[0]!=999){
606 aw[0] = Z[hot_min[0]] / R[hot_min[0]];
607 bw[0] = 0.0;
608 }else{
609 aw[0] = Z[hot_max[0]] / R[hot_max[0]];
610 bw[0] = 0.0;
611 }//else
612 }//else
613
614 for(int i=1;i<3;i++){
615 if(hot_max[i]!=-999 && hot_min[i]!=999){
616 if(std::abs(Z[hot_max[i]] - Z[hot_min[i]]) > ZERO_LIMIT) {
617 aw[i] = (R[hot_max[i]]- R[hot_min[i]]) / (Z[hot_max[i]]-Z[hot_min[i]]);
618 bw[i] = R[hot_max[i]] - Z[hot_max[i]]*aw[i];
619 aw[i] = 1.0/aw[i];
620 }else if(i<2){
621 aw[i] = Z[hot_min[i]] / R[hot_min[i]];
622 bw[i] = 0.0;
623 } else{
624 aw[i] = Z[hot_max[i]] / R[hot_max[i]];
625 bw[i] = 0.0;
626 }
627 }else{
628 if(i <2){
629 if(hot_min[i]!=999){
630 aw[i] = Z[hot_min[i]] / R[hot_min[i]];
631 bw[i] = 0.0;
632 }else if(hot_max[i]!=-999){
633 aw[i] = Z[hot_max[i]] / R[hot_max[i]];
634 bw[i] = 0.0;
635 }
636 }else{
637 if(hot_max[i]!=-999){
638 aw[i] = Z[hot_max[i]] / R[hot_max[i]];
639 bw[i] = 0.0;
640 }else if(hot_min[i]!=999){
641 aw[i] = Z[hot_min[i]] / R[hot_min[i]];
642 bw[i] = 0.0;
643 }
644 }
645 }
646 }
647 //==========================================
648 //If the clusters only in RPC1 or RPC2 are used for fitting,
649 //then refit by adding vertex (R, Z) = (0, 0) will be done
650 //
651 if(refitFlag){
652 aw[1] = Z_refit/R_refit;
653 bw[1] = 0.0;
654 ATH_MSG_DEBUG("the result of refit : aw/bw = " << aw[1] << "/" << bw[1]);
655 }
656 //==========================================
657
658}//abcal()
659
660// --------------------------------------------------------------------------------
661// --------------------------------------------------------------------------------
662void TrigL2MuonSA::ClusterPatFinder::removeSimilarRoad(std::vector<TrigL2MuonSA::ClusterPattern>& crPatterns) const
663{
664 int nGroup = 1;
665
666 ATH_MSG_DEBUG("============= setGroup start ========================");
667 setGroup(nGroup, crPatterns);
668
669 ATH_MSG_DEBUG("============= selectGoodFit start ========================");
670 selectGoodFit(nGroup, crPatterns);
671}
672
673// --------------------------------------------------------------------------------
674// --------------------------------------------------------------------------------
675
677 std::vector<TrigL2MuonSA::ClusterPattern>& crPatterns) const
678{
679 nGroup = 1;
680 crPatterns.at(0).group = 0; //initial index is defined as first group (No.0)
681 if(crPatterns.size() > 1){
682 for(unsigned int iClus_start = 1; iClus_start < crPatterns.size(); iClus_start++){
683 ATH_MSG_DEBUG("checked road : clusterID = {" << crPatterns.at(iClus_start).clustersID[0] << "," << crPatterns.at(iClus_start).clustersID[1] << "," << crPatterns.at(iClus_start).clustersID[2] << "," << crPatterns.at(iClus_start).clustersID[3] << "," << crPatterns.at(iClus_start).clustersID[4] << "," << crPatterns.at(iClus_start).clustersID[5] << "," << crPatterns.at(iClus_start).clustersID[6] << "," << crPatterns.at(iClus_start).clustersID[7] << "}");
684 for(int igroup = 0; igroup < nGroup; igroup++){
685 bool isDiffGroupFlag = false;
686 int countDiffId_min = 9999;
687 for(unsigned int iClus_test = 0; iClus_test < crPatterns.size(); iClus_test++){
688 if(crPatterns.at(iClus_test).group != igroup) continue;
689 int countDiffId = 0;
690 bool isDiffFlag = false;
691 ATH_MSG_DEBUG("the compared road : clusterID = {" << crPatterns.at(iClus_test).clustersID[0] << "," << crPatterns.at(iClus_test).clustersID[1] << "," << crPatterns.at(iClus_test).clustersID[2] << "," << crPatterns.at(iClus_test).clustersID[3] << "," << crPatterns.at(iClus_test).clustersID[4] << "," << crPatterns.at(iClus_test).clustersID[5] << "," << crPatterns.at(iClus_test).clustersID[6] << "," << crPatterns.at(iClus_test).clustersID[7] << "}");
692 for(int iLay = 0; iLay < 8; iLay++){
693 if(crPatterns.at(iClus_test).clustersID[iLay] > -1 && crPatterns.at(iClus_start).clustersID[iLay] > -1){
694 if(crPatterns.at(iClus_test).clustersID[iLay] != crPatterns.at(iClus_start).clustersID[iLay]) countDiffId++;
695 }
696 }
697 ATH_MSG_DEBUG("the number of different id's clusters = " << countDiffId);
698 if(countDiffId > 1){ isDiffFlag = true;}
699 else{ if(countDiffId_min > countDiffId) countDiffId_min = countDiffId;}
700 if(isDiffFlag) isDiffGroupFlag = true;
701 }//iClus_test
702 if(!isDiffGroupFlag){
703 ATH_MSG_DEBUG("this set may be in this group");
704 crPatterns.at(iClus_start).groupCand.emplace(igroup, countDiffId_min);
705 }// if isDiffGroupFlag
706 }// igroup
707 if(crPatterns.at(iClus_start).groupCand.empty()){
708 ATH_MSG_DEBUG("this road is accepted, Group No. " << nGroup);
709 crPatterns.at(iClus_start).group = nGroup;
710 nGroup++;
711 }//if groupCand
712 else{
713 ATH_MSG_DEBUG("this road is denied, searching the appropriate group......");
714 int theGroup = 0;
715 int minDiff = 2;
716 for(auto itGrp = crPatterns.at(iClus_start).groupCand.begin(); itGrp != crPatterns.at(iClus_start).groupCand.end(); ++itGrp){
717 ATH_MSG_DEBUG("group No." << itGrp->first << ", number of different ID." << itGrp->second);
718 if(minDiff > (itGrp->second)){
719 theGroup = itGrp->first;
720 minDiff = itGrp->second;
721 }
722 }
723 ATH_MSG_DEBUG("the group of this road is defined as No." << theGroup);
724 crPatterns.at(iClus_start).group = theGroup;
725 }// else groupCand
726 }//iClus_start
727 }
728}
729// --------------------------------------------------------------------------------
730// --------------------------------------------------------------------------------
732 std::vector<TrigL2MuonSA::ClusterPattern>& crPatterns) const
733{
734
735 for(int iGroup = 0; iGroup < nGroup; iGroup++){
736 std::vector<TrigL2MuonSA::ClusterPattern> crpat_group;
737 crpat_group.clear();
738 int Nclus_max = -999;
739 for(TrigL2MuonSA::ClusterPattern& pat : crPatterns ){
740 if(pat.group != iGroup) continue;
741 for(int ilay = 0; ilay < 8; ilay++){
742 if(pat.clustersID[ilay] > -1) pat.nclusters++;
743 }
744 if(Nclus_max < pat.nclusters) Nclus_max = pat.nclusters;
745 crpat_group.push_back(pat);
746 ATH_MSG_DEBUG("the number of clusters = " << pat.nclusters);
747 }
748 ATH_MSG_DEBUG("max number of clusters = " << Nclus_max);
749 double smallestdMM = 999999;
750 double smallestdMO = 999999;
751
753 bestPat.Clear();
754 for(TrigL2MuonSA::ClusterPattern& grpat : crpat_group){
755 if(Nclus_max == grpat.nclusters){
756 if(grpat.dMM < smallestdMM ||
757 (grpat.dMM == smallestdMM && grpat.dMO < smallestdMO)){
758 bestPat = grpat;
759 smallestdMM = grpat.dMM;
760 smallestdMO = grpat.dMO;
761 }//dMM/dMO selection
762 }
763 }
764 for(TrigL2MuonSA::ClusterPattern& pat : crPatterns){
765 if(bestPat == pat){
766 ATH_MSG_DEBUG("find best clusterPattern!");
767 ATH_MSG_DEBUG("bestPattern aw[1]/bw[1] = " << bestPat.aw[1] << "/" << bestPat.bw[1] << ", pat aw[1]/bw[1] = " << pat.aw[1] << "/" << pat.bw[1]);
768 pat.isGoodFit = true;
769 }
770 }
771 ATH_MSG_DEBUG("clusterID = {" << bestPat.clustersID[0] << "," << bestPat.clustersID[1] << "," << bestPat.clustersID[2] << "," << bestPat.clustersID[3] << "," << bestPat.clustersID[4] << "," << bestPat.clustersID[5] << "," << bestPat.clustersID[6] << "," << bestPat.clustersID[7] << "}");
772 }
773}
774// --------------------------------------------------------------------------------
775// --------------------------------------------------------------------------------
776
#define M_PI
#define ATH_MSG_DEBUG(x)
#define x
const float ZERO_LIMIT
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
double calibR(const std::string &stationName, double R, double Phi) const
void removeSimilarRoad(std::vector< TrigL2MuonSA::ClusterPattern > &crPatterns) const
ClusterPatFinder(const std::string &type, const std::string &name, const IInterface *parent)
bool findPatternPhi(std::vector< double > &phi_middle, std::vector< double > &phi_outer, TrigL2MuonSA::RpcLayerClusters &rpcLayerClusters) const
bool patfinder(std::vector< TrigL2MuonSA::ClusterPattern > &crPattern, TrigL2MuonSA::RpcLayerClusters &rpcLayerClusters) const
bool deltaOK(int l1, int l2, double x1, double x2, int isphi, double &delta) const
void setGroup(int &nGroup, std::vector< TrigL2MuonSA::ClusterPattern > &crPatterns) const
void selectGoodFit(int nGroup, std::vector< TrigL2MuonSA::ClusterPattern > &crPatterns) const
bool findPatternEta(std::vector< std::vector< double > > &aw, std::vector< std::vector< double > > &bw, TrigL2MuonSA::RpcLayerClusters &rpcLayerClusters) const
void abcal(unsigned int result_pat, size_t index[], double aw[], double bw[], TrigL2MuonSA::RpcLayerClusters &rpcLayerClusters) const
bool patfinder_forEta(std::vector< TrigL2MuonSA::ClusterPattern > &crPatterns, TrigL2MuonSA::RpcLayerClusters &rpcLayerClusters) const
void addCluster(const std::string &stationName, int stationEta, bool measuresPhi, unsigned int gasGap, unsigned int doubletR, double gPosX, double gPosY, double gPosZ, TrigL2MuonSA::RpcLayerClusters &rpcLayerClusters) const
Definition index.py:1
std::vector< std::vector< double > > clusters_in_layer_Z
std::vector< std::list< double > > clusters_in_layer_phi
std::vector< std::vector< double > > clusters_in_layer_R
std::vector< std::list< double > > clusters_in_layer_eta