ATLAS Offline Software
Loading...
Searching...
No Matches
SimHitCreatorMS.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "SimHitCreatorMS.h"
6
7// ISF includes
10// Trk
11#include "TrkTrack/Track.h"
13// MuonSpectrometer includes
23
32
33#include "CLHEP/Random/RandLandau.h"
34#include "CLHEP/Random/RandGaussZiggurat.h"
35
36namespace {
37 // the tube number of a tube in a tubeLayer ia encoded in the GeoSerialIdentifier (modulo maxNTubesPerLayer)
38 constexpr unsigned int maxNTubesPerLayer = MdtIdHelper::maxNTubesPerLayer;
39}
40
41//================ Constructor =================================================
42
44 const std::string& n,
45 const IInterface* p ) :
46 base_class(t,n,p),
47 m_incidentSvc("IncidentSvc", n),
49 m_measTool("Muon::MuonTGMeasurementTool/MuonTGMeasurementTool"),
50 m_mdtSimHitCollection(nullptr),
51 m_rpcSimHitCollection(nullptr),
52 m_tgcSimHitCollection(nullptr),
53 m_cscSimHitCollection(nullptr),
54 m_mmSimHitCollection(nullptr),
56 m_mdtCollectionName("MDT_Hits"),
57 m_rpcCollectionName("RPC_Hits"),
58 m_tgcCollectionName("TGC_Hits"),
59 m_cscCollectionName("CSC_Hits"),
60 m_mmCollectionName("MM_Hits"),
61 m_stgcCollectionName("sTGC_Hits"),
62 m_randomSvc("AtDSFMTGenSvc", n),
63 m_randomEngineName("FatrasRnd"),
64 m_randomEngine(nullptr),
65 m_mdtHitIdHelper(nullptr),
66 m_rpcHitIdHelper(nullptr),
67 m_cscHitIdHelper(nullptr),
68 m_tgcHitIdHelper(nullptr),
69 m_mmOffToSimId(nullptr),
70 m_stgcOffToSimId(nullptr),
71 m_muonMgr(nullptr),
73 m_BMGid(-1),
75{
76 // template for property decalration
77 declareProperty("MeasurementTool", m_measTool);
78 declareProperty("MdtSigmaDriftRadius", m_mdtSigmaDriftRadius);
79 // Random number svc
80 declareProperty("RandomNumberService", m_randomSvc, "Random number generator");
81 declareProperty("RandomStreamName", m_randomEngineName, "Name of the random number stream");
82 // extrapolator
83 declareProperty("Extrapolator", m_extrapolator);
84 declareProperty("MDTCollectionName", m_mdtCollectionName);
85 declareProperty("RPCCollectionName", m_rpcCollectionName);
86 declareProperty("TGCCollectionName", m_tgcCollectionName);
87 declareProperty("CSCCollectionName", m_cscCollectionName);
88 declareProperty("MMCollectionName", m_mmCollectionName);
89 declareProperty("sTGCCollectionName", m_stgcCollectionName);
90 declareProperty("CreateAllMdtHits", m_createAllMdtHits);
91}
92
93//================ Initialisation =================================================
94
96{
97
98 // Get Extrapolator from ToolService
99 ATH_CHECK(m_extrapolator.retrieve());
100 // Get IdHelper from ToolService
101 ATH_CHECK(m_idHelperSvc.retrieve());
102 // the MS helpers for the different technologies
103 m_mdtHitIdHelper = MdtHitIdHelper::GetHelper(m_idHelperSvc->mdtIdHelper().tubeMax());
104 m_rpcHitIdHelper = RpcHitIdHelper::GetHelper(m_idHelperSvc->rpcIdHelper().gasGapMax());
107
108 ATH_CHECK(detStore()->retrieve(m_muonMgr));
109
112
113 // get measurement tool
114 ATH_CHECK(m_measTool.retrieve());
115
116 // Random number service
117 ATH_CHECK(m_randomSvc.retrieve());
118 //Get own engine with own seeds:
120 if (!m_randomEngine) {
121 ATH_MSG_ERROR( "[ --- ] Could not get random engine '" << m_randomEngineName << "'" );
122 return StatusCode::FAILURE;
123 }
124
125
126 // Athena/Gaudi framework
127 ATH_CHECK(m_incidentSvc.retrieve());
128 // register to the incident service: BeginEvent for TrackCollection
129 m_incidentSvc->addListener( this, IncidentType::BeginEvent);
130
131 ATH_MSG_INFO( "[ mutrack ] initialize() successful." );
132
133 m_BMGpresent = m_idHelperSvc->mdtIdHelper().stationNameIndex("BMG") != -1;
134 if(m_BMGpresent){
135 ATH_MSG_INFO("Processing configuration for layouts with BMG chambers.");
136 m_BMGid = m_idHelperSvc->mdtIdHelper().stationNameIndex("BMG");
137 for(int phi=6; phi<8; phi++) { // phi sectors
138 for(int eta=1; eta<4; eta++) { // eta sectors
139 for(int side=-1; side<2; side+=2) { // side
140 if( !m_muonMgr->getMuonStation("BMG", side*eta, phi) ) continue;
141 for(int roe=1; roe<= ((m_muonMgr->getMuonStation("BMG", side*eta, phi) )->nMuonReadoutElements()); roe++) { // iterate on readout elemets
142 const MuonGM::MdtReadoutElement* mdtRE =
143 dynamic_cast<const MuonGM::MdtReadoutElement*> ( ( m_muonMgr->getMuonStation("BMG", side*eta, phi) )->getMuonReadoutElement(roe) ); // has to be an MDT
144 if(mdtRE) initDeadChannels(mdtRE);
145 }
146 }
147 }
148 }
149 }
150
151
152 return StatusCode::SUCCESS;
153}
154
155//================ Event Initialization =========================================
156//
157void iFatras::SimHitCreatorMS::handle( const Incident& inc ) {
158 // check the incident type
159 if ( inc.type() == IncidentType::BeginEvent ){
160 ATH_MSG_VERBOSE("[ muon sim hit ] Setting MuonSimHit collections up");
161 // check if the hit collection already contains:
162 // (a) if yes ... try to retrieve it
164 if ( (evtStore()->retrieve(m_mdtSimHitCollection , m_mdtCollectionName)).isFailure() )
165 ATH_MSG_ERROR( "[ --- ] Unable to retrieve MDTSimHitCollection " << m_mdtCollectionName);
166 // (b) if no ... try to create it
167 } else {
169 if ( (evtStore()->record(m_mdtSimHitCollection, m_mdtCollectionName, true)).isFailure() ) {
170 ATH_MSG_ERROR( "[ --- ] Unable to record MDTSimHitCollection " << m_mdtCollectionName);
172 }
173 }
175 if ( (evtStore()->retrieve(m_rpcSimHitCollection , m_rpcCollectionName)).isFailure() )
176 ATH_MSG_ERROR( "[ --- ] Unable to retrieve RPCSimHitCollection " << m_rpcCollectionName);
177 // (b) if no ... try to create it
178 } else {
180 if ( (evtStore()->record(m_rpcSimHitCollection, m_rpcCollectionName, true)).isFailure() ) {
181 ATH_MSG_ERROR( "[ --- ] Unable to record RPCSimHitCollection " << m_rpcCollectionName);
183 }
184 }
186 if ( (evtStore()->retrieve(m_tgcSimHitCollection , m_tgcCollectionName)).isFailure() )
187 ATH_MSG_ERROR( "[ --- ] Unable to retrieve TGCSimHitCollection " << m_tgcCollectionName);
188 // (b) if no ... try to create it
189 } else {
191 if ( (evtStore()->record(m_tgcSimHitCollection, m_tgcCollectionName, true)).isFailure() ) {
192 ATH_MSG_ERROR( "[ --- ] Unable to record TGCSimHitCollection " << m_tgcCollectionName);
194 }
195 }
197 if ( (evtStore()->retrieve(m_cscSimHitCollection , m_cscCollectionName)).isFailure() )
198 ATH_MSG_ERROR( "[ --- ] Unable to retrieve CSCSimHitCollection " << m_cscCollectionName);
199 // (b) if no ... try to create it
200 } else {
202 if ( (evtStore()->record(m_cscSimHitCollection, m_cscCollectionName, true)).isFailure() ) {
203 ATH_MSG_ERROR( "[ --- ] Unable to record CSCSimHitCollection " << m_cscCollectionName);
205 }
206 }
208 if ( (evtStore()->retrieve(m_mmSimHitCollection , m_mmCollectionName)).isFailure() )
209 ATH_MSG_ERROR( "[ --- ] Unable to retrieve MMSimHitCollection " << m_mmCollectionName);
210 // (b) if no ... try to create it
211 } else {
213 if ( (evtStore()->record(m_mmSimHitCollection, m_mmCollectionName, true)).isFailure() ) {
214 ATH_MSG_ERROR( "[ --- ] Unable to record MMSimHitCollection " << m_mmCollectionName);
216 }
217 }
219 if ( (evtStore()->retrieve(m_stgcSimHitCollection , m_stgcCollectionName)).isFailure() )
220 ATH_MSG_ERROR( "[ --- ] Unable to retrieve sTGCSimHitCollection " << m_stgcCollectionName);
221 // (b) if no ... try to create it
222 } else {
224 if ( (evtStore()->record(m_stgcSimHitCollection, m_stgcCollectionName, true)).isFailure() ) {
225 ATH_MSG_ERROR( "[ --- ] Unable to record sTGCSimHitCollection " << m_stgcCollectionName);
227 }
228 }
229 }
230}
231
232
233//================ Track Creation Interface =====================================
235 const std::vector<Trk::HitInfo>& hits) const {
236
237 // iterate and assign as well the layer
238 std::vector<Trk::HitInfo>::const_iterator plIter = hits.begin();
239 std::vector<Trk::HitInfo>::const_iterator plIterEnd = hits.end();
240 for ( ; plIter != plIterEnd; ++plIter ){
241 // get the parameters & associated layer
242 const Trk::TrackParameters* parm = (*plIter).trackParms.get();
243 double timeInfo = (*plIter).time;
244 const Trk::Layer* currLay = m_extrapolator->trackingGeometry()->associatedLayer( parm->position() );
245
246 if (!currLay) continue;
247
248 Identifier id(currLay->layerType());
249
250 // NSW hits
251 if ( m_idHelperSvc->isMM(id) || m_idHelperSvc->issTgc(id) ) {
252 // hit ID
253 int simID = offIdToSimId(id);
254 // local position : at MTG layer ( corresponds to the middle of the gas gap )
255 // generating particle info
256 double mom = parm->momentum().mag();
257 double mass = isp.mass();
258 double eKin = sqrt( mom*mom+mass*mass) - mass;
259 // the rest of information needs adjustment once full sim hits available
260 double energyDeposit = 1.;
261 const Amg::Vector3D& pos=parm->position();
262 const Amg::Vector3D unitMom=parm->momentum().normalized();
263 // cos of incident angle
264 float cosAngle = std::abs(unitMom.dot(parm->associatedSurface().normal()));
265 float segLengthSTGC = 2.85/cosAngle; // segment length in sTGC gas gap
266 // positions where particle enters and exits the sTGC gas gap
267 const Amg::Vector3D& entryPos(pos - 0.5*segLengthSTGC*unitMom);
268 const Amg::Vector3D& exitPos(pos + 0.5*segLengthSTGC*unitMom);
269
270 HepMcParticleLink partLink(HepMC::uniqueID(isp), 0,
273 if ( m_idHelperSvc->isMM(id) ) {
274 m_mmSimHitCollection->Emplace(simID, timeInfo, pos,
275 isp.pdgCode(), eKin, unitMom,
276 energyDeposit, partLink) ;
277 }
278 else {
279 m_stgcSimHitCollection->Emplace(simID, timeInfo, exitPos,
280 isp.pdgCode(), unitMom, energyDeposit,
281 partLink, eKin, entryPos);
282 }
283
284 ATH_MSG_VERBOSE("[ muhit ] NSW hit created.");
285
286 } else if (m_idHelperSvc->isMdt(id)) { // (A) special treatment for MDTs to find closest channel and nearby hits
287 double pitch = 0.;
288 // get the identifier
289 Identifier hid = m_measTool->nearestDetEl(currLay,parm,false,pitch);
290 //
291 if (m_idHelperSvc->mdtIdHelper().valid(hid)) {
292 // create first hit
293 bool hitCreated = createHit(isp, currLay,parm,hid,timeInfo,pitch, true);
294 if (m_createAllMdtHits) {
295 // nearby hits - check range
296 const MuonGM::MdtReadoutElement* mdtROE = m_muonMgr->getMdtReadoutElement(hid);
297 if (!mdtROE) continue;
298 int tMax = mdtROE->getNtubesperlayer();
299 int tCur = m_idHelperSvc->mdtIdHelper().tube(hid);
300 // recalculate id
301 int next=-1;
302 while (tCur+next>0) {
303 Identifier nextId = m_idHelperSvc->mdtIdHelper().channelID(m_idHelperSvc->mdtIdHelper().stationName(hid),
304 m_idHelperSvc->mdtIdHelper().stationEta(hid),
305 m_idHelperSvc->mdtIdHelper().stationPhi(hid),
306 m_idHelperSvc->mdtIdHelper().multilayer(hid),
307 m_idHelperSvc->mdtIdHelper().tubeLayer(hid),
308 tCur+next);
309 if (!m_idHelperSvc->mdtIdHelper().valid(nextId)) break;
310 hitCreated = createHit(isp, currLay,parm,nextId,timeInfo,pitch,true);
311 if (!hitCreated) break;
312 next--;
313 }
314 next = 1;
315 while (tCur+next <= tMax) {
316 Identifier nextId = m_idHelperSvc->mdtIdHelper().channelID(m_idHelperSvc->mdtIdHelper().stationName(hid),
317 m_idHelperSvc->mdtIdHelper().stationEta(hid),
318 m_idHelperSvc->mdtIdHelper().stationPhi(hid),
319 m_idHelperSvc->mdtIdHelper().multilayer(hid),
320 m_idHelperSvc->mdtIdHelper().tubeLayer(hid),
321 tCur+next);
322 if (!m_idHelperSvc->mdtIdHelper().valid(nextId)) break;
323 hitCreated = createHit(isp, currLay,parm,nextId,timeInfo,pitch,true);
324 if (!hitCreated) break;
325 next++;
326 }
327 } // hits outside central plane
328 } // hit corresponding to the intersection with the central plane
329 } else { // (B) not an MDT nor NSW layer
330 double pitch = 0.;
331 Identifier hid = m_measTool->nearestDetEl(currLay,parm,false,pitch);
332
333 // check if this is valid
334 if ( hid.get_identifier32().get_compact()>0 && createHit(isp, currLay,parm,hid,timeInfo,pitch,false) )
335 ATH_MSG_VERBOSE("[ muhit ] Hit in MS created.");
336 // reset id for the other side
337 hid = m_measTool->nearestDetEl(currLay,parm,true,pitch);
338 // again check if this is valid
339 if ( hid.get_identifier32().get_compact()>0 && createHit(isp, currLay,parm,hid,timeInfo,pitch,true) )
340 ATH_MSG_VERBOSE("[ muhit ] Hit in MS created.");
341 } // end of asocciated layer check
342 } // end of the loop over TrackParameters
343}
344
345
347 const Trk::Layer* lay,const Trk::TrackParameters* parm, Identifier id, double globalTimeEstimate, double /* pitch */, bool /* smear */) const
348{
349 // MDT SECTION
350 if (m_idHelperSvc->isMdt(id)) {
351
352 int simId = m_mdtHitIdHelper->BuildMdtHitId(m_idHelperSvc->mdtIdHelper().stationNameString(m_idHelperSvc->mdtIdHelper().stationName(id)),
353 m_idHelperSvc->mdtIdHelper().stationPhi(id), m_idHelperSvc->mdtIdHelper().stationEta(id),
354 m_idHelperSvc->mdtIdHelper().multilayer(id), m_idHelperSvc->mdtIdHelper().tubeLayer(id),
355 m_idHelperSvc->mdtIdHelper().tube(id));
356
357 ATH_MSG_VERBOSE( "[ muhit ] Creating MDTSimHit with identifier " << simId );
358 // local position from the mdt's i
359 const MuonGM::MdtReadoutElement* MdtRoEl = m_muonMgr->getMdtReadoutElement(id);
360 if(m_BMGpresent && m_idHelperSvc->mdtIdHelper().stationName(id) == m_BMGid ) {
361 auto myIt = m_DeadChannels.find(MdtRoEl->identify());
362 if( myIt != m_DeadChannels.end() ){
363 if( std::find( (myIt->second).begin(), (myIt->second).end(), id) != (myIt->second).end() ) {
364 ATH_MSG_DEBUG("Skipping tube with identifier " << m_idHelperSvc->mdtIdHelper().show_to_string(id) );
365 return false;
366 }
367 }
368 }
369 // local position from the mdt's
370 const Amg::Vector3D localPos = m_muonMgr->getMdtReadoutElement(id)->globalToLocalTransf(id) * parm->position();
371 // drift radius
372 double residual = m_measTool->residual(lay,parm,id);
373 if (std::abs(residual)<15.075) {
374
375 double dlh = sqrt(15.075*15.075-residual*residual);
376 double de = 0.02*dlh/15.075;
377 double energyDeposit= de + 0.005*CLHEP::RandGaussZiggurat::shoot(m_randomEngine);
378 while (energyDeposit<0.) energyDeposit= de + 0.005*CLHEP::RandGaussZiggurat::shoot(m_randomEngine);
379
380 // a new simhit
381 HepMcParticleLink partLink(HepMC::uniqueID(isp), 0,
384 m_mdtSimHitCollection->Emplace(simId,globalTimeEstimate,
385 std::abs(residual),
386 localPos,
387 partLink,
388 2*dlh, energyDeposit, isp.pdgCode(),isp.momentum().mag() ) ;
389 return true;
390 } else {
391 return false;
392 }
393 } else if (m_idHelperSvc->isRpc(id)) {
394 // local position from the rpc's
395 const Amg::Vector3D localPos = m_muonMgr->getRpcReadoutElement(id)->globalToLocalTransf(id)*parm->position();
396 int simId = m_rpcHitIdHelper->BuildRpcHitId(m_idHelperSvc->rpcIdHelper().stationNameString(m_idHelperSvc->rpcIdHelper().stationName(id)),
397 m_idHelperSvc->rpcIdHelper().stationPhi(id), m_idHelperSvc->rpcIdHelper().stationEta(id),
398 m_idHelperSvc->rpcIdHelper().doubletZ(id), m_idHelperSvc->rpcIdHelper().doubletR(id),
399 m_idHelperSvc->rpcIdHelper().gasGap(id), m_idHelperSvc->rpcIdHelper().doubletPhi(id),
400 m_idHelperSvc->rpcIdHelper().measuresPhi(id));
401
402 ATH_MSG_VERBOSE( "[ muhit ] Creating RPCSimHit with identifier " << simId );
403
404 double energyDeposit= 1.5e-03 + 3.9e-04*CLHEP::RandLandau::shoot(m_randomEngine);
405 while (energyDeposit<0.) energyDeposit= 1.5e-03 + 3.9e-04*CLHEP::RandLandau::shoot(m_randomEngine);
406
407 // a new simhit
408 HepMcParticleLink partLink(HepMC::uniqueID(isp), 0,
411 m_rpcSimHitCollection->Emplace(simId,globalTimeEstimate, localPos, partLink, localPos, energyDeposit,1.,isp.pdgCode(),isp.momentum().mag() ) ;
412
413 } else if (m_idHelperSvc->isTgc(id) && !m_idHelperSvc->tgcIdHelper().isStrip(id) ) {
414 // take eta hits only
415 // local position
416 const Amg::Vector3D localPos = Amg::Translation3D(-1.4, 0., 0.)*m_muonMgr->getTgcReadoutElement(id)->globalToLocalTransf(id)*parm->position();
417 // local direction
418 Amg::Vector3D localDir = m_muonMgr->getTgcReadoutElement(id)->globalToLocalTransf(id).rotation()*parm->momentum().normalized();
419
420 int simId = m_tgcHitIdHelper->BuildTgcHitId(m_idHelperSvc->tgcIdHelper().stationNameString(m_idHelperSvc->tgcIdHelper().stationName(id)),
421 m_idHelperSvc->tgcIdHelper().stationPhi(id), m_idHelperSvc->tgcIdHelper().stationEta(id),
422 m_idHelperSvc->tgcIdHelper().gasGap(id));
423
424 ATH_MSG_VERBOSE( "[ muhit ] Creating TGCSimHit with identifier " << simId );
425
426 // TO DO: adust energy deposit and step length ( 1keV,3 mm ? )
427 double energyDeposit= 1.3e-03 + 6.e-04*CLHEP::RandGaussZiggurat::shoot(m_randomEngine);
428 while (energyDeposit<0.) energyDeposit= 1.3e-03 + 6.e-04*CLHEP::RandGaussZiggurat::shoot(m_randomEngine);
429 double stepLength=3.;
430
431 // a new simhit
432 HepMcParticleLink partLink(HepMC::uniqueID(isp), 0,
435 m_tgcSimHitCollection->Emplace(simId,globalTimeEstimate, localPos, localDir, partLink, energyDeposit, stepLength ) ;
436 } else if (m_idHelperSvc->isCsc(id)) {
437 // one of eta/phi hits only
438
439 Amg::Vector3D dir(parm->momentum().normalized());
440
442 float energyDeposit= 0.24e-03 + 1.1e-03*CLHEP::RandGaussZiggurat::shoot(m_randomEngine);
443 while (energyDeposit<0.) energyDeposit= 0.24e-03 + 1.1e-03*CLHEP::RandGaussZiggurat::shoot(m_randomEngine);
444 // cos of incident angle
445 float cs=std::abs(dir.dot(parm->associatedSurface().normal()));
446 float hitlength = 5./cs;
448
449 Amg::Vector3D startPos(parm->position()-0.5*hitlength*dir);
450 Amg::Vector3D endPos(parm->position()+0.5*hitlength*dir);
451 const Amg::Transform3D globalToLocTransf{m_muonMgr->getCscReadoutElement(id)->globalToLocalTransf(id)};
452 Amg::Vector3D hitStart = globalToLocTransf*startPos;
453 Amg::Vector3D hitEnd = globalToLocTransf*endPos;
454
455 // the lundcode (from CSCSensitiveDetector)
456 int lundcode=0;
457 int pdgcode= isp.pdgCode();
458
459 if (pdgcode == 22) lundcode=1;
460 else if (pdgcode == 13 ) lundcode=6;
461 else if (pdgcode == -13) lundcode=5;
462 else lundcode = 999;
463 // else if Trk::nonInteracting lundcode = 999;
464
465 int simId = m_cscHitIdHelper->BuildCscHitId(m_idHelperSvc->cscIdHelper().stationNameString(m_idHelperSvc->cscIdHelper().stationName(id)),
466 m_idHelperSvc->cscIdHelper().stationPhi(id), m_idHelperSvc->cscIdHelper().stationEta(id),
467 m_idHelperSvc->cscIdHelper().chamberLayer(id), m_idHelperSvc->cscIdHelper().wireLayer(id));
468
469 ATH_MSG_VERBOSE( "[ muhit ] Creating CSCSimHit with identifier " << simId );
470
471 // a new simhit
472 HepMcParticleLink partLink(HepMC::uniqueID(isp), 0,
475 const double kineticEnergy{-1.}; // dummy value
476 m_cscSimHitCollection->Emplace(simId,globalTimeEstimate,energyDeposit, hitStart, hitEnd, lundcode, partLink, kineticEnergy ) ;
477 }
478
479 return false;
480}
481
483
484 if (m_idHelperSvc->isMM(id)) {
485
486 int simID = m_mmOffToSimId->convert(id);
487
488 //verify
489 Identifier check_id = m_mmOffToSimId->convert(simID);
490
491 if ( check_id != id ) {
492
493 ATH_MSG_WARNING("MM Id conversion error!");
494 ATH_MSG_WARNING(m_idHelperSvc->mmIdHelper().print_to_string(id));
495 ATH_MSG_WARNING(m_idHelperSvc->mmIdHelper().print_to_string(check_id));
496
497 }
498
499 return simID;
500 } else if (m_idHelperSvc->issTgc(id)) {
501
502 int simID = m_stgcOffToSimId->convert(id);
503
504 //verify
505 Identifier check_id = m_stgcOffToSimId->convert(simID);
506
507 if ( check_id != id ) {
508
509 ATH_MSG_WARNING("sTGC Id conversion error!");
510 ATH_MSG_WARNING(m_idHelperSvc->stgcIdHelper().print_to_string(id));
511 ATH_MSG_WARNING(m_idHelperSvc->stgcIdHelper().print_to_string(check_id));
512
513 }
514
515 return simID;
516 }
517
518
519 return 0;
520}
522 PVConstLink cv = mydetEl->getMaterialGeom(); // it is "Multilayer"
523 int nGrandchildren = cv->getNChildVols();
524 if(nGrandchildren <= 0) return;
525
526 Identifier detElId = mydetEl->identify();
527
528 int name = m_idHelperSvc->mdtIdHelper().stationName(detElId);
529 int eta = m_idHelperSvc->mdtIdHelper().stationEta(detElId);
530 int phi = m_idHelperSvc->mdtIdHelper().stationPhi(detElId);
531 int ml = m_idHelperSvc->mdtIdHelper().multilayer(detElId);
532 std::vector<Identifier> deadTubes;
533
534 for(int layer = 1; layer <= mydetEl->getNLayers(); layer++){
535 for(int tube = 1; tube <= mydetEl->getNtubesperlayer(); tube++){
536 bool tubefound = false;
537 for(unsigned int kk=0; kk < cv->getNChildVols(); kk++) {
538 int tubegeo = cv->getIdOfChildVol(kk).value() % maxNTubesPerLayer;
539 int layergeo = ( cv->getIdOfChildVol(kk).value() - tubegeo ) / maxNTubesPerLayer;
540 if( tubegeo == tube && layergeo == layer ) {
541 tubefound=true;
542 break;
543 }
544 if( layergeo > layer ) break; // don't loop any longer if you cannot find tube anyway anymore
545 }
546 if(!tubefound) {
547 Identifier deadTubeId = m_idHelperSvc->mdtIdHelper().channelID( name, eta, phi, ml, layer, tube );
548 deadTubes.push_back( deadTubeId );
549 ATH_MSG_VERBOSE("adding dead tube (" << tube << "), layer(" << layer
550 << "), phi(" << phi << "), eta(" << eta << "), name(" << name
551 << "), multilayerId(" << ml << ") and identifier " << deadTubeId <<" .");
552 }
553 }
554 }
555 std::sort(deadTubes.begin(), deadTubes.end());
556 m_DeadChannels[detElId] = deadTubes;
557}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
AtlasHitsVector< CSCSimHit > CSCSimHitCollection
AtlasHitsVector< MDTSimHit > MDTSimHitCollection
AtlasHitsVector< MMSimHit > MMSimHitCollection
AtlasHitsVector< RPCSimHit > RPCSimHitCollection
AtlasHitsVector< TGCSimHit > TGCSimHitCollection
static const CscHitIdHelper * GetHelper()
The generic ISF particle definition,.
Definition ISFParticle.h:42
const Amg::Vector3D & momentum() const
The current momentum vector of the ISFParticle.
int pdgCode() const
PDG value.
double mass() const
mass of the particle
value_type get_compact() const
Get the compact id.
Identifier32 get_identifier32() const
Get the 32-bit version Identifier, will be invalid if >32 bits needed.
static const MdtHitIdHelper * GetHelper(unsigned int nTubes=78)
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 getNtubesperlayer() const
Returns the number of tubes in each tube layer.
Identifier identify() const override final
Returns the ATLAS Identifier of the MuonReadOutElement.
static const RpcHitIdHelper * GetHelper(unsigned int nGasGaps=2)
static const TgcHitIdHelper * GetHelper()
Base Class for a Detector Layer in the Tracking realm.
Definition Layer.h:72
int layerType() const
get the Layer coding
const Amg::Vector3D & momentum() const
Access method for the momentum.
const Amg::Vector3D & position() const
Access method for the position.
virtual const Surface & associatedSurface() const override=0
Access to the Surface associated to the Parameters.
virtual const Amg::Vector3D & normal() const
Returns the normal vector of the Surface (i.e.
ToolHandle< Trk::ITimedExtrapolator > m_extrapolator
Tool using the track creator per event.
ToolHandle< Muon::IMuonTGMeasTool > m_measTool
Muon TrackingGeometry Measurement Tool.
const CscHitIdHelper * m_cscHitIdHelper
const MdtHitIdHelper * m_mdtHitIdHelper
int offIdToSimId(Identifier id) const
void initDeadChannels(const MuonGM::MdtReadoutElement *mydetEl)
ServiceHandle< IIncidentSvc > m_incidentSvc
Incident Service.
const RpcHitIdHelper * m_rpcHitIdHelper
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
CSCSimHitCollection * m_cscSimHitCollection
void handle(const Incident &inc)
handle for incident service
SimHitCreatorMS(const std::string &, const std::string &, const IInterface *)
std::map< Identifier, std::vector< Identifier > > m_DeadChannels
MMSimHitCollection * m_mmSimHitCollection
RPCSimHitCollection * m_rpcSimHitCollection
const MuonGM::MuonDetectorManager * m_muonMgr
bool createHit(const ISF::ISFParticle &isp, const Trk::Layer *, const Trk::TrackParameters *, Identifier, double, double, bool) const
Private HitCreate method - returns bool for a successful hit creation.
void createHits(const ISF::ISFParticle &isp, const std::vector< Trk::HitInfo > &hits) const
Loop over the hits and call the hit creator - also provide the ISF particle to register the truth lin...
ServiceHandle< IAtRndmGenSvc > m_randomSvc
Pointer to the random number generator service.
const TgcHitIdHelper * m_tgcHitIdHelper
MM_SimIdToOfflineId * m_mmOffToSimId
MDTSimHitCollection * m_mdtSimHitCollection
sTgcSimIdToOfflineId * m_stgcOffToSimId
sTGCSimHitCollection * m_stgcSimHitCollection
virtual StatusCode initialize()
std::string m_randomEngineName
Name of the random number stream.
TGCSimHitCollection * m_tgcSimHitCollection
CLHEP::HepRandomEngine * m_randomEngine
Random Engine.
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:114
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Translation< double, 3 > Translation3D
int uniqueID(const T &p)
ParametersBase< TrackParametersDim, Charged > TrackParameters
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
AtlasHitsVector< sTGCSimHit > sTGCSimHitCollection