Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
bfield2root.cc
Go to the documentation of this file.
1 // Author: David Lawrence June 25, 2004
2 //
3 //
4 // hd_ana.cc
5 //
6 
7 #include <iostream>
8 #include <iomanip>
9 #include <string>
10 using namespace std;
11 
12 #include <stdlib.h>
13 
14 #include <DANA/DApplication.h>
16 #include <JANA/JParameterManager.h>
17 
18 #include <TFile.h>
19 #include <TTree.h>
20 #include <TVector3.h>
21 #include <TH2.h>
22 
23 int32_t RUN_NUMBER = 30000;
24 
25 int Nr = 81;
26 int Nphi = 1;
27 int Nz = 401;
28 
29 double Rmin = 1.0*2.54;
30 double Rmax = 81.0*2.54;
31 
32 double Phimin = 0.0;
33 double Phimax = 0.0;
34 
35 double Zmin = -126.0*2.54;
36 double Zmax = 274.0*2.54;
37 double Z0 = 0.0;
38 
39 bool INCLUDE_GRADIENTS = false;
40 
41 void Usage(void);
42 void ParseCommandLineArgs(int narg, char* argv[], vector<char*> &unused_args);
43 
44 //-----------
45 // main
46 //-----------
47 int main(int narg, char *argv[])
48 {
49 
50  // Parse command line arguments and then create a DApplication
51  vector<char*> unused_args;
52  ParseCommandLineArgs(narg, argv, unused_args);
53 
54  if( !unused_args.empty() ){
55  cout << "The following arguments will be passed to DApplication:" << endl;
56  for(auto a : unused_args) cout << " " << a << endl;
57  cout << endl;
58  }
59 
60  DApplication *dapp = new DApplication(unused_args.size(), unused_args.empty() ? NULL:&unused_args[0]);
61  dapp->Init();
62 
63  // open ROOT file
64  float val[100];
65  TFile* ROOTfile = new TFile("bfield.root","RECREATE","Produced by bfield2root");
66  ROOTfile->SetCompressionLevel(6);
67  cout<<"Opened ROOT file \"bfield.root\""<<endl;
68 
69  // Have Dapplication create Magnetic Field Map
70  DMagneticFieldMap *bfield = dapp->GetBfield(RUN_NUMBER);
71 
72  // Create Tree
73  TTree *tree = new TTree("Bfield","Magnetic Field");
74  tree->SetMarkerStyle(8);
75  tree->SetMarkerColor(kBlue);
76  string leaves = "x/F:y:z:r:phi:Bx:By:Bz:Br:Bphi";
78  leaves += ":dBxdx:dBxdy:dBxdz";
79  leaves += ":dBydx:dBydy:dBydz";
80  leaves += ":dBzdx:dBzdy:dBzdz";
81  }
82  tree->Branch("B",val,leaves.c_str());
83 
84  // Loop over cylindrical grid and fill tree
85  double r = Rmin;
86  for(int ir=0; ir<Nr; ir++){
87  if(Nr>1) r = Rmin + (double)ir*(Rmax-Rmin)/(double)(Nr-1);
88  double phi = Phimin;
89  for(int iphi=0; iphi<Nphi; iphi++){
90  if(Nphi>1) phi = Phimin + (double)iphi*(Phimax-Phimin)/(double)(Nphi-1);
91  double z = Zmin;
92  for(int iz=0; iz<Nz; iz++){
93  if(Nz>1) z = Zmin + (double)iz*(Zmax-Zmin)/(double)(Nz-1);
94 
95  double x = r*cos(phi);
96  double y = r*sin(phi);
97 
98  double Bx, By, Bz;
99  double dBxdx, dBxdy, dBxdz;
100  double dBydx, dBydy, dBydz;
101  double dBzdx, dBzdy, dBzdz;
102 
103  bfield->GetFieldAndGradient(x, y, z-Z0, Bx, By, Bz,
104  dBxdx, dBxdy, dBxdz,
105  dBydx, dBydy, dBydz,
106  dBzdx, dBzdy, dBzdz);
107 
108  TVector3 B(Bx, By, Bz);
109  double Br = B.Dot(TVector3(x, y, 0.0))/sqrt(x*x + y*y);
110  double Bphi = atan2(By, Bx);
111 
112  val[0] = x;
113  val[1] = y;
114  val[2] = z;
115  val[3] = r;
116  val[4] = phi;
117  val[5] = Bx;
118  val[6] = By;
119  val[7] = Bz;
120  val[8] = Br;
121  val[9] = Bphi;
122 
123  val[10] = dBxdx;
124  val[11] = dBxdy;
125  val[12] = dBxdz;
126 
127  val[13] = dBydx;
128  val[14] = dBydy;
129  val[15] = dBydz;
130 
131  val[16] = dBzdx;
132  val[17] = dBzdy;
133  val[18] = dBzdz;
134 
135  tree->Fill();
136  }
137  }
138  }
139 
140  // Create 2D histos in R and Z
141  TH2D *Bz_vs_r_vs_z = new TH2D("Bz_vs_r_vs_z", "", Nz, Zmin, Zmax, Nr, Rmin, Rmax);
142  Bz_vs_r_vs_z->SetXTitle("z (cm)");
143  Bz_vs_r_vs_z->SetYTitle("r (cm)");
144  Bz_vs_r_vs_z->SetStats(0);
145  TH2D *Btot_vs_r_vs_z = (TH2D*)Bz_vs_r_vs_z->Clone("Btot_vs_r_vs_z");
146  TH2D *dBtot_vs_r_vs_z = (TH2D*)Bz_vs_r_vs_z->Clone("dBtot_vs_r_vs_z");
147  for(int ibin=1; ibin<=Bz_vs_r_vs_z->GetNbinsX(); ibin++){
148  double z = Bz_vs_r_vs_z->GetXaxis()->GetBinCenter(ibin);
149  for(int jbin=1; jbin<=Bz_vs_r_vs_z->GetNbinsY(); jbin++){
150  double r = Bz_vs_r_vs_z->GetYaxis()->GetBinCenter(jbin);
151 
152  double Bx, By, Bz;
153  double dBxdx, dBxdy, dBxdz;
154  double dBydx, dBydy, dBydz;
155  double dBzdx, dBzdy, dBzdz;
156 
157  bfield->GetFieldAndGradient(r, 0.0, z-Z0, Bx, By, Bz,
158  dBxdx, dBxdy, dBxdz,
159  dBydx, dBydy, dBydz,
160  dBzdx, dBzdy, dBzdz);
161  double Btot = sqrt(Bx*Bx + By*By + Bz*Bz);
162 
163  // Gradient of magnitude
164  TVector3 gradient(dBxdx*Bx/Btot + dBydx*By/Btot + dBzdx*Bz/Btot,
165  dBxdy*Bx/Btot + dBydy*By/Btot + dBzdy*Bz/Btot,
166  dBxdz*Bx/Btot + dBydz*By/Btot + dBzdz*Bz/Btot);
167  double dBtot = gradient.Mag();
168 
169  Bz_vs_r_vs_z->SetBinContent(ibin, jbin, Bz);
170  Btot_vs_r_vs_z->SetBinContent(ibin, jbin, Btot);
171  dBtot_vs_r_vs_z->SetBinContent(ibin, jbin, dBtot);
172  }
173  }
174 
175  // Create 2D histos in X and Z that cover a larger range
176  TH2D *Btot_vs_x_vs_z = new TH2D("Btot_vs_x_vs_z", "", 800, -100.0, 700.0, 400, -200.0, 200.0);
177  Btot_vs_x_vs_z->SetXTitle("x (cm)");
178  Btot_vs_x_vs_z->SetYTitle("r (cm)");
179  Btot_vs_x_vs_z->SetStats(0);
180  for(int ibin=1; ibin<=Btot_vs_x_vs_z->GetNbinsX(); ibin++){
181  double z = Btot_vs_x_vs_z->GetXaxis()->GetBinCenter(ibin);
182  for(int jbin=1; jbin<=Btot_vs_x_vs_z->GetNbinsY(); jbin++){
183  double x = Btot_vs_x_vs_z->GetYaxis()->GetBinCenter(jbin);
184 
185  double Bx, By, Bz;
186  double dBxdx, dBxdy, dBxdz;
187  double dBydx, dBydy, dBydz;
188  double dBzdx, dBzdy, dBzdz;
189 
190  bfield->GetFieldAndGradient(x, 0.0, z-Z0, Bx, By, Bz,
191  dBxdx, dBxdy, dBxdz,
192  dBydx, dBydy, dBydz,
193  dBzdx, dBzdy, dBzdz);
194  double Btot = sqrt(Bx*Bx + By*By + Bz*Bz);
195 
196  Btot_vs_x_vs_z->SetBinContent(ibin, jbin, Btot);
197  }
198  }
199 
200  // Angle
201  TH2D *cos_theta_vs_r_vs_z = new TH2D("cos_theta_vs_r_vs_z", "", 651, -25, 625.0, 400, 0.0, 200.0);
202  cos_theta_vs_r_vs_z->SetXTitle("z (cm)");
203  cos_theta_vs_r_vs_z->SetYTitle("r (cm)");
204  cos_theta_vs_r_vs_z->SetStats(0);
205  for(int ibin=1; ibin<=cos_theta_vs_r_vs_z->GetNbinsX(); ibin++){
206  double z = cos_theta_vs_r_vs_z->GetXaxis()->GetBinCenter(ibin);
207  for(int jbin=1; jbin<=cos_theta_vs_r_vs_z->GetNbinsY(); jbin++){
208  double r = cos_theta_vs_r_vs_z->GetYaxis()->GetBinCenter(jbin);
209 
210  double Bx, By, Bz;
211  bfield->GetField(r, 0.0, z-Z0, Bx, By, Bz);
212  double Btot = sqrt(Bx*Bx + By*By + Bz*Bz);
213 
214  cos_theta_vs_r_vs_z->SetBinContent(ibin, jbin, Bz/Btot);
215  }
216  }
217 
218  // Zoom in to TOF
219  TH2D *Btot_vs_r_vs_z_tof = new TH2D("Btot_vs_r_vs_z_tof", "", 61, 590.0, 650.0, 200, 76.0, 180.0);
220  Btot_vs_r_vs_z_tof->SetXTitle("z (cm)");
221  Btot_vs_r_vs_z_tof->SetYTitle("r (cm)");
222  Btot_vs_r_vs_z_tof->SetStats(0);
223  TH2D *Bz_vs_r_vs_z_tof = (TH2D*)Btot_vs_r_vs_z_tof->Clone("Bz_vs_r_vs_z_tof");
224  TH2D *Br_vs_r_vs_z_tof = (TH2D*)Btot_vs_r_vs_z_tof->Clone("Br_vs_r_vs_z_tof");
225  for(int ibin=1; ibin<=Btot_vs_r_vs_z_tof->GetNbinsX(); ibin++){
226  double z = Btot_vs_r_vs_z_tof->GetXaxis()->GetBinCenter(ibin);
227  for(int jbin=1; jbin<=Btot_vs_r_vs_z_tof->GetNbinsY(); jbin++){
228  double r = Btot_vs_r_vs_z_tof->GetYaxis()->GetBinCenter(jbin);
229 
230  double Bx, By, Bz;
231  double dBxdx, dBxdy, dBxdz;
232  double dBydx, dBydy, dBydz;
233  double dBzdx, dBzdy, dBzdz;
234 
235  bfield->GetFieldAndGradient(r, 0.0, z-Z0, Bx, By, Bz,
236  dBxdx, dBxdy, dBxdz,
237  dBydx, dBydy, dBydz,
238  dBzdx, dBzdy, dBzdz);
239  double Btot = sqrt(Bx*Bx + By*By + Bz*Bz);
240  double Br = sqrt(Bx*Bx + By*By);
241 
242  Btot_vs_r_vs_z_tof->SetBinContent(ibin, jbin, Btot);
243  Bz_vs_r_vs_z_tof->SetBinContent(ibin, jbin, Bz);
244  Br_vs_r_vs_z_tof->SetBinContent(ibin, jbin, Br);
245  }
246  }
247 
248  ROOTfile->Write();
249  delete ROOTfile;
250  cout<<endl<<"Closed ROOT file"<<endl;
251 
252  return 0;
253 }
254 
255 //-----------------------
256 // Usage
257 //-----------------------
258 void Usage(void)
259 {
260  cout<<endl;
261  cout<<"Usage:"<<endl;
262  cout<<" bfield2root [options]"<<endl;
263  cout<<endl;
264  cout<<" options:"<<endl;
265  cout<<" -h, --help Show this Usage statement"<<endl;
266  cout<<" -R # Set the run number to use when accessing field map"<<endl;
267  cout<<" -Nr # Set the number of grid points in R"<<endl;
268  cout<<" -Nphi # Set the number of grid points in Phi"<<endl;
269  cout<<" -Nz # Set the number of grid points in Z"<<endl;
270  cout<<" -Rmin # Set the minimum value for R (cm)"<<endl;
271  cout<<" -Rmax # Set the maximum value for R (cm)"<<endl;
272  cout<<" -Phimin # Set the minimum value for Phi (radians)"<<endl;
273  cout<<" -Phimax # Set the maximum value for Phi (radians)"<<endl;
274  cout<<" -Zmin # Set the minimum value for Z (cm)"<<endl;
275  cout<<" -Zmax # Set the maximum value for Z (cm)"<<endl;
276  cout<<" -Z0 # Shift the map's z-coordinate"<<endl;
277  cout<<" -G Include gradient values in tree"<<endl;
278  cout<<endl;
279  cout<<" The bfield to root program can be used to generate a ROOT TTree of the"<<endl;
280  cout<<"magnetic field of the Hall-D solenoid. The field is read from the same source"<<endl;
281  cout<<"as is used by the reconstruction and simulation programs. Since it is a DANA"<<endl;
282  cout<<"based program, it accepts the same same arguments to manipulate the field as"<<endl;
283  cout<<"other DANA programs. Namely, -PBFIELD_MAP=XXX and -PBFIELD_TYPE=YYY ."<<endl;
284  cout<<endl;
285  cout<<"For example: -PBFIELD_MAP=Magnets/Solenoid/solenoid_1500"<<endl;
286  cout<<endl;
287  cout<<"The entries in the TTree are evaluated on a grid in cylindrical coordinates"<<endl;
288  cout<<"that likely does not reflect the points in the underlying map. As such, the"<<endl;
289  cout<<"values in the tree are a result of the interpolation of the underlying map's"<<endl;
290  cout<<"points."<<endl;
291  cout<<endl;
292 
293 }
294 
295 //-----------------------
296 // ParseCommandLineArgs
297 //-----------------------
298 void ParseCommandLineArgs(int narg, char* argv[], vector<char*> &unused_args)
299 {
300  unused_args.push_back(argv[0]);
301 
302  for(int i=1; i<narg; i++){
303  string arg(argv[i]);
304  string next(i<narg-1 ? argv[i+1]:"");
305  float argf = atof(next.c_str());
306  int argi = atoi(next.c_str());
307  bool used_next = false; // keep track if "next" is used so we can have a single error check below
308 
309  if(arg=="-h" || arg=="--help"){Usage(); exit(0);}
310  else if(arg=="-R" ){used_next=true; RUN_NUMBER = argi;}
311  else if(arg=="-Nr" ){used_next=true; Nr = argi;}
312  else if(arg=="-Nphi" ){used_next=true; Nphi = argi;}
313  else if(arg=="-Nz" ){used_next=true; Nz = argi;}
314  else if(arg=="-Rmin" ){used_next=true; Rmin = argf;}
315  else if(arg=="-Rmax" ){used_next=true; Rmax = argf;}
316  else if(arg=="-Phimin"){used_next=true; Phimin = argf;}
317  else if(arg=="-Phimax"){used_next=true; Phimax = argf;}
318  else if(arg=="-Zmin" ){used_next=true; Zmin = argf;}
319  else if(arg=="-Zmax" ){used_next=true; Zmax = argf;}
320  else if(arg=="-Z0" ){used_next=true; Z0 = argf;}
321  else if(arg=="-G" ){INCLUDE_GRADIENTS=true;}
322  else{ unused_args.push_back(argv[i]); }
323 
324  if(used_next){
325  // skip to next argument
326  i++;
327 
328  // If i is now > than narg, then no value was passed to an "-XXX" argument
329  if(i>narg){
330  _DBG_<<"No argument given for \""<<arg<<"\" argument!"<<endl;
331  Usage();
332  exit(-1);
333  }
334  }
335  }
336 }
337 
TFile * ROOTfile
void dBtot_vs_r_vs_z(void)
DApplication * dapp
double Zmax
Definition: bfield2root.cc:36
bool INCLUDE_GRADIENTS
Definition: bfield2root.cc:39
Double_t x[NCHANNELS]
Definition: st_tw_resols.C:39
virtual 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 =0
#define y
DMagneticFieldMap * GetBfield(unsigned int run_number=1)
void Btot_vs_r_vs_z(void)
int Nr
Definition: bfield2root.cc:25
double Zmin
Definition: bfield2root.cc:35
double Rmax
Definition: bfield2root.cc:30
double Rmin
Definition: bfield2root.cc:29
int Nz
Definition: bfield2root.cc:27
void ParseCommandLineArgs(int narg, char *argv[], vector< char * > &unused_args)
Definition: bfield2root.cc:298
double Phimin
Definition: bfield2root.cc:32
#define _DBG_
Definition: HDEVIO.h:12
int Nphi
Definition: bfield2root.cc:26
jerror_t Init(void)
double sqrt(double)
double sin(double)
static unsigned int RUN_NUMBER
Definition: mc2coda.c:24
double Phimax
Definition: bfield2root.cc:33
double Z0
Definition: bfield2root.cc:37
virtual void GetField(const DVector3 &pos, DVector3 &Bout) const =0
void Usage(JApplication &app)
Definition: hd_ana.cc:33
int main(int argc, char *argv[])
Definition: gendoc.cc:6