Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sHelix.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file sHelix.cxx
1 #include <iostream>
2 #include <fstream>
3 #include "sHelix.h"
4 #include "TMath.h"
5 
6 //=================
8  fR(0),
9  fW(0),
10  fC(0),
11  fPhi(0),
12  fX0(0),
13  fY0(0),
14  fZ0(0),
15  fDebug(false)
16 {
17 }
18 //=================
19 sHelix::sHelix(float x0, float y0, float z0, float px, float py, float pz, float q, float b) { // [cm] [GeV] [e] [Tesla]
20  fX0 = x0;
21  fY0 = y0;
22  fZ0 = z0;
23  float qB = q*b; //[e]x[Tesla]
24  fW = qB; //[angular frequency]
25  fPhi = TMath::Pi()+TMath::ATan2(-py,-px); //[rad]
26  float pt = TMath::Sqrt(px*px+py*py);
27  float p = TMath::Sqrt(px*px+py*py+pz*pz);;
28  fR = pt/(0.3*qB)*100; //[cm]
29  fC = pz/pt*fR*fW; //[pitch]
30  //std::cout << "sHelix:: p " << p << " | pt " << pt << " | phi " << fPhi*180/TMath::Pi() << std::endl;
31  fDebug = false;
32 }
33 //=================
34 void sHelix::breakIntoPieces(float t1, float t2, float xx[100][3]) {
35  // returns coordinates of 100 equidistant pieces of this track
36  float dt = (t2-t1)/101;
37  for(int n=0;n!=100; ++n) {
38  float ti = t1+(n+1)*dt;
39  xx[n][0] = x(ti);
40  xx[n][1] = y(ti);
41  xx[n][2] = z(ti);
42  }
43  return;
44 }
45 //=================
46 float sHelix::findFirstInterceptTo(float rd, float hz) {
47  if(fDebug)
48  std::cout << "***** findFirstInterceptTo r:" << rd << " z:" << hz << std::endl;
49  // returns t of first intercept of the helix to a cylinder(r,hz);
50  float t_1, t_2, t_3, t_4;
51 
52  // step 1: solving X^2 + Y^2 = r^2
53  // equation: a cosx + b sinx + c = 0
54  // a = - 2 R Y0 - 2 R^2 Cos(Phi)
55  // b = 2 R X0 - 2 R^2 Sin(Phi)
56  // c = 2 R^2 + X0^2 + Y0^2 - r^2 + 2 R ( Y0 Cos(Phi) - X0 Sin(Phi) )
57  // x = Phi - W T
58  // solution: (a^2 + b^2) sinx = -bc +- sqrt( a^2 (a^2+b^2-c^2) )
59  float a = 2*fR*( fY0 - fR*TMath::Cos(fPhi) );
60  float b = -2*fR*( fX0 + fR*TMath::Sin(fPhi) );
61  float c = 2*fR*fR + fX0*fX0 + fY0*fY0 - rd*rd + 2*fR*(fX0*TMath::Sin(fPhi) - fY0*TMath::Cos(fPhi));
62  //std::cout << "a =" << a << std::endl;
63  //std::cout << "b =" << b << std::endl;
64  //std::cout << "c =" << c << std::endl;
65  if( a*a + b*b < c*c ) { // warranties a^2 + b^2 is more than zero
66  if(fDebug) {
67  std::cout << "FAIL: solution is not a real number\n";
68  std::cout << "a*a =" << a*a << std::endl;
69  std::cout << "b*b =" << b*b << std::endl;
70  std::cout << "c*c =" << c*c << std::endl;
71  }
72  return 0;
73  }
74  float sinx_1 = ( -b*c + TMath::Sqrt(a*a*(a*a+b*b-c*c)) ) / ( a*a + b*b );
75  float sinx_2 = ( -b*c - TMath::Sqrt(a*a*(a*a+b*b-c*c)) ) / ( a*a + b*b );
76  if(fDebug) {
77  std::cout << "Sinx_1 " << sinx_1 << std::endl;
78  std::cout << "Sinx_2 " << sinx_2 << std::endl;
79  //std::cout << "r = x_1 / CosPhi " << (-fR*sinx_1+fX0+fR*TMath::Sin(fPhi)) / TMath::Cos(fPhi) << std::endl;
80  //std::cout << "r = x_2 / CosPhi " << (-fR*sinx_2+fX0+fR*TMath::Sin(fPhi)) / TMath::Cos(fPhi) << std::endl;
81  }
82  t_1=t_2=t_3=t_4=99999;
83  // arc sin returns an angle from -Pi/4 to +Pi/4 so I created two more variables to extend to full 2pi
84  float asinx_1, asinx_2, asinx_3, asinx_4;
85  asinx_1 = TMath::ASin(sinx_1);
86  asinx_2 = TMath::ASin(sinx_2);
87  if(asinx_1<0) {
88  asinx_3 = TMath::Pi() - asinx_1;
89  asinx_1+=TMath::TwoPi();
90  } else {
91  asinx_3 = TMath::Pi() - asinx_1;
92  }
93  if(asinx_2<0) {
94  asinx_4 = TMath::Pi() - asinx_2;
95  asinx_2+=TMath::TwoPi();
96  } else {
97  asinx_4 = TMath::Pi() - asinx_2;
98  }
99 
100  //phi-wt = asin
101  if(fDebug) {
102  std::cout << "PHI0 " << fPhi << std::endl;
103  std::cout << "ASinx_1 " << asinx_1 << std::endl;
104  std::cout << "ASinx_2 " << asinx_2 << std::endl;
105  std::cout << "ASinx_3 " << asinx_3 << std::endl;
106  std::cout << "ASinx_4 " << asinx_4 << std::endl;
107  }
108 
109  t_1 = (fPhi - asinx_1)/fW;
110  t_2 = (fPhi - asinx_2)/fW;
111  t_3 = (fPhi - asinx_3)/fW;
112  t_4 = (fPhi - asinx_4)/fW;
113 
114  if(fDebug) {
115  std::cout << "IN R: | x(t) | y(t) || r(t) z(t)" << std::endl;
116  std::cout << "t_1 " << t_1 << " | " << x(t_1) << " " << y(t_1) << " || " << r(t_1) << " " << z(t_1) << std::endl;
117  std::cout << "t_2 " << t_2 << " | " << x(t_2) << " " << y(t_2) << " || " << r(t_2) << " " << z(t_2) << std::endl;
118  std::cout << "t_3 " << t_3 << " | " << x(t_3) << " " << y(t_3) << " || " << r(t_3) << " " << z(t_3) << std::endl;
119  std::cout << "t_4 " << t_4 << " | " << x(t_4) << " " << y(t_4) << " || " << r(t_4) << " " << z(t_4) << std::endl;
120  }
121  if(t_1<0||!TMath::AreEqualAbs(rd,r(t_1),0.1)) t_1 = 99999;
122  if(t_2<0||!TMath::AreEqualAbs(rd,r(t_2),0.1)) t_2 = 99999;
123  if(t_3<0||!TMath::AreEqualAbs(rd,r(t_3),0.1)) t_3 = 99999;
124  if(t_4<0||!TMath::AreEqualAbs(rd,r(t_4),0.1)) t_4 = 99999;
125 
126  float t1 = TMath::Min( t_1, t_2 );
127  t1 = TMath::Min( t1, t_3 );
128  t1 = TMath::Min( t1, t_4 );
129 
130  // step 2: solving |z| = hz
131  t_1 = ( hz - fZ0)/fC;
132  t_2 = (-hz - fZ0)/fC;
133  if(fDebug) {
134  std::cout << "IN Z: | x(t) | y(t) || r(t) z(t)" << std::endl;
135  std::cout << "t_1 " << t_1 << " | " << x(t_1) << " " << y(t_1) << " || " << r(t_1) << " " << z(t_1) << std::endl;
136  std::cout << "t_2 " << t_2 << " | " << x(t_2) << " " << y(t_2) << " || " << r(t_2) << " " << z(t_2) << std::endl;
137  }
138  if(t_1<0||!TMath::AreEqualAbs(hz,z(t_1),0.1)) t_1 = 99999;
139  if(t_2<0||!TMath::AreEqualAbs(hz,z(t_2),0.1)) t_2 = 99999;
140  float t2 = TMath::Min( t_1, t_2 );
141  float tt = TMath::Min(t1,t2);
142  if(fDebug) std::cout << " chosen time " << tt << std::endl;
143  if(tt>4) tt = 99999;
144  return tt;
145 }
146 //=================
147 void sHelix::SaveTracktoRootScript(float ri, float ro, float hz, char *filec) {
148  float t1 = findFirstInterceptTo(ri,hz);
149  float t2 = findFirstInterceptTo(ro,hz);
150  float xx[100],yy[100],zz[100], xt[100],yt[100],zt[100];
151  for(int t=0; t!=100; ++t) {
152  float ti = t/float(100);
153  xx[t] = x(ti);
154  yy[t] = y(ti);
155  zz[t] = z(ti);
156  float tt = t1 + t/100.0*(t2-t1);
157  xt[t] = x(tt);
158  yt[t] = y(tt);
159  zt[t] = z(tt);
160  }
161  std::ofstream out(filec);
162  out << "{\n";
163  out << "float x[100] = {";
164  for(int t=0; t!=100; ++t) out << (t==0?"":",") << xx[t];
165  out << "};\n";
166  out << "float y[100] = {";
167  for(int t=0; t!=100; ++t) out << (t==0?"":",") << yy[t];
168  out << "};\n";
169  out << "float z[100] = {";
170  for(int t=0; t!=100; ++t) out << (t==0?"":",") << zz[t];
171  out << "};\n";
172  out << "float xt[100] = {";
173  for(int t=0; t!=100; ++t) out << (t==0?"":",") << xt[t];
174  out << "};\n";
175  out << "float yt[100] = {";
176  for(int t=0; t!=100; ++t) out << (t==0?"":",") << yt[t];
177  out << "};\n";
178  out << "float zt[100] = {";
179  for(int t=0; t!=100; ++t) out << (t==0?"":",") << zt[t];
180  out << "};\n";
181  out << "TPolyLine3D *pol1 = new TPolyLine3D(100,x,y,z);\n";
182  out << "TPolyLine3D *pol2 = new TPolyLine3D(100,xt,yt,zt);\n";
183  out << "pol2->SetLineColor(kRed);\n";
184  out << "pol2->SetLineWidth(3);\n";
185  out << "pol1->Draw();\n";
186  out << "pol2->Draw();\n";
187  out << "}\n";
188  out.close();
189  return;
190 }