ATLAS Offline Software
Loading...
Searching...
No Matches
MuonCalib::BFieldCorFunc Class Reference

This class allows the user to get the difference between the drift time measured by a tube operated in a magnetic field \( \vec{B} \) and the drift time which would be measured by this tube if \( \vec{B} \) vanished. More...

#include <BFieldCorFunc.h>

Inheritance diagram for MuonCalib::BFieldCorFunc:
Collaboration diagram for MuonCalib::BFieldCorFunc:

Public Types

using ParVec = std::vector<double>

Public Member Functions

 BFieldCorFunc (const std::string &quality, const CalibFunc::ParVec &parameters, const IRtRelation *rt)
 Constructor: quality = "high", slow but accurate initialization initialization of the correction function, quality = "medium", compromise between speed and accuracy of the initialization of the correction function (default), quality = "low", fast initialization of the correction function at the price of lower quality.
 BFieldCorFunc (const CalibFunc::ParVec &parameters, const IRtRelation *rt)
 Constructor: parameters[0] = high voltage [V], parameters[1] = \( \epsilon \),.
double epsilon () const
 < get the \( \epsilon \) parameter of the B-field correction function
void setRtRelationship (const IRtRelation &rt)
 < set the \( \epsilon \) parameter of the B-field correction function = eps
std::string name () const
 get the class name
double correction (double t, double B_wire, double B_mu) const
 get t(r, \( \vec{B} \)!=0)-t(r, \( \vec{B} \)=0); t = drift time t [ns] for B=0; B_wire = magnetic field parallel to the anode wire of the given tube, B_mu = magnetic field orthogonal to the wire and parallel to the muon trajectory in the given tube [B] = Tesla
double correction_to_B (double t, double B_wire, double B_mu, double B_factor=-1.0) const
virtual std::string typeName () const
unsigned int nPar () const
const ParVecparameters () const
double par (unsigned int index) const

Private Member Functions

void init (const std::string &quality, const CalibFunc::ParVec &params, const IRtRelation *rt)
double t_from_r (const double r, const IRtRelation *rt) const
double integral (const double r_min, const double r_max, const IRtRelation *rt) const

Private Attributes

std::vector< double > m_param {}
std::string m_quality {}
double m_step_size {0.}
Amg::VectorX m_alpha
double m_t_min {-std::numeric_limits<double>::max()}
double m_t_max {std::numeric_limits<double>::max()}
double m_r_min {-std::numeric_limits<double>::max()}
double m_r_max {std::numeric_limits<double>::max()}
ParVec m_parameters {}

Detailed Description

This class allows the user to get the difference between the drift time measured by a tube operated in a magnetic field \( \vec{B} \) and the drift time which would be measured by this tube if \( \vec{B} \) vanished.

Correction:

\[ t(r,\vec{B}) = t(r,\vec{B}=0) + B_\perp^{2-\epsilon}\cdot \int\limits_{25\ \mu m}^{r} \frac{v_{B=0}^{1-\epsilon}(r')} {E^{2-\epsilon}(r')}\,dr' \]

.

\( B_\perp = |\vec{B}_\perp| \); \( \vec{B}_\perp = \vec{B}_{wire}+\vec{B}_\mu \);

\( \vec{B}_{wire} \): magnetic field parallel to the anode wire of the given tube;

\( \vec{B}_\mu \): magnetic field magnetic field perpendicular to wire and parallel to the muon trajectory in the given tube.

Definition at line 47 of file BFieldCorFunc.h.

Member Typedef Documentation

◆ ParVec

using MuonCalib::CalibFunc::ParVec = std::vector<double>
inherited

Definition at line 35 of file CalibFunc.h.

Constructor & Destructor Documentation

◆ BFieldCorFunc() [1/2]

BFieldCorFunc::BFieldCorFunc ( const std::string & quality,
const CalibFunc::ParVec & parameters,
const IRtRelation * rt )
explicit

Constructor: quality = "high", slow but accurate initialization initialization of the correction function, quality = "medium", compromise between speed and accuracy of the initialization of the correction function (default), quality = "low", fast initialization of the correction function at the price of lower quality.

parameters[0] = high voltage [V], parameters[1] = \( \epsilon \),

Definition at line 20 of file BFieldCorFunc.cxx.

20 :
22 init(quality, parameters, rt);
23}
void init(const std::string &quality, const CalibFunc::ParVec &params, const IRtRelation *rt)
const ParVec & parameters() const
Definition CalibFunc.h:40
IMdtBFieldCorFunc(const CalibFunc::ParVec &vec)

◆ BFieldCorFunc() [2/2]

BFieldCorFunc::BFieldCorFunc ( const CalibFunc::ParVec & parameters,
const IRtRelation * rt )
explicit

