Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DMagneticFieldMapFineMesh.cc
Go to the documentation of this file.
1 // $Id$
2 //
3 // File: DMagneticFieldMapFineMesh.cc
4 
5 #include <unistd.h>
6 #include <sys/stat.h>
7 #include <cmath>
8 using namespace std;
9 #ifdef HAVE_EVIO
10 #include <evioFileChannel.hxx>
11 #include <evioUtil.hxx>
12 using namespace evio;
13 #endif
14 
16 
17 #include "JANA/JException.h"
18 
19 #include <DAQ/HDEVIO.h>
20 
21 
22 //---------------------------------
23 // DMagneticFieldMapFineMesh (Constructor)
24 //---------------------------------
25 DMagneticFieldMapFineMesh::DMagneticFieldMapFineMesh(JApplication *japp, int32_t runnumber, string namepath)
26 {
27  jcalib = japp->GetJCalibration(runnumber);
28  jresman = japp->GetJResourceManager(runnumber);
29 
30  JParameterManager *jparms = japp->GetJParameterManager();
31  jparms->SetDefaultParameter("BFIELD_MAP", namepath);
32 
33  int Npoints = ReadMap(namepath, runnumber);
34  if(Npoints==0){
35  _DBG_<<"Error getting JCalibration object for magnetic field!"<<endl;
36  japp->Quit();
37  }
38 
39  GetFineMeshMap(namepath,runnumber);
40 }
41 
42 //---------------------------------
43 // DMagneticFieldMapFineMesh (Constructor)
44 //---------------------------------
45 DMagneticFieldMapFineMesh::DMagneticFieldMapFineMesh(JCalibration *jcalib, string namepath,int32_t runnumber)
46 {
47  this->jcalib = jcalib;
48  GetFineMeshMap(namepath,runnumber);
49 }
50 
51 //---------------------------------
52 // ~DMagneticFieldMapFineMesh (Destructor)
53 //---------------------------------
55 {
56 
57 }
58 
59 //---------------------------------
60 // ReadMap
61 //---------------------------------
62 int DMagneticFieldMapFineMesh::ReadMap(string namepath, int32_t runnumber, string context)
63 {
64  /// Read the magnetic field map in from the calibration database.
65  /// This will read in the map and figure out the number of grid
66  /// points in each direction (x,y, and z) and the range in each.
67  /// The gradiant of the field is calculated for all but the most
68  /// exterior points and saved to use in later calls to GetField(...).
69 
70  // Read in map from calibration database. This should really be
71  // built into a run-dependent geometry framework, but for now
72  // we do it this way.
73  if(!jcalib){
74  jerr << "ERROR: jcalib pointer is NULL in DMagneticFieldMapFineMesh::ReadMap() !" << endl;
75  return 0;
76  }
77 
78  jout<<"Reading Magnetic field map from "<<namepath<<" ..."<<endl;
79  vector< vector<float> > Bmap;
80 
81  // Newer maps are stored as resources while older maps were stored
82  // directly in the calib DB. Here, we hardwire in the names of the old
83  // maps that are stored directly in the DB so we know whether to
84  // get them via the resource manager or not.
85  vector<string> old_maps;
86  old_maps.push_back("Magnets/Solenoid/solenoid_1500_poisson_20090814_01");
87  old_maps.push_back("Magnets/Solenoid/solenoid_1050_poisson_20091123_02");
88  old_maps.push_back("Magnets/Solenoid/solenoid_1500_poisson_20090814_01");
89  old_maps.push_back("Magnets/Solenoid/solenoid_1500_20090312-2");
90  old_maps.push_back("Magnets/Solenoid/solenoid_1600_20090312-2");
91  old_maps.push_back("Magnets/Solenoid/solenoid_1500kinked");
92 
93  bool is_old_map = false;
94  for(unsigned int i=0; i<old_maps.size(); i++){
95  if(old_maps[i] == namepath){
96 
97  // This map is stored directly in the calibration DB.
98  jcalib->Get(namepath, Bmap);
99 
100  is_old_map = true;
101  break;
102  }
103  }
104 
105  if(!is_old_map){
106  // This map is NOT stored directly in the calibration DB.
107  // Try getting it as a JANA resource.
108  jresman->Get(namepath, Bmap);
109  }
110 
111 
112  jout<<Bmap.size()<<" entries found (";
113 
114  // The map should be on a grid with equal spacing in x,y, and z.
115  // Here we want to determine the number of points in each of these
116  // dimensions and the range. Note that all of or maps right now are
117  // 2-dimensional with extent only in x and z.
118  // The easiest way to do this is to use a map<float, int> to make a
119  // histogram of the entries by using the key to hold the extent
120  // so that the number of entries will be equal to the number of
121  // different values.
122  map<float, int> xvals;
123  map<float, int> yvals;
124  map<float, int> zvals;
125  xmin = ymin = zmin = 1.0E6;
126  xmax = ymax = zmax = -1.0E6;
127  for(unsigned int i=0; i<Bmap.size(); i++){
128  vector<float> &a = Bmap[i];
129  float &x = a[0];
130  float &y = a[1];
131  float &z = a[2];
132 
133  // Convert from inches to cm and shift in z by 26 inches to align
134  // the origin with the GEANT defined one.
135  x *= 2.54;
136  y *= 2.54;
137  z = (z-0.0)*2.54; // Removed 26" offset 6/22/2009 DL
138 
139  xvals[x] = 1;
140  yvals[y] = 1;
141  zvals[z] = 1;
142  if(x<xmin)xmin=x;
143  if(y<ymin)ymin=y;
144  if(z<zmin)zmin=z;
145  if(x>xmax)xmax=x;
146  if(y>ymax)ymax=y;
147  if(z>zmax)zmax=z;
148  }
149  Nx = xvals.size();
150  Ny = yvals.size();
151  Nz = zvals.size();
152  cout<<" Nx="<<Nx;
153  cout<<" Ny="<<Ny;
154  cout<<" Nz="<<Nz;
155  cout<<" ) at 0x"<<hex<<(unsigned long)this<<dec<<endl;
156 
157  // Create 3D vector so we can index the values by [x][y][z]
158  vector<DBfieldPoint_t> zvec(Nz);
159  vector< vector<DBfieldPoint_t> > yvec;
160  for(int i=0; i<Ny; i++)yvec.push_back(zvec);
161  for(int i=0; i<Nx; i++)Btable.push_back(yvec);
162 
163  // Distance between map points for r and z
164  dx = (xmax-xmin)/(double)(Nx-1);
165  dy = (ymax-ymin)/(double)((Ny < 2)? 1 : Ny-1);
166  dz = (zmax-zmin)/(double)(Nz-1);
167 
168  one_over_dx=1./dx;
169  one_over_dz=1./dz;
170 
171  // Copy values into Btable
172  for(unsigned int i=0; i<Bmap.size(); i++){
173  vector<float> &a = Bmap[i];
174  int xindex = (int)floor((a[0]-xmin+dx/2.0)/dx); // the +dx/2.0 guarantees against round-off errors
175  int yindex = (int)(Ny<2 ? 0:floor((a[1]-ymin+dy/2.0)/dy));
176  int zindex = (int)floor((a[2]-zmin+dz/2.0)/dz);
177  DBfieldPoint_t *b = &Btable[xindex][yindex][zindex];
178  b->x = a[0];
179  b->y = a[1];
180  b->z = a[2];
181  b->Bx = a[3];
182  b->By = a[4];
183  b->Bz = a[5];
184  }
185 
186  // Calculate gradient at every point in the map.
187  // The derivatives are calculated wrt to the *index* of the
188  // field map, not the physical unit. This is because
189  // the fractions used in interpolation are fractions
190  // between indices.
191  for(int index_x=0; index_x<Nx; index_x++){
192  int index_x0 = index_x - (index_x>0 ? 1:0);
193  int index_x1 = index_x + (index_x<Nx-1 ? 1:0);
194  for(int index_z=1; index_z<Nz-1; index_z++){
195  int index_z0 = index_z - (index_z>0 ? 1:0);
196  int index_z1 = index_z + (index_z<Nz-1 ? 1:0);
197 
198  // Right now, all of our maps are 2-D with no y extent
199  // so we comment out the following for-loop and hardwire
200  // the index_y values to zero
201  //for(int index_y=1; index_y<Ny-1; index_y++){
202  // int index_y0 = index_y-1;
203  // int index_y1 = index_y+1;
204  if(Ny>1){
205  _DBG_<<"Field map appears to be 3 dimensional. Code is currently"<<endl;
206  _DBG_<<"unable to handle this. Exiting..."<<endl;
207  exit(-1);
208  }else{
209  int index_y=0;
210  /*
211  int index_y0, index_y1;
212  index_y=index_y0=index_y1=0;
213  */
214  double d_index_x=double(index_x1-index_x0);
215  double d_index_z=double(index_z1-index_z0);
216 
217  DBfieldPoint_t *Bx0 = &Btable[index_x0][index_y][index_z];
218  DBfieldPoint_t *Bx1 = &Btable[index_x1][index_y][index_z];
219  //DBfieldPoint_t *By0 = &Btable[index_x][index_y0][index_z];
220  //DBfieldPoint_t *By1 = &Btable[index_x][index_y1][index_z];
221  DBfieldPoint_t *Bz0 = &Btable[index_x][index_y][index_z0];
222  DBfieldPoint_t *Bz1 = &Btable[index_x][index_y][index_z1];
223 
224  DBfieldPoint_t *g = &Btable[index_x][index_y][index_z];
225  g->dBxdx = (Bx1->Bx - Bx0->Bx)/d_index_x;
226  //g->dBxdy = (By1->Bx - By0->Bx)/(double)(index_y1-index_y0);
227  g->dBxdz = (Bz1->Bx - Bz0->Bx)/d_index_z;
228 
229  g->dBydx = (Bx1->By - Bx0->By)/d_index_x;
230  //g->dBydy = (By1->By - By0->By)/(double)(index_y1-index_y0);
231  g->dBydz = (Bz1->By - Bz0->By)/d_index_z;
232 
233  g->dBzdx = (Bx1->Bz - Bx0->Bz)/d_index_x;
234  //g->dBzdy = (By1->Bz - By0->Bz)/(double)(index_y1-index_y0);
235  g->dBzdz = (Bz1->Bz - Bz0->Bz)/d_index_z;
236 
237  DBfieldPoint_t *B11 = &Btable[index_x1][index_y][index_z1];
238  DBfieldPoint_t *B01 = &Btable[index_x0][index_y][index_z1];
239  DBfieldPoint_t *B10 = &Btable[index_x1][index_y][index_z0];
240  DBfieldPoint_t *B00 = &Btable[index_x0][index_y][index_z0];
241 
242  g->dBxdxdz=(B11->Bx - B01->Bx - B10->Bx + B00->Bx)/d_index_x/d_index_z;
243  g->dBzdxdz=(B11->Bz - B01->Bz - B10->Bz + B00->Bz)/d_index_x/d_index_z;
244  }
245  }
246  }
247 
248  return Bmap.size();
249 }
250 
251 // Use bicubic interpolation to find the field at the point (x,y).
252 //See Numerical Recipes in C (2nd ed.), pp.125-127.
253 void DMagneticFieldMapFineMesh::GetFieldBicubic(double x,double y,double z,
254  double &Bx_,double &By_,
255  double &Bz_) const{
256  // table of weight factors for bicubic interpolation
257  static const int wt[16][16]=
258  { {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
259  {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
260  {-3, 0, 0, 3, 0, 0, 0, 0,-2, 0, 0,-1, 0, 0, 0, 0},
261  {2, 0, 0,-2, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0},
262  {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
263  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
264  {0, 0, 0, 0,-3, 0, 0, 3, 0, 0, 0, 0,-2, 0, 0,-1},
265  {0, 0, 0, 0, 2, 0, 0,-2, 0, 0, 0, 0, 1, 0, 0, 1},
266  {-3,3, 0, 0,-2,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
267  {0, 0, 0, 0, 0, 0, 0, 0,-3, 3, 0, 0,-2,-1, 0, 0},
268  {9,-9, 9,-9, 6, 3,-3,-6, 6,-6,-3, 3, 4, 2, 1, 2},
269  {-6,6,-6, 6,-4,-2, 2, 4,-3, 3, 3,-3,-2,-1,-1,-2},
270  {2,-2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
271  {0, 0, 0, 0, 0, 0, 0, 0, 2,-2, 0, 0, 1, 1, 0, 0},
272  {-6, 6,-6,6,-3,-3, 3, 3,-4, 4, 2,-2,-2,-2,-1,-1},
273  {4,-4, 4,-4, 2, 2,-2,-2, 2,-2,-2, 2, 1, 1, 1, 1}};
274  double temp[16];
275  double cl[16],coeff[4][4];
276 
277  // radial distance and radial component of bfield
278  double r = sqrt(x*x + y*y);
279  double Br_=0.;
280 
281  // If the point (x,y,z) is outside the fine-mesh grid, interpolate
282  // on the coarse grid
283  //if (true){
284  if (z<zminFine || z>=zmaxFine || r>=rmaxFine){
285  // Get closest indices for this point
286  int index_x = (int)floor((r-xmin)*one_over_dx + 0.5);
287  //if(index_x<0 || index_x>=Nx)return;
288  if (index_x>=Nx) return;
289  else if (index_x<0) index_x=0;
290  int index_z = (int)floor((z-zmin)*one_over_dz + 0.5);
291  if(index_z<0 || index_z>=Nz)return;
292 
293  int index_y = 0;
294 
295  int i, j, k, m=0;
296  int index_x1 = index_x + (index_x<Nx-1 ? 1:0);
297  int index_z1 = index_z + (index_z<Nz-1 ? 1:0);
298 
299  // Pointers to magnetic field structure
300  const DBfieldPoint_t *B00 = &Btable[index_x][index_y][index_z];
301  const DBfieldPoint_t *B01 = &Btable[index_x][index_y][index_z1];
302  const DBfieldPoint_t *B11 = &Btable[index_x1][index_y][index_z1];
303  const DBfieldPoint_t *B10 = &Btable[index_x1][index_y][index_z];
304 
305  // First compute the interpolation for Br
306  temp[0]=B00->Bx;
307  temp[1]=B01->Bx;
308  temp[2]=B11->Bx;
309  temp[3]=B10->Bx;
310 
311  temp[8]=B00->dBxdx;
312  temp[9]=B01->dBxdx;
313  temp[10]=B11->dBxdx;
314  temp[11]=B10->dBxdx;
315 
316  temp[4]=B00->dBxdz;
317  temp[5]=B01->dBxdz;
318  temp[6]=B11->dBxdz;
319  temp[7]=B10->dBxdz;
320 
321  temp[12]=B00->dBxdxdz;
322  temp[13]=B01->dBxdxdz;
323  temp[14]=B11->dBxdxdz;
324  temp[15]=B10->dBxdxdz;
325 
326  for (i=0;i<16;i++){
327  double tmp2=0.0;
328  for (k=0;k<16;k++) tmp2+=wt[i][k]*temp[k];
329  cl[i]=tmp2;
330  }
331  for (i=0;i<4;i++)
332  for (j=0;j<4;j++) coeff[i][j]=cl[m++];
333 
334  double t=(z - B00->z)*one_over_dz;
335  double u=(r - B00->x)*one_over_dx;
336  for (i=3;i>=0;i--){
337  Br_=t*Br_+((coeff[i][3]*u+coeff[i][2])*u+coeff[i][1])*u+coeff[i][0];
338  }
339 
340  // Next compute the interpolation for Bz
341  temp[0]=B00->Bz;
342  temp[1]=B01->Bz;
343  temp[2]=B11->Bz;
344  temp[3]=B10->Bz;
345 
346  temp[8]=B00->dBzdx;
347  temp[9]=B01->dBzdx;
348  temp[10]=B11->dBzdx;
349  temp[11]=B10->dBzdx;
350 
351  temp[4]=B00->dBzdz;
352  temp[5]=B01->dBzdz;
353  temp[6]=B11->dBzdz;
354  temp[7]=B10->dBzdz;
355 
356  temp[12]=B00->dBzdxdz;
357  temp[13]=B01->dBzdxdz;
358  temp[14]=B11->dBzdxdz;
359  temp[15]=B10->dBzdxdz;
360 
361  for (i=0;i<16;i++){
362  double tmp2=0.0;
363  for (k=0;k<16;k++) tmp2+=wt[i][k]*temp[k];
364  cl[i]=tmp2;
365  }
366  m=0;
367  for (i=0;i<4;i++)
368  for (j=0;j<4;j++) coeff[i][j]=cl[m++];
369 
370  Bz_=0.;
371  for (i=3;i>=0;i--){
372  Bz_=t*Bz_+((coeff[i][3]*u+coeff[i][2])*u+coeff[i][1])*u+coeff[i][0];
373  }
374  }
375  else{ // otherwise do a simple lookup in the fine-mesh table
376  unsigned int indr=(unsigned int)floor((r-rminFine)*rscale);
377  unsigned int indz=(unsigned int)floor((z-zminFine)*zscale);
378 
379  Bz_=mBfine[indr][indz].Bz;
380  Br_=mBfine[indr][indz].Br;
381  // printf("Bz Br %f %f\n",Bz,Br);
382  }
383 
384  // Convert r back to x,y components
385  double cos_theta = x/r;
386  double sin_theta = y/r;
387  if(r==0.0){
388  cos_theta=1.0;
389  sin_theta=0.0;
390  }
391  // Rotate back into phi direction
392  Bx_=Br_*cos_theta;
393  By_=Br_*sin_theta;
394 
395 }
396 
397 // Use bicubic interpolation to find the field and field gradient at the point
398 // (x,y). See Numerical Recipes in C (2nd ed.), pp.125-127.
399 void DMagneticFieldMapFineMesh::InterpolateField(double r,double z,double &Br,
400  double &Bz,double &dBrdr,
401  double &dBrdz,double &dBzdr,
402  double &dBzdz) const{
403  // table of weight factors for bicubic interpolation
404  static const int wt[16][16]=
405  { {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
406  {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
407  {-3, 0, 0, 3, 0, 0, 0, 0,-2, 0, 0,-1, 0, 0, 0, 0},
408  {2, 0, 0,-2, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0},
409  {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
410  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
411  {0, 0, 0, 0,-3, 0, 0, 3, 0, 0, 0, 0,-2, 0, 0,-1},
412  {0, 0, 0, 0, 2, 0, 0,-2, 0, 0, 0, 0, 1, 0, 0, 1},
413  {-3,3, 0, 0,-2,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
414  {0, 0, 0, 0, 0, 0, 0, 0,-3, 3, 0, 0,-2,-1, 0, 0},
415  {9,-9, 9,-9, 6, 3,-3,-6, 6,-6,-3, 3, 4, 2, 1, 2},
416  {-6,6,-6, 6,-4,-2, 2, 4,-3, 3, 3,-3,-2,-1,-1,-2},
417  {2,-2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
418  {0, 0, 0, 0, 0, 0, 0, 0, 2,-2, 0, 0, 1, 1, 0, 0},
419  {-6, 6,-6,6,-3,-3, 3, 3,-4, 4, 2,-2,-2,-2,-1,-1},
420  {4,-4, 4,-4, 2, 2,-2,-2, 2,-2,-2, 2, 1, 1, 1, 1}};
421  double temp[16];
422  double cl[16],coeff[4][4];
423 
424  // Get closest indices for the point (r,z)
425  int index_x = (int)floor((r-xmin)*one_over_dx + 0.5);
426  if (index_x>=Nx) return;
427  else if (index_x<0) index_x=0;
428  int index_z = (int)floor((z-zmin)*one_over_dz + 0.5);
429  if(index_z<0 || index_z>=Nz)return;
430  int index_y = 0;
431 
432  int i, j, k, m=0;
433  int index_x1 = index_x + (index_x<Nx-1 ? 1:0);
434  int index_z1 = index_z + (index_z<Nz-1 ? 1:0);
435 
436  // Pointers to magnetic field structure
437  const DBfieldPoint_t *B00 = &Btable[index_x][index_y][index_z];
438  const DBfieldPoint_t *B01 = &Btable[index_x][index_y][index_z1];
439  const DBfieldPoint_t *B11 = &Btable[index_x1][index_y][index_z1];
440  const DBfieldPoint_t *B10 = &Btable[index_x1][index_y][index_z];
441 
442  // First compute the interpolation for Br
443  temp[0]=B00->Bx;
444  temp[1]=B01->Bx;
445  temp[2]=B11->Bx;
446  temp[3]=B10->Bx;
447 
448  temp[8]=B00->dBxdx;
449  temp[9]=B01->dBxdx;
450  temp[10]=B11->dBxdx;
451  temp[11]=B10->dBxdx;
452 
453  temp[4]=B00->dBxdz;
454  temp[5]=B01->dBxdz;
455  temp[6]=B11->dBxdz;
456  temp[7]=B10->dBxdz;
457 
458  temp[12]=B00->dBxdxdz;
459  temp[13]=B01->dBxdxdz;
460  temp[14]=B11->dBxdxdz;
461  temp[15]=B10->dBxdxdz;
462 
463  for (i=0;i<16;i++){
464  double tmp2=0.0;
465  for (k=0;k<16;k++) tmp2+=wt[i][k]*temp[k];
466  cl[i]=tmp2;
467  }
468  for (i=0;i<4;i++)
469  for (j=0;j<4;j++) coeff[i][j]=cl[m++];
470 
471  double t=(z - B00->z)*one_over_dz;
472  double u=(r - B00->x)*one_over_dx;
473  Br=dBrdr=dBrdz=0.;
474  for (i=3;i>=0;i--){
475  double c3u=coeff[i][3]*u;
476  Br=t*Br+((c3u+coeff[i][2])*u+coeff[i][1])*u+coeff[i][0];
477  dBrdr=t*dBrdr+(3.*c3u+2.*coeff[i][2])*u+coeff[i][1];
478  dBrdz=u*dBrdz+(3.*coeff[3][i]*t+2.*coeff[2][i])*t+coeff[1][i];
479  }
480  dBrdr/=dx;
481  dBrdz/=dz;
482 
483  // Next compute the interpolation for Bz
484  temp[0]=B00->Bz;
485  temp[1]=B01->Bz;
486  temp[2]=B11->Bz;
487  temp[3]=B10->Bz;
488 
489  temp[8]=B00->dBzdx;
490  temp[9]=B01->dBzdx;
491  temp[10]=B11->dBzdx;
492  temp[11]=B10->dBzdx;
493 
494  temp[4]=B00->dBzdz;
495  temp[5]=B01->dBzdz;
496  temp[6]=B11->dBzdz;
497  temp[7]=B10->dBzdz;
498 
499  temp[12]=B00->dBzdxdz;
500  temp[13]=B01->dBzdxdz;
501  temp[14]=B11->dBzdxdz;
502  temp[15]=B10->dBzdxdz;
503 
504  for (i=0;i<16;i++){
505  double tmp2=0.0;
506  for (k=0;k<16;k++) tmp2+=wt[i][k]*temp[k];
507  cl[i]=tmp2;
508  }
509  m=0;
510  for (i=0;i<4;i++)
511  for (j=0;j<4;j++) coeff[i][j]=cl[m++];
512 
513  Bz=dBzdr=dBzdz=0.;
514  for (i=3;i>=0;i--){
515  double c3u=coeff[i][3]*u;
516  Bz=t*Bz+((c3u+coeff[i][2])*u+coeff[i][1])*u+coeff[i][0];
517  dBzdr=t*dBzdr+(3.*c3u+2.*coeff[i][2])*u+coeff[i][1];
518  dBzdz=u*dBzdz+(3.*coeff[3][i]*t+2.*coeff[2][i])*t+coeff[1][i];
519  }
520  dBzdr/=dx;
521  dBzdz/=dz;
522 }
523 
524 // Find the field and field gradient at the point (x,y,z).
526  double &Bx_,double &By_,
527  double &Bz_,
528  double &dBxdx_,
529  double &dBxdy_,
530  double &dBxdz_,
531  double &dBydx_,
532  double &dBydy_,
533  double &dBydz_,
534  double &dBzdx_,
535  double &dBzdy_,
536  double &dBzdz_) const{
537  // radial distance
538  double r = sqrt(x*x + y*y);
539  if (r>xmax || z>zmax || z<zmin){
540  Bx_=0.0,By_=0.0,Bz_=0.0;
541  dBxdx_=0.0,dBxdy_=0.0,dBxdz_=0.0;
542  dBydx_=0.0,dBydy_=0.0,dBydz_=0.0;
543  dBzdx_=0.0,dBzdy_=0.0,dBzdz_=0.0;
544  return;
545  }
546 
547  // radial component of B and gradient
548  double Br_=0.,dBrdx_=0.,dBrdz_=0.;
549  // Initialize z-component
550  Bz_=0.;
551 
552  // If the point (x,y,z) is outside the fine-mesh grid, interpolate
553  // on the coarse grid
554  //if (true){
555  if (z<zminFine || z>=zmaxFine || r>=rmaxFine){
556  //InterpolateField(r,z,Br_,Bz_,dBrdx_,dBrdz_,dBzdx_,dBzdz_);
557  // Get closest indices for this point
558  int index_x = static_cast<int>(r*one_over_dx);
559  int index_z = static_cast<int>((z-zmin)*one_over_dz);
560  int index_y = 0;
561 
562  if(index_x>=0 && index_x<Nx && index_z>=0 && index_z<Nz){
563  const DBfieldPoint_t *B = &Btable[index_x][index_y][index_z];
564 
565  // Fractional distance between map points.
566  double ur = (r - B->x)*one_over_dx;
567  double uz = (z - B->z)*one_over_dz;
568 
569  // Use gradient to project grid point to requested position
570  Br_ = B->Bx+B->dBxdx*ur+B->dBxdz*uz;
571  Bz_ = B->Bz+B->dBzdx*ur+B->dBzdz*uz;
572  dBrdx_=B->dBxdx;
573  dBrdz_=B->dBxdz;
574  dBzdx_=B->dBzdx;
575  dBzdz_=B->dBzdz;
576  }
577  }
578  else{ // otherwise do a simple lookup in the fine-mesh table
579  unsigned int indr=static_cast<unsigned int>(r*rscale);
580  unsigned int indz=static_cast<unsigned int>((z-zminFine)*zscale);
581  const DBfieldCylindrical_t *field=&mBfine[indr][indz];
582 
583  Bz_=field->Bz;
584  Br_=field->Br;
585  dBrdx_=field->dBrdr;
586  dBrdz_=field->dBrdz;
587  dBzdz_=field->dBzdz;
588  dBzdx_=field->dBzdr;
589 
590  // printf("Bz Br %f %f\n",Bz,Br);
591  }
592 
593 
594  // Convert r back to x,y components
595  double cos_theta = x/r;
596  double sin_theta = y/r;
597  if(r==0.0){
598  cos_theta=1.0;
599  sin_theta=0.0;
600  }
601  // Rotate back into phi direction
602  Bx_=Br_*cos_theta;
603  By_=Br_*sin_theta;
604 
605  dBxdx_ =dBrdx_*cos_theta*cos_theta;
606  dBxdy_ =dBrdx_*cos_theta*sin_theta;
607  dBxdz_ =dBrdz_*cos_theta;
608  dBydx_=dBxdy_;
609  dBydy_ = dBrdx_*sin_theta*sin_theta;
610  dBydz_ = dBrdz_*sin_theta;
611  dBzdx_ = dBzdx_*cos_theta;
612  dBzdy_ = dBzdx_*sin_theta;
613 
614  /*
615  printf("Grad %f %f %f %f %f %f %f %f %f\n",dBxdx_,dBxdy_,dBxdz_,
616  dBydx_,dBydy_,dBydz_,dBzdx_,dBzdy_,dBzdz_);
617  */
618 }
619 
620 //-------------
621 // GetFieldGradient
622 //-------------
623 void DMagneticFieldMapFineMesh::GetFieldGradient(double x, double y, double z,
624  double &dBxdx, double &dBxdy,
625  double &dBxdz,
626  double &dBydx, double &dBydy,
627  double &dBydz,
628  double &dBzdx, double &dBzdy,
629  double &dBzdz) const{
630 
631  // Get closest indices for this point
632  double r = sqrt(x*x + y*y);
633  int index_x = (int)floor((r-xmin)*one_over_dx + 0.5);
634  //if(index_x<0 || index_x>=Nx)return;
635  if (index_x>=Nx) return;
636  else if (index_x<0) index_x=0;
637  int index_z = (int)floor((z-zmin)*one_over_dz + 0.5);
638  if(index_z<0 || index_z>=Nz)return;
639 
640  int index_y = 0;
641 
642  const DBfieldPoint_t *B = &Btable[index_x][index_y][index_z];
643 
644  // Convert r back to x,y components
645  double cos_theta = x/r;
646  double sin_theta = y/r;
647  if(r==0.0){
648  cos_theta=1.0;
649  sin_theta=0.0;
650  }
651 
652  // Rotate back into phi direction
653  dBxdx = B->dBxdx*cos_theta*cos_theta*one_over_dx;
654  dBxdy = B->dBxdx*cos_theta*sin_theta*one_over_dx;
655  dBxdz = B->dBxdz*cos_theta*one_over_dz;
656  dBydx = B->dBxdx*sin_theta*cos_theta*one_over_dx;
657  dBydy = B->dBxdx*sin_theta*sin_theta*one_over_dx;
658  dBydz = B->dBxdz*sin_theta*one_over_dz;
659  dBzdx = B->dBzdx*cos_theta*one_over_dx;
660  dBzdy = B->dBzdx*sin_theta*one_over_dx;
661  dBzdz = B->dBzdz*one_over_dz;
662  /*
663  printf("old Grad %f %f %f %f %f %f %f %f %f\n",dBxdx,dBxdy,dBxdz,
664  dBydx,dBydy,dBydz,dBzdx,dBzdy,dBzdz);
665  */
666 }
667 
668 
669 
670 //---------------------------------
671 // GetField
672 //---------------------------------
673 void DMagneticFieldMapFineMesh::GetField(double x, double y, double z, double &Bx, double &By, double &Bz, int method) const
674 {
675  /// This calculates the magnetic field at an arbitrary point
676  /// in space using the field map read from the calibaration
677  /// database. It interpolates between grid points using the
678  /// gradient values calculated in ReadMap (called from the
679  /// constructor).
680 
681  Bx = By = Bz = 0.0;
682  double Br=0.0;
683 
684  if(Ny>1){
685  _DBG_<<"Field map appears to be 3 dimensional. Code is currently"<<endl;
686  _DBG_<<"unable to handle this. Treating as phi symmetric using y=0."<<endl;
687  }
688 
689  // radial position and angles
690  double r = sqrt(x*x + y*y);
691  if (r>xmax || z>zmax || z<zmin){
692  return;
693  }
694 
695  double cos_theta = x/r;
696  double sin_theta = y/r;
697  if(r==0.0){
698  cos_theta=1.0;
699  sin_theta=0.0;
700  }
701 
702  // If the point (x,y,z) is outside the fine-mesh grid, interpolate
703  // on the coarse grid
704  if (z<zminFine || z>=zmaxFine || r>=rmaxFine){
705  // Get closest indices for this point
706  int index_x = static_cast<int>(r*one_over_dx);
707  //if(index_x<0 || index_x>=Nx)return;
708  if (index_x>=Nx) return;
709 
710  int index_z = static_cast<int>((z-zmin)*one_over_dz);
711  if(index_z<0 || index_z>=Nz)return;
712 
713  int index_y = 0;
714 
715  const DBfieldPoint_t *B = &Btable[index_x][index_y][index_z];
716 
717  // Fractional distance between map points.
718  double ur = (r - B->x)*one_over_dx;
719  double uz = (z - B->z)*one_over_dz;
720 
721  // Use gradient to project grid point to requested position
722  Br = B->Bx+B->dBxdx*ur+B->dBxdz*uz;
723  Bz = B->Bz+B->dBzdx*ur+B->dBzdz*uz;
724  }
725  else{ // otherwise do a simple lookup in the fine-mesh table
726  unsigned int indr=static_cast<unsigned int>(r*rscale);
727  unsigned int indz=static_cast<unsigned int>((z-zminFine)*zscale);
728  const DBfieldCylindrical_t *field=&mBfine[indr][indz];
729 
730  Bz=field->Bz;
731  Br=field->Br;
732  // printf("Bz Br %f %f\n",Bz,Br);
733  }
734 
735  // Rotate back into phi direction
736  Bx = Br*cos_theta;
737  By = Br*sin_theta;
738 }
739 
740 //---------------------------------
741 // GetField
742 //---------------------------------
744 {
745  /// This calculates the magnetic field at an arbitrary point
746  /// in space using the field map read from the calibaration
747  /// database. It interpolates between grid points using the
748  /// gradient values calculated in ReadMap (called from the
749  /// constructor).
750 
751  double Bz=0.,Br=0.0;
752 
753  if(Ny>1){
754  _DBG_<<"Field map appears to be 3 dimensional. Code is currently"<<endl;
755  _DBG_<<"unable to handle this. Treating as phi symmetric using y=0."<<endl;
756  }
757 
758  // radial position and angles
759  double r = pos.Perp();
760  double z = pos.z();
761  if (r>xmax || z>zmax || z<zmin){
762  Bout.SetXYZ(0.0, 0.0, 0.0);
763  return;
764  }
765 
766  double cos_theta = pos.x()/r;
767  double sin_theta = pos.y()/r;
768  if(r==0.0){
769  cos_theta=1.0;
770  sin_theta=0.0;
771  }
772 
773  // If the point (x,y,z) is outside the fine-mesh grid, interpolate
774  // on the coarse grid
775  if (z<zminFine || z>=zmaxFine || r>=rmaxFine){
776  // Get closest indices for this point
777  int index_x = static_cast<int>(r*one_over_dx);
778  //if(index_x<0 || index_x>=Nx)return;
779  if (index_x>=Nx) {Bout.SetXYZ(0.0, 0.0, 0.0); return;}
780 
781  int index_z = static_cast<int>((z-zmin)*one_over_dz);
782  if(index_z<0 || index_z>=Nz){Bout.SetXYZ(0.0, 0.0, 0.0); return;}
783 
784  int index_y = 0;
785 
786  const DBfieldPoint_t *B = &Btable[index_x][index_y][index_z];
787 
788  // Fractional distance between map points.
789  double ur = (r - B->x)*one_over_dx;
790  double uz = (z - B->z)*one_over_dz;
791 
792  // Use gradient to project grid point to requested position
793  Br = B->Bx+B->dBxdx*ur+B->dBxdz*uz;
794  Bz = B->Bz+B->dBzdx*ur+B->dBzdz*uz;
795  }
796  else{ // otherwise do a simple lookup in the fine-mesh table
797  unsigned int indr=static_cast<unsigned int>(r*rscale);
798  unsigned int indz=static_cast<unsigned int>((z-zminFine)*zscale);
799  const DBfieldCylindrical_t *field=&mBfine[indr][indz];
800 
801  Bz=field->Bz;
802  Br=field->Br;
803  // printf("Bz Br %f %f\n",Bz,Br);
804  }
805 
806  // Rotate back into phi direction
807  Bout.SetXYZ(Br*cos_theta,Br*sin_theta,Bz);
808 }
809 
810 
811 
812 
813 // Get the z-component of the magnetic field
814 double DMagneticFieldMapFineMesh::GetBz(double x, double y, double z) const{
815  // radial position
816  double r = sqrt(x*x + y*y);
817  if (r>xmax || z>zmax || z<zmin){
818  return 0.;
819  }
820 
821  // If the point (x,y,z) is outside the fine-mesh grid, interpolate
822  // on the coarse grid
823  if (z<zminFine || z>=zmaxFine || r>=rmaxFine){
824  // Get closest indices for this point
825  int index_x = static_cast<int>(r*one_over_dx);
826  //if(index_x<0 || index_x>=Nx)return 0.;
827  if (index_x>=Nx) return 0.;
828 
829  int index_z = static_cast<int>((z-zmin)*one_over_dz);
830  if(index_z<0 || index_z>=Nz)return 0.;
831 
832  int index_y = 0;
833 
834  const DBfieldPoint_t *B = &Btable[index_x][index_y][index_z];
835 
836  // Fractional distance between map points.
837  double ur = (r - B->x)*one_over_dx;
838  double uz = (z - B->z)*one_over_dz;
839 
840  // Use gradient to project grid point to requested position
841  return (B->Bz + B->dBzdx*ur + B->dBzdz*uz);
842  }
843 
844  // otherwise do a simple lookup in the fine-mesh table
845  unsigned int indr=static_cast<unsigned int>(r*rscale);
846  unsigned int indz=static_cast<unsigned int>((z-zminFine)*zscale);
847 
848  return mBfine[indr][indz].Bz;
849 }
850 
851 // Read a fine-mesh B-field map from an evio file
852 void DMagneticFieldMapFineMesh::GetFineMeshMap(string namepath,int32_t runnumber){
853  // The solenoid field map files are stored in CCDB as /Magnets/Solenoid/BFIELD_MAP_NAME
854  // The fine-mesh files are now stored as /Magnets/Solenoid/finemeshes/BFIELD_MAP_NAME
855  size_t ipos = namepath.rfind("/");
856  if(ipos == string::npos)
857  throw JException("Could not parse field map: "+namepath);
858  string finemesh_namepath = namepath.substr(0,ipos) + "/finemeshes" + namepath.substr(ipos);
859  string evioFileName = "";
860  string evioFileNameToWrite = "";
861  // see if we can get the EVIO file as a resource
862  try {
863  evioFileName = jresman->GetResource(finemesh_namepath);
864  } catch ( JException e ) {
865  // if we can't get it as a resource, try to get it from a local file
866  size_t ipos=namepath.find("/");
867  size_t ipos2=namepath.find("/",ipos+1);
868  evioFileName = namepath.substr(ipos2+1)+".evio";
869  // see if the file exists
870  struct stat stFileInfo;
871  int intStat = stat(evioFileName.c_str(),&stFileInfo);
872  if (intStat != 0) {
873  evioFileNameToWrite = evioFileName;
874  evioFileName = "";
875  }
876  }
877 
878  if(evioFileName != "") {
879  ReadEvioFile(evioFileName);
880  } else{
881  cout << "Fine-mesh evio file does not exist." <<endl;
882  cout << "Constructing the fine-mesh B-field map..." << endl;
883  GenerateFineMesh();
884 #ifdef HAVE_EVIO
885  WriteEvioFile(evioFileNameToWrite);
886 #endif
887  }
888 
889  cout << " rmin: " << rminFine << " rmax: " << rmaxFine
890  << " dr: " << drFine << " zmin: " << zminFine << " zmax: "
891  << zmaxFine << " dz: " << dzFine <<endl;
892  cout << " Number of points in z = " <<NzFine <<endl;
893  cout << " Number of points in r = " << NrFine << endl;
894 }
895 
897  rminFine=0.;
898  rmaxFine=88.5;
899  drFine=0.1;
900  zminFine=0.;
901  zmaxFine=600.;
902  dzFine=0.1;
903  zscale=1./dzFine;
904  rscale=1./drFine;
905  NrFine=(unsigned int)floor((rmaxFine-rminFine)/drFine+0.5);
906  NzFine=(unsigned int)floor((zmaxFine-zminFine)/dzFine+0.5);
907 
908  vector<DBfieldCylindrical_t>zrow;
909  for (unsigned int i=0;i<NrFine;i++){
910  double x=rminFine+drFine*double(i);
911  for (unsigned int j=0;j<NzFine;j++){
912  double z=zminFine+dzFine*double(j);
914  InterpolateField(x,z,temp.Br,temp.Bz,temp.dBrdr,temp.dBrdz,temp.dBzdr,
915  temp.dBzdz);
916  zrow.push_back(temp);
917  }
918  mBfine.push_back(zrow);
919  zrow.clear();
920  }
921 }
922 
924  cout << "Writing fine-mesh B-field data to " << evioFileName << "..." <<endl;
925 
926  // Create vectors of the B-field components and gradients
927  vector<float>Br_;
928  vector<float>Bz_;
929  vector<float>dBrdr_;
930  vector<float>dBrdz_;
931  vector<float>dBzdr_;
932  vector<float>dBzdz_;
933  for (unsigned int i=0;i<NrFine;i++){
934  for (unsigned int j=0;j<NzFine;j++){
935  Br_.push_back(mBfine[i][j].Br);
936  Bz_.push_back(mBfine[i][j].Bz);
937  dBrdr_.push_back(mBfine[i][j].dBrdr);
938  dBrdz_.push_back(mBfine[i][j].dBrdz);
939  dBzdr_.push_back(mBfine[i][j].dBzdr);
940  dBzdz_.push_back(mBfine[i][j].dBzdz);
941  }
942  }
943 
944  // Calculate total buffer size needed (in 32bit words)
945  // and allocate buffer
946  uint32_t buff_size = 8; // EVIO block header
947  buff_size += 2; // outer bank length and header
948  buff_size += 2+6; // minmaxdelta length, header words plus 6 payload words
949  buff_size += 6*(2+NrFine*NzFine); // 6 banks, each with length,header words and NrFine*NzFine payload
950  uint32_t *buff = new uint32_t[buff_size+8]; // +8 for EVIO block trailer
951 
952  // EVIO block header
953  uint32_t *iptr = buff;
954  *iptr++ = buff_size; // Number of 32 bit words in evio block
955  *iptr++ = 1; // Block number
956  *iptr++ = 8; // Length of block header (words)
957  *iptr++ = 1; // Event Count
958  *iptr++ = 0; // Reserved 1
959  *iptr++ = 0x4; // 0x4=EVIO version 4
960  *iptr++ = 0; // Reserved 2
961  *iptr++ = 0xc0da0100; // Magic number
962 
963  // Outermost bank
964  *iptr++ = buff_size - 1 - 8; // -1 for length word. -8 for evio block header
965  *iptr++ = (0x1<<16) + (0x0E<<8) + (0);
966 
967  // Table dimensions bank
968  *iptr++ = 2+6 - 1;
969  *iptr++ = (0x2<<16) + (0x02<<8) + (0);
970  *(float*)iptr++ = (float)rminFine;
971  *(float*)iptr++ = (float)rmaxFine;
972  *(float*)iptr++ = (float)drFine;
973  *(float*)iptr++ = (float)zminFine;
974  *(float*)iptr++ = (float)zmaxFine;
975  *(float*)iptr++ = (float)dzFine;
976 
977  // Table values banks
978  for(uint32_t i=0; i<6; i++){
979  vector<float> *d = NULL;
980  switch(i){
981  case 0: d = &Br_; break;
982  case 1: d = &Bz_; break;
983  case 2: d = &dBrdr_; break;
984  case 3: d = &dBrdz_; break;
985  case 4: d = &dBzdr_; break;
986  case 5: d = &dBzdz_; break;
987  }
988  *iptr++ = 2+NrFine*NzFine - 1;
989  *iptr++ = (0x3<<16) + (0x02<<8) + (i);
990  for(float f : *d) *(float*)iptr++ = f;
991  //for(uint32_t j=0; j<NrFine*NzFine; j++) *(float*)iptr++ = d->at(j);
992  }
993 
994  // EVIO block trailer
995  *iptr++ = 8; // Number of 32 bit words in evio block
996  *iptr++ = 2; // Block number
997  *iptr++ = 8; // Length of block header (words)
998  *iptr++ = 0; // Event Count
999  *iptr++ = 0; // Reserved 1
1000  *iptr++ = (1<<9) + 0x4; // (1<<9) last event in stack 0x4=EVIO version 4
1001  *iptr++ = 0; // Reserved 2
1002  *iptr++ = 0xc0da0100; // Magic number
1003 
1004 
1005  // Write the actual file
1006  ofstream ofs(evioFileName);
1007  ofs.write((char*)buff, (buff_size+8)*4);
1008  ofs.close();
1009 
1010  delete[] buff;
1011 
1012 #ifdef HAVE_EVIO
1013  // Open the evio file channel
1014  unsigned long bufsize=NrFine*NzFine*6*sizeof(float)+6;
1015  evioFileChannel chan(evioFileName,"w",bufsize);
1016  chan.open();
1017 
1018  // create an event tree, root node has (tag=1,num=0)
1019  evioDOMTree tree(1,0);
1020 
1021  float minmaxdelta[6]={(float)rminFine,(float)rmaxFine,(float)drFine,(float)zminFine,(float)zmaxFine,(float)dzFine};
1022  tree.addBank(2,0,minmaxdelta,6);
1023 
1024  // Add the banks
1025  tree.addBank(3,0,Br_);
1026  tree.addBank(3,1,Bz_);
1027  tree.addBank(3,2,dBrdr_);
1028  tree.addBank(3,3,dBrdz_);
1029  tree.addBank(3,4,dBzdr_);
1030  tree.addBank(3,5,dBzdz_);
1031 
1032  chan.write(tree);
1033  chan.close();
1034 #endif // HAVE_EVIO
1035 }
1036 
1037 // Read the B-field data from the evio file
1039  cout << "Reading fine-mesh B-field data from "<< evioFileName << endl;
1040 
1041  // Open EVIO file
1042  HDEVIO hdevio(evioFileName, false);
1043  if(!hdevio.is_open){
1044  jerr << " Unable to open fine-mesh B-field file!" << endl;
1045  return;
1046  }
1047 
1048  // Allocate a small buffer and attempt to read in event.
1049  // This will fail due to the small buffer, but will leave
1050  // the size needed in hdevio.last_event_len so we can reallocate.
1051  uint32_t buff_size=10; // initially allocate small buffer
1052  uint32_t *buff = new uint32_t[buff_size];
1053  hdevio.readNoFileBuff(buff, buff_size);
1055  delete[] buff;
1056  buff_size = hdevio.last_event_len;
1057  buff = new uint32_t[buff_size];
1058  hdevio.readNoFileBuff(buff, buff_size);
1059  }
1060  if(hdevio.err_code != HDEVIO::HDEVIO_OK){
1061  jerr << " Problem reading fine-mesh B-field" << endl;
1062  jerr << hdevio.err_mess.str() << endl;
1063  delete[] buff;
1064  return;
1065  }
1066 
1067  // Top-level bank of banks has tag=1, num=0
1068  uint32_t *iptr = buff;
1069  uint32_t *iend = &iptr[*iptr +1];
1070  iptr = &iptr[2];
1071 
1072  // First bank has tag=2, num=0 and length 6 data words
1073  if(iptr[0] != 6+1){
1074  jerr << " Bad length for minmaxdelta bank!" <<endl;
1075  _exit(-1);
1076  }
1077  float *minmaxdelta = (float*)&iptr[2];
1078  rminFine = minmaxdelta[0];
1079  rmaxFine = minmaxdelta[1];
1080  drFine = minmaxdelta[2];
1081  zminFine = minmaxdelta[3];
1082  zmaxFine = minmaxdelta[4];
1083  dzFine = minmaxdelta[5];
1084  iptr = &iptr[*iptr + 1];
1085 
1086  zscale=1./dzFine;
1087  rscale=1./drFine;
1088 
1089  NrFine=(unsigned int)floor((rmaxFine-rminFine)/drFine+0.5);
1090  NzFine=(unsigned int)floor((zmaxFine-zminFine)/dzFine+0.5);
1091  mBfine.resize(NrFine);
1092  for(auto &m : mBfine) m.resize(NzFine);
1093 
1094  // Next 6 banks have tag=3 and num=0-5 and hold
1095  // the actual table data
1096  for(int num=0; num<=5; num++){
1097  uint32_t mynum = iptr[1] & 0xFF;
1098  float *fptr = (float*)&iptr[2];
1099  uint32_t N = iptr[0] - 1;
1100  iptr = &iptr[N+2];
1101  if(iptr > iend){
1102  jerr << " Bad format of fine mesh B-field file!" << endl;
1103  _exit(-1);
1104  }
1105 
1106  for(uint32_t k=0; k<N; k++){
1107  uint32_t indr=k/NzFine;
1108  uint32_t indz=k%NzFine;
1109  switch( mynum ){
1110  case 0: mBfine[indr][indz].Br = *fptr++; break; // Br
1111  case 1: mBfine[indr][indz].Bz = *fptr++; break; // Bz
1112  case 2: mBfine[indr][indz].dBrdr = *fptr++; break; // dBrdr
1113  case 3: mBfine[indr][indz].dBrdz = *fptr++; break; // dBrdz
1114  case 4: mBfine[indr][indz].dBzdr = *fptr++; break; // dBzdr
1115  case 5: mBfine[indr][indz].dBzdz = *fptr++; break; // dBzdz
1116  }
1117  }
1118  }
1119 
1120  delete[] buff;
1121 }
uint32_t err_code
Definition: HDEVIO.h:192
TVector3 DVector3
Definition: DVector3.h:14
Double_t x[NCHANNELS]
Definition: st_tw_resols.C:39
void GetFieldGradient(double x, double y, double z, double &dBxdx, double &dBxdy, double &dBxdz, double &dBydx, double &dBydy, double &dBydz, double &dBzdx, double &dBzdy, double &dBzdz) const
#define y
bool is_open
Definition: HDEVIO.h:166
double zmax
JApplication * japp
TF1 * f
Definition: FitGains.C:21
int Nz
Definition: bfield2root.cc:27
TEllipse * e
static string evioFileName
stringstream err_mess
Definition: HDEVIO.h:191
uint32_t last_event_len
Definition: HDEVIO.h:184
void ReadEvioFile(string evioFileName)
static evioFileChannel * chan
#define _DBG_
Definition: HDEVIO.h:12
Definition: HDEVIO.h:45
bool readNoFileBuff(uint32_t *user_buff, uint32_t user_buff_len, bool allow_swap=true)
Definition: HDEVIO.cc:499
void GetFineMeshMap(string namepath, int32_t runnumber)
double sqrt(double)
void InterpolateField(double r, double z, double &Br, double &Bz, double &dBrdr, double &dBrdz, double &dBzdr, double &dBzdz) const
int ReadMap(string namepath, int32_t runnumber=1, string context="")
void WriteEvioFile(string evioFileName)
void GetFieldBicubic(double x, double y, double z, double &Bx, double &By, double &Bz) const
Double_t ymin
Definition: bcal_hist_eff.C:89
void GetFieldAndGradient(double x, double y, double z, double &Bx, double &By, double &Bz, double &dBxdx, double &dBxdy, double &dBxdz, double &dBydx, double &dBydy, double &dBydz, double &dBzdx, double &dBzdy, double &dBzdz) const
Double_t ymax
Definition: bcal_hist_eff.C:91
double zmin
double GetBz(double x, double y, double z) const
TH2F * temp
union @6::@8 u
void GetField(const DVector3 &pos, DVector3 &Bout) const
DMagneticFieldMapFineMesh(JApplication *japp, int32_t runnumber=1, string namepath="Magnets/Solenoid/solenoid_1350_poisson_20130925")