9 #include <geometry/bfieldmap/BFieldComponentRadial.h>
10 #include <geometry/bfieldmap/BFieldComponentBeamline.h>
12 #include <framework/utilities/FileSystem.h>
13 #include <framework/logging/Logger.h>
15 #include <boost/iostreams/filtering_stream.hpp>
16 #include <boost/iostreams/device/file.hpp>
17 #include <boost/iostreams/filter/gzip.hpp>
23 namespace io = boost::iostreams;
25 void BFieldComponentRadial::initialize()
27 if (m_mapFilename.empty()) {
28 B2ERROR(
"The filename for the radial magnetic field component is empty !");
32 string fullPath = FileSystem::findFile(
"/data/" + m_mapFilename);
34 if (!FileSystem::fileExists(fullPath)) {
35 B2ERROR(
"The radial magnetic field map file '" << m_mapFilename <<
"' could not be found !");
40 io::filtering_istream fieldMapFile;
41 fieldMapFile.push(io::gzip_decompressor());
42 fieldMapFile.push(io::file_source(fullPath));
45 B2DEBUG(10,
"Loading the radial magnetic field from file '" << m_mapFilename <<
"' in to the memory...");
47 m_mapBuffer.reserve(m_mapSize[0]*m_mapSize[1]);
50 for (
int i = 0; i < m_mapSize[0]; ++i) {
51 for (
int j = 0; j < m_mapSize[1]; j++) {
52 fieldMapFile >> r >> z >> Br >> Bz;
54 m_mapBuffer.push_back({Br, Bz});
58 m_igridPitchR = 1 / m_gridPitchR;
59 m_igridPitchZ = 1 / m_gridPitchZ;
60 m_Layer = m_gapHeight + m_ironPlateThickness;
61 m_iLayer = 1 / m_Layer;
63 B2DEBUG(10,
"... loaded " << m_mapSize[0] <<
"x" << m_mapSize[1] <<
" (r,z) elements.");
74 return {v.
r * a, v.
z * a};
81 return {u.r + v.
r, u.z + v.
z};
86 ROOT::Math::XYZVector BFieldComponentRadial::calculate(
const ROOT::Math::XYZVector& point)
const
88 ROOT::Math::XYZVector B;
92 if (BFieldComponentBeamline::Instance().isInRange(point))
return B;
97 if ((z < m_mapRegionZ[0]) || (z > m_mapRegionZ[1]))
return B;
100 double r2 = point.Perp2();
102 if ((r2 < m_mapRegionR[0]*m_mapRegionR[0]) || (r2 > m_mapRegionR[1]*m_mapRegionR[1]))
return B;
106 double wr = (r - m_mapRegionR[0]) * m_igridPitchR;
107 double wz = (z - m_mapRegionZ[0]) * m_igridPitchZ;
109 int ir =
static_cast<int>(wr);
110 int iz =
static_cast<int>(wz);
112 double za = z - m_mapOffset;
113 double dz_eklm = abs(za) - (m_endyokeZMin - m_gapHeight);
114 if (dz_eklm > 0 && r > m_slotRMin) {
115 double wl = dz_eklm * m_iLayer;
116 int il =
static_cast<int>(wl);
118 double L = m_Layer * il;
119 double l = dz_eklm - L;
120 int ingap = l < m_gapHeight;
121 ir += ingap & (r < m_slotRMin + m_gridPitchR);
123 double zlg = L + m_endyokeZMin, zl0 = zlg - m_gapHeight, zl1 = zlg + m_ironPlateThickness;
129 double zoff = m_mapOffset - m_mapRegionZ[0];
130 int izl0 =
static_cast<int>((zl0 + zoff) * m_igridPitchZ);
131 int izlg =
static_cast<int>((zlg + zoff) * m_igridPitchZ);
132 int izl1 =
static_cast<int>((zl1 + zoff) * m_igridPitchZ);
134 int idz = (izl0 == iz) - (izl1 == iz) + (ingap ? -ig : ig);
135 iz += (za > 0) ? idz : -idz;
140 ir = min(m_mapSize[0] - 2, ir);
141 iz = min(m_mapSize[1] - 2, iz);
146 double wz0 = 1 - wz, wr0 = 1 - wr;
148 const unsigned int strideZ = m_mapSize[1];
149 const unsigned int i00 = ir * strideZ + iz, i01 = i00 + 1, i10 = i00 + strideZ, i11 = i01 + strideZ;
151 double w00 = wz0 * wr0, w01 = wz * wr0, w10 = wz0 * wr, w11 = wz * wr;
152 BFieldPoint Brz = H[i00] * w00 + H[i01] * w01 + H[i10] * w10 + H[i11] * w11;
155 double norm = Brz.
r / r;
156 B.SetXYZ(point.X()*norm, point.Y()*norm, Brz.
z);
164 void BFieldComponentRadial::terminate()
double sqrt(double a)
sqrt for double
BFieldComponentRadial::BFieldPoint operator+(const BFieldComponentRadial::BFieldPoint &u, const BFieldComponentRadial::BFieldPoint &v)
Add two radial bfield points together.
BFieldComponentRadial::BFieldPoint operator*(const BFieldComponentRadial::BFieldPoint &v, double a)
multiply a radial bfield point by a real number
Abstract base class for different kinds of events.
Magnetic field data structure.
double r
Magnetic field in r direction.
double z
Magnetic field in z direction.