ATLAS Offline Software
Loading...
Searching...
No Matches
MagField::AtlasFieldMap Class Reference

Map for magnetic field. More...

#include <AtlasFieldMap.h>

Collaboration diagram for MagField::AtlasFieldMap:

Public Member Functions

 AtlasFieldMap ()=default
 ~AtlasFieldMap ()
bool initializeMap (TFile *rootfile, float solenoidCurrent, float toroidCurrent)
const BFieldZonefindBFieldZone (double z, double r, double phi) const
const BFieldMeshZRgetBFieldMesh () const
bool solenoidOn () const
 status of the magnets
bool toroidOn () const
float solenoidCurrent () const
float toroidCurrent () const
int solenoidZoneId () const

Private Member Functions

AtlasFieldMapoperator= (AtlasFieldMap &&other)=delete
 AtlasFieldMap (const AtlasFieldMap &other)=delete
AtlasFieldMapoperator= (const AtlasFieldMap &other)=delete
 AtlasFieldMap (AtlasFieldMap &&other)=delete
BFieldZonefindZoneSlow (double z, double r, double phi)
int read_packed_data (std::istream &input, std::vector< int > &data) const
int read_packed_int (std::istream &input, int &n) const
void buildLUT ()
void buildZR ()
int memSize () const
 approximate memory footprint in bytes

Private Attributes

std::string m_filename
 Data Members.
float m_solenoidCurrent { 0 }
float m_toroidCurrent { 0 }
int m_solenoidZoneId { -1 }
std::vector< BFieldZonem_zone
BFieldMeshZRm_meshZR { nullptr }
std::vector< double > m_edge [3]
std::vector< int > m_edgeLUT [3]
double m_invq [3] {}
std::vector< const BFieldZone * > m_zoneLUT
double m_zmin { 0 }
double m_zmax { 0 }
int m_nz { 0 }
double m_rmax { 0 }
int m_nr { 0 }
int m_nphi { 0 }
bool m_mapIsInitialized { false }

Detailed Description

Map for magnetic field.

Author
R.D.Schaffer -at- cern.ch

Definition at line 38 of file AtlasFieldMap.h.

Constructor & Destructor Documentation

◆ AtlasFieldMap() [1/3]

MagField::AtlasFieldMap::AtlasFieldMap ( )
default

◆ ~AtlasFieldMap()

MagField::AtlasFieldMap::~AtlasFieldMap ( )
inline

Definition at line 42 of file AtlasFieldMap.h.

42{ delete m_meshZR; }
BFieldMeshZR * m_meshZR

◆ AtlasFieldMap() [2/3]

MagField::AtlasFieldMap::AtlasFieldMap ( const AtlasFieldMap & other)
privatedelete

◆ AtlasFieldMap() [3/3]

MagField::AtlasFieldMap::AtlasFieldMap ( AtlasFieldMap && other)
privatedelete

Member Function Documentation

◆ buildLUT()

void MagField::AtlasFieldMap::buildLUT ( )
private

Definition at line 226 of file AtlasFieldMap.cxx.

