11#include <RtypesCore.h>
21 Double_t HelixBase::fgHelixBz = 0.5;
23 HelixBase::~HelixBase() {}
25 HelixBase::HelixBase() :
40 HelixBase::HelixBase(
const HelixBase& t) :
49 fLambdaCos(t.fLambdaCos),
50 fLambdaSin(t.fLambdaSin),
56 HelixBase::HelixBase(
const TVector3& x,
const TVector3& mom, Double_t charge, Double_t conversion) :
HelixBase() {
57 Double_t pt = mom.Pt();
58 if (TMath::Abs(conversion) < 0.00000001) conversion = -1.0 / 0.299792458 / GetBz();
59 fH = -TMath::Sign(1.0, GetBz() * charge);
60 fCurv = charge / (conversion * pt) * 0.01;
61 if (conversion * pt == 0) fCurv = 0;
62 fCurv = TMath::Abs(fCurv);
63 fLambda = TMath::ATan2(mom.Pz(), pt);
64 fLambdaCos = TMath::Cos(fLambda);
65 fLambdaSin = TMath::Sin(fLambda);
67 Double_t Psi = mom.Phi();
68 fPhi0 = TVector2::Phi_mpi_pi(Psi - fH * TMath::PiOver2());
69 fPhiSin = TMath::Sin(fPhi0);
70 fPhiCos = TMath::Cos(fPhi0);
71 fXc = x.X() - fPhiCos / fCurv;
72 fYc = x.Y() - fPhiSin / fCurv;
104 return TMath::Abs(TMath::TwoPi() / (fH *
GetCurv() * fLambdaCos));
108 void HelixBase::BasePrint()
const {
109 std::cout <<
"*********** HALHELIX ***********" << std::endl;
110 std::cout << Form(
"X0 %4.4f %4.4f %4.4f", fX0, fY0, fZ0) << std::endl;
111 std::cout << Form(
"Xc = %4.4f Yc=%4.4f L=%4.4f ", fXc, fYc, fLambda) << std::endl;
112 std::cout << Form(
"Phi0=%4.2f Curv=%4.4f", fPhi0 / TMath::DegToRad(), fCurv) << std::endl;
116 Double_t pt = mom.Pt();
117 if (TMath::Abs(conversion) < 0.00000001) conversion = -1 / 0.299792458 / GetBz();
118 fH = -TMath::Sign(1.0, GetBz() * charge);
119 fCurv = charge / (conversion * pt);
120 if (conversion * pt == 0) fCurv = 0;
121 fCurv = TMath::Abs(fCurv * 0.01);
122 fLambda = TMath::ATan2(mom.Pz(), pt);
123 fLambdaCos = TMath::Cos(fLambda);
124 fLambdaSin = TMath::Sin(fLambda);
125 Double_t Psi = mom.Phi();
126 fPhi0 = Psi - fH * TMath::PiOver2();
127 if (fPhi0 < -TMath::Pi()) fPhi0 += TMath::TwoPi();
128 if (fPhi0 > TMath::Pi()) fPhi0 -= TMath::TwoPi();
129 fPhiSin = TMath::Sin(fPhi0);
130 fPhiCos = TMath::Cos(fPhi0);
131 fXc = x.X() - fPhiCos / fCurv;
132 fYc = x.Y() - fPhiSin / fCurv;
146 Double_t conversion) {
147 Double_t pt = TMath::Sqrt(px * px + py * py);
148 if (TMath::Abs(conversion) < 0.00000001) conversion = -1 / 0.299792458 / GetBz();
149 fH = -TMath::Sign(1.0, GetBz() * charge);
150 fCurv = charge / (conversion * pt);
151 if (conversion * pt == 0) fCurv = 0;
152 fCurv = TMath::Abs(fCurv * 0.01);
153 fLambda = TMath::ATan2(pz, pt);
154 fLambdaCos = TMath::Cos(fLambda);
155 fLambdaSin = TMath::Sin(fLambda);
158 if (pt != 0 && pz != 0) Psi = TMath::ATan2(py, px);
159 fPhi0 = Psi - fH * TMath::PiOver2();
160 if (fPhi0 < -TMath::Pi()) fPhi0 += TMath::TwoPi();
161 if (fPhi0 > TMath::Pi()) fPhi0 -= TMath::TwoPi();
162 fPhiSin = TMath::Sin(fPhi0);
163 fPhiCos = TMath::Cos(fPhi0);
164 fXc = x - fPhiCos / fCurv;
165 fYc = y - fPhiSin / fCurv;
174 Double_t HelixBase::GetBz() {
return fgHelixBz; }
177 if (
this != &helix) {
182 fLambda = helix.fLambda;
192 if (fCurv == 0) {
return TVector3(fX0 - s * fLambdaCos * fPhiSin, fY0 + s * fLambdaCos * fPhiCos, fZ0 + s * fLambdaSin); }
193 Double_t overC = 1.0 / fCurv;
194 return TVector3(fX0 + (TMath::Cos(fPhi0 + s * fH * fCurv * fLambdaCos) - fPhiCos) * overC,
195 fY0 + (TMath::Sin(fPhi0 + s * fH * fCurv * fLambdaCos) - fPhiSin) * overC,
196 fZ0 + s * fLambdaSin);
201 Double_t HelixBase::FudgePathLenght(
const TVector3& vec)
const {
203 Double_t dx = vec.X() - fX0;
204 Double_t dy = vec.Y() - fY0;
207 s = (dy * fPhiCos - dx * fPhiSin) / fLambdaCos;
209 s = TMath::ATan2(dy * fPhiCos - dx * fPhiSin, 1. / fCurv + dx * fPhiCos + dy * fPhiSin) / (fH * fCurv * fLambdaCos);
222 Double_t t1 = fLambdaCos * (fX0 * fPhiSin - fY0 * fPhiCos);
223 Double_t t12 = fY0 * fY0;
224 Double_t t13 = fPhiCos * fPhiCos;
225 Double_t t15 = r * r;
226 Double_t t16 = fX0 * fX0;
227 Double_t t20 = -fLambdaCos * fLambdaCos * (2.0 * fX0 * fPhiSin * fY0 * fPhiCos + t12 - t12 * t13 - t15 + t13 * t16);
232 t20 = TMath::Sqrt(t20);
233 s1 = (t1 - t20) / (fLambdaCos * fLambdaCos);
234 s2 = (t1 + t20) / (fLambdaCos * fLambdaCos);
236 Double_t t1 = fY0 * fCurv;
237 Double_t t2 = fPhiSin;
238 Double_t t3 = fCurv * fCurv;
239 Double_t t4 = fY0 * t2;
240 Double_t t5 = fPhiCos;
241 Double_t t6 = fX0 * t5;
242 Double_t t8 = fX0 * fX0;
243 Double_t t11 = fY0 * fY0;
244 Double_t t14 = r * r;
245 Double_t t15 = t14 * fCurv;
246 Double_t t17 = t8 * t8;
247 Double_t t19 = t11 * t11;
248 Double_t t21 = t11 * t3;
249 Double_t t23 = t5 * t5;
250 Double_t t32 = t14 * t14;
251 Double_t t35 = t14 * t3;
252 Double_t t38 = 8.0 * t4 * t6 - 4.0 * t1 * t2 * t8 - 4.0 * t11 * fCurv * t6 + 4.0 * t15 * t6 + t17 * t3 + t19 * t3
253 + 2.0 * t21 * t8 + 4.0 * t8 * t23 - 4.0 * t8 * fX0 * fCurv * t5 - 4.0 * t11 * t23
254 - 4.0 * t11 * fY0 * fCurv * t2 + 4.0 * t11 - 4.0 * t14 + t32 * t3 + 4.0 * t15 * t4 - 2.0 * t35 * t11
256 Double_t t40 = (-t3 * t38);
261 t40 = TMath::Sqrt(t40);
263 Double_t t43 = fX0 * fCurv;
264 Double_t t45 = 2.0 * t5 - t35 + t21 + 2.0 - 2.0 * t1 * t2 - 2.0 * t43 - 2.0 * t43 * t5 + t8 * t3;
265 Double_t t46 = fH * fLambdaCos * fCurv;
267 s1 = (-fPhi0 + 2.0 * TMath::ATan((-2.0 * t1 + 2.0 * t2 + t40) / t45)) / t46;
268 s2 = -(fPhi0 + 2.0 * TMath::ATan((2.0 * t1 - 2.0 * t2 + t40) / t45)) / t46;
274 if (!TMath::IsNaN(s1)) {
275 if (TMath::Abs(s1 - p) < TMath::Abs(s1))
277 else if (TMath::Abs(s1 + p) < TMath::Abs(s1))
280 if (!TMath::IsNaN(s2)) {
281 if (TMath::Abs(s2 - p) < TMath::Abs(s2))
283 else if (TMath::Abs(s2 + p) < TMath::Abs(s2))
304 Double_t dx = point.X() - fX0;
305 Double_t dy = point.Y() - fY0;
306 Double_t dz = point.Z() - fZ0;
308 Double_t Phase = TMath::ATan2(fYc - fY0, fXc - fX0) + TMath::Pi();
309 if (Phase < -TMath::Pi()) { Phase += TMath::TwoPi(); }
310 if (Phase > TMath::Pi()) { Phase -= TMath::TwoPi(); }
311 Double_t CosPhase = TMath::Cos(Phase);
312 Double_t SinPhase = TMath::Sin(Phase);
317 s = (dy * CosPhase - dx * SinPhase) / fLambdaCos;
320 const Double_t overC = 1.0 / fCurv;
321 s = atan2(dy * CosPhase - dx * SinPhase, overC + dx * CosPhase + dy * SinPhase) / (fH * fCurv * fLambdaCos);
322 period = TMath::Abs(TMath::TwoPi() / (fH * fCurv * fLambdaCos));
327 const Double_t MaxPrecisionNeeded = 0.000001;
328 const int MaxIterations = 100;
334 Double_t t34 = fCurv * fLambdaCos * fLambdaCos;
335 Double_t t41 = fLambdaSin * fLambdaSin;
336 Double_t t6, t7, t11, t12, t19;
345 Double_t ds = period;
349 for (j = 1; j < MaxIterations; j++) {
357 for (j = -1; - j < MaxIterations; j--) {
365 if (jmin) s += jmin * ds;
375 for (
int i = 0; i < MaxIterations; i++) {
376 t6 = Phase + s * fH * fCurv * fLambdaCos;
378 t11 = dx - overC * (t7 - CosPhase);
380 t19 = dy - overC * (t12 - SinPhase);
381 s -= (t11 * t12 * fH * fLambdaCos - t19 * t7 * fH * fLambdaCos - (dz - s * fLambdaSin) * fLambdaSin)
382 / (t12 * t12 * fLambdaCos * fLambdaCos + t11 * t7 * t34 + t7 * t7 * fLambdaCos * fLambdaCos + t19 * t12 * t34 + t41);
383 if (TMath::Abs(sOld - s) < MaxPrecisionNeeded)
break;
393 if ((fCurv == 0 && h.fCurv != 0) || ((fCurv != 0 && h.fCurv == 0))) {
404 TVector3 a(-fLambdaCos * fPhiSin, fLambdaCos * fPhiCos, fLambdaSin);
405 TVector3 b(-h.fLambdaCos * h.fPhiSin, h.fLambdaCos * h.fPhiCos, h.fLambdaSin);
409 s2 = (k - ab * g) / (ab * ab - 1.);
418 Double_t dd = ::sqrt(dx * dx + dy * dy);
419 Double_t r1 = 1. / fCurv;
420 Double_t r2 = 1. / h.
GetCurv();
422 Double_t cosAlpha = (r1 * r1 + dd * dd - r2 * r2) / (2 * r1 * dd);
426 if (TMath::Abs(cosAlpha) < 1) {
427 const Double_t overDD = 1.0 / dd;
428 Double_t sinAlpha = TMath::Sin(TMath::ACos(cosAlpha));
429 xx =
BaseGetXcenter() + r1 * (cosAlpha * dx - sinAlpha * dy) * overDD;
430 yy =
BaseGetYcenter() + r1 * (sinAlpha * dx + cosAlpha * dy) * overDD;
432 xx =
BaseGetXcenter() + r1 * (cosAlpha * dx + sinAlpha * dy) * overDD;
433 yy =
BaseGetYcenter() + r1 * (cosAlpha * dy - sinAlpha * dx) * overDD;
437 int rsign = ((r2 - r1) > dd ? -1 : 1);
449 const Double_t MinStepSize = 10 * 0.000001;
450 const Double_t MinRange = 10 * 0.01;
452 Double_t range = TMath::Max(2 * dmin, MinRange);
453 Double_t ds = range / 10;
454 Double_t slast = -999999, ss, d;
458 while (ds > MinStepSize) {
459 for (ss = s1; ss < s2 + ds; ss += ds) {
478 }
else if (s == slast) {
493 Double_t HelixBase::Distance(
const TVector3& p, Bool_t scanPeriods)
const {
497 HelixBase::HelixBase(Double_t x,
504 Double_t conversion) :
505 HelixBase(TVector3(x, y, z), TVector3(px, py, pz), charge, conversion) {}
520 Double_t newPhase = TMath::ATan2(origin.Y() - fYc, origin.X() - fXc);
521 const Double_t conversion = -1.0 / 0.299792458 / GetBz();
522 const Double_t charge = -TMath::Sign(1.0, GetBz() * fH);
523 Double_t pt = TMath::Abs(charge / (conversion * fCurv) * 0.01);
526 if (newPhase < -TMath::Pi()) newPhase += TMath::TwoPi();
527 if (newPhase > TMath::Pi()) newPhase -= TMath::TwoPi();
528 Double_t shiftPhase = newPhase + fH * TMath::PiOver2();
529 return TVector3(pt * TMath::Cos(shiftPhase), pt * TMath::Sin(shiftPhase), pt * TMath::Tan(fLambda));
531 return TVector3(0, 0, 0);
536 if (period <= 0)
return TMath::Min(s1, s2);
541 return TMath::Min(s1, s2);
547 Double_t newPhase = TMath::ATan2(pos.Y() - fYc, pos.X() - fXc);
548 const Double_t conversion = -1.0 / 0.299792458 / GetBz();
549 const Double_t charge = -TMath::Sign(1.0, GetBz() * fH);
550 Double_t pt = TMath::Abs(charge / (conversion * fCurv) * 0.01);
551 if (newPhase < -TMath::Pi()) newPhase += TMath::TwoPi();
552 if (newPhase > TMath::Pi()) newPhase -= TMath::TwoPi();
553 Double_t shiftPhase = newPhase + fH * TMath::PiOver2();
554 mom.SetXYZ(pt * TMath::Cos(shiftPhase), pt * TMath::Sin(shiftPhase), pt * TMath::Tan(fLambda));
static Double_t MaxPath()
Double_t BaseGetYcenter() const
Double_t GetRotationDirection() const
Double_t GetPeriod() const
void BaseShift(Double_t x, Double_t y, Double_t z)
Int_t BaseIntersection(Double_t R, TVector3 &x1, TVector3 &x2) const
Double_t GetPathAbsMin(Double_t s1, Double_t s2) const
Double_t GetDipAngle() const
TVector3 BasePosition(Double_t s) const
HelixBase & operator=(const HelixBase &helix)
TVector3 BaseMomentum(Double_t s) const
void BaseSetParams(const TVector3 &x, const TVector3 &mom, Double_t charge, Double_t conversion=0.)
Double_t BaseGetXcenter() const
static void SetMagField(Double_t Bz)
void PathLengths(const HelixBase &h, Double_t &s1, Double_t &s2) const
void BasePathLength(Double_t r, Double_t x, Double_t y, Double_t &s1, Double_t &s2) const
TVector3 BaseGetStartPoint() const
void BaseFullEval(Double_t s, TVector3 &mom, TVector3 &pos) const