Constructor: parameters[0] = high voltage [V], parameters[1] = \( \epsilon \),.

Definition at line 25 of file BFieldCorFunc.cxx.

25 :
27 init("medium", parameters, rt);
28}

Member Function Documentation

◆ correction()

double BFieldCorFunc::correction ( double t,
double B_wire,
double B_mu ) const
virtual

get t(r, \( \vec{B} \)!=0)-t(r, \( \vec{B} \)=0); t = drift time t [ns] for B=0; B_wire = magnetic field parallel to the anode wire of the given tube, B_mu = magnetic field orthogonal to the wire and parallel to the muon trajectory in the given tube [B] = Tesla

Implements MuonCalib::IMdtBFieldCorFunc.

Definition at line 182 of file BFieldCorFunc.cxx.

182 {
184 // VARIABLES //
186 double B_perp{std::hypot(B_wire, B_mu)}; // B orthogonal to the
187 // electron drift path
188 double B_factor{std::pow(B_perp, 2.0 - m_param[1])};
189 double precision{0.1}; // precision of the correction in ns
190 double t_max{t}; // upper time search limit
191 double t_min{t - 2 * correction_to_B(t, B_wire, B_mu, B_factor)}; // lower time search limit
192 if (t_min < m_t_min) t_min = m_t_min;
193 double time{t}; // auxiliary time variable
194 double integ{0.0}; // integral
195 double tmean{0.5 * (m_t_min + m_t_max)}; // mean time
196 double tlength{m_t_max - m_t_min}; // length of drift-time interval
197
199 // DRIFT TIME CHECK //
201 if (t <= m_t_min) { return 0.0; }
202 if (t > m_t_max) {
203 t_max = m_t_max;
204 time = m_t_max;
205 }
206
208 // SEARCH FOR THE CORRECTED DRIFT TIME //
210 while (t_max - t_min > precision) {
211 integ = 0.0;
212 for (int k = 0; k < m_alpha.rows(); k++) {
213 integ += m_alpha[k] * std::legendre(k, 2 * (0.5 * (t_min + t_max) - tmean) / tlength);
214 }
215 if (0.5 * (t_min + t_max) + B_factor * integ > time) {
216 t_max = 0.5 * (t_min + t_max);
217 } else {
218 t_min = 0.5 * (t_min + t_max);
219 }
220 }
221
222 return B_factor * integ;
223} // end BFieldCorFunc::correction
std::vector< double > m_param
double correction_to_B(double t, double B_wire, double B_mu, double B_factor=-1.0) const
time(flags, cells_name, *args, **kw)

◆ correction_to_B()

double BFieldCorFunc::correction_to_B ( double t,
double B_wire,
double B_mu,
double B_factor = -1.0 ) const

Definition at line 225 of file BFieldCorFunc.cxx.

225 {
227 // VARIABLES //
229 if (B_factor < 0) {
230 const double B_perp{std::hypot(B_wire, B_mu)};
231 // B orthogonal to the electron drift path
232 B_factor = std::pow(B_perp, 2.0 - m_param[1]);
233 }
234 double time{t};
235 double integ{0.0}; // integral
236 double tmean{0.5 * (m_t_min + m_t_max)}; // mean time
237 double tlength{m_t_max - m_t_min}; // length of drift-time interval
238
240 // DRIFT TIME CHECK //
242 if (t <= m_t_min) { return 0.0; }
243 if (t > m_t_max) { time = m_t_max; }
244
246 // CALCULATE THE CORRECTION //
248 for (int k = 0; k < m_alpha.rows(); k++) {
249 integ += m_alpha[k] * std::legendre(k, 2 * (time - tmean) / tlength);
250 }
251
252 return B_factor * integ;
253} // end BFieldCorFunc::correction_to_B

◆ epsilon()

double BFieldCorFunc::epsilon ( ) const

< get the \( \epsilon \) parameter of the B-field correction function

Definition at line 175 of file BFieldCorFunc.cxx.

175{ return m_param[1]; }

◆ init()

void BFieldCorFunc::init ( const std::string & quality,
const CalibFunc::ParVec & params,
const IRtRelation * rt )
private

Definition at line 30 of file BFieldCorFunc.cxx.