227{
228
229 // make lists of (z,r,phi) edges of all zones
230 for (int j = 0; j < 3; j++) { // z, r, phi
231 for (unsigned i = 0; i < m_zone.size(); i++) {
232 double e[2];
233 e[0] = m_zone[i].min(j);
234 e[1] = m_zone[i].max(j);
235 for (int k = 0; k < 2; k++) {
236 // for the phi edge, fit into [-pi,pi]
237 if (j == 2 && e[k] > M_PI) {
238 e[k] -= 2.0 * M_PI;
239 }
240 m_edge[j].push_back(e[k]);
241 }
242 }
243 // add -pi and +pi to phi, just in case
244 m_edge[2].push_back(-M_PI);
245 m_edge[2].push_back(M_PI);
246 // sort
247 sort(m_edge[j].begin(), m_edge[j].end());
248 // remove duplicates
249 // must do this by hand to allow small differences due to rounding in phi
250 int i = 0;
251 for (unsigned k = 1; k < m_edge[j].size(); k++) {
252 if (fabs(m_edge[j][i] - m_edge[j][k]) < 1.0e-6) {
253 continue;
254 }
255 m_edge[j][++i] = m_edge[j][k];
256 }
257 m_edge[j].resize(i + 1);
258 // because of the small differences allowed in the comparison above,
259 // m_edge[][] values do not exactly match the m_zone[] boundaries.
260 // we have to fix this up in order to avoid invalid field values
261 // very close to the zone boundaries.
262 for (unsigned i = 0; i < m_zone.size(); i++) {
263 for (unsigned k = 0; k < m_edge[j].size(); k++) {
264 if (fabs(m_zone[i].min(j) - m_edge[j][k]) < 1.0e-6) {
265 m_zone[i].adjustMin(j, m_edge[j][k]);
266 }
267 if (fabs(m_zone[i].max(j) - m_edge[j][k]) < 1.0e-6) {
268 m_zone[i].adjustMax(j, m_edge[j][k]);
269 }
270 }
271 }
272 }
273 // build LUT for edge finding
274 for (int j = 0; j < 3; j++) { // z, r, phi
275 // find the size of the smallest interval
276 const double width = m_edge[j].back() - m_edge[j].front();
277 double q(width);
278 for (unsigned i = 0; i < m_edge[j].size() - 1; i++) {
279 q = std::min(q, m_edge[j][i + 1] - m_edge[j][i]);
280 }
281 // find the number of cells in the LUT
282 int n = int(width / q) + 1;
283 q = width / (n + 0.5);
284 m_invq[j] = 1.0 / q;
285 n++;
286 // fill the LUT
287 int m = 0;
288 for (int i = 0; i < n; i++) { // index of LUT
289 if (q * i + m_edge[j].front() > m_edge[j][m + 1]) {
290 m++;
291 }
292 m_edgeLUT[j].push_back(m);
293 }
294 }
295 // store min/max for speedup
296 m_zmin = m_edge[0].front();
297 m_zmax = m_edge[0].back();
298 m_rmax = m_edge[1].back();
299 // build LUT for zone finding
300 m_nz = m_edge[0].size() - 1;
301 m_nr = m_edge[1].size() - 1;
302 m_nphi = m_edge[2].size() - 1;
303 m_zoneLUT.reserve(m_nz * m_nr * m_nphi);
304 for (int iz = 0; iz < m_nz; iz++) {
305 const double z = 0.5 * (m_edge[0][iz] + m_edge[0][iz + 1]);
306 for (int ir = 0; ir < m_nr; ir++) {
307 const double r = 0.5 * (m_edge[1][ir] + m_edge[1][ir + 1]);
308 for (int iphi = 0; iphi < m_nphi; iphi++) {
309 const double phi = 0.5 * (m_edge[2][iphi] + m_edge[2][iphi + 1]);
310 const BFieldZone* zone = findZoneSlow(z, r, phi);
311 m_zoneLUT.push_back(zone);
312 }
313 }
314 }
315 // build LUT in each zone
316 for (unsigned i = 0; i < m_zone.size(); i++) {
317 m_zone[i].buildLUT();
318 }
319}
#define M_PI
Scalar phi() const
phi method
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
const double width
#define z
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
std::vector< BFieldZone > m_zone
std::vector< double > m_edge[3]
BFieldZone * findZoneSlow(double z, double r, double phi)
std::vector< const BFieldZone * > m_zoneLUT
std::vector< int > m_edgeLUT[3]
int ir
counter of the current depth
Definition fastadd.cxx:49
int r
Definition globals.cxx:22

◆ buildZR()

void MagField::AtlasFieldMap::buildZR ( )
private

Definition at line 325 of file AtlasFieldMap.cxx.

