BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
KalFitAlg/src/coil/Bfield.cxx
Go to the documentation of this file.
1//
2// Bfield class
3//
4// 27-Mar-1999 : KUNIYA Toshio
5// Enabled QCS compornent
6//
7// 21-Feb-1999 : KUNIYA Toshio
8// Keeping comatibility, Bfield class is modified.
9// No longer fortran common block is used for bfield map.
10// Access functions are prepared for fortran call.
11//
12
13#include "KalFitAlg/coil/Bfield.h"
14
15#include "CLHEP/Geometry/Point3D.h"
16#include "CLHEP/Matrix/Matrix.h"
17#include "CLHEP/Matrix/SymMatrix.h"
18#include "CLHEP/Matrix/Vector.h"
19#include "CLHEP/Vector/ThreeVector.h"
20#ifndef ENABLE_BACKWARDS_COMPATIBILITY
21typedef HepGeom::Point3D<double> HepPoint3D;
22#endif
23
24using CLHEP::Hep3Vector;
25using CLHEP::HepMatrix;
26using CLHEP::HepSymMatrix;
27using CLHEP::HepVector;
28
29// prototype of file scoped function to call fortran routine
30// ... read B field map with ID = imap from a file
31/*wangdy
32extern "C" {
33 extern void geo_coil_readmap_
34 (int *imap, double (*bz)[399], double (*br)[399], double (*bphi)[399]);
35 extern void geo_coil_readqcsrmap_
36 (double (*bzqr)[163], double (*brqr)[163], double (*bphiqr)[163]);
37 extern void geo_coil_readqcslmap_
38 (double (*bzrl)[51][52], double (*brql)[51][52], double (*bphiqr)[51][52]);
39}
40 */
41
43
44Bfield* Bfield::_field[200] = { 0 }; // All of 200 elements are initialized.
45
47 if ( !_field[imap] ) _field[imap] = new Bfield( imap );
48 return _field[imap];
49}
50
51Bfield::Bfield( int imap ) {
52 std::cout << std::endl;
53 std::cout << "***********************************************" << std::endl;
54 std::cout << " Bfield class MAP ID = " << imap << std::endl;
55 std::cout << " #### R < 174 cm, -152 < Z < 246 cm #### " << std::endl;
56 std::cout << " C++ version 1.00 " << std::endl;
57 std::cout << "***********************************************" << std::endl;
58
59 const double uniformBz[10] = { 0, 15, 14.5, 14, 13, 12.5, 12, 11, 10, 15.5 };
60
61 //...initialization
62 for ( int i = 0; i < 175; i++ )
63 for ( int j = 0; j < 399; j++ )
64 {
65 _Bz[i][j] = 0;
66 _Br[i][j] = 0;
67 _Bz[i][j] = 0;
68 if ( i < 101 && j < 163 )
69 {
70 _BzQR[i][j] = 0;
71 _BrQR[i][j] = 0;
72 _BphiQR[i][j] = 0;
73 }
74 }
75 for ( int i = 0; i < 17; i++ )
76 for ( int j = 0; j < 51; j++ )
77 for ( int k = 0; k < 52; k++ )
78 {
79 _BzQL[i][j][k] = 0;
80 _BrQL[i][j][k] = 0;
81 _BphiQL[i][j][k] = 0;
82 }
83
84 //...
85 _fieldID = imap;
86
87 //...read B field map
88
89 if ( imap < 10 )
90 {
91 //
92 // uniform B field map
93 //
94 m_Bx = 0.;
95 m_By = 0.;
96 m_Bz = uniformBz[imap];
97 m_Bfld.setX( (double)m_Bx );
98 m_Bfld.setY( (double)m_By );
99 m_Bfld.setZ( (double)m_Bz );
100 std::cout << "Bfield class >> creating uniform B field with id = " << imap;
101 std::cout << ", (Bx,By,Bz) = " << m_Bfld << std::endl;
102 }
103 else
104 {
105 //
106 // non-uniform B field map
107 //
108 std::cout << "Bfield class >> loading non-uniform B field map" << std::endl;
109 /*wangdy
110 geo_coil_readmap_(&imap, _Bz, _Br, _Bphi);
111 if( _fieldID == 21 ) {
112 std::cout << "Bfield class >> loading QCS" << std::endl;
113 geo_coil_readqcsrmap_(_BzQR,_BrQR, _BphiQR);
114 geo_coil_readqcslmap_(_BzQL,_BrQL, _BphiQL);
115 }
116 */
117 updateCache( 0., 0., 0. );
118 }
119 std::cout << std::endl;
120}
121
122// Bfield::~Bfield(){};
123
124const Hep3Vector& Bfield::fieldMap( double x, double y, double z ) const {
125
126 if ( _fieldID > 10 )
127 {
128 if ( x != m_x || y != m_y || z != m_z ) updateCache( x, y, z );
129 }
130
131 return m_Bfld;
132}
133
134const Hep3Vector& Bfield::fieldMap( const HepPoint3D& xyz ) const {
135
136 if ( _fieldID > 10 )
137 {
138 double x = xyz.x();
139 double y = xyz.y();
140 double z = xyz.z();
141 if ( x != m_x || y != m_y || z != m_z ) updateCache( x, y, z );
142 }
143
144 return m_Bfld;
145}
146
147void Bfield::fieldMap( double* position, double* field ) {
148 if ( _fieldID > 10 )
149 {
150 double x = position[0];
151 double y = position[1];
152 double z = position[2];
153 if ( x != m_x || y != m_y || z != m_z ) updateCache( x, y, z );
154 }
155 field[0] = m_Bx;
156 field[1] = m_By;
157 field[2] = m_Bz;
158 return;
159}
160
161double Bfield::bx( double x, double y, double z ) const {
162
163 if ( _fieldID > 10 )
164 {
165 if ( x != m_x || y != m_y || z != m_z ) updateCache( x, y, z );
166 }
167
168 return m_Bx;
169}
170
171double Bfield::by( double x, double y, double z ) const {
172
173 if ( _fieldID > 10 )
174 {
175 if ( x != m_x || y != m_y || z != m_z ) updateCache( x, y, z );
176 }
177
178 return m_By;
179}
180
181double Bfield::bz( double x, double y, double z ) const {
182
183 if ( _fieldID > 10 )
184 {
185 if ( x != m_x || y != m_y || z != m_z ) updateCache( x, y, z );
186 }
187
188 return m_Bz;
189}
190
191double Bfield::bx( const HepPoint3D& xyz ) const {
192
193 if ( _fieldID > 10 )
194 {
195 double x = xyz.x();
196 double y = xyz.y();
197 double z = xyz.z();
198 if ( x != m_x || y != m_y || z != m_z ) updateCache( x, y, z );
199 }
200
201 return m_Bx;
202}
203
204double Bfield::by( const HepPoint3D& xyz ) const {
205
206 if ( _fieldID > 10 )
207 {
208 double x = xyz.x();
209 double y = xyz.y();
210 double z = xyz.z();
211 if ( x != m_x || y != m_y || z != m_z ) updateCache( x, y, z );
212 }
213
214 return m_By;
215}
216
217double Bfield::bz( const HepPoint3D& xyz ) const {
218
219 if ( _fieldID > 10 )
220 {
221 double x = xyz.x();
222 double y = xyz.y();
223 double z = xyz.z();
224 if ( x != m_x || y != m_y || z != m_z ) updateCache( x, y, z );
225 }
226 return m_Bz;
227}
228
229void Bfield::updateCache( double x, double y, double z ) const {
230
231 // this function is only for non-uniform B field
232
233 if ( _fieldID <= 10 ) return;
234
235 double PI = 3.14159;
236
237 //...
238 double r = (double)sqrt( (double)x * (double)x + (double)y * (double)y );
239 double phi = (double)atan2( (double)y, (double)x );
240
241 //... [cm] --> [mm]
242 double zmm = z * 10.;
243 double rmm = r * 10.;
244 //... make index
245 int tz = (int)( ( zmm + 1520. ) / 10. );
246 int tr = (int)( rmm / 10. );
247
248 //...
249 double bz = 0., br = 0., bphi = 0.;
250
251 if ( zmm >= -1520. && zmm < 2460. && rmm >= 0. && rmm < 1740. )
252 {
253 if ( _Bz[tr][tz] && _Bz[tr][tz + 1] )
254 {
255 double pz = ( zmm + 1520. ) / 10. - (double)tz;
256 double pr = rmm / 10. - (double)tr;
257
258 //...
259 bz = ( _Bz[tr][tz] * ( 1. - pz ) + _Bz[tr][tz + 1] * pz ) * ( 1. - pr ) +
260 ( _Bz[tr + 1][tz] * ( 1. - pz ) + _Bz[tr + 1][tz + 1] * pz ) * pr;
261 //...
262 br = ( _Br[tr][tz] * ( 1. - pz ) + _Br[tr][tz + 1] * pz ) * ( 1. - pr ) +
263 ( _Br[tr + 1][tz] * ( 1. - pz ) + _Br[tr + 1][tz + 1] * pz ) * pr;
264 //...
265 bphi = ( _Bphi[tr][tz] * ( 1. - pz ) + _Bphi[tr][tz + 1] * pz ) * ( 1. - pr ) +
266 ( _Bphi[tr + 1][tz] * ( 1. - pz ) + _Bphi[tr + 1][tz + 1] * pz ) * pr;
267
268 if ( _fieldID == 21 )
269 {
270 //
271 // QCS Right
272 //
273 if ( zmm >= 800. && zmm < 2420. && rmm < 1000. )
274 {
275 int tqz = (int)( ( zmm - 800. ) / 10. );
276 bz += ( ( ( _BzQR[tr][tqz] * ( 1. - pz ) + _BzQR[tr][tqz + 1] * pz ) * ( 1. - pr ) +
277 ( _BzQR[tr + 1][tqz] * ( 1. - pz ) + _BzQR[tr + 1][tqz + 1] * pz ) * pr ) *
278 (double)sin( (double)( 2. * phi + 2. / 180. * (double)PI ) ) );
279 br += ( ( ( _BrQR[tr][tqz] * ( 1. - pz ) + _BrQR[tr][tqz + 1] * pz ) * ( 1. - pr ) +
280 ( _BrQR[tr + 1][tqz] * ( 1. - pz ) + _BrQR[tr + 1][tqz + 1] * pz ) * pr ) *
281 (double)sin( (double)( 2. * phi + 2. / 180. * (double)PI ) ) );
282 bphi += ( ( ( _BphiQR[tr][tqz] * ( 1. - pz ) + _BphiQR[tr][tqz + 1] * pz ) *
283 ( 1. - pr ) +
284 ( _BphiQR[tr + 1][tqz] * ( 1. - pz ) + _BphiQR[tr + 1][tqz + 1] * pz ) *
285 pr ) *
286 (double)cos( (double)( 2. * phi + 2. / 180. * (double)PI ) ) );
287 }
288 //
289 // QCS Left
290 //
291 if ( zmm <= -500. && zmm > -1520. && rmm < 1000. )
292 {
293 int tqz = (int)( ( -zmm - 500. ) / 20. );
294 int tqr = (int)( tr / 2. );
295 pz = ( pz + (double)( tz - (int)( tz / 2. ) * 2. ) ) / 2.;
296 pr = ( pr + (double)( tr - tqr * 2 ) ) / 2.;
297 double f = 1.;
298 // if( phi < (PI/2.) && phi >= (-PI/2.) ) {
299 // phi = PI-phi;
300 // f =-1.;
301 // } else if( phi < -PI/2. ) {
302 // phi = 2.*PI+phi;
303 // }
304 // double pphi = ( phi-PI/2. )/(11.25/180.*PI);
305 double phi_tmp = phi;
306 if ( phi_tmp < ( PI / 2. ) && phi_tmp >= ( -PI / 2. ) )
307 {
308 phi_tmp = PI - phi_tmp;
309 f = -1.;
310 }
311 else if ( phi_tmp < -PI / 2. ) { phi_tmp = 2. * PI + phi_tmp; }
312 double pphi = ( phi_tmp - PI / 2. ) / ( 11.25 / 180. * PI );
313 int tphi = (int)pphi;
314 pphi -= (double)tphi;
315 if ( tphi >= 16 ) tphi -= 16;
316
317 bz += f *
318 ( ( ( _BzQL[tphi][tqr][tqz] * ( 1. - pz ) + _BzQL[tphi][tqr][tqz + 1] * pz ) *
319 ( 1 - pr ) +
320 ( _BzQL[tphi][tqr + 1][tqz] * ( 1. - pz ) +
321 _BzQL[tphi][tqr + 1][tqz + 1] * pz ) *
322 pr ) *
323 ( 1. - pphi ) +
324 ( ( _BzQL[tphi + 1][tqr][tqz] * ( 1. - pz ) +
325 _BzQL[tphi + 1][tqr][tqz + 1] * pz ) *
326 ( 1. - pr ) +
327 ( _BzQL[tphi + 1][tqr + 1][tqz] * ( 1. - pz ) +
328 _BzQL[tphi + 1][tqr + 1][tqz + 1] * pz ) *
329 pr ) *
330 pphi );
331 br += f *
332 ( ( ( _BrQL[tphi][tqr][tqz] * ( 1. - pz ) + _BrQL[tphi][tqr][tqz + 1] * pz ) *
333 ( 1. - pr ) +
334 ( _BrQL[tphi][tqr + 1][tqz] * ( 1. - pz ) +
335 _BrQL[tphi][tqr + 1][tqz + 1] * pz ) *
336 pr ) *
337 ( 1 - pphi ) +
338 ( ( _BrQL[tphi + 1][tqr][tqz] * ( 1. - pz ) +
339 _BrQL[tphi + 1][tqr][tqz + 1] * pz ) *
340 ( 1. - pr ) +
341 ( _BrQL[tphi + 1][tqr + 1][tqz] * ( 1. - pz ) +
342 _BrQL[tphi + 1][tqr + 1][tqz + 1] * pz ) *
343 pr ) *
344 pphi );
345 bphi += f * ( ( ( _BphiQL[tphi][tqr][tqz] * ( 1. - pz ) +
346 _BphiQL[tphi][tqr][tqz + 1] * pz ) *
347 ( 1. - pr ) +
348 ( _BphiQL[tphi][tqr + 1][tqz] * ( 1. - pz ) +
349 _BphiQL[tphi][tqr + 1][tqz + 1] * pz ) *
350 pr ) *
351 ( 1. - pphi ) +
352 ( ( _BphiQL[tphi + 1][tqr][tqz] * ( 1. - pz ) +
353 _BphiQL[tphi + 1][tqr][tqz + 1] * pz ) *
354 ( 1. - pr ) +
355 ( _BphiQL[tphi + 1][tqr + 1][tqz] * ( 1. - pz ) +
356 _BphiQL[tphi + 1][tqr + 1][tqz + 1] * pz ) *
357 pr ) *
358 pphi );
359 }
360 }
361 }
362 else
363 {
364 bz = 0.;
365 br = 0.;
366 bphi = 0.;
367 }
368 }
369 else if ( zmm >= -1520. && zmm <= 2460. && rmm <= 0. && rmm <= 1740. )
370 {
371 if ( tz == 246 ) tz = tz - 1;
372 if ( tr == 174 ) tr = tr - 1;
373 double pz = ( zmm + 1520. ) / 10. - (double)tz;
374 double pr = rmm / 10. - (double)tr;
375 bz = ( _Bz[tr][tz] * ( 1. - pz ) + _Bz[tr][tz + 1] * pz ) * ( 1. - pr ) +
376 ( _Bz[tr + 1][tz] * ( 1. - pz ) + _Bz[tr + 1][tz + 1] * pz ) * pr;
377
378 br = ( _Br[tr][tz] * ( 1. - pz ) + _Br[tr][tz + 1] * pz ) * ( 1. - pr ) +
379 ( _Br[tr + 1][tz] * ( 1. - pz ) + _Br[tr + 1][tz + 1] * pz ) * pr;
380
381 bphi = ( _Bphi[tr][tz] * ( 1. - pz ) + _Bphi[tr][tz + 1] * pz ) * ( 1. - pr ) +
382 ( _Bphi[tr + 1][tz] * ( 1. - pz ) + _Bphi[tr + 1][tz + 1] * pz ) * pr;
383 }
384 else
385 {
386 bz = 0.;
387 br = 0.;
388 bphi = 0.;
389 }
390
391 //... Set B field
392 double Bmag_xy = (double)sqrt( br * br + bphi * bphi );
393 double Bphi_rp = (double)atan2( (double)bphi, (double)br );
394 m_Bx = Bmag_xy * (double)cos( (double)phi + Bphi_rp ) / 1000.;
395 m_By = Bmag_xy * (double)sin( (double)phi + Bphi_rp ) / 1000.;
396 // m_Bx = br * (double)cos((double)phi)/1000.;
397 // m_By = br * (double)sin((double)phi)/1000.;
398 m_Bz = bz / 1000.;
399 m_x = x;
400 m_y = y;
401 m_z = z;
402 m_Bfld.setX( (double)m_Bx );
403 m_Bfld.setY( (double)m_By );
404 m_Bfld.setZ( (double)m_Bz );
405}
406
407//
408//... Fortran callable access functions to Bfield class.
409//
410
411// initialize bfield map
412extern "C" void init_bfield_( int* imap ) {
413 // create Bfiled map ID = imap
414 // Bfield *thisMap = Bfield::getBfield(*imap);
415 (void)Bfield::getBfield( *imap );
416 // It is OK even though 'thisMap' losts its scope at here.
417 // Because address of field map is not deleted from memory
418 // due to static linkaged Bfield class.
419 return;
420}
421
422// retrieving B field corresponding to the POSition
423extern "C" void get_bfield_( int* imap, double* pos, double* field, int* error ) {
424 Bfield* thisMap = Bfield::getBfield( *imap );
425 // std::cout << " > accessing Bfield class from fortran routine." << std::endl;
426 if ( thisMap != 0 )
427 {
428 thisMap->fieldMap( pos, field );
429 *error = 0;
430 }
431 else *error = 1;
432 return;
433}
HepGeom::Point3D< double > HepPoint3D
TFile f("ana_bhabha660a_dqa_mcPat_zy_old.root")
Double_t x[10]
#define PI
DOUBLE_PRECISION tr[3]
void get_bfield_(int *imap, double *pos, double *field, int *error)
void init_bfield_(int *imap)
static Bfield * getBfield(int)
returns Bfield object.
Bfield(int)
Constructor, Destructor.
double bz(double x, double y, double z) const
const Hep3Vector & fieldMap(double x, double y, double z) const
returns B field
double by(double x, double y, double z) const
double bx(double x, double y, double z) const
returns an element of B field
static Bfield * getBfield(int)
returns Bfield object.