CbmRoot
Loading...
Searching...
No Matches
KfFieldRegion.h
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#pragma once
12
13#include "KfDefs.h"
14#include "KfFieldValue.h"
15#include "KfMath.h"
16#include "KfUtils.h"
17
18#include <boost/serialization/access.hpp>
19#include <boost/serialization/array.hpp>
20#include <boost/serialization/optional.hpp>
21#include <boost/serialization/split_free.hpp>
22
23#include <array>
24#include <optional>
25#include <string>
26#include <type_traits>
27
28namespace cbm::algo::kf
29{
30
34 public:
37
40
42 static std::tuple<double, double, double> UndefField(double, double, double);
43
46 static void SetFieldFunction(EFieldType fldType, const FieldFn_t& fn)
47 {
48 fgOriginalFieldType = fldType;
49 fgOriginalField = fn;
50 }
51
59 template<typename T>
60 [[gnu::always_inline]] static FieldValue<T> GetFieldValue(const FieldFn_t& fieldFn, const T& x, const T& y,
61 const T& z);
62
64 static void ForceUseOfOriginalField(bool v = true) { fgForceUseOfOriginalField = v; }
65
68
69 private:
71 };
72
73 namespace detail
74 {
80 template<typename T, EFieldMode FldMode>
81 class alignas(VcMemAlign) FieldRegionBase {
82 };
83
87 template<typename T>
88 class alignas(VcMemAlign) FieldRegionBase<T, EFieldMode::Orig> {
89 template<typename, EFieldMode>
90 friend class FieldRegionBase;
91
92 public:
94 FieldRegionBase() = default;
95
97 FieldRegionBase(const FieldFn_t& fieldFn) : fFieldFn(fieldFn) {}
98
101 template<typename I>
102 FieldRegionBase(const FieldRegionBase<I, EFieldMode::Orig>& other) : fFieldFn(other.fFieldFn)
103 {
104 }
105
107 ~FieldRegionBase() = default;
108
110 FieldRegionBase& operator=(const FieldRegionBase& other) = default;
111
117 FieldValue<T> Get(const T& x, const T& y, const T& z) const
118 {
119 return GlobalField::GetFieldValue(fFieldFn, x, y, z);
120 }
121
123 std::tuple<T, T, T> GetDoubleIntegrals(const T& /*x1*/, const T& /*y1*/, const T& /*z1*/, //
124 const T& /*x2*/, const T& /*y2*/, const T& /*z2*/) const
125 {
126 assert("cbm::algo::kf::FieldRegionBase<T, EFieldMode::Orig>::GetDoubleIntegrals() is not implemented");
127 return {defs::Undef<T>, defs::Undef<T>, defs::Undef<T>};
128 }
129
131 void CheckConsistency() const;
132
136 std::string ToString(int indentLevel = 0, int verbose = 1) const;
137
138 protected:
139 FieldFn_t fFieldFn{defs::ZeroFieldFn};
140 };
141
142
146 template<typename T>
147 class alignas(VcMemAlign) FieldRegionBase<T, EFieldMode::Intrpl> {
148 template<typename, EFieldMode>
149 friend class FieldRegionBase;
150
151 using CoeffArray_t = std::array<std::array<T, 3>, 3>;
152
153 public:
155
157 FieldRegionBase() = default;
158
166 FieldRegionBase(const FieldValue_t& b0, const T& z0, const FieldValue_t& b1, const T& z1, const FieldValue_t& b2,
167 const T& z2)
168 {
169 this->Set(b0, z0, b1, z1, b2, z2);
170 }
171
173 template<typename I>
175 : fZfirst(utils::simd::Cast<I, T>(other.fZfirst))
176 {
177 for (size_t iDim = 0; iDim < fCoeff.size(); ++iDim) {
178 for (size_t iPow = 0; iPow < fCoeff[iDim].size(); ++iPow) {
179 fCoeff[iDim][iPow] = utils::simd::Cast<I, T>(other.fCoeff[iDim][iPow]);
180 }
181 }
182 }
183
185 ~FieldRegionBase() = default;
186
188 FieldRegionBase& operator=(const FieldRegionBase& other) = default;
189
194 FieldValue<T> Get(const T& x, const T& y, const T& z) const;
195
197 std::tuple<T, T, T> GetDoubleIntegrals(const T& x1, const T& y1, const T& z1, //
198 const T& x2, const T& y2, const T& z2) const;
199
201 const T& GetZfirst() const { return fZfirst; }
202
204 const auto& GetCoefficients() const { return fCoeff; }
205
214 void Set(const FieldValue<T>& b0, const T& z0, const FieldValue<T>& b1, const T& z1, const FieldValue<T>& b2,
215 const T& z2);
216
218 void Set(const CoeffArray_t& coeff, const T& z0)
219 {
220 fCoeff = coeff;
221 fZfirst = z0;
222 }
223
226 void Shift(const T& z);
227
229 void CheckConsistency() const;
230
234 std::string ToString(int indentLevel = 0, int verbose = 1) const;
235
236 protected:
237 CoeffArray_t fCoeff{{T(0.)}};
238 T fZfirst{Literal_t<T>()};
239
240 private:
242 friend class boost::serialization::access;
243 template<class Archive>
244 void serialize(Archive& ar, const unsigned int)
245 {
246 ar& fCoeff;
247 ar& fZfirst;
248 }
249 };
250 } // namespace detail
251
252
256 template<typename T>
257 class alignas(VcMemAlign) FieldRegion {
258 template<typename>
259 friend class FieldRegion;
260
261 public:
263 FieldRegion(EFieldMode fldMode = EFieldMode::Intrpl, EFieldType fldType = EFieldType::Normal)
264 : foFldIntrpl(fldMode == EFieldMode::Intrpl ? std::make_optional<detail::FieldRegionBase<T, EFieldMode::Intrpl>>()
265 : std::nullopt)
266 , foFldOrig(fldMode == EFieldMode::Orig ? std::make_optional<detail::FieldRegionBase<T, EFieldMode::Orig>>()
267 : std::nullopt)
268 , fFieldType(fldType)
269 , fFieldMode(fldMode)
270 {
271 }
272
275 template<typename I>
277 : foFldIntrpl(other.foFldIntrpl.has_value()
278 ? std::make_optional(detail::FieldRegionBase<T, EFieldMode::Intrpl>(*other.foFldIntrpl))
279 : std::nullopt)
280 , foFldOrig(other.foFldOrig.has_value()
281 ? std::make_optional(detail::FieldRegionBase<T, EFieldMode::Orig>(*other.foFldOrig))
282 : std::nullopt)
283 , fFieldType(other.fFieldType)
284 , fFieldMode(other.fFieldMode)
285 {
286 }
287
289 FieldRegion(const FieldValue<T>& b0, const T& z0, const FieldValue<T>& b1, const T& z1, const FieldValue<T>& b2,
290 const T& z2)
291 : foFldIntrpl(std::make_optional<detail::FieldRegionBase<T, EFieldMode::Intrpl>>())
292 , foFldOrig(std::nullopt)
293 , fFieldType(EFieldType::Normal)
294 , fFieldMode(EFieldMode::Intrpl)
295 {
296 // Set the field type automatically
297 Set(b0, z0, b1, z1, b2, z2);
298 }
299
303 : foFldIntrpl(std::make_optional(fld))
304 , foFldOrig(std::nullopt)
305 , fFieldType(fieldType)
306 , fFieldMode(EFieldMode::Intrpl)
307 {
308 }
309
312 FieldRegion(EFieldType fieldType, const FieldFn_t& fieldFn)
313 : foFldIntrpl(std::nullopt)
314 , foFldOrig(std::make_optional<detail::FieldRegionBase<T, EFieldMode::Orig>>(fieldFn))
315 , fFieldType(fieldType)
316 , fFieldMode(EFieldMode::Orig)
317 {
318 }
319
321 ~FieldRegion() = default;
322
324 FieldRegion& operator=(const FieldRegion& other) = default;
325
331 FieldValue<T> Get(const T& x, const T& y, const T& z) const
332 {
333 return fFieldMode == EFieldMode::Intrpl ? foFldIntrpl->Get(x, y, z) : foFldOrig->Get(x, y, z);
334 }
335
337 std::tuple<T, T, T> GetDoubleIntegrals(const T& x1, const T& y1, const T& z1, const T& x2, const T& y2,
338 const T& z2) const
339 {
340 return fFieldMode == EFieldMode::Intrpl ? foFldIntrpl->GetDoubleIntegrals(x1, y1, z1, x2, y2, z2)
341 : foFldOrig->GetDoubleIntegrals(x1, y1, z1, x2, y2, z2);
342 }
343
345 EFieldMode GetFieldMode() const { return fFieldMode; }
346
348 EFieldType GetFieldType() const { return fFieldType; }
349
358 void Set(const FieldValue<T>& b0, const T& z0, const FieldValue<T>& b1, const T& z1, const FieldValue<T>& b2,
359 const T& z2)
360 {
361 fFieldMode = EFieldMode::Intrpl;
362 fFieldType = EFieldType::Normal;
363 // Set the field type automatically
364 if (b0.IsZero() && b1.IsZero() && b2.IsZero()) {
365 fFieldType = EFieldType::Null;
366 }
367 foFldIntrpl->Set(b0, z0, b1, z1, b2, z2);
368 }
369
371 void SetFieldType(EFieldType fldType) { fFieldType = fldType; }
372
375 void Shift(const T& z);
376
378 void CheckConsistency() const;
379
383 std::string ToString(int indentLevel = 0, int verbose = 1) const;
384
385 const auto& GetIntrplField() const { return foFldIntrpl; }
386
387 private:
388 friend class boost::serialization::access;
389
391 template<class Archive>
392 void load(Archive& ar, const unsigned int /*version*/)
393 {
395 ar >> field;
396 foFldIntrpl = std::make_optional(field);
397 ar >> fFieldType;
398 ar >> fFieldMode;
399 foFldOrig = std::nullopt; // Note: original field cannot be serialized
400 }
401
403 template<class Archive>
404 void save(Archive& ar, const unsigned int /*version*/) const
405 {
406 if (fFieldMode == EFieldMode::Intrpl) {
407 ar << (*foFldIntrpl);
408 ar << fFieldType;
409 ar << fFieldMode;
410 }
411 else if (fFieldMode == EFieldMode::Orig) {
412 throw std::logic_error("Attempt to serialize a kf::FieldRegion object with fFieldMode == EFieldMode::Orig");
413 }
414 }
415
417 template<class Archive>
418 void serialize(Archive& ar, const unsigned int version)
419 {
420 boost::serialization::split_member(ar, *this, version);
421 }
422
423 std::optional<detail::FieldRegionBase<T, EFieldMode::Intrpl>> foFldIntrpl{std::nullopt};
424 std::optional<detail::FieldRegionBase<T, EFieldMode::Orig>> foFldOrig{std::nullopt};
425 EFieldType fFieldType{EFieldType::Null};
427 };
428
429
430 // -------------------------------------------------------------------------------------------------------------------
431 //
432 template<typename T>
433 inline FieldValue<T> GlobalField::GetFieldValue(const FieldFn_t& fieldFn, const T& x, const T& y, const T& z)
434 {
436 using utils::simd::Cast;
437 for (size_t i = 0; i < utils::simd::Size<T>(); ++i) {
438 auto [bx, by, bz] = fieldFn(Cast<T, double>(x, i), Cast<T, double>(y, i), Cast<T, double>(z, i));
439 B.SetSimdEntry(bx, by, bz, i);
440 }
441 return B;
442 }
443
444} // namespace cbm::algo::kf
std::string ToString(ECbmModuleId modId)
Definition CbmDefs.cxx:70
Common constant definitions for the Kalman Filter library.
Magnetic flux density vector representation.
Collection of generic mathematical methods.
fscal v[fmask::Size]
Definition KfSimdPseudo.h:4
Magnetic field region, corresponding to a hit triplet.
void save(Archive &ar, const unsigned int) const
Serialization save method.
EFieldType GetFieldType() const
Gets the field type.
EFieldMode GetFieldMode() const
Gets field mode.
const auto & GetIntrplField() const
~FieldRegion()=default
Destructor.
FieldRegion(const FieldRegion< I > &other)
Copy constructor.
FieldRegion & operator=(const FieldRegion &other)=default
Copy assignment operator.
void Set(const FieldValue< T > &b0, const T &z0, const FieldValue< T > &b1, const T &z1, const FieldValue< T > &b2, const T &z2)
Interpolates the field by three nodal points with the second order polynomial.
FieldRegion(EFieldMode fldMode=EFieldMode::Intrpl, EFieldType fldType=EFieldType::Normal)
Constructor of the generic field.
std::tuple< T, T, T > GetDoubleIntegrals(const T &x1, const T &y1, const T &z1, const T &x2, const T &y2, const T &z2) const
Gets the double integrals of the field along the track.
FieldRegion(EFieldType fieldType, const FieldFn_t &fieldFn)
Constructor for the field region with the original field function.
FieldRegion(const FieldValue< T > &b0, const T &z0, const FieldValue< T > &b1, const T &z1, const FieldValue< T > &b2, const T &z2)
Constructor for the interpolated field region.
FieldValue< T > Get(const T &x, const T &y, const T &z) const
Gets the field value in a spatial point on the track.
void SetFieldType(EFieldType fldType)
Sets the field type.
void serialize(Archive &ar, const unsigned int version)
Serialization method.
FieldRegion(EFieldType fieldType, const detail::FieldRegionBase< T, EFieldMode::Intrpl > &fld)
Constructor for the interpolated field region.
void load(Archive &ar, const unsigned int)
Serialization load method.
EFieldMode fFieldMode
Field mode.
Magnetic flux density vector.
bool IsZero() const
Checks, if the field value is zero (negligible)
void SetSimdEntry(double bx, double by, double bz, size_t i)
Sets magnetic flux density components to the field function.
Handler for the global magnetic field related functions.
static void SetFieldFunction(EFieldType fldType, const FieldFn_t &fn)
Sets global field function.
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 void ForceUseOfOriginalField(bool v=true)
Forces the use of the original field function.
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.
void Set(const CoeffArray_t &coeff, const T &z0)
Set the coefficients of the polynomial approximation.
const auto & GetCoefficients() const
Gets the coefficients of the polynomial approximation.
void Shift(const T &z)
Shifts the coefficients to another first z-coordinate.
FieldRegionBase & operator=(const FieldRegionBase &other)=default
Copy assignment operator.
const T & GetZfirst() const
Gets the first z-coordinate of the interpolation.
std::string ToString(int indentLevel=0, int verbose=1) const
String representation of the class content.
FieldRegionBase(const FieldValue_t &b0, const T &z0, const FieldValue_t &b1, const T &z1, const FieldValue_t &b2, const T &z2)
Constructor from parameters.
void Set(const FieldValue< T > &b0, const T &z0, const FieldValue< T > &b1, const T &z1, const FieldValue< T > &b2, const T &z2)
Interpolates the field by three nodal points with the second order polynomial.
FieldValue< T > Get(const T &x, const T &y, const T &z) const
Gets the field value in a spatial point on the track.
std::tuple< T, T, T > GetDoubleIntegrals(const T &x1, const T &y1, const T &z1, const T &x2, const T &y2, const T &z2) const
Gets the double integrals of the field along the track.
FieldRegionBase(const FieldRegionBase< I, EFieldMode::Intrpl > &other)
Copy constructor.
std::array< std::array< T, 3 >, 3 > CoeffArray_t
Approximation coefficients array.
FieldRegionBase(const FieldRegionBase< I, EFieldMode::Orig > &other)
Copy constructor.
std::string ToString(int indentLevel=0, int verbose=1) const
String representation of the class content.
FieldValue< T > Get(const T &x, const T &y, const T &z) const
Gets the field value in a spatial point on the track.
std::tuple< T, T, T > GetDoubleIntegrals(const T &, const T &, const T &, const T &, const T &, const T &) const
Gets the double integrals of the field along the track.
FieldRegionBase(const FieldFn_t &fieldFn)
Constructor.
FieldRegionBase & operator=(const FieldRegionBase &other)=default
Copy assignment operator.
Base class of the FieldRegion class (primary template)
EFieldMode
Enumiration for the magnetic field representation variants in the track fitting algorithm.
Definition KfDefs.h:27
@ Intrpl
Interpolated magnetic field.
@ Orig
Original magnetic field function.
typename Literal< T >::type Literal_t
Definition KfDefs.h:55
EFieldType
Magnetic field type in different setup regions.
Definition KfDefs.h:37
@ Normal
Field near the tracker subsystem.
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
Hash for CbmL1LinkKey.