326{
327 // delete if previously allocated
328 delete m_meshZR;
329
330 // find the solenoid zone
331 // solenoid zone always covers 100 < R < 1000, but not necessarily R < 100
332 // so we search for the zone that contains a point at R = 200, Z = 0
333 const BFieldZone* solezone = findBFieldZone(0.0, 200.0, 0.0);
334
335 // instantiate the new ZR map with the same external coverage as the solenoid
336 // zone make sure R = 0 is covered
337 m_meshZR =
338 new BFieldMeshZR(solezone->zmin(), solezone->zmax(), 0.0, solezone->rmax());
339
340 // reserve the right amount of memroy
341 unsigned nmeshz = solezone->nmesh(0);
342 unsigned nmeshr = solezone->nmesh(1);
343 if (solezone->rmin() > 0.0) {
344 nmeshr++;
345 }
346 m_meshZR->reserve(nmeshz, nmeshr);
347
348 // copy the mesh structure in z/r
349 // take care of R = 0 first
350 if (solezone->rmin() > 0.0) {
351 m_meshZR->appendMesh(1, 0.0);
352 }
353 // copy the rest
354 for (int i = 0; i < 2; i++) { // z, r
355 for (unsigned j = 0; j < solezone->nmesh(i); j++) { // loop over mesh points
356 m_meshZR->appendMesh(i, solezone->mesh(i, j));
357 }
358 }
359
360 // loop through the mesh and compute the phi-averaged field
361 for (unsigned iz = 0; iz < m_meshZR->nmesh(0); iz++) { // loop over z
362 double z = m_meshZR->mesh(0, iz);
363 for (unsigned ir = 0; ir < m_meshZR->nmesh(1); ir++) { // loop over r
364 double r = m_meshZR->mesh(1, ir);
365 const int nphi(200); // number of phi slices to average
366 double Br = 0.0;
367 double Bz = 0.0;
368 for (int iphi = 0; iphi < nphi; iphi++) {
369 double phi = double(iphi) / double(nphi) * 2. * M_PI;
370 double xyz[3];
371 xyz[0] = r * cos(phi);
372 xyz[1] = r * sin(phi);
373 xyz[2] = z;
374 double B[3];
375 solezone->getB(xyz, B, nullptr);
376 Br += B[0] * cos(phi) + B[1] * sin(phi);
377 Bz += B[2];
378 }
379 Br *= 1.0 / double(nphi);
380 Bz *= 1.0 / double(nphi);
381 m_meshZR->appendField(BFieldVectorZR(Bz, Br));
382 }
383 }
384
385 // build the internal LUT
386 m_meshZR->buildLUT();
387}
#define xyz
void getB(const double *ATH_RESTRICT xyz, double *ATH_RESTRICT B, double *ATH_RESTRICT deriv=nullptr) const
get the bfield given a point in xyz
double rmax() const
maximum in r
unsigned nmesh(size_t axis) const
number of cells along each axis = 0 (z), 1 (r), 2 (phi)
double zmax() const
maximum in z
double mesh(size_t axis, size_t index) const
coordinate along axis (0 (z), 1 (r), 2 (phi)) of the cell at index (0 to nmesh-1)
double zmin() const
minimum in z
double rmin() const
minimun in r
const BFieldZone * findBFieldZone(double z, double r, double phi) const

◆ findBFieldZone()

const BFieldZone * MagField::AtlasFieldMap::findBFieldZone ( double z,
double r,
double phi ) const

◆ findZoneSlow()

BFieldZone * MagField::AtlasFieldMap::findZoneSlow ( double z,
double r,
double phi )
private

Definition at line 210 of file AtlasFieldMap.cxx.

211{
212 for (int j = m_zone.size() - 1; j >= 0; --j) {
213 if (m_zone[j].inside(z, r, phi)) {
214 return &m_zone[j];
215 }
216 }
217 return nullptr;
218}

◆ getBFieldMesh()

const BFieldMeshZR * MagField::AtlasFieldMap::getBFieldMesh ( ) const

◆ initializeMap()

bool MagField::AtlasFieldMap::initializeMap ( TFile * rootfile,
float solenoidCurrent,
float toroidCurrent )

Definition at line 26 of file AtlasFieldMap.cxx.

