CbmRoot
Loading...
Searching...
No Matches
KfFieldRegion.cxx
Go to the documentation of this file.
1/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Sergei Zharko [committer] */
4
10
11#include "KfFieldRegion.h"
12
13#include "KfUtils.h"
14
15#include <mutex>
16#include <sstream>
17
18#include <fmt/format.h>
19
20namespace cbm::algo::kf
21{
22 using detail::FieldRegionBase;
26
27 // -------------------------------------------------------------------------------------------------------------------
28 //
29 template<typename T>
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)
32 {
33 fZfirst = z0;
34
35 auto dz1 = z1 - z0;
36 auto dz2 = z2 - z0;
37 auto det = utils::simd::One<T>() / (dz1 * dz2 * (z2 - z1));
38 auto w21 = -dz2 * det;
39 auto w22 = dz1 * det;
40 auto w11 = -dz2 * w21;
41 auto w12 = -dz1 * w22;
42
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;
50 }
51 }
52
53 // -------------------------------------------------------------------------------------------------------------------
54 //
55 template<typename T>
56 FieldValue<T> FieldRegionBase<T, EFieldMode::Intrpl>::Get(const T& x, const T& y, const T& z) const
57 {
60 }
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])};
65 }
66
67 // -------------------------------------------------------------------------------------------------------------------
68 //
69 template<typename T>
70 std::tuple<T, T, T>
71 FieldRegionBase<T, EFieldMode::Intrpl>::GetDoubleIntegrals(const T& /*x1*/, const T& /*y1*/, const T& z1, //
72 const T& /*x2*/, const T& /*y2*/, const T& z2) const
73 {
74 // double integral of the field along z
75
77 // TODO: implement the double integral for the original field
78 }
79 auto fld = *this;
80 fld.Shift(z1);
81 T dz = z2 - z1;
82 T dz2 = dz * dz;
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]};
89 }
90
91 // -------------------------------------------------------------------------------------------------------------------
92 //
93 template<typename T>
94 void FieldRegionBase<T, EFieldMode::Intrpl>::Shift(const T& z)
95 {
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);
102 }
103 fZfirst = z;
104 }
105
106 // -------------------------------------------------------------------------------------------------------------------
107 //
108 template<typename T>
109 void FieldRegionBase<T, EFieldMode::Intrpl>::CheckConsistency() const
110 {
111 // Check SIMD data vectors for consistent initialization
112 for (int iD = 0; iD < 3; ++iD) {
113 for (int iC = 0; iC < 3; ++iC) {
114 utils::CheckSimdVectorEquality(fCoeff[iD][iC], fmt::format("FieldRegion::fCoeff[{}][{}]", iD, iC).c_str());
115 }
116 }
117 utils::CheckSimdVectorEquality(fZfirst, "FieldRegion::fZfirst");
118 }
119
120 // -------------------------------------------------------------------------------------------------------------------
121 //
122 template<typename T>
123 std::string FieldRegionBase<T, EFieldMode::Intrpl>::ToString(int indentLevel, int) const
124 {
125 constexpr char IndentChar = '\t';
126 std::stringstream msg;
127 std::string indent(indentLevel, IndentChar);
128 using fmt::format;
129 auto Cnv = [&](const auto& val) { return utils::simd::Cast<T, Literal_t<T>>(val); }; // alias for the conversion fn
130 const auto& coeff = this->fCoeff;
131 msg << indent << format("Field Region: dz = z - ({})", Cnv(this->fZfirst));
132 msg << '\n'
133 << indent << IndentChar
134 << format("Bx(dz) = {:>12} + {:>12} dz + {:>12} dz2", Cnv(coeff[0][0]), Cnv(coeff[0][1]), Cnv(coeff[0][2]));
135 msg << '\n'
136 << indent << IndentChar
137 << format("Bx(dz) = {:>12} + {:>12} dz + {:>12} dz2", Cnv(coeff[1][0]), Cnv(coeff[1][1]), Cnv(coeff[1][2]));
138 msg << '\n'
139 << indent << IndentChar
140 << format("Bx(dz) = {:>12} + {:>12} dz + {:>12} dz2", Cnv(coeff[2][0]), Cnv(coeff[2][1]), Cnv(coeff[2][2]));
142 msg << indent
143 << "\nWARNING: the GlobalField::ForceUseOfOriginalField() is enabled, so the magnetic field interpolation "
144 << indent
145 << "\nis replaced with the global magnetic function for debugging purposes. If you see this message and are "
146 << indent
147 << "\nnot sure, what is going on, please call GlobalField::ForceUseOfOriginalField(false) and re-run the "
148 "routine";
149 }
150 return msg.str();
151 }
152
153
154 // -------------------------------------------------------------------------------------------------------------------
155 //
156 template<typename T>
157 void FieldRegionBase<T, EFieldMode::Orig>::CheckConsistency() const
158 {
159 // Check SIMD data vectors for consistent initialization
160 }
161
162 // -------------------------------------------------------------------------------------------------------------------
163 //
164 template<typename T>
165 std::string FieldRegionBase<T, EFieldMode::Orig>::ToString(int indentLevel, int) const
166 {
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";
171 return msg.str();
172 }
173
174
175 namespace detail
176 {
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>;
183 } // namespace detail
184
185
186 // -------------------------------------------------------------------------------------------------------------------
187 //
188 template<typename T>
189 void FieldRegion<T>::Shift(const T& z)
190 {
191 if (fFieldMode == EFieldMode::Intrpl) {
192 foFldIntrpl->Shift(z);
193 }
194 }
195
196 // -------------------------------------------------------------------------------------------------------------------
197 //
198 template<typename T>
199 std::string FieldRegion<T>::ToString(int indentLevel, int) const
200 {
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';
206 msg << indent
207 << (fFieldMode == EFieldMode::Intrpl ? foFldIntrpl->ToString(indentLevel) : foFldOrig->ToString(indentLevel));
208 return msg.str();
209 }
210
211 // -------------------------------------------------------------------------------------------------------------------
212 //
213 template<typename T>
215 {
216 // Check SIMD data vectors for consistent initialization
217
218 if (fFieldMode == EFieldMode::Intrpl) {
219 foFldIntrpl->CheckConsistency();
220 }
221 else {
222 foFldOrig->CheckConsistency();
223 }
224 }
225
226 // -------------------------------------------------------------------------------------------------------------------
227 //
228 std::tuple<double, double, double> GlobalField::UndefField(double, double, double)
229 {
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.");
235 }
236
237 template class FieldRegion<float>;
238 template class FieldRegion<double>;
239 template class FieldRegion<fvec>;
240} // namespace cbm::algo::kf
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 >
Definition KfDefs.h:127
DataOut Cast(const DataT &val)
Converts a value of type DataT to type DataOut.
Definition KfUtils.h:212
DataT One()
Returns a value of the data type set to one.
Definition KfUtils.h:316
void CheckSimdVectorEquality(fvec v, const char *name)
Checks, if a SIMD vector horizontally equal TODO: Find this method in the VC!
Definition KfUtils.cxx:29
@ Intrpl
Interpolated magnetic field.
EFieldType
Magnetic field type in different setup regions.
Definition KfDefs.h:37
@ Null
No magnetic field.
std::function< std::tuple< double, double, double >(double, double, double)> FieldFn_t
Magnetic field function type Signature: tuple<Bx, By, Bz>(x, y, z);.
Definition KfDefs.h:66