ATLAS Offline Software
RpcRoadDefiner.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 <cmath>
6 #include <functional>
7 #include <type_traits>
8 
9 #include "RpcRoadDefiner.h"
12 
13 // --------------------------------------------------------------------------------
14 // --------------------------------------------------------------------------------
15 
17 {
18  ATH_CHECK(m_idHelperSvc.retrieve());
19 
20  ATH_CHECK(m_regionSelector.retrieve());
21  ATH_MSG_DEBUG("Retrieved the RegionSelector tool ");
22 
23  return StatusCode::SUCCESS;
24 }
25 
26 // --------------------------------------------------------------------------------
27 // --------------------------------------------------------------------------------
28 
30  const xAOD::MuonRoI* p_roi,
31  const bool insideOut,
32  TrigL2MuonSA::MuonRoad& muonRoad,
33  const TrigL2MuonSA::RpcLayerHits& rpcLayerHits,
34  const ToolHandle<RpcPatFinder>* rpcPatFinder,
35  TrigL2MuonSA::RpcFitResult& rpcFitResult,
36  const double roiEtaMinLow,
37  const double roiEtaMaxLow,
38  const double roiEtaMinHigh,
39  const double roiEtaMaxHigh) const
40 {
41  const double ZERO_LIMIT = 1e-5;
42 
43  if (m_use_rpc && !insideOut) {
44  std::array<std::reference_wrapper<double>, 3> aw {
45  rpcFitResult.slope_inner, rpcFitResult.slope_middle, rpcFitResult.slope_outer
46  };
47  std::array<std::reference_wrapper<double>, 3> bw {
48  rpcFitResult.offset_inner, rpcFitResult.offset_middle, rpcFitResult.offset_outer
49  };
50  rpcFitResult.isSuccess = (*rpcPatFinder)->findPatternEta(aw, bw, rpcLayerHits);
51 
52  for(int i=0;i<3;i++){
53  if(std::abs(aw[i].get()) <= ZERO_LIMIT) rpcFitResult.isSuccess = false;
54  }
55 
56  double phi_middle;
57  double phi_outer;
58  if ( (*rpcPatFinder)->findPatternPhi(phi_middle, phi_outer, rpcLayerHits)) {
59  rpcFitResult.phi = phi_middle;
60  rpcFitResult.phi_middle = phi_middle;
61  rpcFitResult.phi_outer = phi_outer;
62  } else {
63  rpcFitResult.phi = p_roi->phi();
64  }
65  ATH_MSG_DEBUG("RpcPatFinder: Found: " << rpcFitResult.isSuccess << " Slopes: " << aw[0] << "," << aw[1] << "," << aw[2] << " Offsets: " << bw[0] << "," << bw[1] << "," << bw[2]);
66  } else {
67  ATH_MSG_DEBUG("Skip rpcPatFinder");
68  }
69 
70  muonRoad.isEndcap = false;
71  if(!insideOut) {
72  muonRoad.phiMiddle = rpcFitResult.phi;
73  } else {
74  muonRoad.phiMiddle = muonRoad.extFtfMiddlePhi;
75  rpcFitResult.phi = muonRoad.extFtfMiddlePhi;
76  rpcFitResult.phi_middle = muonRoad.extFtfMiddlePhi;
77  rpcFitResult.phi_outer = muonRoad.extFtfMiddlePhi;
78  }
79  muonRoad.phiRoI = p_roi->phi();
80  muonRoad.side = (p_roi->phi()<0.)? 0 : 1;
81  muonRoad.LargeSmall = ((p_roi->getSectorID() + 1)/2 )%2;
82 
83  const int PhysicsSector = ((p_roi->getSectorID() + 1)/4 )%8 + 1;
84 
85  int special = 0;
86  if (muonRoad.LargeSmall == 0 && (PhysicsSector == 6 || PhysicsSector == 8 )) special = 1; // BIM BIR
87  if (muonRoad.LargeSmall == 1 && (PhysicsSector == 6 || PhysicsSector == 7 )) special = 1; //feets
88  muonRoad.Special = special;
89 
90  auto fillAllLayersWith = [&muonRoad](const int& station, const double& value) -> void {
91  std::fill(std::begin(muonRoad.rWidth[station]), std::end(muonRoad.rWidth[station]), value);
92  };
93 
94  if (!rpcFitResult.isSuccess) {
95  if (!insideOut) {
96  fillAllLayersWith(0, 500); // Inner
97  fillAllLayersWith(1, 650); // Middle
98  fillAllLayersWith(2, 800); // Outer
99  fillAllLayersWith(3, 500); // EndcapInner
100  fillAllLayersWith(9, 650); // BME
101  fillAllLayersWith(10, 650); // BMG
102  } else {
103  fillAllLayersWith(0, 250); // Inner
104  fillAllLayersWith(1, 400); // Middle
105  fillAllLayersWith(2, 600); // Outer
106  fillAllLayersWith(3, 300); // EndcapInner
107  fillAllLayersWith(9, 400); // BME
108  fillAllLayersWith(10, 400); // BMG
109  }
110  } else {
111  fillAllLayersWith(0, 400); // Inner
112  fillAllLayersWith(1, 200); // Middle
113  fillAllLayersWith(2, 400); // Outer
114  fillAllLayersWith(3, 400); // EndcapInner
115  fillAllLayersWith(9, m_rWidth_RPC_Failed); // BME
116  fillAllLayersWith(10, m_rWidth_RPC_Failed); // BMG
117  }
118 
119  std::vector<IdentifierHash> mdtHashList;
120 
121  // get sector_trigger and sector_overlap by using the region selector
122  IdContext context = m_idHelperSvc->mdtIdHelper().module_context();
123 
124  double etaMin = p_roi->eta()-.02;
125  double etaMax = p_roi->eta()+.02;
126  double phiMin = muonRoad.phiMiddle-.01;
127  double phiMax = muonRoad.phiMiddle+.01;
128  if(phiMax > M_PI) phiMax -= M_PI*2.;
129  if(phiMin < -M_PI) phiMin += M_PI*2.;
130 
131  auto roi = std::make_unique<TrigRoiDescriptor>( p_roi->eta(), etaMin, etaMax, muonRoad.phiMiddle, phiMin, phiMax );
132 
133  if (roi) m_regionSelector->lookup(ctx)->HashIDList( *roi, mdtHashList);
134  else {
135  TrigRoiDescriptor fullscan_roi( true );
136  m_regionSelector->lookup(ctx)->HashIDList(fullscan_roi, mdtHashList);
137  }
138 
139  int &sector_trigger {muonRoad.MDT_sector_trigger}, &sector_overlap {muonRoad.MDT_sector_overlap};
140  sector_trigger = (PhysicsSector - 1)*2 + muonRoad.LargeSmall;
141  sector_overlap = 99;
142 
143  for( const IdentifierHash& hash : mdtHashList){
144 
145  Identifier id;
146  if( m_idHelperSvc->mdtIdHelper().get_id(hash, id, &context) !=0 ) ATH_MSG_ERROR("problem converting hash list to id");
147 
148  muonRoad.stationList.push_back(id);
149  const int stationPhi = m_idHelperSvc->mdtIdHelper().stationPhi(id);
150  const std::string name = m_idHelperSvc->mdtIdHelper().stationNameString(m_idHelperSvc->mdtIdHelper().stationName(id));
151 
152  if ( name[1]=='M' && name[2]=='E' ) continue;//exclude BME
153  if ( name[1]=='M' && name[2]=='G' ) continue;//exclude BMG
154 
155  const int LargeSmall = (name[2]=='S' || name[2]=='F' || name[2]=='G' ) ? 1 : 0;
156  const int sector = (stationPhi-1)*2 + LargeSmall;
157 
158  if (sector != sector_trigger) sector_overlap = sector;
159  if (sector != sector_trigger and sector_overlap != 99 and sector != sector_overlap) ATH_MSG_ERROR("Multiple sector overlaps not expected");
160  }
161 
163  auto fillAllSectorsWith = [&muonRoad](const int& station, const double& aw, const double& bw) -> void {
164  std::fill(std::begin(muonRoad.aw[station]), std::end(muonRoad.aw[station]), aw);
165  std::fill(std::begin(muonRoad.bw[station]), std::end(muonRoad.bw[station]), bw);
166  };
167 
168  if (!insideOut) {
169  if (rpcFitResult.isSuccess) { // MOD this code is very suspicious
170  fillAllSectorsWith(0, rpcFitResult.slope_inner, rpcFitResult.offset_inner); //Barrel inner
171  fillAllSectorsWith(1, rpcFitResult.slope_middle, rpcFitResult.offset_middle); //Barrel middle
172  fillAllSectorsWith(2, rpcFitResult.slope_outer, rpcFitResult.offset_outer); //Barrel outer
173  fillAllSectorsWith(3, rpcFitResult.slope_inner, rpcFitResult.offset_inner); //Endcap inner
174  fillAllSectorsWith(9, rpcFitResult.slope_middle, rpcFitResult.offset_middle); //BME
175  fillAllSectorsWith(10, rpcFitResult.slope_middle, rpcFitResult.offset_middle); //BMG
176 
177  } else {
178  auto compute_aw = [&ZERO_LIMIT](double etaMin, double etaMax) -> double {
179  const double eta = 0.5 * (etaMin + etaMax);
180  if (std::abs(eta) < ZERO_LIMIT) return 0.;
181  const double theta = 2.* std::atan(std::exp(-std::abs(eta)));
182  return std::tan(theta) * (eta / std::abs(eta)); // preserves sign
183  };
184 
185  const double awLow = compute_aw(roiEtaMinLow, roiEtaMaxLow);
186  const double awHigh = compute_aw(roiEtaMinHigh, roiEtaMaxHigh);
187 
188  fillAllSectorsWith(0, awLow, 0.); //Barrel inner
189  fillAllSectorsWith(1, awLow, 0.); //Barrel middle
190  fillAllSectorsWith(2, awHigh, 0.); //Barrel outer
191  fillAllSectorsWith(3, awLow, 0.); //Endcap inner
192  fillAllSectorsWith(9, awLow, 0.); //BME
193  fillAllSectorsWith(10, awLow, 0.); //BMG
194  }
195  } else {
196 
197  ATH_MSG_DEBUG("Use aw_ftf and bw_ftf as aw and bw");
198  fillAllSectorsWith(0, muonRoad.aw_ftf[0][0], muonRoad.bw_ftf[0][0]); //Barrel inner
199  fillAllSectorsWith(1, muonRoad.aw_ftf[1][0], muonRoad.bw_ftf[1][0]); //Barrel middle
200  fillAllSectorsWith(2, muonRoad.aw_ftf[2][0], muonRoad.bw_ftf[2][0]); //Barrel outer
201  fillAllSectorsWith(3, muonRoad.aw_ftf[3][0], muonRoad.bw_ftf[3][0]); //Endcap inner
202  fillAllSectorsWith(9, muonRoad.aw_ftf[9][0], muonRoad.bw_ftf[9][0]); //BME
203  fillAllSectorsWith(10, muonRoad.aw_ftf[10][0], muonRoad.bw_ftf[10][0]); //BMG
204  }
205 
206  ATH_MSG_DEBUG("muonRoad.phiMiddle: " << muonRoad.phiMiddle);
207 
208  return StatusCode::SUCCESS;
209 }
210 
211 // --------------------------------------------------------------------------------
212 // --------------------------------------------------------------------------------
TrigL2MuonSA::MuonRoad::MDT_sector_overlap
int MDT_sector_overlap
Definition: MuonRoad.h:89
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::RpcFitResult
Definition: RpcFitResult.h:14
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:83
TrigL2MuonSA::RpcRoadDefiner::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: RpcRoadDefiner.h:62
TrigL2MuonSA::RpcFitResult::offset_middle
double offset_middle
Definition: RpcFitResult.h:53
TrigL2MuonSA::RpcRoadDefiner::m_regionSelector
ToolHandle< IRegSelTool > m_regionSelector
Definition: RpcRoadDefiner.h:61
theta
Scalar theta() const
theta method
Definition: AmgMatrixBasePlugin.h:75
PlotCalibFromCool.begin
begin
Definition: PlotCalibFromCool.py:94
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
athena.value
value
Definition: athena.py:124
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
TrigL2MuonSA::RpcRoadDefiner::defineRoad
StatusCode defineRoad(const EventContext &ctx, const xAOD::MuonRoI *p_roi, const bool insideOut, TrigL2MuonSA::MuonRoad &muonRoad, const TrigL2MuonSA::RpcLayerHits &rpcLayerHits, const ToolHandle< RpcPatFinder > *rpcPatFinder, TrigL2MuonSA::RpcFitResult &rpcFitResult, const double roiEtaMinLow, const double roiEtaMaxLow, const double roiEtaMinHigh, const double roiEtaMaxHigh) const
Definition: RpcRoadDefiner.cxx:29
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
TrigL2MuonSA::RpcRoadDefiner::initialize
virtual StatusCode initialize() override
Definition: RpcRoadDefiner.cxx:16
TrigL2MuonSA::MuonRoad::aw
double aw[N_STATION][N_SECTOR]
Definition: MuonRoad.h:83
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:92
TrigL2MuonSA::MuonRoad::side
int side
Definition: MuonRoad.h:78
TrigL2MuonSA::MuonRoad::phiRoI
double phiRoI
Definition: MuonRoad.h:82
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
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
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
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
TrigL2MuonSA::RpcFitResult::phi_middle
double phi_middle
Definition: RpcFitResult.h:51
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
ZERO_LIMIT
const float ZERO_LIMIT
Definition: VP1TriggerHandleL2.cxx:37
TrigL2MuonSA::RpcFitResult::phi_outer
double phi_outer
Definition: RpcFitResult.h:55
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:239
TrigL2MuonSA::MuonRoad::bw_ftf
double bw_ftf[N_STATION][N_SECTOR]
Definition: MuonRoad.h:95
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
TrigL2MuonSA::RpcLayerHits
Definition: RpcPatFinder.h:20
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
lumiFormat.fill
fill
Definition: lumiFormat.py:104
RpcRoadDefiner.h
get
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition: hcg.cxx:127
TrigL2MuonSA::MuonRoad::extFtfMiddlePhi
double extFtfMiddlePhi
Definition: MuonRoad.h:93
TrigL2MuonSA::RpcFitResult::slope_outer
double slope_outer
Definition: RpcFitResult.h:56
TrigL2MuonSA::MuonRoad::aw_ftf
double aw_ftf[N_STATION][N_SECTOR]
Definition: MuonRoad.h:94
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
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
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