29{
30 // save currents
33
34 // open the tree
35 TTree* tree = (TTree*)rootfile->Get("BFieldMap");
36 // if ( tree == 0 ) {
37 // // no tree
38 // ATH_MSG_ERROR("readMap(): TTree 'BFieldMap' does not exist in ROOT
39 // field map"); return StatusCode::FAILURE;
40 // }
41 int id;
42 double zmin;
43 double zmax;
44 double rmin;
45 double rmax;
46 double phimin;
47 double phimax;
48 double bscale;
49 int ncond;
50 bool* finite;
51 double* p1x;
52 double* p1y;
53 double* p1z;
54 double* p2x;
55 double* p2y;
56 double* p2z;
57 double* curr;
58 int nmeshz;
59 int nmeshr;
60 int nmeshphi;
61 double* meshz;
62 double* meshr;
63 double* meshphi;
64 int nfield;
65 short* fieldz;
66 short* fieldr;
67 short* fieldphi;
68 // define the fixed-sized branches first
69 tree->SetBranchAddress("id", &id);
70 tree->SetBranchAddress("zmin", &zmin);
71 tree->SetBranchAddress("zmax", &zmax);
72 tree->SetBranchAddress("rmin", &rmin);
73 tree->SetBranchAddress("rmax", &rmax);
74 tree->SetBranchAddress("phimin", &phimin);
75 tree->SetBranchAddress("phimax", &phimax);
76 tree->SetBranchAddress("bscale", &bscale);
77 tree->SetBranchAddress("ncond", &ncond);
78 tree->SetBranchAddress("nmeshz", &nmeshz);
79 tree->SetBranchAddress("nmeshr", &nmeshr);
80 tree->SetBranchAddress("nmeshphi", &nmeshphi);
81 tree->SetBranchAddress("nfield", &nfield);
82 // prepare arrays - need to know the maximum sizes
83 // open the tree of buffer sizes (may not exist in old maps)
84 unsigned maxcond(0);
85
86 unsigned maxmeshz(0);
87
88 unsigned maxmeshr(0);
89
90 unsigned maxmeshphi(0);
91
92 unsigned maxfield(0);
93 TTree* tmax = (TTree*)rootfile->Get("BFieldMapSize");
94 if (tmax != nullptr) {
95 tmax->SetBranchAddress("maxcond", &maxcond);
96 tmax->SetBranchAddress("maxmeshz", &maxmeshz);
97 tmax->SetBranchAddress("maxmeshr", &maxmeshr);
98 tmax->SetBranchAddress("maxmeshphi", &maxmeshphi);
99 tmax->SetBranchAddress("maxfield", &maxfield);
100 tmax->GetEntry(0);
101 } else { // "BFieldMapSize" tree does not exist
102 for (int i = 0; i < tree->GetEntries(); i++) {
103 tree->GetEntry(i);
104 maxcond = std::max(maxcond, (unsigned)ncond);
105 maxmeshz = std::max(maxmeshz, (unsigned)nmeshz);
106 maxmeshr = std::max(maxmeshr, (unsigned)nmeshr);
107 maxmeshphi = std::max(maxmeshphi, (unsigned)nmeshphi);
108 maxfield = std::max(maxfield, (unsigned)nfield);
109 }
110 }
111 finite = new bool[maxcond];
112 p1x = new double[maxcond];
113 p1y = new double[maxcond];
114 p1z = new double[maxcond];
115 p2x = new double[maxcond];
116 p2y = new double[maxcond];
117 p2z = new double[maxcond];
118 curr = new double[maxcond];
119 meshz = new double[maxmeshz];
120 meshr = new double[maxmeshr];
121 meshphi = new double[maxmeshphi];
122 fieldz = new short[maxfield];
123 fieldr = new short[maxfield];
124 fieldphi = new short[maxfield];
125 // define the variable length branches
126 tree->SetBranchAddress("finite", finite);
127 tree->SetBranchAddress("p1x", p1x);
128 tree->SetBranchAddress("p1y", p1y);
129 tree->SetBranchAddress("p1z", p1z);
130 tree->SetBranchAddress("p2x", p2x);
131 tree->SetBranchAddress("p2y", p2y);
132 tree->SetBranchAddress("p2z", p2z);
133 tree->SetBranchAddress("curr", curr);
134 tree->SetBranchAddress("meshz", meshz);
135 tree->SetBranchAddress("meshr", meshr);
136 tree->SetBranchAddress("meshphi", meshphi);
137 tree->SetBranchAddress("fieldz", fieldz);
138 tree->SetBranchAddress("fieldr", fieldr);
139 tree->SetBranchAddress("fieldphi", fieldphi);
140
141 // reserve the space for m_zone so that it won't move as the vector grows
142 m_zone.reserve(tree->GetEntries());
143 // read all tree and store
144 for (int i = 0; i < tree->GetEntries(); i++) {
145 tree->GetEntry(i);
146 BFieldZone z(id, zmin, zmax, rmin, rmax, phimin, phimax, bscale);
147 m_zone.push_back(z);
148 m_zone.back().reserve(nmeshz, nmeshr, nmeshphi);
149 for (int j = 0; j < ncond; j++) {
150 double p1[3];
151
152 double p2[3];
153 p1[0] = p1x[j];
154 p1[1] = p1y[j];
155 p1[2] = p1z[j];
156 p2[0] = p2x[j];
157 p2[1] = p2y[j];
158 p2[2] = p2z[j];
159 BFieldCond cond(finite[j], p1, p2, curr[j]);
160 m_zone.back().appendCond(cond);
161 }
162 for (int j = 0; j < nmeshz; j++) {
163 m_zone.back().appendMesh(0, meshz[j]);
164 }
165 for (int j = 0; j < nmeshr; j++) {
166 m_zone.back().appendMesh(1, meshr[j]);
167 }
168 for (int j = 0; j < nmeshphi; j++) {
169 m_zone.back().appendMesh(2, meshphi[j]);
170 }
171 for (int j = 0; j < nfield; j++) {
172 BFieldVector<short> field(fieldz[j], fieldr[j], fieldphi[j]);
173 m_zone.back().appendField(field);
174 }
175 }
176 // clean up
177 tree->Delete();
178 delete[] finite;
179 delete[] p1x;
180 delete[] p1y;
181 delete[] p1z;
182 delete[] p2x;
183 delete[] p2y;
184 delete[] p2z;
185 delete[] curr;
186 delete[] meshz;
187 delete[] meshr;
188 delete[] meshphi;
189 delete[] fieldz;
190 delete[] fieldr;
191 delete[] fieldphi;
192 // build the LUTs
193 buildLUT();
194 buildZR();
195
196 // setup id for solenoid bfield zone
197 BFieldZone* solezone = findZoneSlow(0.0, 0.0, 0.0);
198 if (solezone) {
199 m_solenoidZoneId = solezone->id();
200 }
201
202 return true;
203}
int id() const
float toroidCurrent() const
float solenoidCurrent() const
static std::vector< std::string > rootfile
Definition iLumiCalc.h:30
TChain * tree