30 {
32 // PARAMETERS //
34 m_quality = quality;
36
38 // CONSISTENCY CHECK //
40 if (m_param.size() != 2) {
41 THROW_EXCEPTION("Wrong number of parameters!");
42 return;
43 }
44
46 // VARIABLES //
48 unsigned int nb_points(31); // number of sample points for the integral
49 // in the correction function
50 double step{0.}; // r step size
51 double time{0.}; // auxiliary time variable
52 BaseFunctionFitter fitter(6); // 6 fit parameters for the integral by
53 // default ("medium quality")
54 LegendrePolynomial legendre{};
55
57 // QUALITY SETTING //
59 if (m_quality == "high") {
60 fitter.set_number_of_coefficients(8);
61 nb_points = 31;
62 m_step_size = 0.02;
63 }
64 if (m_quality == "medium") {
65 fitter.set_number_of_coefficients(8);
66 nb_points = 31;
67 m_step_size = 0.06;
68 }
69 if (m_quality == "low") {
70 fitter.set_number_of_coefficients(8);
71 nb_points = 31;
72 m_step_size = 0.12;
73 }
74 // sample points for the integral factor in the correction function
75 std::vector<SamplePoint> sample_points(nb_points);
76
78 // CALCULATE THE INTEGRAL PART OF THE CORRECTION FUNCTION //
80 m_t_min = (rt)->tLower();
81 m_t_max = (rt)->tUpper();
82
83 // minimum and maximum radius //
84 m_r_min = 0.025 * CLHEP::mm; // minimum radius
85 m_r_max = rt->radius(m_t_max); // maximum radius
86 if (m_r_max > 17.0 || m_r_max < m_r_min) {
87 MsgStream log(Athena::getMessageSvc(), "BFieldCorFunc");
88 log << MSG::INFO << "UNPHYSICAL MAXIMUM DRIFT RADIUS OF " << m_r_max << ", WILL BE SET TO 17.0!" << endmsg;
89 m_r_max = 17.0;
90 }
91 step = ((m_r_max - m_r_min) / static_cast<double>(nb_points - 1));
92
93 // set the sample points //
94 double prev_r = 0;
95 double prev_integral = 0;
96 for (unsigned int k = 0; k < nb_points; k++) {
97 time = t_from_r(m_r_min + k * step, rt);
98 sample_points[k].set_x1(2 * (time - 0.5 * (m_t_min + m_t_max)) / (m_t_max - m_t_min));
99 double new_r = rt->radius(time);
100 double new_integral = 1.0e9 * integral(prev_r, new_r, rt) + prev_integral;
101 sample_points[k].set_x2(new_integral);
102 sample_points[k].set_error(1.0);
103 prev_r = new_r;
104 prev_integral = new_integral;
105 }
106
107 // perform the fit //
108 fitter.fit_parameters(sample_points, 1, nb_points, legendre);
109 m_alpha = fitter.coefficients();
110
111} // end BFieldCorFunc::init
#define endmsg
double t_from_r(const double r, const IRtRelation *rt) const
double integral(const double r_min, const double r_max, const IRtRelation *rt) const
virtual double radius(double t) const =0
returns drift radius for a given time
IMessageSvc * getMessageSvc(bool quiet=false)
const ShapeFitter * fitter
#define THROW_EXCEPTION(MESSAGE)
Definition throwExcept.h:10

◆ integral()

double BFieldCorFunc::integral ( const double r_min,
const double r_max,
const IRtRelation * rt ) const
private

Definition at line 140 of file BFieldCorFunc.cxx.

140 {
141 // catch fp exceptions//
142 if (m_r_min < 1e-10 || r_min < m_r_min) return 0.0;
143
145 // VARIABLES //
147 const double E0{m_param[0] / std::log(m_r_max / m_r_min)}; // E(r)=E0/r
148 double radius{r_max};
149 double rp{r_min}; // auxiliary radius variables
150 double integ{0.0}; // current value of the integral
151 // double step(0.010); // integration step size [mm]
152 double step{m_step_size}; // integration step size [mm]
153 double time{0.}; // drift time
154
156 // r IN [m_r_min, m_r_max]? //
158 if (r_max < r_min) { return 0.0; }
159 if (r_max > m_r_max) { radius = m_r_max; }
160
162 // INTEGRATION //
164 double delta = step;
165 while (rp < radius) {
166 time = t_from_r(rp, rt);
167 if (rp + step > radius) delta = radius - rp;
168 integ += 1.0e-3 * delta * std::pow(std::abs(rt->driftVelocity(time)) * 1.0e6, 1.0 - m_param[1]) /
169 std::pow(E0 / (rp * 1.0e-3), 2.0 - m_param[1]);
170 rp += step;
171 }
172
173 return integ;
174} // end BFieldCorFunc::integral
ReadCards * rp
virtual double driftVelocity(double t) const =0
Returns the drift velocity for a given time.

◆ name()

std::string BFieldCorFunc::name ( ) const
virtual

get the class name

get t(r, \( \vec{B} \) !=0)-t(r, \( \vec{B} \) =0); t = measured drift time t [ns]; B_wire = magnetic field parallel to the anode wire of the given tube, B_mu = magnetic field orthogonal to the wire and parallel to the muon trajectory in the given tube [B] = Tesla

