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  std::vector<TrigL2MuonSA::MuonRoad>& clusterRoad,
37  TrigL2MuonSA::RpcLayerClusters& rpcLayerClusters,
38  const ToolHandle<ClusterPatFinder>* clusterPatFinder,
39  std::vector<TrigL2MuonSA::RpcFitResult>& clusterFitResults,
40  double roiEtaMinLow,
41  double roiEtaMaxLow,
42  double roiEtaMinHigh,
43  double roiEtaMaxHigh) const
44 {
45  const double ZERO_LIMIT = 1e-5;
46  const int N_STATION = 3; //0:inner, 1:middle, 2:outer
47 
48  const int N_LAYER = 5; // 0: inner, 1: middle, 2: outer 4: BME 5: BMG
49  const int N_SECTOR = 2; // 0: normal, 1:overlap
50 
51  if (m_use_rpc) {
52  std::vector< std::vector< double > > aw, bw;
53  std::vector< double > clearRoad;
54  clearRoad.clear();
55  aw.assign(N_STATION, clearRoad);
56  bw.assign(N_STATION, clearRoad);
57  ATH_MSG_DEBUG("start searching eta pattern");
58  if ( (*clusterPatFinder)->findPatternEta(aw, bw, rpcLayerClusters) ) {
59  for(unsigned int iClus = 0; iClus < aw[1].size(); iClus++){
60  TrigL2MuonSA::RpcFitResult clusFitResult;
61  clusFitResult.Clear();
62  clusFitResult.isSuccess = true;
63  clusFitResult.offset_inner = (bw[0]).at(iClus);
64  clusFitResult.offset_middle = (bw[1]).at(iClus);
65  clusFitResult.offset_outer = (bw[2]).at(iClus);
66  clusFitResult.slope_inner = 1.0/(aw[0]).at(iClus);
67  clusFitResult.slope_middle = 1.0/(aw[1]).at(iClus);
68  clusFitResult.slope_outer = 1.0/(aw[2]).at(iClus);
69  ATH_MSG_DEBUG("==========================================================");
70  ATH_MSG_DEBUG("inner clusterRoad slope/offset = " << clusFitResult.slope_inner << "/" << clusFitResult.offset_inner);
71  ATH_MSG_DEBUG("middle clusterRoad slope/offset = " << clusFitResult.slope_middle << "/" << clusFitResult.offset_middle);
72  ATH_MSG_DEBUG("outer clusterRoad slope/offset = " << clusFitResult.slope_outer << "/" << clusFitResult.offset_outer);
73  for(int i=0;i<N_STATION;i++){
74  if(std::abs(1.0/aw[i].at(iClus)) <= ZERO_LIMIT) clusFitResult.isSuccess = false;
75  }
76  clusterFitResults.push_back(clusFitResult);
77  }
78  ATH_MSG_DEBUG("==========================================================");
79  } else {
80  TrigL2MuonSA::RpcFitResult clusFitResult;
81  clusFitResult.Clear();
82  clusFitResult.isSuccess = false;
83  clusterFitResults.push_back(clusFitResult);
84  }
85 
86  ATH_MSG_DEBUG("start searching phi pattern");
87  std::vector<double> phi_middle, phi_outer;
88  phi_middle.clear(); phi_outer.clear();
89  if ( (*clusterPatFinder)->findPatternPhi(phi_middle, phi_outer, rpcLayerClusters) ){
90  double phi_middle_tot = 0;
91  double phi_outer_tot = 0;
92  size_t npatternPhi = phi_middle.size();
93  if(npatternPhi > 0){
94  for(double& phi : phi_middle){
95  phi_middle_tot = phi_middle_tot + phi;
96  }
97  for(double& phi : phi_outer){
98  phi_outer_tot = phi_outer_tot + phi;
99  }
100  double phi_middle_center = phi_middle_tot/npatternPhi;
101  double phi_outer_center = phi_outer_tot/npatternPhi;
102  ATH_MSG_DEBUG("center of phi middle/outer = " << phi_middle_center << "/" << phi_outer_center);
103  for(unsigned int iClus_fit = 0; iClus_fit < clusterFitResults.size(); iClus_fit++){
104  clusterFitResults.at(iClus_fit).phi = phi_middle_center;
105  clusterFitResults.at(iClus_fit).phi_middle = phi_middle_center;
106  clusterFitResults.at(iClus_fit).phi_outer = phi_outer_center;
107  }
108  } else {
109  for(unsigned int iClus_fit = 0; iClus_fit < clusterFitResults.size(); iClus_fit++){
110  clusterFitResults.at(iClus_fit).phi = p_roi->phi();
111  clusterFitResults.at(iClus_fit).phi_middle = p_roi->phi();
112  clusterFitResults.at(iClus_fit).phi_outer = p_roi->phi();
113  }
114  }
115  } else {
116  for(unsigned int iClus_fit = 0; iClus_fit < clusterFitResults.size(); iClus_fit++){
117  clusterFitResults.at(iClus_fit).phi = p_roi->phi();
118  }
119  }
120  }
121  if(clusterFitResults.empty()){
122  TrigL2MuonSA::RpcFitResult clusFitResult;
123  clusFitResult.Clear();
124  clusFitResult.isSuccess = false;
125  clusFitResult.phi = p_roi->phi();
126  clusterFitResults.push_back(clusFitResult);
127  }
128 
129  ATH_MSG_DEBUG("stored cluster eta/phi pattern to clusterRoad");
130  for(unsigned int iClus_fit = 0; iClus_fit < clusterFitResults.size(); iClus_fit++){
131  TrigL2MuonSA::MuonRoad muonRoad;
132  muonRoad.Clear();
133  // RPC data is not available -> use RoI
134 
135  muonRoad.isEndcap = false;
136  muonRoad.phiMiddle = clusterFitResults.at(iClus_fit).phi;
137  muonRoad.phiRoI = p_roi->phi();
138  muonRoad.side = (p_roi->phi()<0.)? 0 : 1;
139  muonRoad.LargeSmall = ((p_roi->getSectorID() + 1)/2 )%2;
140 
141  int PhysicsSector = ((p_roi->getSectorID() + 1)/4 )%8 + 1;
142 
143  int special = 0;
144  if (muonRoad.LargeSmall == 0 && (PhysicsSector == 6 || PhysicsSector == 8 ))
145  special = 1;
146  else if (muonRoad.LargeSmall == 1 && (PhysicsSector == 6 || PhysicsSector == 7 ))
147  special = 1;
148  muonRoad.Special = special;
149 
150  for (int i_station=0; i_station<6; i_station++) {
151  for (int i_layer=0; i_layer<8; i_layer++) {
152  if(!clusterFitResults.at(iClus_fit).isSuccess) {
153  if (i_station==0) muonRoad.rWidth[i_station][i_layer] = 500;//for inner
154  else if (i_station==1) muonRoad.rWidth[i_station][i_layer] = 650;//for middle
155  else if (i_station==2) muonRoad.rWidth[i_station][i_layer] = 800;//for outer
156  else if (i_station==3) muonRoad.rWidth[i_station][i_layer] = 500;//EndcapInner
157  else if (i_station==4) muonRoad.rWidth[9][i_layer] = 650;//BME
158  else if (i_station==5) muonRoad.rWidth[10][i_layer] = 650;//BMG
159  else muonRoad.rWidth[i_station][i_layer] = m_rWidth_RPC_Failed;
160  }
161  else {
162  if (i_station==0) muonRoad.rWidth[i_station][i_layer] = 400;//for inner
163  else if (i_station==1) muonRoad.rWidth[i_station][i_layer] = 200;//for middle
164  else if (i_station==2) muonRoad.rWidth[i_station][i_layer] = 400;//for outer
165  else if (i_station==3) muonRoad.rWidth[i_station][i_layer] = 400;//EndcapInner
166  else if (i_station==4) muonRoad.rWidth[9][i_layer] = m_rWidth_RPC_Failed;//BME
167  else if (i_station==5) muonRoad.rWidth[10][i_layer] = m_rWidth_RPC_Failed;//BMG
168  else muonRoad.rWidth[i_station][i_layer] = m_rWidth_RPC_Failed;
169  }
170  }
171  }
172  int sector_trigger = 99;
173  int sector_overlap = 99;
174  std::vector<Identifier> stationList;
175  std::vector<IdentifierHash> mdtHashList;
176 
177  // get sector_trigger and sector_overlap by using the region selector
178  IdContext context = m_idHelperSvc->mdtIdHelper().module_context();
179 
180  double etaMin = p_roi->eta()-.02;
181  double etaMax = p_roi->eta()+.02;
182  double phiMin = muonRoad.phiMiddle-.01;
183  double phiMax = muonRoad.phiMiddle+.01;
184  if(phiMax > M_PI) phiMax -= M_PI*2.;
185  if(phiMin < M_PI*-1) phiMin += M_PI*2.;
186 
187  TrigRoiDescriptor* roi = new TrigRoiDescriptor( p_roi->eta(), etaMin, etaMax, p_roi->phi(), phiMin, phiMax );
188 
189  const IRoiDescriptor* iroi = static_cast<IRoiDescriptor*> (roi);
190 
191  if (iroi) m_regionSelector->lookup( Gaudi::Hive::currentContext() )->HashIDList(*iroi, mdtHashList);
192  else {
193  TrigRoiDescriptor fullscan_roi( true );
194  m_regionSelector->lookup( Gaudi::Hive::currentContext() )->HashIDList(fullscan_roi, mdtHashList);
195  }
196 
197  if(roi) delete roi;
198 
199  for( const IdentifierHash& hash : mdtHashList){
200 
201  Identifier id;
202  const int convert = m_idHelperSvc->mdtIdHelper().get_id(hash, id, &context);
203 
204  if(convert!=0) ATH_MSG_ERROR("problem converting hash list to id");
205 
206  muonRoad.stationList.push_back(id);
207  const int stationPhi = m_idHelperSvc->mdtIdHelper().stationPhi(id);
208  std::string name = m_idHelperSvc->mdtIdHelper().stationNameString(m_idHelperSvc->mdtIdHelper().stationName(id));
209 
210  if ( name[1]=='M' && name[2]=='E' ) continue;//exclude BME
211  else if ( name[1]=='M' && name[2]=='G' ) continue;//exclude BMG
212 
213  int LargeSmall = 0;
214  if(name[2]=='S' || name[2]=='F' || name[2]=='G' ) LargeSmall = 1;
215  int sector = (stationPhi-1)*2 + LargeSmall;
216  if(sector_trigger == 99)
217  sector_trigger = sector;
218  else if(sector_trigger != sector)
219  sector_overlap = sector;
220  }
221 
222  int MDT_tr = (PhysicsSector - 1)*2 + muonRoad.LargeSmall;
223  if (MDT_tr == sector_overlap) {
224  sector_overlap = sector_trigger;
225  sector_trigger = MDT_tr;
226  }
227 
228  muonRoad.MDT_sector_trigger = sector_trigger;
229  muonRoad.MDT_sector_overlap = sector_overlap;
230 
231  if (clusterFitResults.at(iClus_fit).isSuccess) {
232  for (int i_sector=0; i_sector<N_SECTOR; i_sector++) {
233  muonRoad.aw[0][i_sector] = clusterFitResults.at(iClus_fit).slope_inner;
234  muonRoad.bw[0][i_sector] = clusterFitResults.at(iClus_fit).offset_inner;
235  muonRoad.aw[1][i_sector] = clusterFitResults.at(iClus_fit).slope_middle;
236  muonRoad.bw[1][i_sector] = clusterFitResults.at(iClus_fit).offset_middle;
237  muonRoad.aw[2][i_sector] = clusterFitResults.at(iClus_fit).slope_outer;
238  muonRoad.bw[2][i_sector] = clusterFitResults.at(iClus_fit).offset_outer;
239  muonRoad.aw[3][i_sector] = clusterFitResults.at(iClus_fit).slope_inner; // Endcap Inner
240  muonRoad.bw[3][i_sector] = clusterFitResults.at(iClus_fit).offset_inner;
241  muonRoad.aw[9][i_sector] = clusterFitResults.at(iClus_fit).slope_middle;//BME
242  muonRoad.bw[9][i_sector] = clusterFitResults.at(iClus_fit).offset_middle;
243  muonRoad.aw[10][i_sector] = clusterFitResults.at(iClus_fit).slope_middle;//BMG
244  muonRoad.bw[10][i_sector] = clusterFitResults.at(iClus_fit).offset_middle;
245  }
246  } else {
247  double roiEtaLow = (roiEtaMinLow + roiEtaMaxLow) * 0.5;
248  double roiEtaHigh = (roiEtaMinHigh + roiEtaMaxHigh) * 0.5;
249  double thetaLow = std::atan(std::exp(-std::abs(roiEtaLow)))*2.;
250  double thetaHigh = std::atan(std::exp(-std::abs(roiEtaHigh)))*2.;
251  double awLow = (std::abs(roiEtaLow) > ZERO_LIMIT)? std::tan(thetaLow)*(std::abs(roiEtaLow)/roiEtaLow): 0.;
252  double awHigh = (std::abs(roiEtaHigh) > ZERO_LIMIT)? std::tan(thetaHigh)*(std::abs(roiEtaHigh)/roiEtaHigh): 0.;
253 
254  for (int i_station=0; i_station<N_LAYER; i_station++) {
255  for (int i_sector=0; i_sector<N_SECTOR; i_sector++) {
256  muonRoad.aw[i_station][i_sector] = awLow;
257  muonRoad.bw[i_station][i_sector] = 0;
258  if (i_station==2) muonRoad.aw[i_station][i_sector] = awHigh;
259  else if (i_station==3) muonRoad.aw[i_station][i_sector] = awLow; //EI
260  else if (i_station==4) muonRoad.aw[9][i_sector] = awLow; //BME
261  else if (i_station==5) muonRoad.aw[10][i_sector] = awLow; //BMG
262  }
263  }
264  }
265  clusterRoad.push_back(muonRoad);
266  }
267  ATH_MSG_DEBUG("finished ClusterRoadDefiner algorithm... leave");
268  return StatusCode::SUCCESS;
269 }
270 
271 // --------------------------------------------------------------------------------
272 // --------------------------------------------------------------------------------
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
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
TrigL2MuonSA::ClusterRoadDefiner::defineRoad
StatusCode defineRoad(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
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