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 TString sName(inpFName);
65 if (gSystem->ExpandPathName(sName)) {
66 LOG(fatal) << "Failed to expand file name " << inpFName;
67 }
68 std::ifstream in(sName.Data(), std::ifstream::in);
69 if (in.fail()) {
70 LOG(fatal) << "Failed to open file " << inpFName;
71 return false;
72 }
73 std::string line;
74 int valI, component = -1, nParams = 0, header[4] = {-1, -1, -1, -1}; // iR, iZ, iQuadrant, nVal
75 SolParam* curParam = nullptr;
76
77 while (std::getline(in, line)) {
78 if (line.empty() || line[0] == '#') {
79 continue; // empy or comment
80 }
81 std::stringstream ss(line);
82 int cnt = 0;
83
84 if (component < 0) {
85 while (cnt < 4 && (ss >> header[cnt++])) {
86 ;
87 }
88 if (cnt != 4) {
89 LOG(fatal) << "Wrong header " << line;
90 return false;
91 }
92 curParam = &mSolPar[header[0]][header[1]][header[2]];
93 } else {
94 while (cnt < header[3] && (ss >> curParam->parBxyz[component][cnt++])) {
95 ;
96 }
97 if (cnt != header[3]) {
98 LOG(fatal) << "Wrong data (npar=" << cnt << ") for param " << header[0] << " " << header[1] << " " << header[2]
99 << " " << header[3] << " " << line;
100 return false;
101 }
102 }
103 component++;
104 if (component > 2) {
105 component = -1; // next header expected
106 nParams++;
107 }
108 }
109 //
110 LOG(info) << "Loaded " << nParams << " params from " << inpFName;
111 if (nParams != kNSolRRanges * kNSolZRanges * kNQuadrants) {
112 LOG(fatal) << "Was expecting " << kNSolRRanges * kNSolZRanges * kNQuadrants << " params";
113 }
114 return true;
115}
116#endif // GPUCA_STANDALONE
117
118//_______________________________________________________________________
119bool MagFieldFast::Field(const double xyz[3], double bxyz[3]) const
120{
121 // get field
122 int zSeg, rSeg, quadrant;
123 if (!GetSegment(xyz[kX], xyz[kY], xyz[kZ], zSeg, rSeg, quadrant)) {
124 return false;
125 }
126 const SolParam* par = &mSolPar[rSeg][zSeg][quadrant];
127 bxyz[kX] = CalcPol(par->parBxyz[kX], xyz[kX], xyz[kY], xyz[kZ]) * mFactorSol;
128 bxyz[kY] = CalcPol(par->parBxyz[kY], xyz[kX], xyz[kY], xyz[kZ]) * mFactorSol;
129 bxyz[kZ] = CalcPol(par->parBxyz[kZ], xyz[kX], xyz[kY], xyz[kZ]) * mFactorSol;
130 //
131 return true;
132}
133
134//_______________________________________________________________________
135bool MagFieldFast::GetBcomp(EDim comp, const double xyz[3], double& b) const
136{
137 // get field
138 int zSeg, rSeg, quadrant;
139 if (!GetSegment(xyz[kX], xyz[kY], xyz[kZ], zSeg, rSeg, quadrant)) {
140 return false;
141 }
142 const SolParam* par = &mSolPar[rSeg][zSeg][quadrant];
143 b = CalcPol(par->parBxyz[comp], xyz[kX], xyz[kY], xyz[kZ]) * mFactorSol;
144 //
145 return true;
146}
147
148//_______________________________________________________________________
149bool MagFieldFast::GetBcomp(EDim comp, const math_utils::Point3D<double> xyz, double& b) const
150{
151 // get field
152 int zSeg, rSeg, quadrant;
153 if (!GetSegment(xyz.X(), xyz.Y(), xyz.Z(), zSeg, rSeg, quadrant)) {
154 return false;
155 }
156 const SolParam* par = &mSolPar[rSeg][zSeg][quadrant];
157 b = CalcPol(par->parBxyz[comp], xyz.X(), xyz.Y(), xyz.Z()) * mFactorSol;
158 //
159 return true;
160}
161
162//_______________________________________________________________________
163bool MagFieldFast::GetBcomp(EDim comp, const math_utils::Point3D<float> xyz, float& b) const
164{
165 // get field
166 int zSeg, rSeg, quadrant;
167 if (!GetSegment(xyz.X(), xyz.Y(), xyz.Z(), zSeg, rSeg, quadrant)) {
168 return false;
169 }
170 const SolParam* par = &mSolPar[rSeg][zSeg][quadrant];
171 b = CalcPol(par->parBxyz[comp], xyz.X(), xyz.Y(), xyz.Z()) * mFactorSol;
172 //
173 return true;
174}
175
176//_______________________________________________________________________
177bool MagFieldFast::GetBcomp(EDim comp, const float xyz[3], float& b) const
178{
179 // get field
180 int zSeg, rSeg, quadrant;
181 if (!GetSegment(xyz[kX], xyz[kY], xyz[kZ], zSeg, rSeg, quadrant)) {
182 return false;
183 }
184 const SolParam* par = &mSolPar[rSeg][zSeg][quadrant];
185 b = CalcPol(par->parBxyz[comp], xyz[kX], xyz[kY], xyz[kZ]) * mFactorSol;
186 //
187 return true;
188}
189
190//_______________________________________________________________________
191bool MagFieldFast::Field(const float xyz[3], float bxyz[3]) const
192{
193 // get field
194 int zSeg, rSeg, quadrant;
195 if (!GetSegment(xyz[kX], xyz[kY], xyz[kZ], zSeg, rSeg, quadrant)) {
196 return false;
197 }
198 const SolParam* par = &mSolPar[rSeg][zSeg][quadrant];
199 bxyz[kX] = CalcPol(par->parBxyz[kX], xyz[kX], xyz[kY], xyz[kZ]) * mFactorSol;
200 bxyz[kY] = CalcPol(par->parBxyz[kY], xyz[kX], xyz[kY], xyz[kZ]) * mFactorSol;
201 bxyz[kZ] = CalcPol(par->parBxyz[kZ], xyz[kX], xyz[kY], xyz[kZ]) * mFactorSol;
202 //
203 return true;
204}
205
206//_______________________________________________________________________
207bool MagFieldFast::Field(const math_utils::Point3D<float> xyz, float bxyz[3]) const
208{
209 // get field
210 int zSeg, rSeg, quadrant;
211 if (!GetSegment(xyz.X(), xyz.Y(), xyz.Z(), zSeg, rSeg, quadrant)) {
212 return false;
213 }
214 const SolParam* par = &mSolPar[rSeg][zSeg][quadrant];
215 bxyz[kX] = CalcPol(par->parBxyz[kX], xyz.X(), xyz.Y(), xyz.Z()) * mFactorSol;
216 bxyz[kY] = CalcPol(par->parBxyz[kY], xyz.X(), xyz.Y(), xyz.Z()) * mFactorSol;
217 bxyz[kZ] = CalcPol(par->parBxyz[kZ], xyz.X(), xyz.Y(), xyz.Z()) * mFactorSol;
218 //
219 return true;
220}
221
222//_______________________________________________________________________
223bool MagFieldFast::Field(const math_utils::Point3D<double> xyz, double bxyz[3]) const
224{
225 // get field
226 int zSeg, rSeg, quadrant;
227 if (!GetSegment(xyz.X(), xyz.Y(), xyz.Z(), zSeg, rSeg, quadrant)) {
228 return false;
229 }
230 const SolParam* par = &mSolPar[rSeg][zSeg][quadrant];
231 bxyz[kX] = CalcPol(par->parBxyz[kX], xyz.X(), xyz.Y(), xyz.Z()) * mFactorSol;
232 bxyz[kY] = CalcPol(par->parBxyz[kY], xyz.X(), xyz.Y(), xyz.Z()) * mFactorSol;
233 bxyz[kZ] = CalcPol(par->parBxyz[kZ], xyz.X(), xyz.Y(), xyz.Z()) * mFactorSol;
234 //
235 return true;
236}
237
238//_______________________________________________________________________
239bool MagFieldFast::GetSegment(float x, float y, float z, int& zSeg, int& rSeg, int& quadrant) const
240{
241 // get segment of point location
242 const float zGridSpaceInv = 1.f / (kSolZMax * 2 / (float)kNSolZRanges);
243 zSeg = -1;
244 if (z < kSolZMax) {
245 if (z > -kSolZMax) {
246 zSeg = (z + kSolZMax) * zGridSpaceInv; // solenoid params
247 } else { // need to check dipole params
248 return false;
249 }
250 } else {
251 return false;
252 }
253 // R segment
254 float xx = x * x, yy = y * y, rr = xx + yy;
255 for (rSeg = 0; rSeg < kNSolRRanges; rSeg++) {
256 if (rr < kSolR2Max[rSeg]) {
257 break;
258 }
259 }
260 if (rSeg == kNSolRRanges) {
261 return false;
262 }
263 quadrant = GetQuadrant(x, y);
264 return true;
265}
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"