◆ memSize()

int MagField::AtlasFieldMap::memSize ( ) const
private

approximate memory footprint in bytes

Definition at line 393 of file AtlasFieldMap.cxx.

394{
395 int size = 0;
396 size += sizeof(BFieldCache);
397 size += sizeof(BFieldCacheZR);
398 for (unsigned i = 0; i < m_zone.size(); i++) {
399 size += m_zone[i].memSize();
400 }
401 for (int i = 0; i < 3; i++) {
402 size += sizeof(double) * m_edge[i].capacity();
403 size += sizeof(int) * m_edgeLUT[i].capacity();
404 }
405 size += sizeof(BFieldZone*) * m_zoneLUT.capacity();
406 if (m_meshZR) {
407 size += m_meshZR->memSize();
408 }
409 return size;
410}

◆ operator=() [1/2]

AtlasFieldMap & MagField::AtlasFieldMap::operator= ( AtlasFieldMap && other)
privatedelete

◆ operator=() [2/2]

AtlasFieldMap & MagField::AtlasFieldMap::operator= ( const AtlasFieldMap & other)
privatedelete

◆ read_packed_data()

int MagField::AtlasFieldMap::read_packed_data ( std::istream & input,
std::vector< int > & data ) const
private

◆ read_packed_int()

int MagField::AtlasFieldMap::read_packed_int ( std::istream & input,
int & n ) const
private

◆ solenoidCurrent()

float MagField::AtlasFieldMap::solenoidCurrent ( ) const
inline

Definition at line 60 of file AtlasFieldMap.h.

60{ return m_solenoidCurrent; }

◆ solenoidOn()

