ATLAS Offline Software
Loading...
Searching...
No Matches
MdtDataPreparator.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 "MdtDataPreparator.h"
6
8#include "Identifier/Identifier.h"
12
13#include "MdtRegionDefiner.h"
14
16
18
20
23#include <unordered_set>
24namespace {
25 // the tube number of a tube in a tubeLayer in encoded in the GeoSerialIdentifier (modulo maxNTubesPerLayer)
26 constexpr unsigned int maxNTubesPerLayer = MdtIdHelper::maxNTubesPerLayer;
27}
28
29// --------------------------------------------------------------------------------
30// --------------------------------------------------------------------------------
31
33{
34
35 // Locate RegionSelector
36 ATH_CHECK( m_regionSelector.retrieve());
37
38 ATH_CHECK( m_mdtRegionDefiner.retrieve() );
39 ATH_MSG_DEBUG("Retrieved service " << m_mdtRegionDefiner);
40
41 ATH_CHECK( m_idHelperSvc.retrieve() );
42 ATH_CHECK(m_mdtPrepContainerKey.initialize());
43
44 if(!m_isPhase2){
45
46 const MuonGM::MuonDetectorManager* muonDetMgr=nullptr;
47 ATH_CHECK( detStore()->retrieve(muonDetMgr) );
48 ATH_MSG_DEBUG("Retrieved GeoModel from DetectorStore.");
49
50 if(m_idHelperSvc->mdtIdHelper().stationNameIndex("BMG") != -1){ //if we have BMGs
51
52 ATH_MSG_INFO("Processing configuration for layouts with BMG chambers.");
53 m_BMGid = m_idHelperSvc->mdtIdHelper().stationNameIndex("BMG");
54 for(int phi=6; phi<8; phi++) { // phi sectors - BMGs are ony in (6 aka 12) and (7 aka 14)
55 for(int eta=1; eta<4; eta++) { // eta sectors - BMGs are in eta 1 to 3
56 for(int side=-1; side<2; side+=2) { // side - both sides have BMGs
57 if( !muonDetMgr->getMuonStation("BMG", side*eta, phi) ) continue;
58 for(int roe=1; roe<=( muonDetMgr->getMuonStation("BMG", side*eta, phi) )->nMuonReadoutElements(); roe++) { // iterate on readout elemets
59 const MuonGM::MdtReadoutElement* mdtRE =
60 dynamic_cast<const MuonGM::MdtReadoutElement*> ( ( muonDetMgr->getMuonStation("BMG", side*eta, phi) )->getMuonReadoutElement(roe) ); // has to be an MDT
61 if(mdtRE) initDeadChannels(mdtRE);
62 }
63 }
64 }
65 }
66 }
67 }
68 return StatusCode::SUCCESS;
69}
70
71// --------------------------------------------------------------------------------
72// --------------------------------------------------------------------------------
73
75 const EventContext& ctx,
76 const TrigRoiDescriptor* p_roids,
77 const TrigL2MuonSA::RpcFitResult& rpcFitResult,
78 TrigL2MuonSA::MuonRoad& muonRoad,
79 TrigL2MuonSA::MdtRegion& mdtRegion,
80 TrigL2MuonSA::MdtHits& mdtHits) const
81{
82 // define regions
83 ATH_CHECK( m_mdtRegionDefiner->getMdtRegions(p_roids, rpcFitResult, muonRoad, mdtRegion) );
84
85 ATH_CHECK( getMdtHits(ctx, p_roids, muonRoad, mdtHits) );
86
87 return StatusCode::SUCCESS;
88}
89
90// --------------------------------------------------------------------------------
91// --------------------------------------------------------------------------------
92
94 const EventContext& ctx,
95 const TrigRoiDescriptor* p_roids,
96 const TrigL2MuonSA::TgcFitResult& tgcFitResult,
97 TrigL2MuonSA::MuonRoad& muonRoad,
98 TrigL2MuonSA::MdtRegion& mdtRegion,
99 TrigL2MuonSA::MdtHits& mdtHits) const
100{
101 // define regions
102 ATH_CHECK( m_mdtRegionDefiner->getMdtRegions(p_roids, tgcFitResult, muonRoad, mdtRegion) );
103
104 ATH_CHECK( getMdtHits(ctx, p_roids, muonRoad, mdtHits) );
105
106 return StatusCode::SUCCESS;
107}
108
109
110// --------------------------------------------------------------------------------
111// --------------------------------------------------------------------------------
112
114 const EventContext& ctx,
115 const TrigRoiDescriptor* p_roids,
116 TrigL2MuonSA::MuonRoad& muonRoad,
117 TrigL2MuonSA::MdtHits& mdtHits) const
118{
119 std::vector<IdentifierHash> mdtHashList;
120
122
123 ATH_MSG_DEBUG("Use RoI based data access");
124
125 m_regionSelector->lookup(ctx)->HashIDList(*p_roids, mdtHashList);
126 ATH_MSG_DEBUG("mdtHashList.size()=" << mdtHashList.size());
127
128 } else {
129
130 ATH_MSG_DEBUG("Use full data access");
131
132 TrigRoiDescriptor fullscan_roi( true );
133 m_regionSelector->lookup( ctx )->HashIDList(fullscan_roi, mdtHashList);
134 ATH_MSG_DEBUG("mdtHashList.size()=" << mdtHashList.size());
135
136 }
137
138 ATH_CHECK( collectMdtHitsFromPrepData(ctx, mdtHashList, mdtHits, muonRoad) );
139
140 return StatusCode::SUCCESS;
141}
142
143// --------------------------------------------------------------------------------
144// --------------------------------------------------------------------------------
145
147 const std::vector<IdentifierHash>& v_idHash,
148 TrigL2MuonSA::MdtHits& mdtHits,
149 const TrigL2MuonSA::MuonRoad& muonRoad) const
150{
151
152 // Get MDT container
153 if (v_idHash.empty()) {
154 ATH_MSG_DEBUG("Hash list is empty");
155 return StatusCode::SUCCESS;
156 }
158 ATH_CHECK(mdtPrds.isPresent());
159
160 for(const IdentifierHash& id : v_idHash) {
161
162 // Get MDT collections
163 auto mdtCol = mdtPrds->indexFindPtr(id);
164
165 if( mdtCol == nullptr ) {
166 ATH_MSG_DEBUG("MDT prep data collection not found in Hash ID" << (int)id);
167 continue;
168 }
169 if( mdtCol->size() == 0 ) {
170 ATH_MSG_DEBUG("MDT prep data collection is empty in Hash ID" << (int)id);
171 continue;
172 }
173
174 ATH_MSG_DEBUG("Selected Mdt Collection: "
175 << m_idHelperSvc->toStringChamber(mdtCol->identify())
176 << " with size " << mdtCol->size()
177 << "in Hash ID" << (int)id);
178
179 mdtHits.reserve( mdtHits.size() + mdtCol->size() );
180
181 for( const Muon::MdtPrepData* mdt : *mdtCol ) {
182
183 Identifier id = mdt->identify();
184
185 if(m_idHelperSvc->mdtIdHelper().stationName(id) == m_BMGid && m_DeadChannels.count(id)) {
186 ATH_MSG_DEBUG("Skipping tube with identifier " << m_idHelperSvc->toString(id) );
187 continue;
188 }
189
190 const MuonGM::MdtReadoutElement* mdtReadout = mdt->detectorElement();
191 const MuonGM::MuonStation* muonStation = mdtReadout->parentMuonStation();
192
194 tmp.Id = id;
195
196 int TubeLayers = mdtReadout->getNLayers();
197 tmp.TubeLayer = m_idHelperSvc->mdtIdHelper().tubeLayer(id);
198 if(tmp.TubeLayer > TubeLayers) tmp.TubeLayer -= TubeLayers;
199 tmp.Tube = m_idHelperSvc->mdtIdHelper().tube(id);
200 tmp.Multilayer = mdtReadout->getMultilayer();
201 int Layer = (tmp.Multilayer-1)*TubeLayers + tmp.TubeLayer;
202 tmp.Layer = Layer - 1;
203
204 if(Layer==0 or tmp.Tube ==0) continue;
205
206 int drift = mdt->tdc();
207 tmp.DriftTime = drift;
208 tmp.LeadingCoarseTime = (drift>>5) & 0xfff;
209 tmp.LeadingFineTime = drift & 0x1f;
210 tmp.Adc = mdt->adc();
211
212 tmp.name = m_idHelperSvc->mdtIdHelper().stationName(id);
213 tmp.StationEta = mdtReadout->getStationEta();
214 tmp.StationPhi = mdtReadout->getStationPhi();
215
216 std::string chamberType = mdtReadout->getStationType();
217 std::copy_n(chamberType.begin(), std::min<size_t>(4, chamberType.size()), tmp.cType.begin());
218 tmp.readEle = mdtReadout;
219
220 int& chamber {tmp.Chamber};
221 char st = chamberType[1];
222 if (chamberType[0]=='E') {
228 }
229 else {
234 if (st=='E' && chamberType[2]=='E') chamber = xAOD::L2MuonParameters::Chamber::BEE;
235 if (st=='M' && chamberType[2]=='E') chamber = xAOD::L2MuonParameters::Chamber::BME;
236 if (st=='M' && chamberType[2]=='G') chamber = xAOD::L2MuonParameters::Chamber::Backup;
237 }
238
239 double &cXmid{tmp.cXmid}, &cYmid{tmp.cYmid}, &cPhip{tmp.cPhip};
240 Amg::Transform3D trans = muonStation->getNominalAmdbLRSToGlobal();
241 if(!muonStation->endcap()){
242 cXmid = (trans.translation()).z();
243 cYmid = ((trans.translation()).perp() + muonStation->RsizeMdtStation()/2.);
244 }else{
245 cXmid = (trans.translation()).perp();
246 cYmid = (trans.translation()).z();
247 if(cYmid>0) cYmid += muonStation->RsizeMdtStation()/2.;
248 else cYmid -= muonStation->RsizeMdtStation()/2.;
249 }
250 cPhip = (trans.translation()).phi();
251
252 double &R {tmp.R}, &Z {tmp.Z};
253 R = -99999.; Z = -99999.;
254 R = mdtReadout->center(tmp.TubeLayer, tmp.Tube).perp();
255 Z = mdtReadout->center(tmp.TubeLayer, tmp.Tube).z();
256
257 double dphi = 0;
258 double cphi = muonRoad.phi[chamber][0];
259 if( cPhip*cphi>0 ) {
260 dphi = std::abs(cPhip - cphi);
261 } else {
262 if(std::abs(cphi) > M_PI/2.) {
263 double phi1 = (cPhip>0.)? cPhip-M_PI : cPhip+M_PI;
264 double phi2 = (cphi >0.)? cphi -M_PI : cphi +M_PI;
265 dphi = std::abs(phi1) + std::abs(phi2);
266 }
267 else {
268 dphi = std::abs(cPhip) + std::abs(cphi);
269 }
270 }
271
272 if(muonStation->endcap()==1) R = R *std::hypot(1, std::tan(dphi));
273
274 double Rmin = (trans * muonStation->getBlineFixedPointInAmdbLRS()).perp();
275 double OrtoRadialPos = mdtReadout->getStationS();
276 tmp.cInCo = 1./std::cos(std::atan(OrtoRadialPos/Rmin));
277 tmp.cPhi0 = cPhip - std::atan(OrtoRadialPos/Rmin);
278 if(cPhip<0. && (std::abs(M_PI+cPhip) < 0.05) ) cPhip = M_PI;
279
280 ATH_MSG_DEBUG(" ...MDT hit Z/R/chamber/MultiLater/TubeLayer/Tube/Layer/adc/tdc = "
281 << Z << "/" << R << "/" << chamber << "/" << tmp.Multilayer << "/" << tmp.TubeLayer << "/"
282 << tmp.Tube << "/" << Layer << "/" << tmp.Adc << "/" << drift);
283
284 mdtHits.push_back(std::move(tmp));
285
286 } // end of MdtPrepDataCollection loop
287 } // end of hashList loop
288
289 return StatusCode::SUCCESS;
290}
291
292// --------------------------------------------------------------------------------
293// --------------------------------------------------------------------------------
294
296 PVConstLink cv = mydetEl->getMaterialGeom(); // it is "Multilayer"
297 int nGrandchildren = cv->getNChildVols();
298 if(nGrandchildren <= 0) return;
299
300 std::vector<int> tubes;
301 geoGetIds ([&] (int id) { tubes.push_back (id); }, cv);
302 std::sort (tubes.begin(), tubes.end());
303
304 Identifier detElId = mydetEl->identify();
305
306 int name = m_idHelperSvc->mdtIdHelper().stationName(detElId);
307 int eta = m_idHelperSvc->mdtIdHelper().stationEta(detElId);
308 int phi = m_idHelperSvc->mdtIdHelper().stationPhi(detElId);
309 int ml = m_idHelperSvc->mdtIdHelper().multilayer(detElId);
310
311 std::vector<int>::iterator it = tubes.begin();
312 for(int layer = 1; layer <= mydetEl->getNLayers(); layer++){
313 for(int tube = 1; tube <= mydetEl->getNtubesperlayer(); tube++){
314 int want_id = layer*maxNTubesPerLayer + tube;
315 if (it != tubes.end() && *it == want_id) {
316 ++it;
317 }
318 else {
319 it = std::lower_bound (tubes.begin(), tubes.end(), want_id);
320 if (it != tubes.end() && *it == want_id) {
321 ++it;
322 }
323 else {
324 Identifier deadTubeId = m_idHelperSvc->mdtIdHelper().channelID( name, eta, phi, ml, layer, tube );
325 m_DeadChannels.insert(deadTubeId);
326 ATH_MSG_VERBOSE("adding dead tube (" << tube << "), layer(" << layer
327 << "), phi(" << phi << "), eta(" << eta << "), name(" << name
328 << "), multilayerId(" << ml << ") and identifier " << deadTubeId <<" .");
329 }
330 }
331 }
332 }
333}
334
335// --------------------------------------------------------------------------------
336// --------------------------------------------------------------------------------
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar perp() const
perp method - perpendicular length
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
Visitor to collect all IDs under a GeoModel node.
void geoGetIds(FUNCTION f, const GeoGraphNode *node, int depthLimit=1)
Template helper for running the visitor.
Definition GeoGetIds.h:82
const ServiceHandle< StoreGateSvc > & detStore() const
This is a "hash" representation of an Identifier.
static constexpr int maxNTubesPerLayer
The maxNTubesPerLayer represents the absolute maximum of tubes which are built into a single multilay...
Definition MdtIdHelper.h:68
int getNLayers() const
Returns the number of tube layers inside the multilayer.
int getMultilayer() const
Returns the multilayer represented by the readout element.
int getNtubesperlayer() const
Returns the number of tubes in each tube layer.
virtual const Amg::Vector3D & center(const Identifier &) const override final
Return the center of the surface associated with this identifier In the case of silicon it returns th...
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
const MuonStation * getMuonStation(const std::string &stName, int eta, int phi) const
double getStationS() const
Seems to be exclusively used by the MDTs --> Move it to MdtReadoutElement.
Identifier identify() const override final
Returns the ATLAS Identifier of the MuonReadOutElement.
const Amg::Transform3D & getNominalAmdbLRSToGlobal() const
const Amg::Vector3D & getBlineFixedPointInAmdbLRS() const
double RsizeMdtStation() const
Class to represent measurements from the Monitored Drift Tubes.
Definition MdtPrepData.h:33
bool isPresent() const
Is the referenced object present in SG?
StatusCode collectMdtHitsFromPrepData(const EventContext &ctx, const std::vector< IdentifierHash > &v_idHash, TrigL2MuonSA::MdtHits &mdtHits, const TrigL2MuonSA::MuonRoad &muonRoad) const
StatusCode prepareData(const EventContext &ctx, const TrigRoiDescriptor *p_roids, const TrigL2MuonSA::RpcFitResult &rpcFitResult, TrigL2MuonSA::MuonRoad &muonRoad, TrigL2MuonSA::MdtRegion &mdtRegion, TrigL2MuonSA::MdtHits &mdtHits) const
std::unordered_set< Identifier > m_DeadChannels
void initDeadChannels(const MuonGM::MdtReadoutElement *mydetEl)
virtual StatusCode initialize() override
StatusCode getMdtHits(const EventContext &ctx, const TrigRoiDescriptor *p_roids, TrigL2MuonSA::MuonRoad &muonRoad, TrigL2MuonSA::MdtHits &mdtHits) const
Gaudi::Property< bool > m_use_RoIBasedDataAccess
Gaudi::Property< bool > m_isPhase2
ToolHandle< IRegSelTool > m_regionSelector
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
ToolHandle< MdtRegionDefiner > m_mdtRegionDefiner
SG::ReadHandleKey< Muon::MdtPrepDataContainer > m_mdtPrepContainerKey
double phi[N_STATION][N_SECTOR]
Definition MuonRoad.h:85
nope - should be used for standalone also, perhaps need to protect the class def bits ifndef XAOD_ANA...
Eigen::Affine3d Transform3D
std::vector< MdtHitData > MdtHits
Definition MdtData.h:56
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
@ BarrelInner
Inner station in the barrel spectrometer.
@ EndcapOuter
Outer station in the endcap spectrometer.
@ BarrelMiddle
Middle station in the barrel spectrometer.
@ EndcapMiddle
Middle station in the endcap spectrometer.
@ BEE
BEE measurement point.
@ EndcapExtra
Extra station in the endcap spectrometer.
@ BarrelOuter
Outer station in the barrel spectrometer.
@ BME
BME measurement point.
@ EndcapInner
Inner station in the endcap spectrometer.