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#include "KfVisit.h"
18
19#include <boost/serialization/access.hpp>
20#include <boost/serialization/array.hpp>
21#include <boost/serialization/optional.hpp>
22#include <boost/serialization/split_free.hpp>
23
24#include <array>
25#include <optional>
26#include <string>
27#include <type_traits>
28
29namespace cbm::algo::kf
30{
31
35 public:
37 ~GlobalField() = delete;
38
41
44
46 static std::tuple<double, double, double> UndefField(double, double, double);
47
50 static void SetFieldFunction(EFieldType fldType, const FieldFn_t& fn)
51 {
52 fgOriginalFieldType = fldType;
53 fgOriginalField = fn;
54 }
55
63 template<typename T>
64 [[gnu::always_inline]] static FieldValue<T> GetFieldValue(const FieldFn_t& fieldFn, T x, T y, T z);
65
67 static void ForceUseOfOriginalField(bool v = true) { fgForceUseOfOriginalField = v; }
68
71
72 private:
74 };
75
76
77 namespace detail
78 {
84 template<typename T, EFieldMode FldMode>
85 class alignas(VcMemAlign) ConcreteFieldRegion {
86 };
87
88
92 template<typename T>
93 class alignas(VcMemAlign) ConcreteFieldRegion<T, EFieldMode::Interpolated> {
94 template<typename, EFieldMode>
95 friend class ConcreteFieldRegion;
96
97 using CoeffArray_t = std::array<std::array<T, 3>, 3>;
98
99 public:
101
104
110 {
111 this->Set(b0, b1, b2);
112 }
113
115 template<typename I>
117 : fZfirst(utils::simd::Cast<I, T>(other.fZfirst))
118 , fFieldType(other.fFieldType)
119 {
120 for (size_t iDim = 0; iDim < fCoeff.size(); ++iDim) {
121 for (size_t iPow = 0; iPow < fCoeff[iDim].size(); ++iPow) {
122 fCoeff[iDim][iPow] = utils::simd::Cast<I, T>(other.fCoeff[iDim][iPow]);
123 }
124 }
125 }
126
129
132
135
138
141
146 FieldValue<T> Get(T x, T y, T z) const;
147
150 const auto& GetCoefficients() const { return fCoeff; }
151
160 std::tuple<T, T, T> GetDoubleIntegrals(T x1, T y1, T z1, T x2, T y2, T z2) const;
161
165
167 const T& GetZfirst() const { return fZfirst; }
168
175 void Set(const FieldValue<T>& b0, const FieldValue<T>& b1, const FieldValue<T>& b2);
176
179 void Set(const CoeffArray_t& coeff, T z0)
180 {
181 fCoeff = coeff;
182 fZfirst = z0;
183 }
184
186 void SetFieldType(EFieldType type) { fFieldType = type; }
187
190 void Shift(T z);
191
193 void CheckConsistency() const;
194
198 std::string ToString(int indentLevel = 0, int verbose = 1) const;
199
202 static constexpr EFieldMode Mode() { return EFieldMode::Interpolated; }
203
204 private:
208
210 friend class boost::serialization::access;
211 template<class Archive>
212 void serialize(Archive& ar, const unsigned int)
213 {
214 ar& fCoeff;
215 ar& fZfirst;
216 ar& fFieldType;
217 }
218 };
219
220
224 template<typename T>
225 class alignas(VcMemAlign) ConcreteFieldRegion<T, EFieldMode::Original> {
226 template<typename, EFieldMode>
228
229 public:
232
236 ConcreteFieldRegion(EFieldType type, const FieldFn_t& fieldFn) : fFieldFn(fieldFn), fFieldType(type) {}
237
240 template<typename I>
246
249
252
255
258
261
267 FieldValue<T> Get(T x, T y, T z) const { return GlobalField::GetFieldValue(fFieldFn, x, y, z); }
268
270 std::tuple<T, T, T> GetDoubleIntegrals(T /*x1*/, T /*y1*/, T /*z1*/, T /*x2*/, T /*y2*/, T /*z2*/) const
271 {
272 assert("cbm::algo::kf::ConcreteFieldRegion<T, EFieldMode::Original>::GetDoubleIntegrals() is not implemented");
274 }
275
279
281 void CheckConsistency() const;
282
284 // TODO: remove?
285 void SetFieldType(EFieldType type) { fFieldType = type; }
286
290 std::string ToString(int indentLevel = 0, int verbose = 1) const;
291
294 static constexpr EFieldMode Mode() { return EFieldMode::Original; }
295
296 private:
299 };
300 } // namespace detail
301
302
306 template<typename T>
307 class alignas(VcMemAlign) FieldRegion {
308 template<typename>
309 friend class FieldRegion;
310
311 public:
312 template<EFieldMode Mode>
316 using FieldRegionVariant_t = typename std::variant<Interpolated_t, Original_t>;
317
319 FieldRegion() = default;
320
322 FieldRegion(const FieldRegion&) = default;
323
326
331 FieldRegion(const FieldValue<T>& b0, const FieldValue<T>& b1, const FieldValue<T>& b2)
332 : fFrVariant(FieldRegionVariant_t(std::in_place_type<Interpolated_t>, b0, b1, b2))
333 {
334 }
335
339 FieldRegion(EFieldType type, const FieldFn_t& fieldFn)
340 : fFrVariant(FieldRegionVariant_t(std::in_place_type<Original_t>, type, fieldFn))
341 {
342 }
343
345
347 ~FieldRegion() = default;
348
351
354
358 template<typename I>
360 {
361 return kf::visit(
362 [&other](const auto& c) -> FieldRegion { return FieldRegion(other, Tag<std::decay_t<decltype(c)>::Mode()>{}); },
363 other.fFrVariant);
364 }
365
371 FieldValue<T> Get(T x, T y, T z) const
372 {
373 return kf::visit([&x, &y, &z](const auto& c) -> FieldValue<T> { return c.Get(x, y, z); }, fFrVariant);
374 }
375
379 template<EFieldMode FieldMode>
381 {
382 return std::get_if<ConcreteFieldRegion_t<FieldMode>>(&fFrVariant);
383 }
384
388 template<EFieldMode FieldMode>
390 {
391 return std::get_if<ConcreteFieldRegion_t<FieldMode>>(&fFrVariant);
392 }
393
395 std::tuple<T, T, T> GetDoubleIntegrals(T x1, T y1, T z1, T x2, T y2, T z2) const
396 {
397 return kf::visit([&x1, &y1, &z1, &x2, &y2, &z2](
398 const auto& c) -> std::tuple<T, T, T> { return c.GetDoubleIntegrals(x1, y1, z1, x2, y2, z2); },
399 fFrVariant);
400 }
401
404 {
405 return kf::visit([](const auto& c) { return std::decay_t<decltype(c)>::Mode(); }, fFrVariant);
406 }
407
410 {
411 return kf::visit([](const auto& c) -> EFieldType { return c.GetFieldType(); }, fFrVariant);
412 }
413
415 template<EFieldMode FieldMode, typename... Args>
416 static constexpr FieldRegion Create(Args... args)
417 {
418 return FieldRegion(args..., Tag<FieldMode>{});
419 }
420
424 template<typename... Args>
425 static constexpr FieldRegion Create(EFieldMode mode, Args... args)
426 {
427 switch (mode) {
430 default: return FieldRegion(args..., Tag<EFieldMode::Original>{});
431 }
432 __builtin_unreachable(); // No return is reachable
433 }
434
440 void Set(const FieldValue<T>& b0, const FieldValue<T>& b1, const FieldValue<T>& b2)
441 {
442 kf::visit(
443 [&b0, &b1, &b2](auto&& c) -> void {
444 if constexpr (std::decay_t<decltype(c)>::Mode() == EFieldMode::Interpolated) {
445 c.Set(b0, b1, b2);
446 }
447 },
448 fFrVariant);
449 }
450
453 {
454 kf::visit([type](auto&& c) { c.SetFieldType(type); }, fFrVariant);
455 }
456
459 void Shift(T z)
460 {
461 kf::visit(
462 [&z](auto&& c) -> void {
463 if constexpr (std::decay_t<decltype(c)>::Mode() == EFieldMode::Interpolated) {
464 c.Shift(z);
465 }
466 },
467 fFrVariant);
468 }
469
471 void CheckConsistency() const
472 {
473 kf::visit([](const auto& c) -> void { return c.CheckConsistency(); }, fFrVariant);
474 }
475
479 std::string ToString(int indentLevel = 0, int verbose = 1) const
480 {
481 return kf::visit(
482 [indentLevel, verbose](const auto& c) -> std::string { return c.ToString(indentLevel, verbose); }, fFrVariant);
483 }
484
485 private:
489 template<typename I, EFieldMode FieldMode>
492 std::in_place_type<ConcreteFieldRegion_t<FieldMode>>,
493 ConcreteFieldRegion_t<FieldMode>(std::get<detail::ConcreteFieldRegion<I, FieldMode>>(other.fFrVariant))))
494 {
495 }
496
498 template<class Archive>
499 void load(Archive& ar, const unsigned int /*version*/)
500 {
501 auto fieldRegion = Interpolated_t{};
502 ar >> fieldRegion;
503 fFrVariant.template emplace<Interpolated_t>(std::move(fieldRegion));
504 }
505
507 template<class Archive>
508 void save(Archive& ar, const unsigned int /*version*/) const
509 {
510 if (std::holds_alternative<Interpolated_t>(fFrVariant)) {
511 ar << std::get<Interpolated_t>(fFrVariant);
512 }
513 else {
514 throw std::logic_error("Attempt to serialize a kf::FieldRegion object with fFieldMode == EFieldMode::Original");
515 }
516 }
517
519 friend class boost::serialization::access;
520 template<class Archive>
521 void serialize(Archive& ar, const unsigned int version)
522 {
523 boost::serialization::split_member(ar, *this, version);
524 }
525
527 };
528
529
530 // -------------------------------------------------------------------------------------------------------------------
531 //
532 template<typename T>
533 inline FieldValue<T> GlobalField::GetFieldValue(const FieldFn_t& fieldFn, T x, T y, T z)
534 {
536 using utils::simd::Cast;
537 for (size_t i = 0; i < utils::simd::Size<T>(); ++i) {
538 auto [bx, by, bz] = fieldFn(Cast<T, double>(x, i), Cast<T, double>(y, i), Cast<T, double>(z, i));
539 B.SetSimdEntry(bx, by, bz, Cast<T, double>(z, i), i);
540 }
541 return B;
542 }
543
544} // namespace cbm::algo::kf
Mode
Definition Defs.h:21
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
Optimized implementation of std::visit.
Some class B.
FieldRegionVariant_t fFrVariant
A variant of concrete field region.
void save(Archive &ar, const unsigned int) const
Serialization save method.
typename detail::ConcreteFieldRegion< T, Mode > ConcreteFieldRegion_t
std::tuple< T, T, T > GetDoubleIntegrals(T x1, T y1, T z1, T x2, T y2, T z2) const
Gets the double integrals of the field along the track.
ConcreteFieldRegion_t< EFieldMode::Interpolated > Interpolated_t
EFieldType GetFieldType() const
Gets field type.
EFieldMode GetFieldMode() const
Gets field mode.
void Set(const FieldValue< T > &b0, const FieldValue< T > &b1, const FieldValue< T > &b2)
Interpolates the field by three nodal points with the second order polynomial.
ConcreteFieldRegion_t< EFieldMode::Original > Original_t
~FieldRegion()=default
Constructor from a concrete field.
void CheckConsistency() const
Consistency checker.
FieldRegion(const FieldValue< T > &b0, const FieldValue< T > &b1, const FieldValue< T > &b2)
Constructor for interpolated field.
FieldRegion()=default
Default constructor.
FieldRegion & operator=(const FieldRegion &)=default
Copy assignment operator.
std::string ToString(int indentLevel=0, int verbose=1) const
String representation of the class content.
void Shift(T z)
Shifts the coefficients to another first z-coordinate.
typename std::variant< Interpolated_t, Original_t > FieldRegionVariant_t
FieldValue< T > Get(T x, T y, T z) const
Gets the field value in a spatial point on the track.
static constexpr FieldRegion Create(EFieldMode mode, Args... args)
Creates a field region.
static constexpr FieldRegion Create(Args... args)
Creates a field region.
FieldRegion(FieldRegion &&)=default
Move constructor.
FieldRegion(EFieldType type, const FieldFn_t &fieldFn)
Constructor for original field.
void SetFieldType(EFieldType type)
Sets the field type.
static FieldRegion CopyConvert(const FieldRegion< I > &other)
Creates a converted copy of the field with a different floating point type.
FieldRegion(const FieldRegion &)=default
Copy constructor.
FieldRegion(const FieldRegion< I > &other, Tag< FieldMode >)
Constructor from a field region with another floating point type.
void serialize(Archive &ar, const unsigned int version)
ConcreteFieldRegion_t< FieldMode > * GetConcrete()
Gets a pointer to the concrete field instance (mutable access)
void load(Archive &ar, const unsigned int)
Serialization load method.
const ConcreteFieldRegion_t< FieldMode > * GetConcrete() const
Gets a pointer to the concrete field instance (constant access)
FieldRegion & operator=(FieldRegion &&)=default
Move assignment operator.
Magnetic flux density vector.
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 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 FieldValue< T > GetFieldValue(const FieldFn_t &fieldFn, T x, T y, T z)
Creates a field value object in a spactial point of a generic floating-point type.
static FieldFn_t fgOriginalField
Global variable to store the field function (x,y,z)->(Bx,By,Bz)
static bool IsUsingOriginalFieldForced()
Checks if the original field function is used.
~GlobalField()=delete
Destructor of static class.
static bool fgForceUseOfOriginalField
Flag to force the use of the original field in all field classes.
void Set(const FieldValue< T > &b0, const FieldValue< T > &b1, const FieldValue< T > &b2)
Interpolates the field by three nodal points with the second order polynomial.
ConcreteFieldRegion & operator=(const ConcreteFieldRegion &)=default
Copy assignment operator.
ConcreteFieldRegion(ConcreteFieldRegion &&)=default
Move constructor.
ConcreteFieldRegion(const FieldValue_t &b0, const FieldValue_t &b1, const FieldValue_t &b2)
Constructor from parameters.
ConcreteFieldRegion(const ConcreteFieldRegion< I, EFieldMode::Interpolated > &other)
Copy constructor (with type conversion)
const auto & GetCoefficients() const
Gets the coefficients of the polynomial approximation.
ConcreteFieldRegion(const ConcreteFieldRegion &)=default
Copy constructor (from the same type)
std::array< std::array< T, 3 >, 3 > CoeffArray_t
Approximation coefficients array.
FieldValue< T > Get(T x, T y, T z) const
Gets the field value in a spatial point on the track.
void Shift(T z)
Shifts the coefficients to another first z-coordinate.
static constexpr EFieldMode Mode()
Returns the mode of the field.
std::tuple< T, T, T > GetDoubleIntegrals(T x1, T y1, T z1, T x2, T y2, T z2) const
Gets the double integrals of the field along the track.
ConcreteFieldRegion & operator=(ConcreteFieldRegion &&)=default
Move 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.
void Set(const CoeffArray_t &coeff, T z0)
Set the coefficients of the polynomial approximation.
ConcreteFieldRegion & operator=(const ConcreteFieldRegion &)=default
Copy assignment operator.
ConcreteFieldRegion(const ConcreteFieldRegion< I, EFieldMode::Original > &other)
Copy constructor (with type change)
ConcreteFieldRegion(ConcreteFieldRegion &&)=default
Move constructor.
FieldValue< T > Get(T x, T y, T z) const
Gets the field value in a spatial point on the track.
ConcreteFieldRegion(EFieldType type, const FieldFn_t &fieldFn)
Constructor.
std::tuple< T, T, T > GetDoubleIntegrals(T, T, T, T, T, T) const
Gets the double integrals of the field along the track.
static constexpr EFieldMode Mode()
Returns the mode of the field.
ConcreteFieldRegion(const ConcreteFieldRegion &)=default
Copy constructor (from the same type)
std::string ToString(int indentLevel=0, int verbose=1) const
String representation of the class content.
ConcreteFieldRegion & operator=(ConcreteFieldRegion &&)=default
Move assignment operator.
FieldFn_t fFieldFn
Field function: (x,y,z) [cm] -> (Bx,By,Bz) [kG].
Concrete representation of the FieldRegion class (primary template)
constexpr auto ZeroFieldFn
Zero magnetic field function.
Definition KfDefs.h:237
constexpr T2 Undef
Undefined values.
Definition KfDefs.h:218
DataOut Cast(const DataT &val)
Converts a value of type DataT to type DataOut.
Definition KfUtils.h:212
EFieldMode
Enumiration for the magnetic field representation variants in the track fitting algorithm.
Definition KfDefs.h:108
@ Original
Original magnetic field function.
Definition KfDefs.h:110
@ Interpolated
Interpolated magnetic field.
Definition KfDefs.h:109
typename Literal< T >::type Literal_t
Definition KfDefs.h:158
EFieldType
Magnetic field type in different setup regions.
Definition KfDefs.h:126
@ Normal
Field near the tracker subsystem.
Definition KfDefs.h:127
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:169
Hash for CbmL1LinkKey.
A generic tag for tag dispatching.
Definition KfDefs.h:28