EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mfield2eve.C
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file mfield2eve.C
1 
2 //
3 // export LD_LIBRARY_PATH=<bmf-library-installation-place>:${LD_LIBRARY_PATH}
4 //
5 // root -l
6 // root [] gSystem->Load("libbmf.so"); gSystem->AddIncludePath("-I../include");
7 // root [] .x mfield2eve.C+
8 //
9 
10 #include <math.h>
11 
12 #include <TEveManager.h>
13 #include <TEveArrow.h>
14 #include <TEveLine.h>
15 
16 #include <TVector2.h>
17 #include <TCanvas.h>
18 #include <TStyle.h>
19 #include <TH1D.h>
20 #include <TPad.h>
21 #include <TLine.h>
22 
23 #include <BeastMagneticField.h>
24 
25 // 63126 = 510 x 126; [cm], [T];
26 #define _MAP_ZMIN_ (-500.0)
27 #define _MAP_ZDIM_ 501
28 
29 #define _MAP_RMIN_ 0.0
30 #define _MAP_RDIM_ 126
31 
32 #define _COORD_CFF_ 1.0
33 #define _FIELD_CFF_ 1.0
34 #define _STEP_ 2.0
35 
36 // NB: prefer to use {z,r} 2D coordinate sequence in this code;
38 
39 // Z -> in [cm] here, sorry;
40 #define _KICK_ZMIN_ 160.0
41 #define _KICK_ZDIM_ 100
42 #define _KICK_ZSTEP_ 1.0
43 
44 // Theta -> in [degree]; from 0 to 40 in 1 degree steps;
45 #define _KICK_TMIN_ 0
46 #define _KICK_TDIM_ 40
47 #define _KICK_TSTEP_ 1.0
48 
49 // Use this momentum for normalization; does not really matter;
50 #define _P0_ 10.0
51 
52 // ----------------------------------------------------------------------------------------------
53 
54 void mfield2eve( void )
55 {
56  double kicksigs[_KICK_TDIM_];
57 
58  gStyle->SetOptStat(0);
59 
60  TEveManager::Create();
61 
62  auto bmf = new BeastMagneticField("../data/mfield.4col.dat");
63 
64  {
65  // Assume IP at (0,0); may check how beam size along Z axis spoils the picture?;
66  double z0 = 0.0;
67 
68  // Up to eta~1 with a step of 1 degree;
69  for(unsigned is=0; is<_KICK_TDIM_; is++) {
70  double theta = is*_KICK_TSTEP_, slope = tan(theta*TMath::Pi()/180.);
71 
72  // Between 150cm and 250cm (?) with a step of 1cm;
73  double accu = 0.0, avg = 0.0, avg_sqr = 0.0;
74  for(unsigned iz=0; iz<_KICK_ZDIM_; iz++) {
75  double z = _KICK_ZMIN_ + iz*_KICK_ZSTEP_, r = (z-z0)*slope, br, bz;
76 
77  int ret = bmf->GetFieldValue(r, z, br, bz); assert(!ret);
78  TVector2 n(1.0, slope), b(bz, br);
79  double norm = (b.Norm(n)).Mod();
80  // Assume ~420mrad kick for 1 GeV/c and 1.3T*m B*dl (HERMES); may want to cross-check!;
81  double kick = (420.0/_P0_) * sqrt(1.0+slope*slope)*_KICK_ZSTEP_ * b.Mod()*tan(b.DeltaPhi(n)) / (1.3*100.0);
82  accu += kick;
83 
84  avg += accu;
85  avg_sqr += accu*accu;
86  } //for iz
87 
88  avg /= _KICK_ZDIM_; avg_sqr /= _KICK_ZDIM_;
89 
90  double dsp = sqrt(avg_sqr - avg*avg);
91  kicksigs[is] = dsp;
92  printf(" %3d -> <kick> %7.2f [mrad] -> sigma %7.2f [mrad]\n", is, avg, dsp);
93  } //for is
94  }
95 
96  {
97  double qstep = 1.0, alen = qstep*0.8;
98 
99  for(unsigned ir=0; ir<25; ir++) {
100  unsigned counter = 0;
101  double rr = ir*5.0, zz = 0.0;
102 
103  for( ; ; ) {
104  double B[2];
105 
106  double bz, br;
107  // NB: prefer to regularize GetField() on Z-axis;
108  if (!bmf->GetFieldValue(ir ? rr : 0.0, zz, br, bz)) break;
109 
110  double norm = sqrt(br*br+bz*bz);
111 
112  TEveArrow *ea = new TEveArrow(0.0, alen*br/norm, alen*bz/norm, 0.0, rr, zz);
113  int color = (zz >= _KICK_ZMIN_ && zz <= _KICK_ZMIN_ + _KICK_ZDIM_*_KICK_ZSTEP_) ? kRed : kOrange;
114  ea->SetMainColor(color);
115  ea->SetPickable(kFALSE);
116  ea->SetTubeR(1.50);
117  ea->SetConeR(1.00);
118  ea->SetConeL(1.00);
119  gEve->AddElement(ea);
120 
121  zz += (bz/norm)*qstep; rr += (br/norm)*qstep;
122 
123  if (zz > 300.0) break;
124  if (counter++ > 1000) break;
125  } //for inf
126  } //for ir
127 
128  for(unsigned iq=0; iq<5; iq++) {
129  double th = (iq+1)*5*TMath::Pi()/180.;
130 
131  auto pt = new TEveLine(2);
132  pt->SetMainColor(kWhite);
133  pt->SetPickable(kFALSE);
134  pt->SetPoint(0, 0., 0., 0.);
135  pt->SetPoint(1, 0., 300.*tan(th), 300.);
136  gEve->AddElement(pt);
137  } //for iq
138  }
139 
140  gEve->FullRedraw3D(kTRUE);
141 
142  {
143  TCanvas *c1 = new TCanvas("c1", "c1", 0, 0, 800, 500);
144  TH1D *dspH = new TH1D("", "", _KICK_TDIM_, 0.0, _KICK_TDIM_*_KICK_TSTEP_);
145 
146  double p0 = 30.0;
147 
148  // Up to eta~1 with a step of 1 degree;
149  for(unsigned is=0; is<_KICK_TDIM_; is++) {
150  double theta = is*_KICK_TSTEP_;
151  int ibin = (int)floor((theta-_KICK_TMIN_)/_KICK_TSTEP_);
152 
153  if (ibin >= 0 && ibin < _KICK_TDIM_)
154  dspH->SetBinContent(is+1, (_P0_/p0)*kicksigs[ibin]);
155  } //for is
156 
157  dspH->SetMinimum( 0.0);
158  dspH->SetMaximum(10.0);
159  dspH->GetXaxis()->SetTitle("Scattered hadron polar angle, [degree]");
160  dspH->GetXaxis()->SetTitleFont(52);
161  dspH->GetXaxis()->SetTitleSize(0.05);
162  dspH->GetXaxis()->SetLabelFont(52);
163  dspH->GetXaxis()->SetLabelSize(0.04);
164  dspH->GetXaxis()->SetTitleOffset(0.90);
165  dspH->GetYaxis()->SetTitle("Direction variation, [mrad]");
166  dspH->GetYaxis()->SetTitleFont(52);
167  dspH->GetYaxis()->SetTitleSize(0.05);
168  dspH->GetYaxis()->SetLabelFont(52);
169  dspH->GetYaxis()->SetLabelSize(0.04);
170  dspH->GetYaxis()->SetTitleOffset(0.80);
171  gPad->SetGrid();
172  dspH->SetLineWidth(2);
173  dspH->SetFillColor(kGreen+1);
174  dspH->Draw();
175 
176  TLine *line = new TLine(25., 0., 25., 10.);
177  line->SetLineColor(kRed);
178  line->SetLineWidth(2);
179  line->SetLineStyle(5);
180  line->Draw();
181  }
182 } // mfield2eve()