Belle II Software development
BFieldComponentBeamline.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <geometry/bfieldmap/BFieldComponentBeamline.h>
10
11#include <framework/utilities/FileSystem.h>
12#include <framework/logging/Logger.h>
13#include <framework/utilities/MathHelpers.h>
14
15#include <boost/iostreams/filtering_stream.hpp>
16#include <boost/iostreams/device/file.hpp>
17#include <boost/iostreams/filter/gzip.hpp>
18
19#include <cmath>
20#include <limits>
21
22using namespace std;
23namespace io = boost::iostreams;
24namespace Belle2 {
29
31 struct triangle_t {
33 short int j0{0};
35 short int j1{0};
37 short int j2{0};
39 short int n0{0};
41 short int n1{0};
43 short int n2{0};
44 };
45
47 struct xy_t {
48 double x{0};
49 double y{0};
50 };
51
63 public:
65 [[nodiscard]] const vector<xy_t>& getPoints() const { return m_points;}
67 [[nodiscard]] const vector<triangle_t>& getTriangles() const { return m_triangles;}
68
71
73 TriangularInterpolation(vector<xy_t>& pc, vector<triangle_t>& ts, double d)
74 {
75 init(pc, ts, d);
76 }
77
80
89 void init(vector<xy_t>& points, vector<triangle_t>& triangles, double d)
90 {
91 std::swap(points, m_points);
92 std::swap(triangles, m_triangles);
93 const double inf = numeric_limits<double>::infinity();
94 double xmin = inf, xmax = -inf;
95 double ymin = inf, ymax = -inf;
96 auto limit = [&xmin, &xmax, &ymin, &ymax](const xy_t & p) -> void {
97 xmin = std::min(xmin, p.x); xmax = std::max(xmax, p.x);
98 ymin = std::min(ymin, p.y); ymax = std::max(ymax, p.y);
99 };
100 for (const auto& t : m_triangles) {
101 limit(m_points[t.j0]);
102 limit(m_points[t.j1]);
103 limit(m_points[t.j2]);
104 }
105 double xw = xmax - xmin;
106 double yw = ymax - ymin;
107
108 xmin -= xw * (1. / 256), xmax += xw * (1. / 256);
109 ymin -= yw * (1. / 256), ymax += yw * (1. / 256);
110 int nx = lrint(xw * (1 + 1. / 128) / d), ny = lrint(yw * (1 + 1. / 128) / d);
111 nx = std::max(nx, 2);
112 ny = std::max(ny, 2);
113 makeIndex(nx, xmin, xmax, ny, ymin, ymax);
114 }
115
121 [[nodiscard]] xy_t triangleCenter(const triangle_t& p) const
122 {
123 const xy_t& p0 = m_points[p.j0], &p1 = m_points[p.j1], &p2 = m_points[p.j2];
124 return {(p0.x + p1.x + p2.x)* (1. / 3), (p0.y + p1.y + p2.y)* (1. / 3)};
125 }
126
137 void makeIndex(int nx, double xmin, double xmax, int ny, double ymin, double ymax)
138 {
139 m_nx = nx, m_ny = ny, m_xmin = xmin, m_xmax = xmax, m_ymin = ymin, m_ymax = ymax;
140 m_ixnorm = (nx - 1) / (xmax - xmin), m_iynorm = (ny - 1) / (ymax - ymin);
141 double dx = (xmax - xmin) / (nx - 1), dy = (ymax - ymin) / (ny - 1);
142 // cout<<nx<<" "<<xmin<<" "<<xmax<<" "<<ny<<" "<<ymin<<" "<<ymax<<endl;
143 m_spatialIndex.resize(nx * ny);
144 m_triangleCenters.resize(m_triangles.size());
145 for (unsigned int i = 0; i < m_triangles.size(); i++) m_triangleCenters[i] = triangleCenter(m_triangles[i]);
146
147 m_triangleAreas.resize(m_triangles.size());
148 auto getTriangleArea = [this](const triangle_t& p) ->double{
149 const xy_t& p0 = m_points[p.j0], &p1 = m_points[p.j1], &p2 = m_points[p.j2];
150 double d21x = p2.x - p1.x, d21y = p2.y - p1.y;
151 double d01x = p0.x - p1.x, d01y = p0.y - p1.y;
152 return 1 / (d21x * d01y - d21y * d01x);
153 };
154 for (unsigned int i = 0; i < m_triangles.size(); i++) m_triangleAreas[i] = getTriangleArea(m_triangles[i]);
155
156
157 for (int ix = 0; ix < nx; ix++) {
158 double x = xmin + ix * dx;
159 for (int iy = 0; iy < ny; iy++) {
160 double y = ymin + iy * dy;
161 int imin = -1; double dmin = 1e100;
162 for (unsigned int i = 0; i < m_triangleCenters.size(); i++) {
163 const xy_t& p = m_triangleCenters[i];
164 double d = square(p.x - x) + square(p.y - y);
165 if (d < dmin) {imin = i; dmin = d;}
166 }
167 int k = iy + ny * ix;
168 m_spatialIndex[k] = imin;
169 }
170 }
171 }
172
182 [[nodiscard]] short int sideCross(short int prev, short int curr, const xy_t& r, const xy_t& v0) const
183 {
184 const double vx = r.x - v0.x, vy = r.y - v0.y;
185 auto isCrossed = [&vx, &vy, &v0](const xy_t & p1, const xy_t & p0) -> bool {
186 double u0x = p0.x, u0y = p0.y;
187 double ux = p1.x - u0x, uy = p1.y - u0y;
188 double dx = u0x - v0.x, dy = u0y - v0.y;
189 double D = uy * vx - ux * vy;
190 double t = dx * vy - dy * vx;
191 double s = dx * uy - dy * ux;
192 return ((t < D) != (t < 0)) && ((s < D) != (s < 0));
193 };
194
195 const triangle_t& p = m_triangles[curr];
196 const xy_t& p0 = m_points[p.j0], &p1 = m_points[p.j1], &p2 = m_points[p.j2];
197 if (p.n0 != prev && isCrossed(p1, p2)) return p.n0;
198 if (p.n1 != prev && isCrossed(p2, p0)) return p.n1;
199 if (p.n2 != prev && isCrossed(p0, p1)) return p.n2;
200 return m_triangles.size();
201 }
202
212 void weights(short int i, const xy_t& r, double& w0, double& w1, double& w2) const
213 {
214 const triangle_t& p = m_triangles[i];
215 const xy_t& p0 = m_points[p.j0], &p1 = m_points[p.j1], &p2 = m_points[p.j2];
216 double dx2 = p2.x - r.x, dy2 = p2.y - r.y;
217 double d21x = p2.x - p1.x, d21y = p2.y - p1.y;
218 double d02x = p0.x - p2.x, d02y = p0.y - p2.y;
219 w0 = (dx2 * d21y - dy2 * d21x) * m_triangleAreas[i];
220 w1 = (dx2 * d02y - dy2 * d02x) * m_triangleAreas[i];
221 w2 = 1 - (w0 + w1);
222 }
223
233 [[nodiscard]] short int findTriangle(const xy_t& r0) const
234 {
235 unsigned int ix = lrint((r0.x - m_xmin) * m_ixnorm), iy = lrint((r0.y - m_ymin) * m_iynorm);
236 short int curr = (ix < m_nx && iy < m_ny) ? m_spatialIndex[iy + m_ny * ix] : 0;
237 xy_t r = m_triangleCenters[curr];
238 const short int end = m_triangles.size();
239 short int prev = end;
240 do {
241 short int next = sideCross(prev, curr, r, r0);
242 if (next == end) break;
243 prev = curr;
244 curr = next;
245 } while (true);
246 return curr;
247 }
248 protected:
250 vector<triangle_t> m_triangles;
252 vector<xy_t> m_points;
254 vector<xy_t> m_triangleCenters;
256 vector<double> m_triangleAreas;
258 vector<short int> m_spatialIndex;
260 double m_xmin;
262 double m_xmax;
264 double m_ymin;
266 double m_ymax;
268 unsigned int m_nx;
270 unsigned int m_ny;
272 double m_ixnorm{1};
274 double m_iynorm{1};
275 };
276
287 public:
302
311 void init(const string& fieldmapname, const string& interpolname, double validRadius)
312 {
313 if (fieldmapname.empty()) {
314 B2ERROR("The filename for the beamline magnetic field component is empty !");
315 return;
316 }
317 std::string l_fieldmapname = FileSystem::findFile("/data/" + fieldmapname);
318
319 if (interpolname.empty()) {
320 B2ERROR("The filename for the triangulation of the beamline magnetic field component is empty !");
321 return;
322 }
323 std::string l_interpolname = FileSystem::findFile("/data/" + interpolname);
324
325 m_rmax = validRadius;
326
327 B2DEBUG(50, "Delaunay triangulation of the beamline field map: " << l_interpolname);
328 B2DEBUG(50, "Beamline field map: " << l_fieldmapname);
329
330 // load interpolation triangles
331 ifstream INd(l_interpolname);
332 int nts; INd >> nts;
333 B2DEBUG(50, "Total number of triangles: " << nts);
334 vector<triangle_t> ts;
335 ts.reserve(nts);
336 // load triangle definitions from file
337 {
338 triangle_t p;
339 while (INd >> nts >> p.j0 >> p.j1 >> p.j2 >> p.n0 >> p.n1 >> p.n2) ts.push_back(p);
340 }
341
342 //Load the map file
343 io::filtering_istream IN;
344 IN.push(io::gzip_decompressor());
345 IN.push(io::file_source(l_fieldmapname));
346
347 int nrphi;
348 IN >> nrphi >> m_rj >> m_nr >> m_nphi;
349 IN >> m_nz >> m_zj >> m_dz0 >> m_dz1;
350 m_idphi = m_nphi / M_PI;
351 m_rj2 = m_rj * m_rj;
352 m_idz0 = 1 / m_dz0;
353 m_idz1 = 1 / m_dz1;
354 int nz0 = 2 * int(m_zj / m_dz0);
355 m_zmax = (m_nz - (nz0 + 1)) / 2 * m_dz1 + m_zj;
356 m_nz1 = (m_nz - (nz0 + 1)) / 2;
357 m_nz2 = m_nz1 + nz0;
358 // cout<<_zmax<<" "<<nz0<<" "<<m_nz1<<" "<<m_nz2<<endl;
359
360 struct cs_t {double c, s;};
361 vector<cs_t> cs(nrphi);
362 vector<xy_t> pc;
363 vector<ROOT::Math::XYZVector> tbc;
364 pc.reserve(nrphi);
365 char cbuf[256]; IN.getline(cbuf, 256);
366 double rmax = 0;
367 for (int j = 0; j < nrphi; j++) {
368 IN.getline(cbuf, 256);
369 char* next = cbuf;
370 double r = strtod(next, &next);
371 double phi = strtod(next, &next);
372 strtod(next, &next);
373 double Br = strtod(next, &next);
374 double Bphi = strtod(next, &next);
375 double Bz = strtod(next, nullptr);
376 r *= 100;
377 rmax = std::max(r, rmax);
378 if (phi == 0) {
379 cs[j] = { 1, 0};
380 } else if (phi == 180) {
381 cs[j] = { -1, 0};
382 } else {
383 phi *= M_PI / 180;
384 cs[j] = {cos(phi), sin(phi)};
385 }
386 double x = r * cs[j].c, y = r * cs[j].s;
387 pc.push_back({x, y});
388 if (cs[j].s == 0) Bphi = 0;
389 double Bx = Br * cs[j].c - Bphi * cs[j].s;
390 double By = Br * cs[j].s + Bphi * cs[j].c;
391 tbc.emplace_back(Bx, By, Bz);
392 }
393 // cout<<"Field map has data points up to R="<<rmax<<" cm."<<endl;
394
395 m_idr = m_nr / (rmax - m_rj);
396 m_rmax = std::min(m_rmax, rmax);
397 bool reduce = m_rj > m_rmax;
398
399 // if valid radius is within the triangular mesh try to reduce
400 // field map keeping only points which participate to the
401 // interpolation
402 vector<bool> ip;
403 if (reduce) {
404 ip.resize(nrphi, false);
405 vector<bool> it(ts.size(), false);
406 auto inside = [this](const xy_t & p)->bool{
407 return p.x * p.x + p.y * p.y < m_rmax * m_rmax;
408 };
409
410 for (int i = 0, imax = ts.size(); i < imax; i++) {
411 const triangle_t& p = ts[i];
412 const xy_t& p0 = pc[p.j0], &p1 = pc[p.j1], &p2 = pc[p.j2];
413 if (inside(p0) || inside(p1) || inside(p2)) {
414 it[i] = true;
415 ip[p.j0] = true;
416 ip[p.j1] = true;
417 ip[p.j2] = true;
418 }
419 }
420
421 vector<short int> pindx(nrphi, -1);
422 int rnp = 0;
423 for (int i = 0, imax = ip.size(); i < imax; i++) {
424 if (ip[i]) pindx[i] = rnp++;
425 }
426 vector<xy_t> rpc;
427 rpc.reserve(rnp);
428 for (int i = 0, imax = pc.size(); i < imax; i++) {
429 if (ip[i]) rpc.push_back(pc[i]);
430 }
431
432 vector<short int> tindx(ts.size(), -1);
433 short int rnt = 0;
434 for (int i = 0, imax = it.size(); i < imax; i++) {
435 if (it[i]) tindx[i] = rnt++;
436 }
437 vector<triangle_t> rts;
438 rts.reserve(rnt);
439 short int nt = ts.size();
440 auto newind = [&nt, &tindx, &rnt](short int n) -> short int {return (n < nt) ? tindx[n] : rnt;};
441 for (int i = 0, imax = ts.size(); i < imax; i++) {
442 if (it[i]) {
443 const triangle_t& t = ts[i];
444 rts.push_back({pindx[t.j0], pindx[t.j1], pindx[t.j2], newind(t.n0), newind(t.n1), newind(t.n2)});
445 }
446 }
447
448 B2DEBUG(50, "Reduce map size to cover only region R<" << m_rmax << " cm: Ntriangles=" << rnt << " Nxypoints = " << rnp <<
449 " Nzslices=" << m_nz << " NBpoints = " << rnp * m_nz);
450 std::swap(rpc, pc);
451 std::swap(rts, ts);
452 } else {
453 ip.resize(nrphi, true);
454 }
455 m_nxy = pc.size();
456
457 m_triInterpol.init(pc, ts, 0.1);
458
459 vector<ROOT::Math::XYZVector> bc(m_nxy * m_nz);
460 unsigned int count = 0;
461 for (int i = 0; i < nrphi; i++) {
462 if (ip[i]) bc[count++] = ROOT::Math::XYZVector(tbc[i]);
463 }
464
465 for (int i = 1; i < m_nz; ++i) {
466 for (int j = 0; j < nrphi; j++) {
467 IN.getline(cbuf, 256);
468 if (!ip[j]) continue;
469 char* next = cbuf;
470 next = strchr(next, ' ');
471 next = strchr(next + 1, ' ');
472 next = strchr(next + 1, ' ');
473 double Br = strtod(next, &next);
474 double Bphi = strtod(next, &next);
475 double Bz = strtod(next, nullptr);
476 if (cs[j].s == 0) Bphi = 0;
477 double Bx = Br * cs[j].c - Bphi * cs[j].s;
478 double By = Br * cs[j].s + Bphi * cs[j].c;
479 bc[count++].SetXYZ(Bx, By, Bz);
480 }
481 }
482 assert(count == bc.size());
483 swap(bc, m_B);
484 }
485
495 int zIndexAndWeight(double z, double& w1) const
496 {
497 if (std::abs(z) > m_zmax) return -1;
498 double fz;
499 int iz = 0;
500 if (z < - m_zj) {
501 fz = (z + m_zmax) * m_idz1;
502 } else if (z < m_zj) {
503 fz = (z + m_zj) * m_idz0;
504 iz = m_nz1;
505 } else {
506 fz = (z - m_zj) * m_idz1;
507 iz = m_nz2;
508 }
509 int jz = static_cast<int>(fz);
510 w1 = fz - jz;
511 iz += jz;
512 if (iz == m_nz) {
513 --iz;
514 w1 = 1;
515 }
516 return iz;
517 }
518
528 [[nodiscard]] bool inRange(const ROOT::Math::XYZVector& v) const
529 {
530 if (std::abs(v.Z()) > m_zmax) return false;
531 double R2 = v.X() * v.X() + v.Y() * v.Y();
532 if (R2 > m_rmax * m_rmax) return false;
533 return true;
534 }
535
545 [[nodiscard]] ROOT::Math::XYZVector interpolateField(const ROOT::Math::XYZVector& v) const
546 {
547 ROOT::Math::XYZVector res = {0, 0, 0};
548 double R2 = v.X() * v.X() + v.Y() * v.Y();
549 if (R2 > m_rmax * m_rmax) return res;
550 double wz1;
551 int iz = zIndexAndWeight(v.Z(), wz1);
552 if (iz < 0) return res;
553 double wz0 = 1 - wz1;
554
555 if (R2 < m_rj2) { // triangular interpolation
556 xy_t xy = {v.X(), std::abs(v.Y())};
557 double w0, w1, w2;
558 short int it = m_triInterpol.findTriangle(xy);
559 m_triInterpol.weights(it, xy, w0, w1, w2);
560 auto t = m_triInterpol.getTriangles().begin() + it;
561 int j0 = t->j0, j1 = t->j1, j2 = t->j2;
562 const ROOT::Math::XYZVector* B = m_B.data() + m_nxy * iz;
563 ROOT::Math::XYZVector b = (B[j0] * w0 + B[j1] * w1 + B[j2] * w2) * wz0;
564 B += m_nxy; // next z-slice
565 b += (B[j0] * w0 + B[j1] * w1 + B[j2] * w2) * wz1;
566 res = b;
567 } else {// r-phi grid
568 double r = sqrt(R2), phi = atan2(std::abs(v.Y()), v.X());
569 double fr = (r - m_rj) * m_idr;
570 double fphi = phi * m_idphi;
571
572 int ir = static_cast<int>(fr);
573 int iphi = static_cast<int>(fphi);
574
575 ir -= (ir == m_nr);
576 iphi -= (iphi == m_nphi);
577
578 double wr1 = fr - ir, wr0 = 1 - wr1;
579 double wphi1 = fphi - iphi, wphi0 = 1 - wphi1;
580 const int nr1 = m_nr + 1, nphi1 = m_nphi + 1;
581 int j00 = m_nxy - nr1 * (nphi1 - iphi) + ir;
582 int j01 = j00 + 1;
583 int j10 = j00 + nr1;
584 int j11 = j01 + nr1;
585
586 double w00 = wr0 * wphi0, w01 = wphi0 * wr1, w10 = wphi1 * wr0, w11 = wphi1 * wr1;
587 const ROOT::Math::XYZVector* B = m_B.data() + m_nxy * iz;
588 ROOT::Math::XYZVector b = (B[j00] * w00 + B[j01] * w01 + B[j10] * w10 + B[j11] * w11) * wz0;
589 B += m_nxy; // next z-slice
590 b += (B[j00] * w00 + B[j01] * w01 + B[j10] * w10 + B[j11] * w11) * wz1;
591 res = b;
592 }
593 if (v.Y() < 0) res.SetY(-res.Y());
594 return res;
595 }
596 protected:
598 vector<ROOT::Math::XYZVector> m_B;
602 int m_nxy{0};
604 int m_nz{0};
606 int m_nz1{0};
608 int m_nz2{0};
610 int m_nr{0};
612 int m_nphi{0};
614 double m_rj{0};
616 double m_rj2{0};
618 double m_zj{0};
620 double m_dz0{0};
622 double m_dz1{0};
624 double m_idz0{0};
626 double m_idz1{0};
628 double m_idphi{0};
630 double m_idr{0};
632 double m_rmax{0};
634 double m_zmax{0};
635 };
636
644
646 {
647 if (m_ler) delete m_ler;
648 if (m_her) delete m_her;
649 }
650
651 bool BFieldComponentBeamline::isInRange(const ROOT::Math::XYZVector& p) const
652 {
653 if (!m_ler || !m_her) return false;
655 ROOT::Math::XYZVector v = -p; // invert coordinates to match ANSYS one
656 double xc = v.X() * c, zs = v.Z() * s, zc = v.Z() * c, xs = v.X() * s;
657 ROOT::Math::XYZVector hv{xc - zs, v.Y(), zc + xs};
658 ROOT::Math::XYZVector lv{xc + zs, v.Y(), zc - xs};
659 return m_ler->inRange(lv) || m_her->inRange(hv);
660 }
661
662 ROOT::Math::XYZVector BFieldComponentBeamline::calculate(const ROOT::Math::XYZVector& p) const
663 {
664 ROOT::Math::XYZVector res;
666 ROOT::Math::XYZVector v = -p; // invert coordinates to match ANSYS one
667 double xc = v.X() * c, zs = v.Z() * s, zc = v.Z() * c, xs = v.X() * s;
668 ROOT::Math::XYZVector hv{xc - zs, v.Y(), zc + xs};
669 ROOT::Math::XYZVector lv{xc + zs, v.Y(), zc - xs};
670 ROOT::Math::XYZVector hb = m_her->interpolateField(hv);
671 ROOT::Math::XYZVector lb = m_ler->interpolateField(lv);
672 ROOT::Math::XYZVector rhb{hb.X()* c + hb.Z()* s, hb.Y(), hb.Z()* c - hb.X()* s};
673 ROOT::Math::XYZVector rlb{lb.X()* c - lb.Z()* s, lb.Y(), lb.Z()* c + lb.X()* s};
674
675 double mhb = std::abs(rhb.X()) + std::abs(rhb.Y()) + std::abs(rhb.Z());
676 double mlb = std::abs(rlb.X()) + std::abs(rlb.Y()) + std::abs(rlb.Z());
677
678 if (mhb < 1e-10) res = rlb;
679 else if (mlb < 1e-10) res = rhb;
680 else {
681 res = 0.5 * (rlb + rhb);
682 }
683 return res;
684 }
685
689
692 {
693 static BFieldComponentBeamline* gInstance = nullptr;
694 return &gInstance;
695 }
696
699 {
700 auto gInstance = GetInstancePtr();
701 if (*gInstance == nullptr) {
702 // Constructor creates a new instance, inits gInstance.
704 }
705 return **gInstance;
706 }
707
709 {
710 auto gInstance = GetInstancePtr();
711 if (*gInstance != nullptr) {
712 B2WARNING("BFieldComponentBeamline: object already instantiated");
713 } else {
714 *gInstance = this;
715 }
716 }
717
719}
The BFieldComponentBeamline class.
std::string m_mapFilename_ler
The filename of the magnetic field map.
BeamlineFieldMapInterpolation * m_ler
Actual magnetic field interpolation object for LER.
BeamlineFieldMapInterpolation * m_her
Actual magnetic field interpolation object for HER.
double m_sinBeamCrossAngle
The sin of the crossing angle of the beams.
double m_cosBeamCrossAngle
The cos of the crossing angle of the beams.
std::string m_interFilename_ler
The filename of the map for interpolation.
std::string m_mapFilename_her
Parameter to set Angle of the beam.
std::string m_interFilename_her
The filename of the map for interpolation.
double m_mapRegionR[2]
The min and max boundaries of the map region in r.
The BeamlineFieldMapInterpolation class.
const TriangularInterpolation & getTriangularInterpolation() const
Expose the triangular interpolation to outside.
double m_rj
Separation radius between triangular and cylindrical meshes.
bool inRange(const ROOT::Math::XYZVector &v) const
Check the space point if the interpolation exists.
int zIndexAndWeight(double z, double &w1) const
For a given Z coordinate calculate the index of Z slice and corresponding weight.
double m_idz1
Inverse of finer Z grid pitch.
int m_nphi
Number of grid points in Phi direction.
int m_nr
Number of grid points in R direction.
double m_zmax
Maximal Z where interpolation is still valid.
double m_rj2
Square of the separation radius between triangular and cylindrical meshes.
int m_nz
Number of field slices in Z direction.
ROOT::Math::XYZVector interpolateField(const ROOT::Math::XYZVector &v) const
Interpolate the magnetic field vector at the specified space point.
int m_nz2
End Z slice number for the finer Z grid.
vector< ROOT::Math::XYZVector > m_B
Buffer for the magnetic field map.
int m_nxy
Number of field points in XY plane.
double m_idz0
Inverse of coarse Z grid pitch.
TriangularInterpolation m_triInterpol
Object to locate point in a triangular mesh.
void init(const string &fieldmapname, const string &interpolname, double validRadius)
Initializes the magnetic field component.
double m_rmax
Maximal radius where interpolation is still valid.
BeamlineFieldMapInterpolation()=default
Default constructor.
~BeamlineFieldMapInterpolation()=default
Default destructor.
int m_nz1
Start Z slice number for the finer Z grid.
static std::string findFile(const std::string &path, bool silent=false)
Search for given file or directory in local or central release directory, and return absolute path if...
The TriangularInterpolation class.
vector< short int > m_spatialIndex
Spatial index.
double m_xmin
Border of the region where the spatial index is constructed.
unsigned int m_ny
Spatial index grid size.
double m_ixnorm
Reciprocals to speedup the index calculation.
~TriangularInterpolation()=default
Destructor.
TriangularInterpolation(vector< xy_t > &pc, vector< triangle_t > &ts, double d)
More complex constructor.
vector< triangle_t > m_triangles
Triangle list.
void init(vector< xy_t > &points, vector< triangle_t > &triangles, double d)
Calculate extents of a triangular mesh and build spatial index.
xy_t triangleCenter(const triangle_t &p) const
Calculate triangle center.
double m_ymin
Border of the region where the spatial index is constructed.
vector< xy_t > m_triangleCenters
Triangle centers.
short int sideCross(short int prev, short int curr, const xy_t &r, const xy_t &v0) const
Determine which triangle side is crossed by a line segment defined by r and v0 points.
const vector< triangle_t > & getTriangles() const
returns list of triangles
double m_xmax
Border of the region where the spatial index is constructed.
void makeIndex(int nx, double xmin, double xmax, int ny, double ymin, double ymax)
Make spatial index.
const vector< xy_t > & getPoints() const
returns list of vertices
vector< double > m_triangleAreas
Triangle areas.
unsigned int m_nx
Spatial index grid size.
short int findTriangle(const xy_t &r0) const
Find the triangle which contain the point.
TriangularInterpolation()=default
Default constructor.
void weights(short int i, const xy_t &r, double &w0, double &w1, double &w2) const
Calculate barycentric coordinates of a point inside triangle.
double m_ymax
Border of the region where the spatial index is constructed.
double m_iynorm
Reciprocals to speedup the index calculation.
constexpr T square(const T &x)
Calculate the square of the input.
Definition MathHelpers.h:21
double sqrt(double a)
sqrt for double
Definition beamHelpers.h:28
virtual void initialize() override
Initializes the magnetic field component.
BFieldComponentBeamline ** GetInstancePtr()
Static function holding the instance.
bool isInRange(const ROOT::Math::XYZVector &point) const
Check presence of beamline field at the specific space point in the detector coordinate frame.
virtual void terminate() override
Terminates the magnetic field component.
virtual ROOT::Math::XYZVector calculate(const ROOT::Math::XYZVector &point) const override
Calculates the magnetic field vector at the specified space point.
virtual ~BFieldComponentBeamline()
The BFieldComponentBeamline destructor.
static BFieldComponentBeamline & Instance()
BFieldComponentBeamline instance.
BFieldComponentBeamline()
The BFieldComponentBeamline constructor.
Abstract base class for different kinds of events.
STL namespace.
short int n1
2nd adjacent triangle in a list of triangles
short int j1
2nd vertex index in a list of xy-points
short int n2
3rd adjacent triangle in a list of triangles
short int j0
1st vertex index in a list of xy-points
short int n0
1st adjacent triangle in a list of triangles
short int j2
3rd vertex index in a list of xy-points
A simple 2d vector structure.
double y
y component
double x
x component