ATLAS Offline Software
MmFastDigiTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 #include "MmFastDigiTool.h"
7 #include "CLHEP/Random/RandGaussZiggurat.h"
8 #include "CLHEP/Random/RandFlat.h"
9 
10 namespace {
11  constexpr double percentage(unsigned int numerator, unsigned int denom) {
12  return 100. * numerator / std::max(denom, 1u);
13  }
14 }
15 namespace MuonR4 {
16 
17  MmFastDigiTool::MmFastDigiTool(const std::string& type, const std::string& name, const IInterface* pIID):
19 
25  return StatusCode::SUCCESS;
26  }
28  std::stringstream statstr{};
29  unsigned allHits{0};
30  for (unsigned int g = 0; g < m_allHits.size(); ++g) {
31  allHits += m_allHits[g];
32  statstr<<" *** Layer "<<(g+1)<<" "<<percentage(m_acceptedHits[g],m_allHits[g])
33  <<"% of "<<m_allHits[g]<<std::endl;
34  }
35  if(!allHits) return StatusCode::SUCCESS;
36  ATH_MSG_INFO("Tried to convert "<<allHits<<" hits. Successes rate per layer "<<std::endl<<statstr.str());
37  return StatusCode::SUCCESS;
38  }
39  StatusCode MmFastDigiTool::digitize(const EventContext& ctx,
40  const TimedHits& hitsToDigit,
41  xAOD::MuonSimHitContainer* sdoContainer) const {
42  const MmIdHelper& idHelper{m_idHelperSvc->mmIdHelper()};
43  // Prepare the temporary cache
44  DigiCache digitCache{};
46  const Muon::DigitEffiData* efficiencyMap{nullptr};
47  ATH_CHECK(SG::get(efficiencyMap, m_effiDataKey, ctx));
48  const NswErrorCalibData* errorCalibDB{nullptr};
49  ATH_CHECK(SG::get(errorCalibDB, m_uncertCalibKey, ctx));
50 
51  CLHEP::HepRandomEngine* rndEngine = getRandomEngine(ctx);
52  xAOD::ChamberViewer viewer{hitsToDigit, m_idHelperSvc.get()};
53  do {
54  DeadTimeMap deadTimes{};
55  for (const TimedHit& simHit : viewer) {
56  if (m_digitizeMuonOnly && !MC::isMuon(simHit)){
57  continue;
58  }
59 
60  const double hitKineticEnergy = simHit->kineticEnergy();
61  // Don't consider electron hits below m_energyThreshold.
62  // Electrons aren't consider for now in any case due to the cut above.
63  // But this may change.
64  if (hitKineticEnergy < m_energyThreshold && MC::isElectron(simHit)) {
65  continue;
66  }
67 
68  const Identifier hitId{simHit->identify()};
69 
70  const MuonGMR4::MmReadoutElement* readOutEle = m_detMgr->getMmReadoutElement(hitId);
71  const Amg::Vector2D locPos{xAOD::toEigen(simHit->localPosition()).block<2,1>(0,0)};
72 
74  const unsigned int hitGapInNsw = (idHelper.multilayer(hitId) -1) * 4 + idHelper.gasGap(hitId) -1;
75  ++m_allHits[hitGapInNsw];
76 
77  const MuonGMR4::StripDesign& design{readOutEle->stripLayer(hitId).design()};
78  bool isValid{false};
79 
80  int channelNumber = design.stripNumber(locPos);
81  if(channelNumber<0){
82  if (!design.insideTrapezoid(locPos)) {
83  ATH_MSG_WARNING("Hit "<<m_idHelperSvc->toString(hitId)<<" "<<Amg::toString(locPos)
84  <<" is outside bounds "<<std::endl<<design<<" rejecting it");
85  }
86  continue;
87  }
88  const Identifier clusId = idHelper.channelID(hitId,
89  idHelper.multilayer(hitId),
90  idHelper.gasGap(hitId),
91  channelNumber, isValid);
92 
93  if(!isValid) {
94  ATH_MSG_WARNING("Invalid strip identifier for layer " << m_idHelperSvc->toStringGasGap(hitId)
95  << " channel " << channelNumber << " locPos " << Amg::toString(locPos));
96  continue;
97  }
98 
99  if(efficiencyMap && efficiencyMap->getEfficiency(clusId) < CLHEP::RandFlat::shoot(rndEngine, 0., 1.)){
100  continue;
101  }
102  if (!passDeadTime(clusId, hitTime(simHit), m_deadTime, deadTimes)) {
104  continue;
105  }
106  NswErrorCalibData::Input errorCalibInput{};
107  errorCalibInput.stripId = clusId;
108  errorCalibInput.locTheta = M_PI- simHit->localDirection().theta();
109  errorCalibInput.clusterAuthor=66; // cluster time projection method
110  const double uncert = errorCalibDB->clusterUncertainty(errorCalibInput);
111  ATH_MSG_VERBOSE("mm hit has theta " << errorCalibInput.locTheta / Gaudi::Units::deg << " and uncertainty " << uncert);
112 
113 
116  constexpr int dummyResponseTime = 100;
117  constexpr float dummyDepositedCharge = 666666;
118 
119  const double newLocalX = CLHEP::RandGaussZiggurat::shoot(rndEngine, locPos.x(), uncert);
120  const int newChannel = design.stripNumber(newLocalX * Amg::Vector2D::UnitX());
121  if (newChannel < 0) {
122  continue;
123  }
124 
125  const Identifier digitId = idHelper.channelID(hitId,
126  idHelper.multilayer(hitId),
127  idHelper.gasGap(hitId),
128  newChannel, isValid);
129 
130  if(!isValid) {
131  ATH_MSG_WARNING("Invalid strip identifier for layer " << m_idHelperSvc->toStringGasGap(hitId)
132  << " channel " << newChannel << " locPos " << Amg::toString(locPos));
133  continue;
134  }
148 
157  const double pull = (newLocalX - (*design.center(newChannel)).x()) / (design.stripPitch() * std::cos(design.stereoAngle()));
158  const double w1 = CLHEP::RandFlat::shoot(rndEngine, 0., 0.5 *(1. - pull));
159  const double w2 = 1 - pull -2*w1;
160  const double w3 = pull + w1;
161  MmDigitCollection* outColl = fetchCollection(hitId, digitCache);
162 
163  const Identifier digitIdB = idHelper.channelID(hitId,
164  idHelper.multilayer(hitId),
165  idHelper.gasGap(hitId),
166  newChannel - 1, isValid);
167 
168  if (isValid) {
169  outColl->push_back(std::make_unique<MmDigit>(digitIdB, dummyResponseTime, w1 * dummyDepositedCharge));
170  }
171  outColl->push_back(std::make_unique<MmDigit>(digitId,dummyResponseTime, w2 * dummyDepositedCharge));
172 
173  const Identifier digitIdA = idHelper.channelID(hitId,
174  idHelper.multilayer(hitId),
175  idHelper.gasGap(hitId),
176  newChannel + 1, isValid);
177  if (isValid) {
178  outColl->push_back(std::make_unique<MmDigit>(digitIdA, dummyResponseTime, w3 * dummyDepositedCharge));
179  }
180 
181  xAOD::MuonSimHit* sdoHit = addSDO(simHit, sdoContainer);
182  sdoHit->setIdentifier(clusId);
183  ++m_acceptedHits[hitGapInNsw];
184  }
185  } while(viewer.next());
187  ATH_CHECK(writeDigitContainer(ctx, m_writeKey, std::move(digitCache), idHelper.module_hash_max()));
188  return StatusCode::SUCCESS;
189  }
190 }
MmDigitCollection
Definition: MmDigitCollection.h:18
MuonR4::MmFastDigiTool::initialize
StatusCode initialize() override final
Definition: MmFastDigiTool.cxx:20
NswErrorCalibData
Definition: NswErrorCalibData.h:19
xAOD::MuonSimHit_v1
Definition: MuonSimHit_v1.h:18
MuonR4::MuonDigitizationTool::passDeadTime
static bool passDeadTime(const Identifier &channelId, const double hitTime, const double deadTimeWindow, DeadTimeMap &deadTimeMap)
Returns whether the new digit is within the dead time window.
Definition: MuonDigitizationTool.cxx:164
MuonGMR4::MmReadoutElement
Definition: MmReadoutElement.h:18
MmFastDigiTool.h
MuonGMR4::StripDesign
Definition: StripDesign.h:30
MuonR4::MmFastDigiTool::finalize
StatusCode finalize() override final
Definition: MmFastDigiTool.cxx:27
xAOD::MuonSimHit_v1::setIdentifier
void setIdentifier(const Identifier &id)
Sets the global ATLAS identifier.
Definition: xAODMuonSimHit_V1.cxx:43
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
M_PI
#define M_PI
Definition: ActiveFraction.h:11
deg
#define deg
Definition: SbPolyhedron.cxx:17
TimedHitPtr< xAOD::MuonSimHit >
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
isValid
bool isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
Definition: AtlasPID.h:872
SG::VarHandleKey::empty
bool empty() const
Test if the key is blank.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:150
x
#define x
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
xAOD::ChamberViewer
Definition: ChamberViewer.h:59
Amg::toString
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Definition: GeoPrimitivesToStringConverter.h:40
SG::get
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
Definition: ReadCondHandle.h:287
MuonR4::MuonDigitizationTool::getRandomEngine
CLHEP::HepRandomEngine * getRandomEngine(const EventContext &ctx) const
Definition: MuonDigitizationTool.cxx:129
python.CaloCondTools.g
g
Definition: CaloCondTools.py:15
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
xAOD::EgammaHelpers::isElectron
bool isElectron(const xAOD::Egamma *eg)
is the object an electron (not Fwd)
Definition: EgammaxAODHelpers.cxx:12
MuonR4::MmFastDigiTool::m_digitizeMuonOnly
Gaudi::Property< bool > m_digitizeMuonOnly
Definition: MmFastDigiTool.h:49
MuonR4::MmFastDigiTool::DigiCache
OutDigitCache_t< MmDigitCollection > DigiCache
Definition: MmFastDigiTool.h:33
python.StandardJetMods.pull
pull
Definition: StandardJetMods.py:309
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
MuonR4::MmFastDigiTool::m_effiDataKey
SG::ReadCondHandleKey< Muon::DigitEffiData > m_effiDataKey
Definition: MmFastDigiTool.h:36
MuonGMR4::StripLayer::design
const StripDesign & design(bool phiView=false) const
Returns the underlying strip design.
compute_lumi.denom
denom
Definition: compute_lumi.py:76
NswErrorCalibData::Input::stripId
Identifier stripId
Identifier of the strip.
Definition: NswErrorCalibData.h:27
MuonGMR4::MmReadoutElement::stripLayer
const StripLayer & stripLayer(const Identifier &measId) const
Muon::DigitEffiData
Definition: DigitEffiData.h:23
MuonR4::MuonDigitizationTool::addSDO
xAOD::MuonSimHit * addSDO(const TimedHit &hit, xAOD::MuonSimHitContainer *sdoContainer) const
Adds the timed simHit to the output SDO container.
Definition: MuonDigitizationTool.cxx:142
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
MuonR4::MuonDigitizationTool::writeDigitContainer
StatusCode writeDigitContainer(const EventContext &ctx, const SG::WriteHandleKey< DigitCont > &key, OutDigitCache_t< DigitColl > &&digitCache, unsigned int hashMax) const
Helper function to move the collected digits into the final DigitContainer.
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
ChamberViewer.h
MuonR4::MmFastDigiTool::m_deadTime
Gaudi::Property< double > m_deadTime
Definition: MmFastDigiTool.h:47
MuonR4::MmFastDigiTool::MmFastDigiTool
MmFastDigiTool(const std::string &type, const std::string &name, const IInterface *pIID)
Definition: MmFastDigiTool.cxx:17
MuonR4::MuonDigitizationTool::hitTime
static double hitTime(const TimedHit &hit)
Returns the global time of the hit which is the sum of eventTime & individual hit time.
Definition: MuonDigitizationTool.cxx:63
MuonR4
This header ties the generic definitions in this package.
Definition: HoughEventData.h:16
MuonR4::MuonDigitizationTool::initialize
StatusCode initialize() override
Definition: MuonDigitizationTool.cxx:11
MmIdHelper
Definition: MmIdHelper.h:54
MuonR4::MuonDigitizationTool
Barebone implementation of the I/O infrastructure for all MuonDigitizationTools.
Definition: MuonDigitizationTool.h:30
MuonR4::MuonDigitizationTool::TimedHits
std::vector< TimedHitPtr< xAOD::MuonSimHit > > TimedHits
Definition: MuonDigitizationTool.h:58
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
MuonR4::MmFastDigiTool::m_writeKey
SG::WriteHandleKey< MmDigitContainer > m_writeKey
Definition: MmFastDigiTool.h:34
MuonR4::MuonDigitizationTool::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: MuonDigitizationTool.h:113
MuonR4::MuonDigitizationTool::m_detMgr
const MuonGMR4::MuonDetectorManager * m_detMgr
Definition: MuonDigitizationTool.h:111
MuonR4::MuonDigitizationTool::DeadTimeMap
std::unordered_map< Identifier, double > DeadTimeMap
Definition: MuonDigitizationTool.h:100
NswErrorCalibData::Input
Helper struct to be parsed to the object to derive the specific error of the cluster.
Definition: NswErrorCalibData.h:25
MuonR4::MmFastDigiTool::m_energyThreshold
Gaudi::Property< double > m_energyThreshold
Definition: MmFastDigiTool.h:51
MuonR4::MmFastDigiTool::digitize
StatusCode digitize(const EventContext &ctx, const TimedHits &hitsToDigit, xAOD::MuonSimHitContainer *sdoContainer) const override final
Digitize the time ordered hits and write them to the digit format specific for the detector technolog...
Definition: MmFastDigiTool.cxx:39
MuonR4::MuonDigitizationTool::fetchCollection
DigitColl * fetchCollection(const Identifier &hitId, OutDigitCache_t< DigitColl > &digitCache) const
Helper function that provides fetches the proper DigitCollection from the DigitCache for a given hit ...
MuonR4::MmFastDigiTool::m_uncertCalibKey
SG::ReadCondHandleKey< NswErrorCalibData > m_uncertCalibKey
Definition: MmFastDigiTool.h:39
HepMCHelpers.h
isMuon
bool isMuon(const T &p)
Definition: AtlasPID.h:202
Identifier
Definition: IdentifierFieldParser.cxx:14