33 #include "CLHEP/Random/RandLandau.h" 
   34 #include "CLHEP/Random/RandGaussZiggurat.h" 
   45                                           const IInterface*  
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),
 
   55   m_stgcSimHitCollection(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),
 
   72   m_mdtSigmaDriftRadius(0.08),
 
   74   m_createAllMdtHits(true)
 
   77   declareProperty(
"MeasurementTool",              
m_measTool);
 
   80   declareProperty(
"RandomNumberService",          
m_randomSvc,        
"Random number generator");
 
   81   declareProperty(
"RandomStreamName",             
m_randomEngineName, 
"Name of the random number stream");
 
  119   m_randomEngine = m_randomSvc->GetEngine(m_randomEngineName);
 
  120   if (!m_randomEngine) {
 
  121     ATH_MSG_ERROR( 
"[ --- ] Could not get random engine '" << m_randomEngineName << 
"'" );
 
  122     return StatusCode::FAILURE;
 
  129   m_incidentSvc->addListener( 
this, IncidentType::BeginEvent);
 
  133   m_BMGpresent = m_idHelperSvc->mdtIdHelper().stationNameIndex(
"BMG") != -1;
 
  135     ATH_MSG_INFO(
"Processing configuration for layouts with BMG chambers.");
 
  136     m_BMGid = m_idHelperSvc->mdtIdHelper().stationNameIndex(
"BMG");
 
  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++) { 
 
  144             if(mdtRE) initDeadChannels(mdtRE);
 
  152   return StatusCode::SUCCESS;
 
  159   if ( inc.type() == IncidentType::BeginEvent ){
 
  163     if ( evtStore()->contains<MDTSimHitCollection>(m_mdtCollectionName) ){
 
  164       if ( (evtStore()->
retrieve(m_mdtSimHitCollection , m_mdtCollectionName)).isFailure() )
 
  165         ATH_MSG_ERROR( 
"[ --- ] Unable to retrieve MDTSimHitCollection " << m_mdtCollectionName);
 
  169       if ( (evtStore()->record(m_mdtSimHitCollection, m_mdtCollectionName, 
true)).isFailure() ) {
 
  170         ATH_MSG_ERROR( 
"[ --- ] Unable to record MDTSimHitCollection " << m_mdtCollectionName);
 
  171         delete m_mdtSimHitCollection; m_mdtSimHitCollection=
nullptr;
 
  174     if ( evtStore()->contains<RPCSimHitCollection>(m_rpcCollectionName) ){
 
  175       if ( (evtStore()->
retrieve(m_rpcSimHitCollection , m_rpcCollectionName)).isFailure() )
 
  176         ATH_MSG_ERROR( 
"[ --- ] Unable to retrieve RPCSimHitCollection " << m_rpcCollectionName);
 
  180       if ( (evtStore()->record(m_rpcSimHitCollection, m_rpcCollectionName, 
true)).isFailure() ) {
 
  181         ATH_MSG_ERROR( 
"[ --- ] Unable to record RPCSimHitCollection " << m_rpcCollectionName);
 
  182         delete m_rpcSimHitCollection; m_rpcSimHitCollection=
nullptr;
 
  185     if ( evtStore()->contains<TGCSimHitCollection>(m_tgcCollectionName) ){
 
  186       if ( (evtStore()->
retrieve(m_tgcSimHitCollection , m_tgcCollectionName)).isFailure() )
 
  187         ATH_MSG_ERROR( 
"[ --- ] Unable to retrieve TGCSimHitCollection " << m_tgcCollectionName);
 
  191       if ( (evtStore()->record(m_tgcSimHitCollection, m_tgcCollectionName, 
true)).isFailure() ) {
 
  192         ATH_MSG_ERROR( 
"[ --- ] Unable to record TGCSimHitCollection " << m_tgcCollectionName);
 
  193         delete m_tgcSimHitCollection; m_tgcSimHitCollection=
nullptr;
 
  196     if ( evtStore()->contains<CSCSimHitCollection>(m_cscCollectionName) ){
 
  197       if ( (evtStore()->
retrieve(m_cscSimHitCollection , m_cscCollectionName)).isFailure() )
 
  198         ATH_MSG_ERROR( 
"[ --- ] Unable to retrieve CSCSimHitCollection " << m_cscCollectionName);
 
  202       if ( (evtStore()->record(m_cscSimHitCollection, m_cscCollectionName, 
true)).isFailure() ) {
 
  203         ATH_MSG_ERROR( 
"[ --- ] Unable to record CSCSimHitCollection " << m_cscCollectionName);
 
  204         delete m_cscSimHitCollection; m_cscSimHitCollection=
nullptr;
 
  207     if ( evtStore()->contains<MMSimHitCollection>(m_mmCollectionName) ){
 
  208       if ( (evtStore()->
retrieve(m_mmSimHitCollection , m_mmCollectionName)).isFailure() )
 
  209         ATH_MSG_ERROR( 
"[ --- ] Unable to retrieve MMSimHitCollection " << m_mmCollectionName);
 
  213       if ( (evtStore()->record(m_mmSimHitCollection, m_mmCollectionName, 
true)).isFailure() ) {
 
  214         ATH_MSG_ERROR( 
"[ --- ] Unable to record MMSimHitCollection " << m_mmCollectionName);
 
  215         delete m_mmSimHitCollection; m_mmSimHitCollection=
nullptr;
 
  218     if ( evtStore()->contains<sTGCSimHitCollection>(m_stgcCollectionName) ){
 
  219       if ( (evtStore()->
retrieve(m_stgcSimHitCollection , m_stgcCollectionName)).isFailure() )
 
  220         ATH_MSG_ERROR( 
"[ --- ] Unable to retrieve sTGCSimHitCollection " << m_stgcCollectionName);
 
  224       if ( (evtStore()->record(m_stgcSimHitCollection, m_stgcCollectionName, 
true)).isFailure() ) {
 
  225         ATH_MSG_ERROR( 
"[ --- ] Unable to record sTGCSimHitCollection " << m_stgcCollectionName);
 
  226         delete m_stgcSimHitCollection; m_stgcSimHitCollection=
nullptr;
 
  235                                           const std::vector<Trk::HitInfo>& 
hits)
 const {
 
  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 ){
 
  243     double timeInfo = (*plIter).time;
 
  244     const Trk::Layer*        currLay = m_extrapolator->trackingGeometry()->associatedLayer( parm->
position() );
 
  246     if (!currLay) 
continue;
 
  251     if ( m_idHelperSvc->isMM(
id) ||  m_idHelperSvc->issTgc(
id) ) {
 
  253       int simID = offIdToSimId(
id);
 
  265       float segLengthSTGC = 2.85/cosAngle; 
 
  273       if ( m_idHelperSvc->isMM(
id) )  {
 
  274         m_mmSimHitCollection->Emplace(simID, timeInfo, 
pos,
 
  279         m_stgcSimHitCollection->Emplace(simID, timeInfo, exitPos,
 
  281                                         partLink, eKin, entryPos);
 
  286     }  
else if (m_idHelperSvc->isMdt(
id)) {    
 
  289       Identifier hid = m_measTool->nearestDetEl(currLay,parm,
false,pitch);
 
  291       if (m_idHelperSvc->mdtIdHelper().valid(hid)) {
 
  293         bool hitCreated = createHit(isp, currLay,parm,hid,timeInfo,pitch, 
true);
 
  294         if (m_createAllMdtHits) {
 
  297           if (!mdtROE) 
continue;
 
  299           int tCur = m_idHelperSvc->mdtIdHelper().tube(hid);
 
  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),
 
  309             if (!m_idHelperSvc->mdtIdHelper().valid(nextId)) 
break;
 
  310             hitCreated = createHit(isp, currLay,parm,nextId,timeInfo,pitch,
true);
 
  311             if (!hitCreated) 
break;
 
  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),
 
  322             if (!m_idHelperSvc->mdtIdHelper().valid(nextId)) 
break;
 
  323             hitCreated = createHit(isp, currLay,parm,nextId,timeInfo,pitch,
true);
 
  324             if (!hitCreated) 
break;
 
  331       Identifier hid = m_measTool->nearestDetEl(currLay,parm,
false,pitch);
 
  337       hid = m_measTool->nearestDetEl(currLay,parm,
true,pitch);
 
  350   if (m_idHelperSvc->isMdt(
id)) {
 
  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));
 
  357     ATH_MSG_VERBOSE(  
"[ muhit ] Creating MDTSimHit with identifier " <<  simId );
 
  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) );
 
  370     const Amg::Vector3D  localPos = m_muonMgr->getMdtReadoutElement(
id)->globalToLocalTransf(
id) * parm->
position();
 
  372     double residual = m_measTool->residual(lay,parm,
id);
 
  376       double de = 0.02*dlh/15.075;
 
  377       double energyDeposit= de + 0.005*CLHEP::RandGaussZiggurat::shoot(m_randomEngine);
 
  384       m_mdtSimHitCollection->Emplace(simId,globalTimeEstimate,
 
  393   } 
else if (m_idHelperSvc->isRpc(
id)) {
 
  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));
 
  402     ATH_MSG_VERBOSE(  
"[ muhit ] Creating RPCSimHit with identifier " <<  simId );
 
  404     double energyDeposit= 1.5e-03 + 3.9e-04*CLHEP::RandLandau::shoot(m_randomEngine);
 
  411     m_rpcSimHitCollection->Emplace(simId,globalTimeEstimate, localPos, partLink, localPos, 
energyDeposit,1.,isp.
pdgCode(),isp.
momentum().mag() ) ;
 
  413   } 
else if (m_idHelperSvc->isTgc(
id) && !m_idHelperSvc->tgcIdHelper().isStrip(
id) ) {
 
  418     Amg::Vector3D localDir = m_muonMgr->getTgcReadoutElement(
id)->globalToLocalTransf(
id).rotation()*parm->
momentum().normalized();
 
  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));
 
  424     ATH_MSG_VERBOSE(  
"[ muhit ] Creating TGCSimHit with identifier " <<  simId );
 
  427     double energyDeposit= 1.3e-03 + 6.e-04*CLHEP::RandGaussZiggurat::shoot(m_randomEngine);
 
  429     double stepLength=3.;
 
  435     m_tgcSimHitCollection->Emplace(simId,globalTimeEstimate, localPos, localDir, partLink, 
energyDeposit, stepLength ) ;
 
  436   } 
else if (m_idHelperSvc->isCsc(
id)) {
 
  442     float energyDeposit= 0.24e-03 + 1.1e-03*CLHEP::RandGaussZiggurat::shoot(m_randomEngine);
 
  446     float hitlength = 5./cs;
 
  451     const Amg::Transform3D globalToLocTransf{m_muonMgr->getCscReadoutElement(
id)->globalToLocalTransf(
id)};
 
  459     if (pdgcode == 22) lundcode=1;
 
  460     else if (pdgcode == 13 ) lundcode=6;
 
  461     else if (pdgcode == -13) lundcode=5;
 
  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));
 
  469     ATH_MSG_VERBOSE(  
"[ muhit ] Creating CSCSimHit with identifier " <<  simId );
 
  475     const double kineticEnergy{-1.}; 
 
  476     m_cscSimHitCollection->Emplace(simId,globalTimeEstimate,
energyDeposit, hitStart, hitEnd, lundcode, partLink, kineticEnergy ) ;
 
  484   if (m_idHelperSvc->isMM(
id)) {
 
  486     int simID = m_mmOffToSimId->convert(
id);
 
  489     Identifier check_id = m_mmOffToSimId->convert(simID);
 
  491     if ( check_id != 
id ) {
 
  495       ATH_MSG_WARNING(m_idHelperSvc->mmIdHelper().print_to_string(check_id));
 
  500   } 
else if (m_idHelperSvc->issTgc(
id)) {
 
  502     int simID = m_stgcOffToSimId->convert(
id);
 
  505     Identifier check_id = m_stgcOffToSimId->convert(simID);
 
  507     if ( check_id != 
id ) {
 
  511       ATH_MSG_WARNING(m_idHelperSvc->stgcIdHelper().print_to_string(check_id));
 
  522   PVConstLink cv = mydetEl->getMaterialGeom(); 
 
  523   int nGrandchildren = cv->getNChildVols();
 
  524   if(nGrandchildren <= 0) 
return;
 
  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;
 
  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 ) {
 
  544         if( layergeo > 
layer ) 
break; 
 
  548         deadTubes.push_back( deadTubeId );
 
  550                         << 
"), phi(" << 
phi << 
"), eta(" << 
eta << 
"), name(" << 
name 
  551                         << 
"), multilayerId(" << ml << 
") and identifier " << deadTubeId <<
" .");
 
  555   std::sort(deadTubes.begin(), deadTubes.end());
 
  556   m_DeadChannels[detElId] = deadTubes;