CbmRoot
Loading...
Searching...
No Matches
KfField.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
9
10// FIXME: naming fFieldVariant - FieldVariant_t
11
12#pragma once
13
14#include "KfDefs.h"
15#include "KfFieldRegion.h"
16#include "KfFieldSlice.h"
17#include "KfVisit.h"
18
19#include <boost/serialization/access.hpp>
20#include <boost/serialization/split_free.hpp>
21
22#include <array>
23#include <optional>
24#include <set>
25
26// TODO: Treat field at primary vertex as another field layer (field slice)
27
28namespace cbm::algo::kf
29{
30 namespace detail
31 {
36 template<typename T, EFieldMode FldMode>
37 class alignas(VcMemAlign) ConcreteField {
38 };
39
40
44 template<typename T>
45 class alignas(VcMemAlign) ConcreteField<T, EFieldMode::Original> {
46 template<typename, EFieldMode>
47 friend class ConcreteField;
48
49 public:
51 ConcreteField() = default;
52
58 ConcreteField(FieldFn_t fieldFn, std::vector<T>& fieldSliceZ, FieldRegion<T>& vtxField, EFieldType type)
59 : fvFieldSliceZ(std::move(fieldSliceZ))
60 , fFieldFn(fieldFn)
61 , fPrimVertexField(std::move(vtxField))
62 , fFieldType(type)
63 {
64 }
65
68 template<typename I>
70 : fFieldFn(other.fFieldFn)
71 , fPrimVertexField(std::move(FieldRegion<T>::CopyConvert(other.fPrimVertexField)))
72 , fFieldType(other.fFieldType)
73 {
74 fvFieldSliceZ.reserve(other.fvFieldSliceZ.size());
75 for (const auto& slice : other.fvFieldSliceZ) {
76 fvFieldSliceZ.emplace_back(utils::simd::Cast<I, T>(slice));
77 }
78 }
79
81 ConcreteField(const ConcreteField&) = default;
82
85
88
91
94 const FieldFn_t& GetFieldFunction() const { return fFieldFn; }
95
99
105 FieldValue<T> GetFieldValue(int sliceId, T x, T y) const
106 {
108 }
109
114 const FieldValue<T> GetFieldValueForLine(int sliceId, const TrackParam<T>& tp) const
115 {
116 T dz = fvFieldSliceZ[sliceId] - tp.GetZ();
117 return GetFieldValue(sliceId, tp.GetX() + tp.GetTx() * dz, tp.GetY() + tp.GetTy() * dz);
118 }
119
123
126 int GetNofFieldSlices() const { return fvFieldSliceZ.size(); }
127
131 void RemoveSlice(int iLayer) { fvFieldSliceZ.erase(fvFieldSliceZ.begin() + iLayer); }
132
137 std::string ToString(int indentLevel, int verbose) const;
138
141 static constexpr EFieldMode Mode() { return EFieldMode::Original; }
142
143 private:
144 std::vector<T> fvFieldSliceZ{};
148 };
149
150
154 template<typename T>
155 class alignas(VcMemAlign) ConcreteField<T, EFieldMode::Interpolated> {
156 template<typename, EFieldMode>
157 friend class ConcreteField;
158
159 public:
160 using SlicesContainer_t = std::vector<FieldSlice<T>>;
161
163 ConcreteField() = default;
164
170 : fvFieldSlices(std::move(fieldSlices))
171 , fPrimVertexField(std::move(vtxField))
172 , fFieldType(type)
173 {
174 }
175
178 template<typename I>
180 : fPrimVertexField(std::move(FieldRegion<T>::CopyConvert(other.fPrimVertexField)))
181 , fFieldType(other.fFieldType)
182 {
183 fvFieldSlices.reserve(other.fvFieldSlices.size());
184 for (const auto& slice : other.fvFieldSlices) {
185 fvFieldSlices.emplace_back(FieldSlice<T>(slice));
186 }
187 }
188
190 ConcreteField(const ConcreteField&) = default;
191
194
197
200
204 const auto& GetFieldSlice(int sliceID) const { return fvFieldSlices[sliceID]; }
205
209
215 FieldValue<T> GetFieldValue(int sliceID, T x, T y) const { return fvFieldSlices[sliceID].GetFieldValue(x, y); }
216
221 const FieldValue<T> GetFieldValueForLine(int sliceID, const TrackParam<T>& tp) const
222 {
223 T dz = fvFieldSlices[sliceID].GetZref() - tp.GetZ();
224 return GetFieldValue(sliceID, tp.GetX() + tp.GetTx() * dz, tp.GetY() + tp.GetTy() * dz);
225 }
226
230
233 int GetNofFieldSlices() const { return fvFieldSlices.size(); }
234
238 void RemoveSlice(int iLayer) { fvFieldSlices.erase(fvFieldSlices.begin() + iLayer); }
239
244 std::string ToString(int indentLevel, int verbose) const;
245
248 static constexpr EFieldMode Mode() { return EFieldMode::Interpolated; }
249
250 private:
254
256 friend class boost::serialization::access;
257 template<class Archive>
258 void serialize(Archive& ar, const unsigned int)
259 {
260 ar& fvFieldSlices;
262 ar& fFieldType;
263 }
264 };
265 } // namespace detail
266
267
271 template<typename T>
272 class alignas(VcMemAlign) Field {
273 template<typename>
274 friend class Field;
275 friend class boost::serialization::access;
276
277 public:
278 template<EFieldMode Mode>
280
283 using FieldVariant_t = typename std::variant<Interpolated_t, Original_t>;
284 using SlicesContainer_t = typename Interpolated_t::SlicesContainer_t;
285
287 Field() = default;
288
290 Field(const Field&) = default;
291
293 Field(Field&&) = default;
294
296 ~Field() = default;
297
299 Field& operator=(const Field& other) = default;
300
302 Field& operator=(Field&& other) = default;
303
318 template<EFieldMode FieldMode, typename... Args>
319 static constexpr Field Create(Args... args)
320 {
321 return Field(args..., Tag<FieldMode>{});
322 }
323
327 template<typename I>
328 static Field CopyConvert(const Field<I>& other)
329 {
330 return kf::visit([&other](const auto& c) { return Field(other, Tag<std::decay_t<decltype(c)>::Mode()>{}); },
331 other.fFieldVariant);
332 }
333
337 template<EFieldMode FieldMode>
339 {
340 return std::get_if<ConcreteField_t<FieldMode>>(&fFieldVariant);
341 }
342
346 {
347 return kf::visit([](const auto& c) { return std::decay_t<decltype(c)>::Mode(); }, fFieldVariant);
348 }
349
355 FieldValue<T> GetFieldValue(int sliceId, T x, T y) const
356 {
357 return kf::visit([sliceId, x, y](const auto& c) -> FieldValue<T> { return c.GetFieldValue(sliceId, x, y); },
359 }
360
365 const FieldValue<T> GetFieldValueForLine(int sliceId, const TrackParam<T>& tp) const
366 {
367 return kf::visit([sliceId, &tp](const auto& c) -> FieldValue<T> { return c.GetFieldValueForLine(sliceId, tp); },
369 }
370
373 {
374 return kf::visit([](const auto& c) -> EFieldType { return c.GetFieldType(); }, fFieldVariant);
375 }
376
381 //FieldRegion<T> MakeFieldRegion(const Node& n0, const Node& n1, const Node& n2)
382 //{
383 //}
384
391 // TODO: rename GetFieldRegion -> MakeFieldRegion
392 // FIXME: use kf::visit
394 {
395 if (auto* held = std::get_if<Original_t>(&fFieldVariant)) {
396 // FIXME: FieldRegion constructor
397 return FieldRegion<T>(held->GetFieldType(), held->GetFieldFunction());
398 }
399 else {
400 return FieldRegion<T>(b0, b1, b2);
401 }
402 }
403
407 {
408 return kf::visit([](const auto& c) -> const FieldRegion<T>& { return c.GetPrimVertexField(); }, fFieldVariant);
409 }
410
411
414 void RemoveSlice(int iLayer)
415 {
416 kf::visit([iLayer](auto&& c) -> void { c.RemoveSlice(iLayer); }, fFieldVariant);
417 }
418
422 std::string ToString(int indentLevel, int verbose) const;
423
424 private:
430 : fFieldVariant(FieldVariant_t(std::in_place_type<Interpolated_t>, fieldSlices, vtxField, fieldType))
431 {
432 }
433
439 Field(FieldFn_t fieldFn, std::vector<T>& fieldSliceZ, FieldRegion<T>& vtxField, EFieldType fieldType,
441 : fFieldVariant(FieldVariant_t(std::in_place_type<Original_t>, fieldFn, fieldSliceZ, vtxField, fieldType))
442 {
443 }
444
448 template<typename I, EFieldMode FieldMode>
451 FieldVariant_t(std::in_place_type<ConcreteField_t<FieldMode>>,
452 ConcreteField_t<FieldMode>(std::get<detail::ConcreteField<I, FieldMode>>(other.fFieldVariant))))
453 {
454 }
455
456 // TODO: Fully re-organize serialization
457
459 template<class Archive>
460 void load(Archive& ar, const unsigned int /*version*/)
461 {
462 auto field = Interpolated_t{};
463 ar >> field;
464 fFieldVariant.template emplace<Interpolated_t>(std::move(field));
465 }
466
468 // FIXME: use kf::variant
469 template<class Archive>
470 void save(Archive& ar, const unsigned int /*version*/) const
471 {
472 // FIXME (?) Which type should be serialized? Only double? Or others can be serialized as well?
473 if (std::holds_alternative<Interpolated_t>(fFieldVariant)) {
474 ar << std::get<Interpolated_t>(fFieldVariant);
475 }
476 else {
477 throw std::logic_error("Attempt to serialize a kf::Field object with fFieldMode == EFieldMode::Original");
478 }
479 }
480
482 template<class Archive>
483 void serialize(Archive& ar, const unsigned int version)
484 {
485 boost::serialization::split_member(ar, *this, version);
486 }
487
489 };
490
491
497 struct SliceRef {
501
506 SliceRef(double halfX, double halfY, double refZ) : fHalfSizeX(halfX), fHalfSizeY(halfY), fRefZ(refZ) {}
507
509 bool operator<(const SliceRef& r) const { return fRefZ < r.fRefZ; }
510 };
511
512 public:
514 FieldBuilder() = default;
515
517 FieldBuilder(const FieldBuilder&) = default;
518
520 ~FieldBuilder() = default;
521
524
529 void AddSliceReference(double halfSizeX, double halfSizeY, double refZ);
530
533
535 const FieldFn_t& GetFieldFunction() const { return fFieldFn; }
536
540 template<typename T>
541 Field<T> MakeField(EFieldMode fldMode) const;
542
544 void Reset() { *this = FieldBuilder(); }
545
548
551 void SetFieldFunction(const FieldFn_t& fieldFn, EFieldType fldType)
552 {
553 fFieldFn = fieldFn;
554 fFieldType = fldType;
555 }
556
559 void SetStep(double step = 2.5) { fTargetStep = step; }
560
565 void SetTarget(double x, double y, double z) { fTarget = {x, y, z}; }
566
567 private:
568 std::set<SliceRef> fSliceReferences;
570 double fTargetStep{2.5};
572
575 };
576
577 // -------------------------------------------------------------------------------------------------------------------
578 //
579 template<typename T>
581 {
582 // Check initialization
583 if (std::any_of(fTarget.begin(), fTarget.end(), [](double x) { return !utils::IsFinite(x); })) {
584 throw std::logic_error("FieldBuilder::MakeField: target is undefined");
585 }
586 if (!fSliceReferences.size()) { // TODO: Remove requirement of slice references
587 throw std::logic_error("FieldBuilder::MakeField: no slice references were provided");
588 }
589 if (!fFieldFn) {
590 throw std::logic_error("FieldBuilder::CreateField: no field function is provided");
591 }
592
593 // Initialize the Field object
594 switch (fldMode) {
596 std::vector<T> fieldSlices;
597 fieldSlices.reserve(fSliceReferences.size());
598 for (const auto& ref : fSliceReferences) {
599 fieldSlices.emplace_back(ref.fRefZ);
600 }
601 // FIXME: rewrite signature (Field::CreateOriginal, Field::CreateInterpolated)
602 return Field<T>::template Create<EFieldMode::Original>(fFieldFn, std::move(fieldSlices),
604 } break;
606 default: {
607 typename Field<T>::SlicesContainer_t fieldSlices;
608 fieldSlices.reserve(fSliceReferences.size());
609 for (const auto& ref : fSliceReferences) {
610 fieldSlices.emplace_back(fFieldFn, ref.fHalfSizeX, ref.fHalfSizeY, ref.fRefZ);
611 }
612
613 std::array<FieldValue<T>, 3> fld;
614 {
615 // PV field initialization
616 double z = fTarget[2];
617 for (auto& fldNode : fld) {
619 z += fTargetStep;
620 }
621 }
622 return Field<T>::template Create<EFieldMode::Interpolated>(std::move(fieldSlices),
623 FieldRegion<T>(fld[0], fld[1], fld[2]), fFieldType);
624 } break;
625 }
626 }
627} // namespace cbm::algo::kf
std::string ToString(CbmCutId id)
Convert CbmCutId to a string representation.
Definition CbmCutId.cxx:7
Mode
Definition Defs.h:21
Common constant definitions for the Kalman Filter library.
Magnetic flux density interpolation along the track vs. z-coordinate (header)
A class for a magnetic field approximation on a transverse plane (source)
Optimized implementation of std::visit.
Data members of the Field class (primary template)
Definition KfField.h:37
Field< T > MakeField(EFieldMode fldMode) const
Create field.
Definition KfField.h:580
std::set< SliceRef > fSliceReferences
Set of slice references.
Definition KfField.h:568
double fTargetStep
Step between nodal points for the primary vertex field estimation.
Definition KfField.h:570
EFieldType GetFieldType() const
Gets field type.
Definition KfField.h:532
void ResetSliceReferences()
Resets slicer references.
Definition KfField.h:547
std::array< double, 3 > fTarget
Target position.
Definition KfField.h:574
void AddSliceReference(double halfSizeX, double halfSizeY, double refZ)
Adds a slice reference.
Definition KfField.cxx:80
void SetFieldFunction(const FieldFn_t &fieldFn, EFieldType fldType)
Sets magnetic field function.
Definition KfField.h:551
FieldFn_t fFieldFn
Field function (x, y, z) [cm] -> (Bx, By, Bz) [kG].
Definition KfField.h:569
void SetTarget(double x, double y, double z)
Sets target.
Definition KfField.h:565
FieldBuilder & operator=(const FieldBuilder &)=default
Copy assignment operator.
~FieldBuilder()=default
Destructor.
void Reset()
Resets the instance.
Definition KfField.h:544
EFieldType fFieldType
Field type.
Definition KfField.h:571
const FieldFn_t & GetFieldFunction() const
Gets field function.
Definition KfField.h:535
FieldBuilder()=default
Default constructor.
void SetStep(double step=2.5)
Sets a step for the primary vertex field region estimation.
Definition KfField.h:559
FieldBuilder(const FieldBuilder &)=default
Copy constructor.
Magnetic field region, corresponding to a hit triplet.
Magnetic flux density vector.
Magnetic field manager class.
Definition KfField.h:272
void load(Archive &ar, const unsigned int)
Serialization load method.
Definition KfField.h:460
FieldValue< T > GetFieldValue(int sliceId, T x, T y) const
Creates field value object.
Definition KfField.h:355
void serialize(Archive &ar, const unsigned int version)
Serialization method.
Definition KfField.h:483
typename detail::ConcreteField< T, Mode > ConcreteField_t
Definition KfField.h:279
static constexpr Field Create(Args... args)
Creates a field (compile-time mode selection)
Definition KfField.h:319
void RemoveSlice(int iLayer)
Removes a field slice.
Definition KfField.h:414
const FieldRegion< T > & GetPrimVertexField() const
Gets field region near primary vertex.
Definition KfField.h:406
static Field CopyConvert(const Field< I > &other)
Creates a converted copy of the field with a different floating point type.
Definition KfField.h:328
const FieldValue< T > GetFieldValueForLine(int sliceId, const TrackParam< T > &tp) const
Creates field value for the intersection with a straight track.
Definition KfField.h:365
Field()=default
Default constructor.
const ConcreteField_t< FieldMode > * GetConcrete() const
Gets a pointer to the concrete field instance.
Definition KfField.h:338
FieldVariant_t fFieldVariant
Concrete field implementation.
Definition KfField.h:488
EFieldMode GetFieldMode() const
Gets stored mode of the field.
Definition KfField.h:345
Field(const Field< I > &other, Tag< FieldMode >)
Constructor from a field of another type.
Definition KfField.h:449
~Field()=default
Destructor.
Field(const Field &)=default
Copy constructor for the same class.
Field(SlicesContainer_t &fieldSlices, FieldRegion< T > &vtxField, EFieldType fieldType, Tag< EFieldMode::Interpolated >)
Constructor for interpolated field.
Definition KfField.h:429
ConcreteField_t< EFieldMode::Original > Original_t
Definition KfField.h:282
ConcreteField_t< EFieldMode::Interpolated > Interpolated_t
Definition KfField.h:281
typename std::variant< Interpolated_t, Original_t > FieldVariant_t
Definition KfField.h:283
Field(FieldFn_t fieldFn, std::vector< T > &fieldSliceZ, FieldRegion< T > &vtxField, EFieldType fieldType, Tag< EFieldMode::Original >)
Constructor for original field.
Definition KfField.h:439
EFieldType GetFieldType() const
Gets field type.
Definition KfField.h:372
Field & operator=(Field &&other)=default
Move assignment operator.
Field & operator=(const Field &other)=default
Copy assignment operator.
void save(Archive &ar, const unsigned int) const
Serialization save method.
Definition KfField.h:470
typename Interpolated_t::SlicesContainer_t SlicesContainer_t
Definition KfField.h:284
Field(Field &&)=default
Move constructor.
FieldRegion< T > GetFieldRegion(const FieldValue< T > &b0, const FieldValue< T > &b1, const FieldValue< T > &b2) const
Creates field region object from nodes.
Definition KfField.h:393
friend class Field
Definition KfField.h:274
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.
T GetTy() const
Gets slope along y-axis.
T GetZ() const
Gets z position [cm].
T GetTx() const
Gets slope along x-axis.
T GetY() const
Gets y position [cm].
T GetX() const
Gets x position [cm].
TrackParam classes of different types.
const FieldValue< T > GetFieldValueForLine(int sliceID, const TrackParam< T > &tp) const
Creates field value for the intersection with a straight track.
Definition KfField.h:221
const auto & GetFieldSlice(int sliceID) const
Gets field slice.
Definition KfField.h:204
int GetNofFieldSlices() const
Gets number of field slices in the instance.
Definition KfField.h:233
const FieldRegion< T > & GetPrimVertexField() const
Gets field region near primary vertex.
Definition KfField.h:229
ConcreteField(const ConcreteField &)=default
Default copy constructor for the same type.
FieldRegion< T > fPrimVertexField
Field region near primary vertex (constant field is assumed)
Definition KfField.h:252
static constexpr EFieldMode Mode()
Returns the mode of the field.
Definition KfField.h:248
SlicesContainer_t fvFieldSlices
Array of field slices on different layers.
Definition KfField.h:251
ConcreteField & operator=(const ConcreteField &)=default
Copy assignment operator.
ConcreteField(const ConcreteField< I, EFieldMode::Interpolated > &other)
Copy constructor.
Definition KfField.h:179
std::string ToString(int indentLevel, int verbose) const
String representation of the class.
FieldValue< T > GetFieldValue(int sliceID, T x, T y) const
Creates field value object.
Definition KfField.h:215
ConcreteField & operator=(ConcreteField &&)=default
Move assignment operator.
ConcreteField(ConcreteField &&)=default
Move constructor.
ConcreteField(SlicesContainer_t &fieldSlices, FieldRegion< T > &vtxField, EFieldType type)
Constructor from parameters.
Definition KfField.h:169
std::string ToString(int indentLevel, int verbose) const
String representation of the class.
int GetNofFieldSlices() const
Gets number of field slices in the instance.
Definition KfField.h:126
FieldRegion< T > fPrimVertexField
Field region near primary vertex (constant field is assumed)
Definition KfField.h:146
ConcreteField(FieldFn_t fieldFn, std::vector< T > &fieldSliceZ, FieldRegion< T > &vtxField, EFieldType type)
Constructor from parameters.
Definition KfField.h:58
void RemoveSlice(int iLayer)
Removes a field slice.
Definition KfField.h:131
const FieldValue< T > GetFieldValueForLine(int sliceId, const TrackParam< T > &tp) const
Creates field value for the intersection with a straight track.
Definition KfField.h:114
ConcreteField(ConcreteField &&)=default
Move constructor.
ConcreteField(const ConcreteField< I, EFieldMode::Original > &other)
Copy constructor (generic with type conversion)
Definition KfField.h:69
FieldFn_t fFieldFn
Field function: (x,y,z) [cm] -> (Bx,By,Bz) [kG].
Definition KfField.h:145
std::vector< T > fvFieldSliceZ
z-positions of field slices to emulate EFeildType::Interpolated
Definition KfField.h:144
ConcreteField & operator=(const ConcreteField &)=default
Copy assignment operator.
ConcreteField(const ConcreteField &)=default
Default copy constructor for the same type.
static constexpr EFieldMode Mode()
Returns the mode of the field.
Definition KfField.h:141
FieldValue< T > GetFieldValue(int sliceId, T x, T y) const
Creates field value object.
Definition KfField.h:105
const FieldRegion< T > & GetPrimVertexField() const
Gets field region near primary vertex.
Definition KfField.h:122
ConcreteField & operator=(ConcreteField &&)=default
Move assignment operator.
const FieldFn_t & GetFieldFunction() const
Gets field function.
Definition KfField.h:94
Data members of the Field class (primary template)
Definition KfField.h:37
constexpr auto ZeroFieldFn
Zero magnetic field function.
Definition KfDefs.h:237
constexpr T2 Undef
Undefined values.
Definition KfDefs.h:218
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
EFieldType
Magnetic field type in different setup regions.
Definition KfDefs.h:126
@ Normal
Field near the tracker subsystem.
Definition KfDefs.h:127
@ Null
No magnetic field.
Definition KfDefs.h:128
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.
double fHalfSizeY
Half-size of the slice in y-direction [cm].
Definition KfField.h:499
bool operator<(const SliceRef &r) const
Comparision operator.
Definition KfField.h:509
SliceRef(double halfX, double halfY, double refZ)
Constructor.
Definition KfField.h:506
double fRefZ
Reference z-position of the slice [cm].
Definition KfField.h:500
double fHalfSizeX
Half-size of the slice in x-direction [cm].
Definition KfField.h:498
A generic tag for tag dispatching.
Definition KfDefs.h:28