Implements MuonCalib::CalibFunc.

Definition at line 180 of file BFieldCorFunc.cxx.

180{ return std::string("BFieldCorFunc"); }

◆ nPar()

unsigned int MuonCalib::CalibFunc::nPar ( ) const
inlineinherited

Definition at line 39 of file CalibFunc.h.

39{ return m_parameters.size(); }

◆ par()

double MuonCalib::CalibFunc::par ( unsigned int index) const
inlineinherited

Definition at line 41 of file CalibFunc.h.

41 {
42 return index < nPar() ? m_parameters[index] : 0.;
43 }
unsigned int nPar() const
Definition CalibFunc.h:39
str index
Definition DeMoScan.py:362

◆ parameters()

const ParVec & MuonCalib::CalibFunc::parameters ( ) const
inlineinherited

Definition at line 40 of file CalibFunc.h.

40{ return m_parameters; }

◆ setRtRelationship()

void BFieldCorFunc::setRtRelationship ( const IRtRelation & rt)

< set the \( \epsilon \) parameter of the B-field correction function = eps

< set the r-t relationship used to calculate the B field correction to the measured drift time = rt

Definition at line 176 of file BFieldCorFunc.cxx.

176 {
177 init(m_quality, m_param, &rt);
178}

◆ t_from_r()

double BFieldCorFunc::t_from_r ( const double r,
const IRtRelation * rt ) const
private

Definition at line 112 of file BFieldCorFunc.cxx.

112 {
114 // VARIABLES //
116 constexpr double precision{0.010}; // spatial precision of the inversion
117 double t_max{m_t_max}; // upper time search limit
118 double t_min{m_t_min}; // lower time search limit
119 double r_max{m_r_max}; // upper radius search limit
120 double r_min{m_r_min}; // lower radius search limit
122 // SEARCH FOR THE CORRESPONDING DRIFT TIME //
124 double t_guess, r_guess;
125
126 do {
127 t_guess = t_min + (t_max - t_min) / (r_max - r_min) * (r - r_min);
128 r_guess = rt->radius(t_guess);
129 if (r_guess > r) {
130 r_max = r_guess;
131 t_max = t_guess;
132 } else {
133 r_min = r_guess;
134 t_min = t_guess;
135 }
136 } while (t_max - t_min > 0.1 && std::abs(r_guess - r) > precision);
137 return t_guess;
138} // end BFieldCorFunc::t_from_r
int r
Definition globals.cxx:22

◆ typeName()

virtual std::string MuonCalib::IMdtBFieldCorFunc::typeName ( ) const
inlinevirtualinherited

Implements MuonCalib::CalibFunc.

Definition at line 18 of file IMdtBFieldCorFunc.h.

18{ return "IMdtBFieldCorFunc"; }

Member Data Documentation

◆ m_alpha

Amg::VectorX MuonCalib::BFieldCorFunc::m_alpha
private

Definition at line 109 of file BFieldCorFunc.h.

◆ m_param

std::vector<double> MuonCalib::BFieldCorFunc::m_param {}
private

Definition at line 102 of file BFieldCorFunc.h.

102{};

◆ m_parameters

ParVec MuonCalib::CalibFunc::m_parameters {}
privateinherited

Definition at line 48 of file CalibFunc.h.

48{};

◆ m_quality

std::string MuonCalib::BFieldCorFunc::m_quality {}
private

Definition at line 105 of file BFieldCorFunc.h.

105{}; // quality string ("high", "medium", "low")

◆ m_r_max

double MuonCalib::BFieldCorFunc::m_r_max {std::numeric_limits<double>::max()}
private

Definition at line 120 of file BFieldCorFunc.h.

120{std::numeric_limits<double>::max()};

◆ m_r_min

double MuonCalib::BFieldCorFunc::m_r_min {-std::numeric_limits<double>::max()}
private

Definition at line 119 of file BFieldCorFunc.h.

119{-std::numeric_limits<double>::max()};

◆ m_step_size

double MuonCalib::BFieldCorFunc::m_step_size {0.}
private

Definition at line 106 of file BFieldCorFunc.h.

106{0.}; // integration step size steering the quality

◆ m_t_max

double MuonCalib::BFieldCorFunc::m_t_max {std::numeric_limits<double>::max()}
private

Definition at line 117 of file BFieldCorFunc.h.

117{std::numeric_limits<double>::max()};

◆ m_t_min

double MuonCalib::BFieldCorFunc::m_t_min {-std::numeric_limits<double>::max()}
private

Definition at line 116 of file BFieldCorFunc.h.

116{-std::numeric_limits<double>::max()};

The documentation for this class was generated from the following files: