8#include "GaudiKernel/MsgStream.h"
12#include "GeoModelKernel/throwExcept.h"
48 unsigned int nb_points(31);
60 fitter.set_number_of_coefficients(8);
65 fitter.set_number_of_coefficients(8);
70 fitter.set_number_of_coefficients(8);
75 std::vector<SamplePoint> sample_points(nb_points);
88 log << MSG::INFO <<
"UNPHYSICAL MAXIMUM DRIFT RADIUS OF " <<
m_r_max <<
", WILL BE SET TO 17.0!" <<
endmsg;
95 double prev_integral = 0;
96 for (
unsigned int k = 0; k < nb_points; k++) {
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);
104 prev_integral = new_integral;
108 fitter.fit_parameters(sample_points, 1, nb_points, legendre);
109 m_alpha = fitter.coefficients();
116 constexpr double precision{0.010};
124 double t_guess, r_guess;
127 t_guess = t_min + (t_max - t_min) / (r_max - r_min) * (
r - r_min);
128 r_guess = rt->
radius(t_guess);
136 }
while (t_max - t_min > 0.1 && std::abs(r_guess -
r) > precision);
148 double radius{r_max};
158 if (r_max < r_min) {
return 0.0; }
165 while (
rp < radius) {
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]);
186 double B_perp{std::hypot(B_wire, B_mu)};
188 double B_factor{std::pow(B_perp, 2.0 -
m_param[1])};
189 double precision{0.1};
201 if (t <=
m_t_min) {
return 0.0; }
210 while (t_max - t_min > precision) {
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);
215 if (0.5 * (t_min + t_max) + B_factor * integ > time) {
216 t_max = 0.5 * (t_min + t_max);
218 t_min = 0.5 * (t_min + t_max);
222 return B_factor * integ;
230 const double B_perp{std::hypot(B_wire, B_mu)};
232 B_factor = std::pow(B_perp, 2.0 -
m_param[1]);
242 if (t <=
m_t_min) {
return 0.0; }
248 for (
int k = 0; k <
m_alpha.rows(); k++) {
249 integ +=
m_alpha[k] * std::legendre(k, 2 * (time - tmean) / tlength);
252 return B_factor * integ;
double t_from_r(const double r, const IRtRelation *rt) const
void setRtRelationship(const IRtRelation &rt)
< set the parameter of the B-field correction function = eps
double integral(const double r_min, const double r_max, const IRtRelation *rt) const
std::vector< double > m_param
double correction(double t, double B_wire, double B_mu) const
get t(r, !=0)-t(r, =0); t = drift time t [ns] for B=0; B_wire = magnetic field parallel to the anode ...
std::string name() const
get the class name
BFieldCorFunc(const std::string &quality, const CalibFunc::ParVec ¶meters, const IRtRelation *rt)
Constructor: quality = "high", slow but accurate initialization initialization of the correction func...
void init(const std::string &quality, const CalibFunc::ParVec ¶ms, const IRtRelation *rt)
double epsilon() const
< get the parameter of the B-field correction function
double correction_to_B(double t, double B_wire, double B_mu, double B_factor=-1.0) const
This class performs a fit of a linear combination of base functions to a set of sample points.
const ParVec & parameters() const
std::vector< double > ParVec
IMdtBFieldCorFunc(const CalibFunc::ParVec &vec)
generic interface for a rt-relation
virtual double radius(double t) const =0
returns drift radius for a given time
virtual double driftVelocity(double t) const =0
Returns the drift velocity for a given time.
This class provides a legendre polynomial of order k.
singleton-like access to IMessageSvc via open function and helper
IMessageSvc * getMessageSvc(bool quiet=false)
CscCalcPed - algorithm that finds the Cathode Strip Chamber pedestals from an RDO.
#define THROW_EXCEPTION(MESSAGE)