Project
Loading...
Searching...
No Matches
MagFieldFast.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
15//
16#include "Field/MagFieldFast.h"
17#include <GPUCommonLogger.h>
18
19#include <cmath>
20#include <fstream>
21#include <sstream>
22using namespace std;
23
24using namespace o2::field;
25
27
28const float MagFieldFast::kSolR2Max[MagFieldFast::kNSolRRanges] = {80.f * 80.f, 250.f * 250.f, 400.f * 400.f,
29 423.f * 423.f, 500.f * 500.f};
30
31const float MagFieldFast::kSolZMax = 550.0f;
32
33#ifndef GPUCA_STANDALONE
34#include <TString.h>
35#include <TSystem.h>
36
37//_______________________________________________________________________
38MagFieldFast::MagFieldFast(const string inpFName) : mFactorSol(1.f)
39{
40 // c-tor
41 if (!inpFName.empty() && !LoadData(inpFName)) {
42 LOG(fatal) << "Failed to initialize from " << inpFName;
43 }
44}
45
46//_______________________________________________________________________
47MagFieldFast::MagFieldFast(float factor, int nomField, const string inpFmt) : mFactorSol(factor)
48{
49 // c-tor
50 if (nomField != 2 && nomField != 5) {
51 LOG(fatal) << "No parametrization for nominal field of " << nomField << " kG";
52 }
53 TString pth;
54 pth.Form(inpFmt.data(), nomField);
55 if (!LoadData(pth.Data())) {
56 LOG(fatal) << "Failed to initialize from " << pth.Data();
57 }
58}
59
60//_______________________________________________________________________
61bool MagFieldFast::LoadData(const string inpFName)
62{
63 // load field from text file
64
65 std::ifstream in(gSystem->ExpandPathName(inpFName.data()), std::ifstream::in);
66 if (in.fail()) {
67 LOG(fatal) << "Failed to open file " << inpFName;
68 return false;
69 }
70 std::string line;
71 int valI, component = -1, nParams = 0, header[4] = {-1, -1, -1, -1}; // iR, iZ, iQuadrant, nVal
72 SolParam* curParam = nullptr;
73
74 while (std::getline(in, line)) {
75 if (line.empty() || line[0] == '#') {
76 continue; // empy or comment
77 }
78 std::stringstream ss(line);
79 int cnt = 0;
80
81 if (component < 0) {
82 while (cnt < 4 && (ss >> header[cnt++])) {
83 ;
84 }
85 if (cnt != 4) {
86 LOG(fatal) << "Wrong header " << line;
87 return false;
88 }
89 curParam = &mSolPar[header[0]][header[1]][header[2]];
90 } else {
91 while (cnt < header[3] && (ss >> curParam->parBxyz[component][cnt++])) {
92 ;
93 }
94 if (cnt != header[3]) {
95 LOG(fatal) << "Wrong data (npar=" << cnt << ") for param " << header[0] << " " << header[1] << " " << header[2]
96 << " " << header[3] << " " << line;
97 return false;
98 }
99 }
100 component++;
101 if (component > 2) {
102 component = -1; // next header expected
103 nParams++;
104 }
105 }
106 //
107 LOG(info) << "Loaded " << nParams << " params from " << inpFName;
108 if (nParams != kNSolRRanges * kNSolZRanges * kNQuadrants) {
109 LOG(fatal) << "Was expecting " << kNSolRRanges * kNSolZRanges * kNQuadrants << " params";
110 }
111 return true;
112}
113#endif // GPUCA_STANDALONE
114
115//_______________________________________________________________________
116bool MagFieldFast::Field(const double xyz[3], double bxyz[3]) const
117{
118 // get field
119 int zSeg, rSeg, quadrant;
120 if (!GetSegment(xyz[kX], xyz[kY], xyz[kZ], zSeg, rSeg, quadrant)) {
121 return false;
122 }
123 const SolParam* par = &mSolPar[rSeg][zSeg][quadrant];
124 bxyz[kX] = CalcPol(par->parBxyz[kX], xyz[kX], xyz[kY], xyz[kZ]) * mFactorSol;
125 bxyz[kY] = CalcPol(par->parBxyz[kY], xyz[kX], xyz[kY], xyz[kZ]) * mFactorSol;
126 bxyz[kZ] = CalcPol(par->parBxyz[kZ], xyz[kX], xyz[kY], xyz[kZ]) * mFactorSol;
127 //
128 return true;
129}
130
131//_______________________________________________________________________
132bool MagFieldFast::GetBcomp(EDim comp, const double xyz[3], double& b) const
133{
134 // get field
135 int zSeg, rSeg, quadrant;
136 if (!GetSegment(xyz[kX], xyz[kY], xyz[kZ], zSeg, rSeg, quadrant)) {
137 return false;
138 }
139 const SolParam* par = &mSolPar[rSeg][zSeg][quadrant];
140 b = CalcPol(par->parBxyz[comp], xyz[kX], xyz[kY], xyz[kZ]) * mFactorSol;
141 //
142 return true;
143}
144
145//_______________________________________________________________________
146bool MagFieldFast::GetBcomp(EDim comp, const math_utils::Point3D<double> xyz, double& b) const
147{
148 // get field
149 int zSeg, rSeg, quadrant;
150 if (!GetSegment(xyz.X(), xyz.Y(), xyz.Z(), zSeg, rSeg, quadrant)) {
151 return false;
152 }
153 const SolParam* par = &mSolPar[rSeg][zSeg][quadrant];
154 b = CalcPol(par->parBxyz[comp], xyz.X(), xyz.Y(), xyz.Z()) * mFactorSol;
155 //
156 return true;
157}
158
159//_______________________________________________________________________
160bool MagFieldFast::GetBcomp(EDim comp, const math_utils::Point3D<float> xyz, float& b) const
161{
162 // get field
163 int zSeg, rSeg, quadrant;
164 if (!GetSegment(xyz.X(), xyz.Y(), xyz.Z(), zSeg, rSeg, quadrant)) {
165 return false;
166 }
167 const SolParam* par = &mSolPar[rSeg][zSeg][quadrant];
168 b = CalcPol(par->parBxyz[comp], xyz.X(), xyz.Y(), xyz.Z()) * mFactorSol;
169 //
170 return true;
171}
172
173//_______________________________________________________________________
174bool MagFieldFast::GetBcomp(EDim comp, const float xyz[3], float& b) const
175{
176 // get field
177 int zSeg, rSeg, quadrant;
178 if (!GetSegment(xyz[kX], xyz[kY], xyz[kZ], zSeg, rSeg, quadrant)) {
179 return false;
180 }
181 const SolParam* par = &mSolPar[rSeg][zSeg][quadrant];
182 b = CalcPol(par->parBxyz[comp], xyz[kX], xyz[kY], xyz[kZ]) * mFactorSol;
183 //
184 return true;
185}
186
187//_______________________________________________________________________
188bool MagFieldFast::Field(const float xyz[3], float bxyz[3]) const
189{
190 // get field
191 int zSeg, rSeg, quadrant;
192 if (!GetSegment(xyz[kX], xyz[kY], xyz[kZ], zSeg, rSeg, quadrant)) {
193 return false;
194 }
195 const SolParam* par = &mSolPar[rSeg][zSeg][quadrant];
196 bxyz[kX] = CalcPol(par->parBxyz[kX], xyz[kX], xyz[kY], xyz[kZ]) * mFactorSol;
197 bxyz[kY] = CalcPol(par->parBxyz[kY], xyz[kX], xyz[kY], xyz[kZ]) * mFactorSol;
198 bxyz[kZ] = CalcPol(par->parBxyz[kZ], xyz[kX], xyz[kY], xyz[kZ]) * mFactorSol;
199 //
200 return true;
201}
202
203//_______________________________________________________________________
204bool MagFieldFast::Field(const math_utils::Point3D<float> xyz, float bxyz[3]) const
205{
206 // get field
207 int zSeg, rSeg, quadrant;
208 if (!GetSegment(xyz.X(), xyz.Y(), xyz.Z(), zSeg, rSeg, quadrant)) {
209 return false;
210 }
211 const SolParam* par = &mSolPar[rSeg][zSeg][quadrant];
212 bxyz[kX] = CalcPol(par->parBxyz[kX], xyz.X(), xyz.Y(), xyz.Z()) * mFactorSol;
213 bxyz[kY] = CalcPol(par->parBxyz[kY], xyz.X(), xyz.Y(), xyz.Z()) * mFactorSol;
214 bxyz[kZ] = CalcPol(par->parBxyz[kZ], xyz.X(), xyz.Y(), xyz.Z()) * mFactorSol;
215 //
216 return true;
217}
218
219//_______________________________________________________________________
220bool MagFieldFast::Field(const math_utils::Point3D<double> xyz, double bxyz[3]) const
221{
222 // get field
223 int zSeg, rSeg, quadrant;
224 if (!GetSegment(xyz.X(), xyz.Y(), xyz.Z(), zSeg, rSeg, quadrant)) {
225 return false;
226 }
227 const SolParam* par = &mSolPar[rSeg][zSeg][quadrant];
228 bxyz[kX] = CalcPol(par->parBxyz[kX], xyz.X(), xyz.Y(), xyz.Z()) * mFactorSol;
229 bxyz[kY] = CalcPol(par->parBxyz[kY], xyz.X(), xyz.Y(), xyz.Z()) * mFactorSol;
230 bxyz[kZ] = CalcPol(par->parBxyz[kZ], xyz.X(), xyz.Y(), xyz.Z()) * mFactorSol;
231 //
232 return true;
233}
234
235//_______________________________________________________________________
236bool MagFieldFast::GetSegment(float x, float y, float z, int& zSeg, int& rSeg, int& quadrant) const
237{
238 // get segment of point location
239 const float zGridSpaceInv = 1.f / (kSolZMax * 2 / (float)kNSolZRanges);
240 zSeg = -1;
241 if (z < kSolZMax) {
242 if (z > -kSolZMax) {
243 zSeg = (z + kSolZMax) * zGridSpaceInv; // solenoid params
244 } else { // need to check dipole params
245 return false;
246 }
247 } else {
248 return false;
249 }
250 // R segment
251 float xx = x * x, yy = y * y, rr = xx + yy;
252 for (rSeg = 0; rSeg < kNSolRRanges; rSeg++) {
253 if (rr < kSolR2Max[rSeg]) {
254 break;
255 }
256 }
257 if (rSeg == kNSolRRanges) {
258 return false;
259 }
260 quadrant = GetQuadrant(x, y);
261 return true;
262}
ClassImp(o2::field::MagFieldFast)
Definition of the fast magnetic field parametrization MagFieldFast.
static const float kSolZMax
bool Field(const double xyz[3], double bxyz[3]) const
bool GetBcomp(EDim comp, const double xyz[3], double &b) const
int GetQuadrant(float x, float y) const
bool GetSegment(float x, float y, float z, int &zSeg, int &rSeg, int &quadrant) const
MagFieldFast(const std::string inpFName="")
float CalcPol(const float *cf, float x, float y, float z) const
bool LoadData(const std::string inpFName)
static const float kSolR2Max[kNSolRRanges]
GLint GLenum GLint x
Definition glcorearb.h:403
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLint y
Definition glcorearb.h:270
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
float parBxyz[kNDim][kNPolCoefs]
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"