ATLAS Offline Software
ClusterPatFinder.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 "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):
20 {
21 }
22 
23 // --------------------------------------------------------------------------------
24 // --------------------------------------------------------------------------------
25 
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 // --------------------------------------------------------------------------------
66 bool 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 // --------------------------------------------------------------------------------
85 bool 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(crPat);
224  }
225  }//for i_start
226  }//for l_start
227  return crPatterns.size() > 0;
228 }
229 // --------------------------------------------------------------------------------
230 // --------------------------------------------------------------------------------
231 
232 bool 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 
255 bool 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 
408 bool 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 
478 double 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 
506 void 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 // --------------------------------------------------------------------------------
662 void 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 
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
TrigL2MuonSA::ClusterPattern::aw
double aw[3]
Definition: ClusterPatFinder.h:22
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
dumpTgcDigiDeadChambers.gasGap
list gasGap
Definition: dumpTgcDigiDeadChambers.py:33
AthMsgStreamMacros.h
TrigL2MuonSA::RpcLayerClusters::clusters_in_layer_R
std::vector< std::vector< double > > clusters_in_layer_R
Definition: ClusterPatFinder.h:62
dumpTgcDigiDeadChambers.stationName
dictionary stationName
Definition: dumpTgcDigiDeadChambers.py:30
index
Definition: index.py:1
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
plotBeamSpotCompare.x2
x2
Definition: plotBeamSpotCompare.py:218
TrigL2MuonSA::ClusterPattern::dMM
double dMM
Definition: ClusterPatFinder.h:20
createCablingJSON.doubletR
int doubletR
Definition: createCablingJSON.py:15
M_PI
#define M_PI
Definition: ActiveFraction.h:11
TrigL2MuonSA::ClusterPatFinder::selectGoodFit
void selectGoodFit(int nGroup, std::vector< TrigL2MuonSA::ClusterPattern > &crPatterns) const
Definition: ClusterPatFinder.cxx:731
Phi
@ Phi
Definition: RPCdef.h:8
TrigL2MuonSA::RpcLayerClusters::clusters_in_layer_phi
std::vector< std::list< double > > clusters_in_layer_phi
Definition: ClusterPatFinder.h:60
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
x
#define x
TrigL2MuonSA::ClusterPatFinder::setGroup
void setGroup(int &nGroup, std::vector< TrigL2MuonSA::ClusterPattern > &crPatterns) const
Definition: ClusterPatFinder.cxx:676
TrigL2MuonSA::ClusterPattern::dMO
double dMO
Definition: ClusterPatFinder.h:21
TrigL2MuonSA::RpcLayerClusters::clusters_in_layer_Z
std::vector< std::vector< double > > clusters_in_layer_Z
Definition: ClusterPatFinder.h:61
TrigL2MuonSA::ClusterPattern::clustersID
int clustersID[8]
Definition: ClusterPatFinder.h:24
TrigL2MuonSA::ClusterPattern::bw
double bw[3]
Definition: ClusterPatFinder.h:23
TrigL2MuonSA::ClusterPatFinder::findPatternEta
bool findPatternEta(std::vector< std::vector< double >> &aw, std::vector< std::vector< double >> &bw, TrigL2MuonSA::RpcLayerClusters &rpcLayerClusters) const
Definition: ClusterPatFinder.cxx:232
skel.l2
l2
Definition: skel.GENtoEVGEN.py:399
TrigL2MuonSA::ClusterPatFinder::deltaOK
bool deltaOK(int l1, int l2, double x1, double x2, int isphi, double &delta) const
Definition: ClusterPatFinder.cxx:408
lumiFormat.i
int i
Definition: lumiFormat.py:85
TrigL2MuonSA::ClusterPatFinder::calibR
double calibR(const std::string &stationName, double R, double Phi) const
Definition: ClusterPatFinder.cxx:478
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
test_pyathena.parent
parent
Definition: test_pyathena.py:15
TrigL2MuonSA::RpcLayerClusters
Definition: ClusterPatFinder.h:58
ClusterPatFinder.h
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
TrigL2MuonSA::RpcLayerClusters::clusters_in_layer_eta
std::vector< std::list< double > > clusters_in_layer_eta
Definition: ClusterPatFinder.h:59
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
ZERO_LIMIT
const float ZERO_LIMIT
Definition: VP1TriggerHandleL2.cxx:37
dso-stats.pat
pat
Definition: dso-stats.py:39
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
TrigL2MuonSA::ClusterPattern::Clear
void Clear()
Definition: ClusterPatFinder.h:30
TrigL2MuonSA::ClusterPattern::phi_middle
double phi_middle
Definition: ClusterPatFinder.h:26
TrigL2MuonSA::ClusterPatFinder::findPatternPhi
bool findPatternPhi(std::vector< double > &phi_middle, std::vector< double > &phi_outer, TrigL2MuonSA::RpcLayerClusters &rpcLayerClusters) const
Definition: ClusterPatFinder.cxx:66
TrigL2MuonSA::ClusterPatFinder::patfinder_forEta
bool patfinder_forEta(std::vector< TrigL2MuonSA::ClusterPattern > &crPatterns, TrigL2MuonSA::RpcLayerClusters &rpcLayerClusters) const
Definition: ClusterPatFinder.cxx:255
TrigL2MuonSA::ClusterPatFinder::removeSimilarRoad
void removeSimilarRoad(std::vector< TrigL2MuonSA::ClusterPattern > &crPatterns) const
Definition: ClusterPatFinder.cxx:662
TrigL2MuonSA::ClusterPatFinder::addCluster
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: ClusterPatFinder.cxx:26
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
skel.l1
l1
Definition: skel.GENtoEVGEN.py:398
AthAlgTool
Definition: AthAlgTool.h:26
TrigL2MuonSA::ClusterPattern::phi_outer
double phi_outer
Definition: ClusterPatFinder.h:27
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
TrigL2MuonSA::ClusterPatFinder::ClusterPatFinder
ClusterPatFinder(const std::string &type, const std::string &name, const IInterface *parent)
Definition: ClusterPatFinder.cxx:16
TrigL2MuonSA::ClusterPatFinder::abcal
void abcal(unsigned int result_pat, size_t index[], double aw[], double bw[], TrigL2MuonSA::RpcLayerClusters &rpcLayerClusters) const
Definition: ClusterPatFinder.cxx:506
TrigL2MuonSA::ClusterPattern
Definition: ClusterPatFinder.h:17
TrigL2MuonSA::ClusterPatFinder::patfinder
bool patfinder(std::vector< TrigL2MuonSA::ClusterPattern > &crPattern, TrigL2MuonSA::RpcLayerClusters &rpcLayerClusters) const
Definition: ClusterPatFinder.cxx:85