LDMX Software
TrackingGeometryUser.cxx
1#include "Tracking/Reco/TrackingGeometryUser.h"
2
3#include <vector>
4
5#include "Acts/MagneticField/ConstantBField.hpp"
6#include "Tracking/geo/CalibrationContext.h"
7#include "Tracking/geo/GeometryContext.h"
8#include "Tracking/geo/MagneticFieldContext.h"
9
10namespace tracking::reco {
11
12TrackingGeometryUser::TrackingGeometryUser(const std::string& name,
14 : framework::Producer(name, p) {}
15
16const Acts::GeometryContext& TrackingGeometryUser::geometryContext() {
17 return getNamedCondition<geo::GeometryContext>().get();
18}
19const Acts::MagneticFieldContext& TrackingGeometryUser::magneticFieldContext() {
20 return getNamedCondition<geo::MagneticFieldContext>().get();
21}
22const Acts::CalibrationContext& TrackingGeometryUser::calibrationContext() {
23 return getNamedCondition<geo::CalibrationContext>().get();
24}
25const geo::TrackersTrackingGeometry& TrackingGeometryUser::geometry() {
26 return getNamedCondition<geo::TrackersTrackingGeometry>();
27}
28
29void TrackingGeometryUser::loadBField(const BFieldDistortion& distortion) {
30 loadBField(geometry().fieldMapFile(), distortion);
31}
32
33void TrackingGeometryUser::loadBField(const std::string& path,
34 const BFieldDistortion& distortion) {
35 if (path.empty()) {
36 ldmx_log(warn) << "No B-field map path provided — using zero B-field";
37 b_field_ =
38 std::make_shared<Acts::ConstantBField>(Acts::Vector3(0., 0., 0.));
39 return;
40 }
41
42 if (distortion.isNominal()) {
43 b_field_ = std::make_shared<InterpolatedMagneticField3>(
44 loadDefaultBField(path, defaultTransformPos, defaultTransformBField));
45 return;
46 }
47
48 const Acts::RotationMatrix3 rot{distortion.rotationMatrix()};
49 const Acts::RotationMatrix3 rot_inv{rot.transpose()};
50 const Acts::Vector3 translation{distortion.translation_};
51 const Acts::Vector3 pivot{distortion.pivot_};
52 const double scale{distortion.scale_};
53
54 // undo the distortion, then the nominal ACTS -> map transform
55 auto transform_pos = [rot_inv, translation, pivot](const Acts::Vector3& pos) {
56 return defaultTransformPos(rot_inv * (pos - translation - pivot) + pivot);
57 };
58 // nominal map -> ACTS transform, then redo the distortion
59 auto transform_b = [rot, scale](const Acts::Vector3& field,
60 const Acts::Vector3& pos) {
61 return Acts::Vector3(scale * (rot * defaultTransformBField(field, pos)));
62 };
63
64 ldmx_log(info) << "B-field distortion active (LDMX frame): translation ("
65 << translation(1) << ", " << translation(2) << ", "
66 << translation(0) << ") mm, rotation ("
67 << distortion.rotation_(1) << ", " << distortion.rotation_(2)
68 << ", " << distortion.rotation_(0) << ") rad about ("
69 << pivot(1) << ", " << pivot(2) << ", " << pivot(0)
70 << ") mm, scale " << scale;
71
72 b_field_ = std::make_shared<InterpolatedMagneticField3>(
73 loadDefaultBField(path, transform_pos, transform_b));
74}
75
76BFieldDistortion TrackingGeometryUser::bFieldDistortion(
77 const framework::config::Parameters& parameters) {
78 const auto translation{
79 parameters.get<std::vector<double>>("bfield_translation", {0., 0., 0.})};
80 const auto rotation{
81 parameters.get<std::vector<double>>("bfield_rotation", {0., 0., 0.})};
82 const auto pivot{parameters.get<std::vector<double>>(
83 "bfield_pivot", {0., 0., -DIPOLE_OFFSET})};
84
85 auto require_three = [](const std::string& name,
86 const std::vector<double>& v) {
87 if (v.size() != 3)
88 EXCEPTION_RAISE("BadConf", name + " must have three entries");
89 };
90 require_three("bfield_translation", translation);
91 require_three("bfield_rotation", rotation);
92 require_three("bfield_pivot", pivot);
93
94 // LDMX (x, y, z) -> ACTS (z, x, y); a cyclic permutation, so the rotation
95 // angles reorder the same way as the positions
96 BFieldDistortion distortion;
97 distortion.translation_ =
98 Acts::Vector3(translation[2], translation[0], translation[1]);
99 distortion.rotation_ = Acts::Vector3(rotation[2], rotation[0], rotation[1]);
100 distortion.pivot_ = Acts::Vector3(pivot[2], pivot[0], pivot[1]);
101 distortion.scale_ = parameters.get<double>("bfield_scale", 1.);
102 return distortion;
103}
104
105} // namespace tracking::reco
Class which represents the process under execution.
Definition Process.h:34
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:26
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:75
All classes in the ldmx-sw project use this namespace.
A deliberate mis-placement of the reconstruction magnetic field, used to quantify how well we need to...
double scale_
overall scaling of the field strength
Acts::Vector3 pivot_
centre of rotation [mm], default the field-map origin
Acts::Vector3 rotation_
rotation about x, y, z through pivot [rad]
Acts::RotationMatrix3 rotationMatrix() const
Rz(gamma) * Ry(beta) * Rx(alpha)
Acts::Vector3 translation_
displacement of the magnet [mm]
bool isNominal() const
Exact comparison on purpose: the nominal case reuses the default transforms unchanged,...