bool MagField::AtlasFieldMap::solenoidOn ( ) const
inline

status of the magnets

Definition at line 57 of file AtlasFieldMap.h.

57{ return solenoidCurrent() > 0.0; }

◆ solenoidZoneId()

int MagField::AtlasFieldMap::solenoidZoneId ( ) const
inline

Definition at line 62 of file AtlasFieldMap.h.

62{ return m_solenoidZoneId; }

◆ toroidCurrent()

float MagField::AtlasFieldMap::toroidCurrent ( ) const
inline

Definition at line 61 of file AtlasFieldMap.h.

61{ return m_toroidCurrent; }

◆ toroidOn()

bool MagField::AtlasFieldMap::toroidOn ( ) const
inline

Definition at line 58 of file AtlasFieldMap.h.

58{ return toroidCurrent() > 0.0; }

Member Data Documentation

◆ m_edge

std::vector<double> MagField::AtlasFieldMap::m_edge[3]
private

Definition at line 99 of file AtlasFieldMap.h.

◆ m_edgeLUT

std::vector<int> MagField::AtlasFieldMap::m_edgeLUT[3]
private

Definition at line 100 of file AtlasFieldMap.h.

◆ m_filename

std::string MagField::AtlasFieldMap::m_filename
private

Data Members.

Definition at line 85 of file AtlasFieldMap.h.

◆ m_invq

double MagField::AtlasFieldMap::m_invq[3] {}
private

Definition at line 101 of file AtlasFieldMap.h.

101{}; // 1/stepsize in m_edgeLUT

◆ m_mapIsInitialized

bool MagField::AtlasFieldMap::m_mapIsInitialized { false }
private

Definition at line 110 of file AtlasFieldMap.h.

110{ false };

◆ m_meshZR

BFieldMeshZR* MagField::AtlasFieldMap::m_meshZR { nullptr }
private

Definition at line 96 of file AtlasFieldMap.h.

96{ nullptr };

◆ m_nphi

int MagField::AtlasFieldMap::m_nphi { 0 }
private

Definition at line 109 of file AtlasFieldMap.h.

109{ 0 }; // number of phi bins in zoneLUT

◆ m_nr

int MagField::AtlasFieldMap::m_nr { 0 }
private

Definition at line 108 of file AtlasFieldMap.h.

108{ 0 }; // number of r bins in zoneLUT

◆ m_nz

int MagField::AtlasFieldMap::m_nz { 0 }
private

Definition at line 106 of file AtlasFieldMap.h.

106{ 0 }; // number of z bins in zoneLUT

◆ m_rmax

double MagField::AtlasFieldMap::m_rmax { 0 }
private

Definition at line 107 of file AtlasFieldMap.h.

107{ 0 }; // maximum r

◆ m_solenoidCurrent

float MagField::AtlasFieldMap::m_solenoidCurrent { 0 }
private

Definition at line 88 of file AtlasFieldMap.h.

88{ 0 }; // solenoid current in ampere

◆ m_solenoidZoneId

int MagField::AtlasFieldMap::m_solenoidZoneId { -1 }
private

Definition at line 90 of file AtlasFieldMap.h.

90{ -1 }; // solenoid zone id

◆ m_toroidCurrent

float MagField::AtlasFieldMap::m_toroidCurrent { 0 }
private

Definition at line 89 of file AtlasFieldMap.h.

89{ 0 }; // toroid current in ampere

◆ m_zmax

double MagField::AtlasFieldMap::m_zmax { 0 }
private

Definition at line 105 of file AtlasFieldMap.h.

105{ 0 }; // maximum z

◆ m_zmin

double MagField::AtlasFieldMap::m_zmin { 0 }
private

Definition at line 104 of file AtlasFieldMap.h.

104{ 0 }; // minimum z

◆ m_zone

std::vector<BFieldZone> MagField::AtlasFieldMap::m_zone
private

Definition at line 93 of file AtlasFieldMap.h.

◆ m_zoneLUT

std::vector<const BFieldZone*> MagField::AtlasFieldMap::m_zoneLUT
private

Definition at line 102 of file AtlasFieldMap.h.


The documentation for this class was generated from the following files: