ATLAS Offline Software
Loading...
Searching...
No Matches
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
13using namespace MuonGM;
14
15RT_Relation_DB_DigiTool::RT_Relation_DB_DigiTool(const std::string &type, const std::string &name, const IInterface *parent) :
16 AthAlgTool(type, name, parent) {
17 declareInterface<IMDT_DigitizationTool>(this);
18}
19
21 ATH_MSG_INFO("Initializing RT_Relation_DB_DigiTool");
22 ATH_CHECK(m_calibDbKey.initialize());
23 ATH_CHECK(m_detMgrKey.initialize());
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
46double 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
64 if (data) {
65 // get RT relation and resolution function
66 const MuonCalib::IRtRelation *rtRelation = data->rt();
67 const MuonCalib::IRtResolution *rtResolution = data->rtRes();
68
69 // get inverse rt and calculate time resolution
70 const MuonCalib::ITrRelation *trRelation = data->tr();
71 time = trRelation->driftTime(std::abs(measRadius)).value_or(0.);
72
73 if (time < 0.0) {
74 time = 0.0;
75 ATH_MSG_WARNING("Drift time <0 ! Returning 0.0 as drift time");
76 return (time);
77 }
78
79 double radiusWidth = rtResolution->resolution(time);
80 double velocity = rtRelation->driftVelocity(time);
81 // std::cout << "time = " << time << " drift radius = " << measRadius << " outOfBound = "<< outOfBound << " velocity = " << velocity <<
82 // std::endl;
83
84 if (velocity <= 0) {
85 ATH_MSG_WARNING("Drift velocity <=0 ! Time will not be smeared with resolution but will take the default measRadius-t value");
86 return time;
87 }
88 double timeWidth = radiusWidth / velocity;
89
90 // now smear t according to t resolution
91 double tUp = rtRelation->tUpper();
92 // double tLow = rtRelation->tLower();
93
94 double tmin = time - 3.4 * timeWidth;
95 double tmax = time + 3.4 * timeWidth;
96
97 if (tmin < 0.0) tmin = 0.0;
98 if (tmax > tUp)
99 tmax = trRelation->driftTime(innerTubeRadius).value_or(0.); // tmax = tUp+tLow; //means: tmax = (tmax of rt relation) + (one binwidth )
100
101 double gaussian;
102 constexpr double sqrt_one_over_two_pi = 0.39894228;
103 double p1r = 0.8480 * std::exp(-0.5879 * measRadius);
104 int flag = 0;
105 int cutoff = 0;
106
107 do {
108 cutoff++; // avoid eternal loop in case of problems
109 t = CLHEP::RandFlat::shoot(rndmEngine, tmin, tmax);
110
111 gaussian = (1 - p1r) * sqrt_one_over_two_pi * exp(-(t - time) * (t - time) / (2.0 * timeWidth * timeWidth));
112 if (gaussian >= CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0) || cutoff > 200) { flag = 1; }
113 } while (flag == 0);
114
115 // print summary
116 ATH_MSG_DEBUG("t from r = " << time << " t resolution = " << timeWidth << "\nr resolution = " << radiusWidth
117 << " driftvelocity = " << velocity << "\nsmeared t = " << t << " cutoff = " << cutoff);
118 } else {
119 ATH_MSG_ERROR("Null pointer returned from CalibDBSvc. Returning 0.0 as drift time");
120 return 0.0;
121 }
122
123 return t;
124}
125
126double RT_Relation_DB_DigiTool::getAdcResponse(double radius, CLHEP::HepRandomEngine *rndmEngine) {
127 // parametrization of the average adc value with respect to radius
128 constexpr double p0 = 57.38141;
129 constexpr double p1 = 8.616943;
130 constexpr double p2 = 2.497827;
131 constexpr double p3 = -1.625900;
132 constexpr double p4 = 0.3125281;
133 constexpr double p5 = -0.02929554;
134 constexpr double p6 = 0.001367115;
135 constexpr double p7 = -0.00002541936;
136
137 double adcfunc = p0 + p1 * radius + p2 * std::pow(radius, 2) + p3 * std::pow(radius, 3) + p4 * std::pow(radius, 4) +
138 p5 * std::pow(radius, 5) + p6 * std::pow(radius, 6) + p7 * std::pow(radius, 7);
139
140 // now the resolution function
141 constexpr double g0 = 10.27808;
142 constexpr double g1 = -0.3774593;
143 constexpr double g2 = 0.02751001;
144 constexpr double g3 = -0.0005994742;
145
146 double adcWidth = g0 + g1 * radius + g2 * std::pow(radius, 2) + g3 * std::pow(radius, 3);
147
148 // now smear according to adc width
149 double adc = CLHEP::RandGaussZiggurat::shoot(rndmEngine, adcfunc, adcWidth);
150
151 return adc;
152}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
generic interface for a rt-relation
Definition IRtRelation.h:19
virtual double tUpper() const =0
Returns the upper time covered by the r-t.
virtual double driftVelocity(double t) const =0
Returns the drift velocity for a given time.
Generic interface to retrieve the resolution on the drift radius as a function of the drift time.
virtual double resolution(double t, double bgRate=0.0) const =0
returns resolution for a give time and background rate
virtual std::optional< double > driftTime(const double r) const =0
Interface method for fetching the drift-time from the radius Returns a nullopt if the time is out of ...
MdtFullCalibData::RtRelationPtr RtRelationPtr
RT_Relation_DB_DigiTool(const std::string &type, const std::string &name, const IInterface *parent)
virtual MdtDigiToolOutput digitize(const EventContext &ctx, const MdtDigiToolInput &input, CLHEP::HepRandomEngine *rndmEngine) const override final
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_detMgrKey
SG::ReadCondHandleKey< MuonCalib::MdtCalibDataContainer > m_calibDbKey
virtual StatusCode initialize() override
Gaudi::Property< double > m_effRadius
static double getAdcResponse(double radius, CLHEP::HepRandomEngine *rndmEngine)
double getDriftTime(const EventContext &ctx, double measRadius, double innerTubeRadius, const Identifier &DigitId, CLHEP::HepRandomEngine *rndmEngine) const
Ensure that the Athena extensions are properly loaded.
Definition GeoMuonHits.h:27