ATLAS Offline Software
TgcFastDigiTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 #include "TgcFastDigiTool.h"
5 #include "CLHEP/Random/RandGaussZiggurat.h"
6 #include "CLHEP/Random/RandFlat.h"
7 namespace {
8  constexpr double percentage(unsigned int numerator, unsigned int denom) {
9  return 100. * numerator / std::max(denom, 1u);
10  }
11 }
12 namespace MuonR4 {
13 
14  TgcFastDigiTool::TgcFastDigiTool(const std::string& type, const std::string& name, const IInterface* pIID):
16 
21  return StatusCode::SUCCESS;
22  }
24  ATH_MSG_INFO("Tried to convert "<<m_allHits[0]<<"/"<<m_allHits[1]<<" hits. In, "
25  <<percentage(m_acceptedHits[0], m_allHits[0]) <<"/"
26  <<percentage(m_acceptedHits[1], m_allHits[1]) <<"% of the cases, the conversion was successful");
27  return StatusCode::SUCCESS;
28  }
29 
30  int TgcFastDigiTool::associateBCIdTag(const EventContext& /*ctx*/,
31  const TimedHit& /*timedHit*/) const {
32  return TgcDigit::BC_CURRENT;
33  }
34 
35  bool TgcFastDigiTool::digitizeWireHit(const EventContext& ctx,
36  const TimedHit& timedHit,
37  const Muon::DigitEffiData* efficiencyMap,
38  TgcDigitCollection& outColl,
39  CLHEP::HepRandomEngine* rndEngine) const {
40 
41 
43  const Identifier hitId = timedHit->identify();
44  const TgcIdHelper& idHelper{m_idHelperSvc->tgcIdHelper()};
45  const MuonGMR4::TgcReadoutElement* readOutEle = m_detMgr->getTgcReadoutElement(hitId);
46  const unsigned int gasGap = idHelper.gasGap(hitId);
47 
48  if (!readOutEle->numWireGangs(gasGap)) {
49  ATH_MSG_VERBOSE("There're no wires in "<<m_idHelperSvc->toString(hitId)<<" nothing to do");
50  return false;
51  }
52  ++m_allHits[false];
53  if (efficiencyMap && efficiencyMap->getEfficiency(hitId) < CLHEP::RandFlat::shoot(rndEngine,0.,1.)){
54  ATH_MSG_VERBOSE("Simulated hit "<<xAOD::toEigen(timedHit->localPosition())
55  << m_idHelperSvc->toString(hitId) <<" is rejected because of efficency modelling");
56  return false;
57  }
58 
59  const Amg::Vector2D locSimHitPos{xAOD::toEigen(timedHit->localPosition()).block<2,1>(0,0)};
60 
61  const MuonGMR4::WireGroupDesign& design{readOutEle->wireGangLayout(gasGap)};
62  if (!design.insideTrapezoid(locSimHitPos)) {
63  ATH_MSG_DEBUG("The hit "<<Amg::toString(locSimHitPos)<<" in "<<m_idHelperSvc->toStringGasGap(hitId)
64  <<" is outside of the trapezoid "<<design);
65  return false;
66  }
67  const int wireGrpNum = design.stripNumber(locSimHitPos);
68 
69  if (wireGrpNum < 0) {
70  ATH_MSG_DEBUG("True hit "<<Amg::toString(locSimHitPos)<<" "<<m_idHelperSvc->toStringGasGap(hitId)
71  <<" is not covered by any wire gang");
72  return false;
73  }
74 
75  const double uncert = design.stripPitch() * design.numWiresInGroup(wireGrpNum) / std::sqrt(12);
76  const double locX = CLHEP::RandGaussZiggurat::shoot(rndEngine, locSimHitPos.x(), uncert);
79  const Amg::Vector2D smearedPos{locX, locSimHitPos.y()};
80  const int prdWireNum = design.stripNumber(smearedPos);
81 
82  if (prdWireNum < 0) {
83  if (design.insideTrapezoid(smearedPos)) {
84  ATH_MSG_WARNING("True hit "<<Amg::toString(locSimHitPos, 2)<<" corresponding to "<<wireGrpNum<<" --> "
85  <<Amg::toString(smearedPos)<<" "<<uncert<<" is outside of "<<design);
86  }
87  return false;
88  }
89  bool isValid{false};
90  const Identifier digitId{idHelper.channelID(hitId, gasGap, false, prdWireNum, isValid)};
91  if (!isValid) {
92  ATH_MSG_WARNING("Invalid channel "<< m_idHelperSvc->toStringGasGap(hitId)<<", channel: "<<prdWireNum);
93  return false;
94  }
95  ATH_MSG_VERBOSE("Convert simulated hit "<<m_idHelperSvc->toString(digitId)<<" located at "
96  <<Amg::toString(locSimHitPos, 2)<<" wire group number: "<<prdWireNum
97  <<" wiregroup pos "<<Amg::toString(design.center(prdWireNum).value_or(Amg::Vector2D::Zero()), 2));
98 
99 
100  outColl.push_back(std::make_unique<TgcDigit>(digitId, associateBCIdTag(ctx, timedHit)));
101  ++m_acceptedHits[false];
102  return true;
103  }
104  bool TgcFastDigiTool::digitizeStripHit(const EventContext& ctx,
105  const TimedHit& timedHit,
106  const Muon::DigitEffiData* efficiencyMap,
107  TgcDigitCollection& outColl,
108  CLHEP::HepRandomEngine* rndEngine) const {
109 
110  const Identifier hitId = timedHit->identify();
111  const TgcIdHelper& idHelper{m_idHelperSvc->tgcIdHelper()};
112  const MuonGMR4::TgcReadoutElement* readOutEle = m_detMgr->getTgcReadoutElement(hitId);
113 
114  const unsigned int gasGap = idHelper.gasGap(hitId);
115  if (!readOutEle->numStrips(gasGap)) {
116  ATH_MSG_VERBOSE("There're no strips in "<<m_idHelperSvc->toString(hitId)<<" nothing to do");
117  return false;
118  }
119  ++(m_allHits[true]);
120 
122  if (efficiencyMap && efficiencyMap->getEfficiency(hitId) < CLHEP::RandFlat::shoot(rndEngine,0.,1.)){
123  ATH_MSG_VERBOSE("Simulated hit "<<xAOD::toEigen(timedHit->localPosition())
124  << m_idHelperSvc->toString(hitId) <<" is rejected because of efficency modelling");
125  return false;
126  }
127 
128  const ActsGeometryContext& gctx{getGeoCtx(ctx)};
129 
132 
133  const Amg::Transform3D toPhiRot{readOutEle->globalToLocalTrans(gctx, stripHash) *
134  readOutEle->localToGlobalTrans(gctx, wireHash)};
135  const Amg::Vector2D locSimHitPos{(toPhiRot*xAOD::toEigen(timedHit->localPosition())).block<2,1>(0,0)};
136 
137 
138  const MuonGMR4::RadialStripDesign& design{readOutEle->stripLayout(gasGap)};
139  if (!design.insideTrapezoid(locSimHitPos)) {
140  ATH_MSG_DEBUG("The eta hit "<<Amg::toString(locSimHitPos)<<" in "<<m_idHelperSvc->toStringGasGap(hitId)
141  <<" is outside of the trapezoid "<<std::endl<<design);
142  return false;
143  }
144  int stripNum = design.stripNumber(locSimHitPos);
145  if (stripNum < 0) {
146  ATH_MSG_WARNING("Strip hit "<<Amg::toString(locSimHitPos)<<" cannot be assigned to any active strip for "
147  <<m_idHelperSvc->toStringGasGap(hitId)<<". "<<design);
148  return false;
149  }
151  const Amg::Vector2D stripNorm{design.stripNormal(stripNum)};
152 
155  const double stripPitch = std::abs(*Amg::intersect<2>(design.stripLeftBottom(stripNum), design.stripLeftEdge(stripNum),
156  locSimHitPos, stripNorm)) +
157  std::abs(*Amg::intersect<2>(design.stripRightBottom(stripNum), design.stripRightEdge(stripNum),
158  locSimHitPos, stripNorm));
159 
160  const double uncert = stripPitch / std::sqrt(12);
161  const double locX = CLHEP::RandGaussZiggurat::shoot(rndEngine, locSimHitPos.x(), uncert);
164  const Amg::Vector2D smearedPos{locX, locSimHitPos.y()};
165  const int digitStripNum = design.stripNumber(smearedPos);
166 
167  if (digitStripNum < 0) {
168  if (design.insideTrapezoid(smearedPos)) {
169  ATH_MSG_WARNING("True phi hit "<<Amg::toString(locSimHitPos, 2)<<" corresponding to "<<stripNum<<" --> "
170  <<Amg::toString(smearedPos)<<" "<<uncert<<" is outside of "<<design);
171  }
172  return false;
173  }
174 
175  bool isValid{false};
176  const Identifier digitId{idHelper.channelID(hitId, gasGap, true, digitStripNum, isValid)};
177  if (!isValid) {
178  ATH_MSG_WARNING("Invalid channel "<< m_idHelperSvc->toStringGasGap(hitId)<<", channel: "<<digitStripNum);
179  return false;
180  }
181  ATH_MSG_VERBOSE("Convert simulated hit "<<m_idHelperSvc->toString(digitId)<<" located at "
182  <<Amg::toString(locSimHitPos, 2)<<" phi strip number: "<<digitStripNum
183  <<" strip position "<<Amg::toString(design.center(digitStripNum).value_or(Amg::Vector2D::Zero()), 2));
184 
185  outColl.push_back(std::make_unique<TgcDigit>(digitId, associateBCIdTag(ctx, timedHit)));
186 
187  ++(m_acceptedHits[true]);
188  return true;
189  }
190  StatusCode TgcFastDigiTool::digitize(const EventContext& ctx,
191  const TimedHits& hitsToDigit,
192  xAOD::MuonSimHitContainer* sdoContainer) const {
193 
194  // Prepare the temporary cache
195  DigiCache digitCache{};
197  const Muon::DigitEffiData* efficiencyMap{nullptr};
198  ATH_CHECK(retrieveConditions(ctx, m_effiDataKey, efficiencyMap));
199  const TgcIdHelper& idHelper{m_idHelperSvc->tgcIdHelper()};
200 
201  CLHEP::HepRandomEngine* rndEngine = getRandomEngine(ctx);
202 
203 
204  for (const TimedHit& simHit : hitsToDigit) {
206  if (std::abs(simHit->pdgId()) != 13) continue;
207  TgcDigitCollection* outColl = fetchCollection(simHit->identify(), digitCache);
208 
209  bool digitized = digitizeWireHit(ctx,simHit, efficiencyMap,*outColl, rndEngine);
210  digitized |= digitizeStripHit(ctx, simHit, efficiencyMap,*outColl, rndEngine);
211 
212  if (digitized) {
213  addSDO(simHit, sdoContainer);
214  }
215  }
217  ATH_CHECK(writeDigitContainer(ctx, m_writeKey, std::move(digitCache), idHelper.module_hash_max()));
218  return StatusCode::SUCCESS;
219  }
220 }
MuonR4::TgcFastDigiTool::m_effiDataKey
SG::ReadCondHandleKey< Muon::DigitEffiData > m_effiDataKey
Definition: TgcFastDigiTool.h:69
MuonGMR4::TgcReadoutElement::numWireGangs
unsigned int numWireGangs(unsigned int gasGap) const
Returns the number of wire gangs for a given gasGap [1-3].
dumpTgcDigiDeadChambers.gasGap
list gasGap
Definition: dumpTgcDigiDeadChambers.py:33
MuonGMR4::TgcReadoutElement::wireGangLayout
const WireGroupDesign & wireGangLayout(unsigned int gasGap) const
Returns access to the wire group design of the given gasGap [1-3] If the gap does not have a wires an...
MuonR4::TgcFastDigiTool::initialize
StatusCode initialize() override final
Definition: TgcFastDigiTool.cxx:17
MuonGMR4::WireGroupDesign
Definition: WireGroupDesign.h:23
max
#define max(a, b)
Definition: cfImp.cxx:41
TgcDigit::BC_CURRENT
@ BC_CURRENT
Definition: TgcDigit.h:37
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Trk::locX
@ locX
Definition: ParamDefs.h:43
TgcIdHelper
Definition: TgcIdHelper.h:50
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
MuonR4::TgcFastDigiTool::DigiCache
OutDigitCache_t< TgcDigitCollection > DigiCache
Definition: TgcFastDigiTool.h:65
MuonGMR4::MuonReadoutElement::globalToLocalTrans
Amg::Transform3D globalToLocalTrans(const ActsGeometryContext &ctx) const
Transformations to translate between local <-> global coordinates.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MuonReadoutElement.cxx:78
TimedHitPtr< xAOD::MuonSimHit >
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
isValid
bool isValid(const T &p)
Definition: AtlasPID.h:214
MuonR4::TgcFastDigiTool::TgcFastDigiTool
TgcFastDigiTool(const std::string &type, const std::string &name, const IInterface *pIID)
Definition: TgcFastDigiTool.cxx:14
SG::VarHandleKey::empty
bool empty() const
Test if the key is blank.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:150
MuonR4::TgcFastDigiTool::associateBCIdTag
int associateBCIdTag(const EventContext &ctx, const TimedHit &timedHit) const
: Associates the global bcIdTag to the digit
Definition: TgcFastDigiTool.cxx:30
MuonGMR4::TgcReadoutElement::constructHash
static IdentifierHash constructHash(unsigned int measCh, unsigned int gasGap, const bool isStrip)
Constructs the Hash out of the Identifier fields (channel, gasGap, isStrip)
MuonR4::MuonDigitizationTool::retrieveConditions
StatusCode retrieveConditions(const EventContext &ctx, const SG::ReadCondHandleKey< Container > &key, const Container *&contPtr) const
Helper function to access the conditions data.
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:83
MuonR4::TgcFastDigiTool::digitizeStripHit
bool digitizeStripHit(const EventContext &ctx, const TimedHit &timedHit, const Muon::DigitEffiData *efficiencyMap, TgcDigitCollection &outColl, CLHEP::HepRandomEngine *rndEngine) const
Digitize the strip hit by smearing the truth hit position according to the wire group pitch and then ...
Definition: TgcFastDigiTool.cxx:104
MuonR4::TgcFastDigiTool::finalize
StatusCode finalize() override final
Definition: TgcFastDigiTool.cxx:23
MuonR4::TgcFastDigiTool::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: TgcFastDigiTool.cxx:190
MuonGMR4::TgcReadoutElement::numStrips
unsigned int numStrips(unsigned int gasGap) const
Returns the number of strips for a given gasGap [1-3].
MuonGMR4::TgcReadoutElement::stripLayout
const RadialStripDesign & stripLayout(unsigned int gasGap) const
Returns access to the strip design of the given gasGap [1-3] If the gap does not have strips an excep...
TgcFastDigiTool.h
MuonR4::MuonDigitizationTool::addSDO
void addSDO(const TimedHit &hit, xAOD::MuonSimHitContainer *sdoContainer) const
Adds the timed simHit to the output SDO container.
Definition: MuonDigitizationTool.cxx:148
Amg::toString
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Definition: GeoPrimitivesToStringConverter.h:40
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
MuonR4::MuonDigitizationTool::getRandomEngine
CLHEP::HepRandomEngine * getRandomEngine(const EventContext &ctx) const
Definition: MuonDigitizationTool.cxx:135
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
TgcDigitCollection
Definition: TgcDigitCollection.h:17
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
Muon::DigitEffiData::getEfficiency
double getEfficiency(const Identifier &channelId, bool isInnerQ1=false) const
Returns the signal generation efficiency of the sTgc channel.
Definition: DigitEffiData.cxx:36
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:581
ActsGeometryContext
Include the GeoPrimitives which need to be put first.
Definition: ActsGeometryContext.h:27
compute_lumi.denom
denom
Definition: compute_lumi.py:76
Muon::DigitEffiData
Definition: DigitEffiData.h:23
MuonR4::MuonDigitizationTool::getGeoCtx
const ActsGeometryContext & getGeoCtx(const EventContext &ctx) const
Returns the reference to the ActsGeometryContext needed to fetch global positions from the Readout ge...
Definition: MuonDigitizationTool.cxx:141
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
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)
MuonR4
The CsvMuonSimHitDumper reads a Simulation Hit container for muons and dumps information to csv files...
Definition: MuonSpacePoint.h:11
MuonR4::MuonDigitizationTool::initialize
StatusCode initialize() override
Definition: MuonDigitizationTool.cxx:17
MuonR4::TgcFastDigiTool::m_writeKey
SG::WriteHandleKey< TgcDigitContainer > m_writeKey
Definition: TgcFastDigiTool.h:67
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:60
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
MuonR4::MuonDigitizationTool::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: MuonDigitizationTool.h:122
MuonR4::TgcFastDigiTool::digitizeWireHit
bool digitizeWireHit(const EventContext &ctx, const TimedHit &timedHit, const Muon::DigitEffiData *efficiencyMap, TgcDigitCollection &outColl, CLHEP::HepRandomEngine *rndEngine) const
Digitize the wire hit by smearing the truth hit position according to the wire group pitch and then a...
Definition: TgcFastDigiTool.cxx:35
MuonGMR4::MuonReadoutElement::localToGlobalTrans
const Amg::Transform3D & localToGlobalTrans(const ActsGeometryContext &ctx) const
Returns the local to global transformation into the ATLAS coordinate system.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MuonReadoutElement.cxx:81
MuonR4::MuonDigitizationTool::m_detMgr
const MuonGMR4::MuonDetectorManager * m_detMgr
Definition: MuonDigitizationTool.h:120
IdentifierHash
Definition: IdentifierHash.h:38
MuonGMR4::RadialStripDesign
Definition: RadialStripDesign.h:23
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 ...
MuonGMR4::TgcReadoutElement
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/TgcReadoutElement.h:20
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32