ATLAS Offline Software
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 
5 #include "ClusterRoadDefiner.h"
6 
9 
10 // --------------------------------------------------------------------------------
11 // --------------------------------------------------------------------------------
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_CHECK(m_regionSelector.retrieve());
27  ATH_MSG_DEBUG("Retrieved the RegionSelector tool ");
28 
29  return StatusCode::SUCCESS;
30 }
31 
32 // --------------------------------------------------------------------------------
33 // --------------------------------------------------------------------------------
34 
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 // --------------------------------------------------------------------------------
TrigL2MuonSA::MuonRoad::MDT_sector_overlap
int MDT_sector_overlap
Definition: MuonRoad.h:89
TrigL2MuonSA::N_SECTOR
constexpr int N_SECTOR
Definition: MuonRoad.h:16
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
TrigL2MuonSA::ClusterRoadDefiner::defineRoad
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
Definition: ClusterRoadDefiner.cxx:35
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
AthMsgStreamMacros.h
TrigL2MuonSA::RpcFitResult::phi
double phi
Definition: RpcFitResult.h:44
TrigL2MuonSA::MuonRoad::phiMiddle
double phiMiddle
Definition: MuonRoad.h:81
TrigL2MuonSA::N_LAYER
constexpr int N_LAYER
Definition: MuonRoad.h:17
TrigL2MuonSA::RpcFitResult
Definition: RpcFitResult.h:14
TrigL2MuonSA::RpcFitResult::offset_middle
double offset_middle
Definition: RpcFitResult.h:53
TrigL2MuonSA::RpcFitResult::Clear
void Clear()
Definition: RpcFitResult.h:19
ClusterRoadDefiner.h
TrigL2MuonSA::MuonRoad::bw
double bw[N_STATION][N_SECTOR]
Definition: MuonRoad.h:84
M_PI
#define M_PI
Definition: ActiveFraction.h:11
TrigL2MuonSA::MuonRoad::isEndcap
bool isEndcap
Definition: MuonRoad.h:74
xAOD::MuonRoI_v1::eta
float eta() const
The pseudorapidity ( ) of the muon candidate.
xAOD::etaMax
etaMax
Definition: HIEventShape_v2.cxx:46
TrigL2MuonSA::RpcFitResult::offset_inner
double offset_inner
Definition: RpcFitResult.h:49
TrigRoiDescriptor
nope - should be used for standalone also, perhaps need to protect the class def bits #ifndef XAOD_AN...
Definition: TrigRoiDescriptor.h:56
TrigL2MuonSA::RpcFitResult::offset_outer
double offset_outer
Definition: RpcFitResult.h:57
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
TrigL2MuonSA::MuonRoad::aw
double aw[N_STATION][N_SECTOR]
Definition: MuonRoad.h:83
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
TrigL2MuonSA::MuonRoad::side
int side
Definition: MuonRoad.h:78
TrigL2MuonSA::MuonRoad::phiRoI
double phiRoI
Definition: MuonRoad.h:82
TrigL2MuonSA::ClusterRoadDefiner::initialize
virtual StatusCode initialize() override
Definition: ClusterRoadDefiner.cxx:23
TrigL2MuonSA::MuonRoad::stationList
std::vector< Identifier > stationList
Definition: MuonRoad.h:102
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
TrigL2MuonSA::RpcFitResult::slope_inner
double slope_inner
Definition: RpcFitResult.h:48
TrigL2MuonSA::ClusterRoadDefiner::ClusterRoadDefiner
ClusterRoadDefiner(const std::string &type, const std::string &name, const IInterface *parent)
Definition: ClusterRoadDefiner.cxx:13
lumiFormat.i
int i
Definition: lumiFormat.py:85
TrigL2MuonSA::MuonRoad
Definition: MuonRoad.h:20
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
IRoiDescriptor
Describes the API of the Region of Ineterest geometry.
Definition: IRoiDescriptor.h:23
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TrigL2MuonSA::MuonRoad::MDT_sector_trigger
int MDT_sector_trigger
Definition: MuonRoad.h:88
TrigL2MuonSA::RpcFitResult::slope_middle
double slope_middle
Definition: RpcFitResult.h:52
xAOD::MuonRoI_v1
Class describing a LVL1 muon region of interest.
Definition: MuonRoI_v1.h:29
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
ZERO_LIMIT
const float ZERO_LIMIT
Definition: VP1TriggerHandleL2.cxx:37
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:239
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
TrigL2MuonSA::N_STATION
constexpr int N_STATION
Definition: MuonRoad.h:15
TMVAToMVAUtils::convert
std::unique_ptr< MVAUtils::BDT > convert(TMVA::MethodBDT *bdt, bool isRegression=true, bool useYesNoLeaf=false)
Definition: TMVAToMVAUtils.h:114
TrigL2MuonSA::MuonRoad::LargeSmall
int LargeSmall
Definition: MuonRoad.h:79
TrigL2MuonSA::RpcFitResult::isSuccess
bool isSuccess
Definition: RpcFitResult.h:38
LArCellBinning.etaMin
etaMin
Definition: LArCellBinning.py:84
TrigL2MuonSA::MuonRoad::rWidth
double rWidth[N_STATION][N_LAYER]
Definition: MuonRoad.h:86
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:108
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:567
TrigL2MuonSA::RpcFitResult::slope_outer
double slope_outer
Definition: RpcFitResult.h:56
TrigRoiDescriptor
Athena::TPCnvVers::Current TrigRoiDescriptor
Definition: TrigSteeringEventTPCnv.cxx:68
TrigRoiDescriptor.h
TrigL2MuonSA::MuonRoad::Special
int Special
Definition: MuonRoad.h:80
xAOD::MuonRoI_v1::getSectorID
int getSectorID() const
Get the sector ID number.
Definition: MuonRoI_v1.cxx:133
AthAlgTool
Definition: AthAlgTool.h:26
IdentifierHash
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
Definition: IdentifierHash.h:25
TrigL2MuonSA::MuonRoad::Clear
void Clear()
Definition: MuonRoad.h:25
IdContext
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
Definition: IdContext.h:26
xAOD::MuonRoI_v1::phi
float phi() const
The azimuthal angle ( ) of the muon candidate.
Identifier
Definition: IdentifierFieldParser.cxx:14