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