ATLAS Offline Software
RT_Relation_DB_DigiTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include <iostream>
8 
12 
13 using namespace MuonGM;
14 
15 RT_Relation_DB_DigiTool::RT_Relation_DB_DigiTool(const std::string &type, const std::string &name, const IInterface *parent) :
17  declareInterface<IMDT_DigitizationTool>(this);
18 }
19 
21  ATH_MSG_INFO("Initializing RT_Relation_DB_DigiTool");
24  return StatusCode::SUCCESS;
25 }
26 
28  const MdtDigiToolInput &input,
29  CLHEP::HepRandomEngine *rndmEngine) const {
30  ATH_MSG_DEBUG("Digitizing input ");
32  const Identifier DigitId = input.getHitID();
33  const double maxTubeRadius{detMgr->getMdtReadoutElement(DigitId)->innerTubeRadius()};
34  const double radius{input.radius()};
35  const double eff = 1.0 - (m_effRadius - radius) / (m_effRadius - maxTubeRadius);
36  if ((radius < 0) || (radius > maxTubeRadius) ||
37  (radius >=m_effRadius && CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0) > eff)) {
38  return MdtDigiToolOutput{false, 0., 0.};
39  }
40 
41  MdtDigiToolOutput output(true, getDriftTime(ctx, radius, maxTubeRadius, DigitId, rndmEngine),
42  getAdcResponse(radius, rndmEngine));
43  return output;
44 }
45 
46 double RT_Relation_DB_DigiTool::getDriftTime(const EventContext& ctx,
47  double measRadius,
48  double innerTubeRadius,
49  const Identifier& DigitId,
50  CLHEP::HepRandomEngine *rndmEngine) const {
51  // Get RT relation from DB
53 
54  if (!calibConstants.isValid()) {
55  ATH_MSG_FATAL("Failed to retrieve calib constants "<<m_calibDbKey.fullKey());
56  throw std::runtime_error("No Mdt calibration constants");
57  }
59  const RtRelationPtr& data{calibConstants->getCalibData(DigitId, msgStream())->rtRelation};
60 
61  double time = 0.0;
62  double t = 0.0;
63  bool outOfBound = false;
64 
65  if (data) {
66  // get RT relation and resolution function
67  const MuonCalib::IRtRelation *rtRelation = data->rt();
68  const MuonCalib::IRtResolution *rtResolution = data->rtRes();
69 
70  // get inverse rt and calculate time resolution
71  const MuonCalib::TrRelation *trRelation = data->tr();
72  time = trRelation->tFromR(std::abs(measRadius), outOfBound);
73 
74  if (time < 0.0) {
75  time = 0.0;
76  ATH_MSG_WARNING("Drift time <0 ! Returning 0.0 as drift time");
77  return (time);
78  }
79 
80  double radiusWidth = rtResolution->resolution(time);
81  double velocity = rtRelation->driftvelocity(time);
82  // std::cout << "time = " << time << " drift radius = " << measRadius << " outOfBound = "<< outOfBound << " velocity = " << velocity <<
83  // std::endl;
84 
85  if (velocity <= 0) {
86  ATH_MSG_WARNING("Drift velocity <=0 ! Time will not be smeared with resolution but will take the default measRadius-t value");
87  return time;
88  }
89  double timeWidth = radiusWidth / velocity;
90 
91  // now smear t according to t resolution
92  double tUp = rtRelation->tUpper();
93  // double tLow = rtRelation->tLower();
94 
95  double tmin = time - 3.4 * timeWidth;
96  double tmax = time + 3.4 * timeWidth;
97 
98  bool outOfBound2 = false;
99  if (tmin < 0.0) tmin = 0.0;
100  if (tmax > tUp)
101  tmax = trRelation->tFromR(innerTubeRadius, outOfBound2); // tmax = tUp+tLow; //means: tmax = (tmax of rt relation) + (one binwidth )
102 
103  double gaussian;
104  constexpr double sqrt_one_over_two_pi = 0.39894228;
105  double p1r = 0.8480 * std::exp(-0.5879 * measRadius);
106  int flag = 0;
107  int cutoff = 0;
108 
109  do {
110  cutoff++; // avoid eternal loop in case of problems
111  t = CLHEP::RandFlat::shoot(rndmEngine, tmin, tmax);
112 
113  gaussian = (1 - p1r) * sqrt_one_over_two_pi * exp(-(t - time) * (t - time) / (2.0 * timeWidth * timeWidth));
114  if (gaussian >= CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0) || cutoff > 200) { flag = 1; }
115  } while (flag == 0);
116 
117  // print summary
118  ATH_MSG_DEBUG("t from r = " << time << " t resolution = " << timeWidth << "\nr resolution = " << radiusWidth
119  << " driftvelocity = " << velocity << "\nsmeared t = " << t << " cutoff = " << cutoff);
120  } else {
121  ATH_MSG_ERROR("Null pointer returned from CalibDBSvc. Returning 0.0 as drift time");
122  return 0.0;
123  }
124 
125  return t;
126 }
127 
128 double RT_Relation_DB_DigiTool::getAdcResponse(double radius, CLHEP::HepRandomEngine *rndmEngine) {
129  // parametrization of the average adc value with respect to radius
130  constexpr double p0 = 57.38141;
131  constexpr double p1 = 8.616943;
132  constexpr double p2 = 2.497827;
133  constexpr double p3 = -1.625900;
134  constexpr double p4 = 0.3125281;
135  constexpr double p5 = -0.02929554;
136  constexpr double p6 = 0.001367115;
137  constexpr double p7 = -0.00002541936;
138 
139  double adcfunc = p0 + p1 * radius + p2 * std::pow(radius, 2) + p3 * std::pow(radius, 3) + p4 * std::pow(radius, 4) +
140  p5 * std::pow(radius, 5) + p6 * std::pow(radius, 6) + p7 * std::pow(radius, 7);
141 
142  // now the resolution function
143  constexpr double g0 = 10.27808;
144  constexpr double g1 = -0.3774593;
145  constexpr double g2 = 0.02751001;
146  constexpr double g3 = -0.0005994742;
147 
148  double adcWidth = g0 + g1 * radius + g2 * std::pow(radius, 2) + g3 * std::pow(radius, 3);
149 
150  // now smear according to adc width
151  double adc = CLHEP::RandGaussZiggurat::shoot(rndmEngine, adcfunc, adcWidth);
152 
153  return adc;
154 }
MdtReadoutElement.h
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
MdtDigiToolInput
Definition: MdtDigiToolInput.h:26
MuonCalib::IRtResolution::resolution
virtual double resolution(double t, double bgRate=0.0) const =0
returns resolution for a give time and background rate
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
MuonGM
Ensure that the Athena extensions are properly loaded.
Definition: GeoMuonHits.h:27
MuonCalib::IRtRelation::tUpper
virtual double tUpper(void) const =0
MuonCalib::TrRelation
Definition: TrRelation.h:39
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
RT_Relation_DB_DigiTool::getAdcResponse
static double getAdcResponse(double radius, CLHEP::HepRandomEngine *rndmEngine)
Definition: RT_Relation_DB_DigiTool.cxx:128
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
MuonCalib::TrRelation::tFromR
double tFromR(const double &r, bool &out_of_bound_flag) const
< Get t(r). out_of_bound_flag is set to true if r is out of bounds.
Definition: TrRelation.cxx:56
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
RT_Relation_DB_DigiTool.h
MdtDigiToolOutput
Definition: MdtDigiToolOutput.h:19
ParticleJetTools::p3
Amg::Vector3D p3(const xAOD::TruthVertex *p)
Definition: ParticleJetLabelCommon.cxx:55
MuonCalib::MdtCalibDataContainer::RtRelationPtr
MdtFullCalibData::RtRelationPtr RtRelationPtr
Definition: MdtCalibDataContainer.h:23
MuonCalib::IRtRelation::driftvelocity
virtual double driftvelocity(double t) const =0
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
fitman.g1
g1
Definition: fitman.py:619
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
master.flag
bool flag
Definition: master.py:29
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
RT_Relation_DB_DigiTool::RT_Relation_DB_DigiTool
RT_Relation_DB_DigiTool(const std::string &type, const std::string &name, const IInterface *parent)
Definition: RT_Relation_DB_DigiTool.cxx:15
merge.output
output
Definition: merge.py:17
fitman.g2
g2
Definition: fitman.py:624
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
MdtDigiToolInput.h
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
ParticleGun_SamplingFraction.radius
radius
Definition: ParticleGun_SamplingFraction.py:96
RT_Relation_DB_DigiTool::initialize
virtual StatusCode initialize() override
Definition: RT_Relation_DB_DigiTool.cxx:20
MuonDetectorManager.h
MuonCalib::IRtResolution
generic interface for a resolution function
Definition: IRtResolution.h:14
RT_Relation_DB_DigiTool::digitize
virtual MdtDigiToolOutput digitize(const EventContext &ctx, const MdtDigiToolInput &input, CLHEP::HepRandomEngine *rndmEngine) const override final
Definition: RT_Relation_DB_DigiTool.cxx:27
CaloSwCorrections.time
def time(flags, cells_name, *args, **kw)
Definition: CaloSwCorrections.py:242
RT_Relation_DB_DigiTool::m_detMgrKey
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_detMgrKey
Definition: RT_Relation_DB_DigiTool.h:57
ReadFloatFromCool.adc
adc
Definition: ReadFloatFromCool.py:48
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
dqt_zlumi_alleff_HIST.eff
int eff
Definition: dqt_zlumi_alleff_HIST.py:113
AthAlgTool
Definition: AthAlgTool.h:26
RT_Relation_DB_DigiTool::m_calibDbKey
SG::ReadCondHandleKey< MuonCalib::MdtCalibDataContainer > m_calibDbKey
Definition: RT_Relation_DB_DigiTool.h:54
RT_Relation_DB_DigiTool::m_effRadius
Gaudi::Property< double > m_effRadius
Definition: RT_Relation_DB_DigiTool.h:59
RT_Relation_DB_DigiTool::getDriftTime
double getDriftTime(const EventContext &ctx, double measRadius, double innerTubeRadius, const Identifier &DigitId, CLHEP::HepRandomEngine *rndmEngine) const
Definition: RT_Relation_DB_DigiTool.cxx:46
MuonCalib::IRtRelation
generic interface for a rt-relation
Definition: IRtRelation.h:14