18#include <fmt/format.h>
22 using detail::FieldRegionBase;
30 void FieldRegionBase<T, EFieldMode::Intrpl>::Set(
const FieldValue<T>& b0,
const T& z0,
const FieldValue<T>& b1,
31 const T& z1,
const FieldValue<T>& b2,
const T& z2)
38 auto w21 = -dz2 * det;
40 auto w11 = -dz2 * w21;
41 auto w12 = -dz1 * w22;
43 for (
int iD = 0; iD < 3; ++iD) {
44 auto db1 = b1.GetComponent(iD) - b0.GetComponent(iD);
45 auto db2 = b2.GetComponent(iD) - b0.GetComponent(iD);
46 auto& coeff = fCoeff[iD];
47 coeff[0] = b0.GetComponent(iD);
48 coeff[1] = db1 * w11 + db2 * w12;
49 coeff[2] = db1 * w21 + db2 * w22;
56 FieldValue<T> FieldRegionBase<T, EFieldMode::Intrpl>::Get(
const T&
x,
const T&
y,
const T& z)
const
61 auto dz = z - this->fZfirst;
62 return FieldValue<T>{this->fCoeff[0][0] + dz * (this->fCoeff[0][1] + dz * this->fCoeff[0][2]),
63 this->fCoeff[1][0] + dz * (this->fCoeff[1][1] + dz * this->fCoeff[1][2]),
64 this->fCoeff[2][0] + dz * (this->fCoeff[2][1] + dz * this->fCoeff[2][2])};
71 FieldRegionBase<T, EFieldMode::Intrpl>::GetDoubleIntegrals(
const T& ,
const T& ,
const T& z1,
72 const T& ,
const T& ,
const T& z2)
const
83 T c0 = dz2 * T(1. / 2.);
84 T c1 = dz2 * dz * T(1. / 6.);
85 T c2 = dz2 * dz2 * T(1. / 12.);
86 return {c0 * fld.fCoeff[0][0] + c1 * fld.fCoeff[0][1] + c2 * fld.fCoeff[0][2],
87 c0 * fld.fCoeff[1][0] + c1 * fld.fCoeff[1][1] + c2 * fld.fCoeff[1][2],
88 c0 * fld.fCoeff[2][0] + c1 * fld.fCoeff[2][1] + c2 * fld.fCoeff[2][2]};
94 void FieldRegionBase<T, EFieldMode::Intrpl>::Shift(
const T& z)
96 auto dz = z - fZfirst;
97 for (
int iD = 0; iD < 3; ++iD) {
98 auto& coeff = fCoeff[iD];
99 auto c2dz = coeff[2] * dz;
100 coeff[0] += (coeff[1] + c2dz) * dz;
101 coeff[1] += (2 * c2dz);
109 void FieldRegionBase<T, EFieldMode::Intrpl>::CheckConsistency()
const
112 for (
int iD = 0; iD < 3; ++iD) {
113 for (
int iC = 0; iC < 3; ++iC) {
123 std::string FieldRegionBase<T, EFieldMode::Intrpl>::ToString(
int indentLevel,
int)
const
125 constexpr char IndentChar =
'\t';
126 std::stringstream msg;
127 std::string indent(indentLevel, IndentChar);
130 const auto& coeff = this->fCoeff;
131 msg << indent << format(
"Field Region: dz = z - ({})", Cnv(this->fZfirst));
133 << indent << IndentChar
134 << format(
"Bx(dz) = {:>12} + {:>12} dz + {:>12} dz2", Cnv(coeff[0][0]), Cnv(coeff[0][1]), Cnv(coeff[0][2]));
136 << indent << IndentChar
137 << format(
"Bx(dz) = {:>12} + {:>12} dz + {:>12} dz2", Cnv(coeff[1][0]), Cnv(coeff[1][1]), Cnv(coeff[1][2]));
139 << indent << IndentChar
140 << format(
"Bx(dz) = {:>12} + {:>12} dz + {:>12} dz2", Cnv(coeff[2][0]), Cnv(coeff[2][1]), Cnv(coeff[2][2]));
143 <<
"\nWARNING: the GlobalField::ForceUseOfOriginalField() is enabled, so the magnetic field interpolation "
145 <<
"\nis replaced with the global magnetic function for debugging purposes. If you see this message and are "
147 <<
"\nnot sure, what is going on, please call GlobalField::ForceUseOfOriginalField(false) and re-run the "
157 void FieldRegionBase<T, EFieldMode::Orig>::CheckConsistency()
const
165 std::string FieldRegionBase<T, EFieldMode::Orig>::ToString(
int indentLevel,
int)
const
167 constexpr char IndentChar =
'\t';
168 std::stringstream msg;
169 std::string indent(indentLevel, IndentChar);
170 msg << indent <<
"Field region: created from the original field function";
177 template class FieldRegionBase<float, EFieldMode::Intrpl>;
178 template class FieldRegionBase<double, EFieldMode::Intrpl>;
179 template class FieldRegionBase<fvec, EFieldMode::Intrpl>;
180 template class FieldRegionBase<float, EFieldMode::Orig>;
181 template class FieldRegionBase<double, EFieldMode::Orig>;
182 template class FieldRegionBase<fvec, EFieldMode::Orig>;
192 foFldIntrpl->Shift(z);
201 constexpr char IndentChar =
'\t';
202 std::stringstream msg;
203 std::string indent(indentLevel, IndentChar);
204 msg << indent <<
"FieldType: " <<
static_cast<int>(fFieldType) <<
'\n';
205 msg << indent <<
"FieldMode: " <<
static_cast<int>(fFieldMode) <<
'\n';
207 << (fFieldMode ==
EFieldMode::Intrpl ? foFldIntrpl->ToString(indentLevel) : foFldOrig->ToString(indentLevel));
219 foFldIntrpl->CheckConsistency();
222 foFldOrig->CheckConsistency();
231 &&
"cbm::algo::kf::GlobalField: The original globa magnetic field is required by "
232 "kf::defs::dbg::ForceOriginalField = true. Please provide it with the "
233 "kf::GlobalField::SetGlobalField() function.");
Magnetic flux density interpolation along the track vs. z-coordinate (header)
Magnetic field region, corresponding to a hit triplet.
void Shift(const T &z)
Shifts the coefficients to another first z-coordinate.
void CheckConsistency() const
Consistency checker.
std::string ToString(int indentLevel=0, int verbose=1) const
String representation of the class content.
static EFieldType fgOriginalFieldType
Global field type.
static FieldValue< T > GetFieldValue(const FieldFn_t &fieldFn, const T &x, const T &y, const T &z)
Creates a field value object in a spactial point of a generic floating-point type.
static std::tuple< double, double, double > UndefField(double, double, double)
Undefined magnetic field function.
static FieldFn_t fgOriginalField
Global variable to store the fielf funciton (x,y,z)->(Bx,By,Bz)
static bool IsUsingOriginalFieldForced()
Checks if the original field function is used.
static bool fgForceUseOfOriginalField
Flag to force the use of the original field in all field classes.
constexpr double Undef< double >
DataOut Cast(const DataT &val)
Converts a value of type DataT to type DataOut.
DataT One()
Returns a value of the data type set to one.
void CheckSimdVectorEquality(fvec v, const char *name)
Checks, if a SIMD vector horizontally equal TODO: Find this method in the VC!
@ Intrpl
Interpolated magnetic field.
EFieldType
Magnetic field type in different setup regions.
std::function< std::tuple< double, double, double >(double, double, double)> FieldFn_t
Magnetic field function type Signature: tuple<Bx, By, Bz>(x, y, z);.