18 using namespace ROOT::Experimental;
19 namespace REX = ROOT::Experimental;
50 const Double_t kPtMinSqr = 1e-20;
51 const Double_t kAMin = 1e-10;
52 const Double_t kStepEps = 1e-3;
58 REveTrackPropagator::Helix_t::Helix_t() :
60 fMaxAng(45), fMaxStep(20.f), fDelta(0.1),
61 fPhi(0), fValid(kFALSE),
62 fLam(-1), fR(-1), fPhiStep(-1), fSin(-1), fCos(-1),
64 fPtMag(-1), fPlMag(-1), fLStep(-1)
71 void REveTrackPropagator::Helix_t::UpdateCommon(
const REveVectorD& p,
const REveVectorD& b)
90 void REveTrackPropagator::Helix_t::UpdateHelix(
const REveVectorD& p,
const REveVectorD& b,
91 Bool_t full_update, Bool_t enforce_max_step)
96 TMath::Cross(fE1.Arr(), fE2.Arr(), fE3.Arr());
97 if (fCharge < 0) fE3.NegateXYZ();
101 using namespace TMath;
102 Double_t a = fgkB2C * b.Mag() * Abs(fCharge);
103 if (a > kAMin && fPtMag*fPtMag > kPtMinSqr)
107 fR = Abs(fPtMag / a);
108 fLam = fPlMag / fPtMag;
111 fPhiStep = fMaxAng * DegToRad();
114 Double_t ang = 2.0 * ACos(1.0f - fDelta/fR);
120 Double_t curr_step = fR * fPhiStep * Sqrt(1.0f + fLam*fLam);
121 if (curr_step > fMaxStep || enforce_max_step)
122 fPhiStep *= fMaxStep / curr_step;
124 fLStep = fR * fPhiStep * fLam;
125 fSin = Sin(fPhiStep);
126 fCos = Cos(fPhiStep);
138 void REveTrackPropagator::Helix_t::UpdateRK(
const REveVectorD& p,
const REveVectorD& b)
159 void REveTrackPropagator::Helix_t::Step(
const REveVector4D& v,
const REveVectorD& p,
160 REveVector4D& vOut, REveVectorD& pOut)
166 REveVectorD d = fE2*(fR*fSin) + fE3*(fR*(1-fCos)) + fE1*fLStep;
168 vOut.fT += TMath::Abs(fLStep);
170 pOut = fPl + fE2*(fPtMag*fCos) + fE3*(fPtMag*fSin);
178 vOut += p * (fMaxStep / p.Mag());
203 Double_t REveTrackPropagator::fgDefMagField = 0.5;
204 const Double_t REveTrackPropagator::fgkB2C = 0.299792458e-2;
205 REveTrackPropagator REveTrackPropagator::fgDefault;
207 Double_t REveTrackPropagator::fgEditorMaxR = 2000;
208 Double_t REveTrackPropagator::fgEditorMaxZ = 4000;
213 REveTrackPropagator::REveTrackPropagator(
const std::string& n,
const std::string& t,
214 REveMagField *field, Bool_t own_field) :
220 fOwnMagFiledObj(own_field),
222 fMaxR (350), fMaxZ (450),
223 fNMax (4096), fMaxOrbs (0.5),
225 fEditPathMarks (kTRUE),
226 fFitDaughters (kTRUE), fFitReferences (kTRUE),
228 fFitCluster2Ds (kTRUE), fFitLineSegments (kTRUE),
229 fRnrDaughters (kFALSE), fRnrReferences (kFALSE),
230 fRnrDecay (kFALSE), fRnrCluster2Ds (kFALSE),
234 fProjTrackBreaking(kPTB_Break), fRnrPTBMarkers(kFALSE), fPTBAtt(),
238 fPMAtt.SetMarkerColor(kYellow);
239 fPMAtt.SetMarkerStyle(2);
240 fPMAtt.SetMarkerSize(2);
242 fFVAtt.SetMarkerColor(kRed);
243 fFVAtt.SetMarkerStyle(4);
244 fFVAtt.SetMarkerSize(1.5);
246 fPTBAtt.SetMarkerColor(kBlue);
247 fPTBAtt.SetMarkerStyle(4);
248 fPTBAtt.SetMarkerSize(0.8);
251 fMagFieldObj =
new REveMagFieldConst(0., 0., fgDefMagField);
252 fOwnMagFiledObj = kTRUE;
259 REveTrackPropagator::~REveTrackPropagator()
270 void REveTrackPropagator::OnZeroRefCount()
272 CheckReferenceCount(
"REveTrackPropagator::OnZeroRefCount ");
279 void REveTrackPropagator::CheckReferenceCount(
const std::string& from)
283 REveElement::CheckReferenceCount(from);
291 void REveTrackPropagator::StampAllTracks()
293 for (
auto &i: fBackRefs) {
294 auto track =
dynamic_cast<REveTrack *
>(i.first);
295 if (track) track->StampObjProps();
302 void REveTrackPropagator::InitTrack(
const REveVectorD &v, Int_t charge)
305 fPoints.push_back(fV);
315 void REveTrackPropagator::InitTrack(
const REveVectorF& v, Int_t charge)
318 InitTrack(vd, charge);
324 void REveTrackPropagator::ResetTrack()
327 fPoints.swap(fLastPoints);
336 Int_t REveTrackPropagator::GetCurrentPoint()
const
338 return fPoints.size() - 1;
345 Double_t REveTrackPropagator::GetTrackLength(Int_t start_point, Int_t end_point)
const
347 if (end_point < 0) end_point = fPoints.size() - 1;
350 for (Int_t i = start_point; i < end_point; ++i)
352 sum += (fPoints[i+1] - fPoints[i]).Mag();
360 Bool_t REveTrackPropagator::GoToVertex(REveVectorD& v, REveVectorD& p)
362 Update(fV, p, kTRUE);
364 if ((v-fV).Mag() < kStepEps)
366 fPoints.push_back(v);
370 return fH.fValid ? LoopToVertex(v, p) : LineToVertex(v);
377 Bool_t REveTrackPropagator::GoToLineSegment(
const REveVectorD& s,
const REveVectorD& r, REveVectorD& p)
379 Update(fV, p, kTRUE);
384 ClosestPointBetweenLines(s, r, fV, p, v);
390 return LoopToLineSegment(s, r, p);
397 Bool_t REveTrackPropagator::GoToVertex(REveVectorF& v, REveVectorF& p)
399 REveVectorD vd(v), pd(p);
400 Bool_t result = GoToVertex(vd, pd);
408 Bool_t REveTrackPropagator::GoToLineSegment(
const REveVectorF& s,
const REveVectorF& r, REveVectorF& p)
410 REveVectorD sd(s), rd(r), pd(p);
411 Bool_t result = GoToLineSegment(sd, rd, pd);
420 void REveTrackPropagator::GoToBounds(REveVectorD& p)
422 Update(fV, p, kTRUE);
424 fH.fValid ? LoopToBounds(p): LineToBounds(p);
430 void REveTrackPropagator::GoToBounds(REveVectorF& p)
440 void REveTrackPropagator::Update(
const REveVector4D& v,
const REveVectorD& p,
441 Bool_t full_update, Bool_t enforce_max_step)
443 if (fStepper == kHelix)
445 fH.UpdateHelix(p, fMagFieldObj->GetFieldD(v), !fMagFieldObj->IsConst() || full_update, enforce_max_step);
449 fH.UpdateRK(p, fMagFieldObj->GetFieldD(v));
453 using namespace TMath;
455 Float_t a = fgkB2C * fMagFieldObj->GetMaxFieldMagD() * Abs(fH.fCharge);
461 fH.fPhiStep = fH.fMaxAng * DegToRad();
462 if (fH.fR > fH.fDelta )
464 Double_t ang = 2.0 * ACos(1.0f - fH.fDelta/fH.fR);
465 if (ang < fH.fPhiStep)
470 fH.fRKStep = fH.fR * fH.fPhiStep * Sqrt(1 + fH.fLam*fH.fLam);
471 if (fH.fRKStep > fH.fMaxStep || enforce_max_step)
473 fH.fPhiStep *= fH.fMaxStep / fH.fRKStep;
474 fH.fRKStep = fH.fMaxStep;
479 fH.fRKStep = fH.fMaxStep;
488 void REveTrackPropagator::Step(
const REveVector4D &v,
const REveVectorD &p, REveVector4D &vOut, REveVectorD &pOut)
490 if (fStepper == kHelix)
492 fH.Step(v, p, vOut, pOut);
500 Double_t pm = p.Mag();
501 Double_t nm = 1.0 / pm;
502 vecRKIn[3] = p.fX*nm;
503 vecRKIn[4] = p.fY*nm;
504 vecRKIn[5] = p.fZ*nm;
505 vecRKIn[6] = p.Mag();
507 Double_t vecRKOut[7];
508 StepRungeKutta(fH.fRKStep, vecRKIn, vecRKOut);
510 vOut.fX = vecRKOut[0];
511 vOut.fY = vecRKOut[1];
512 vOut.fZ = vecRKOut[2];
513 vOut.fT = v.fT + fH.fRKStep;
515 pOut.fX = vecRKOut[3]*pm;
516 pOut.fY = vecRKOut[4]*pm;
517 pOut.fZ = vecRKOut[5]*pm;
525 void REveTrackPropagator::LoopToBounds(REveVectorD& p)
527 const Double_t maxRsq = fMaxR*fMaxR;
529 REveVector4D currV(fV);
530 REveVector4D forwV(fV);
531 REveVectorD forwP (p);
533 Int_t np = fPoints.size();
534 Double_t maxPhi = fMaxOrbs*TMath::TwoPi();
536 while (fH.fPhi < maxPhi && np<fNMax)
538 Step(currV, p, forwV, forwP);
541 if (forwV.Perp2() > maxRsq)
543 Float_t t = (fMaxR - currV.R()) / (forwV.R() - currV.R());
546 Warning(
"HelixToBounds",
"In MaxR crossing expected t>=0 && t<=1: t=%f, r1=%f, r2=%f, MaxR=%f.",
547 t, currV.R(), forwV.R(), fMaxR);
550 REveVectorD d(forwV);
554 fPoints.push_back(d);
559 else if (TMath::Abs(forwV.fZ) > fMaxZ)
561 Double_t t = (fMaxZ - TMath::Abs(currV.fZ)) / TMath::Abs((forwV.fZ - currV.fZ));
564 Warning(
"HelixToBounds",
"In MaxZ crossing expected t>=0 && t<=1: t=%f, z1=%f, z2=%f, MaxZ=%f.",
565 t, currV.fZ, forwV.fZ, fMaxZ);
568 REveVectorD d(forwV -currV);
571 fPoints.push_back(d);
579 fPoints.push_back(currV);
588 Bool_t REveTrackPropagator::LoopToVertex(REveVectorD& v, REveVectorD& p)
590 const Double_t maxRsq = fMaxR * fMaxR;
592 REveVector4D currV(fV);
593 REveVector4D forwV(fV);
594 REveVectorD forwP(p);
596 Int_t first_point = fPoints.size();
597 Int_t np = first_point;
599 Double_t prod0=0, prod1;
603 Step(currV, p, forwV, forwP);
604 Update(forwV, forwP);
606 if (PointOverVertex(v, forwV, &prod1))
611 if (IsOutsideBounds(forwV, maxRsq, fMaxZ))
617 fPoints.push_back(forwV);
622 }
while (np < fNMax);
625 if (np > first_point)
627 if ((v - currV).Mag() > kStepEps)
629 Double_t step_frac = prod0 / (prod0 - prod1);
634 Float_t orig_max_step = fH.fMaxStep;
635 fH.fMaxStep = step_frac * (forwV - currV).Mag();
636 Update(currV, p, kTRUE, kTRUE);
637 Step(currV, p, forwV, forwP);
640 fPoints.push_back(currV);
642 fH.fMaxStep = orig_max_step;
647 REveVectorD off(v - currV);
648 off *= 1.0f / currV.fT;
649 DistributeOffset(off, first_point, np, p);
655 fPoints.push_back(v);
665 Bool_t REveTrackPropagator::LoopToLineSegment(
const REveVectorD& s,
const REveVectorD& r, REveVectorD& p)
667 const Double_t maxRsq = fMaxR * fMaxR;
668 const Double_t rMagInv = 1./r.Mag();
670 REveVector4D currV(fV);
671 REveVector4D forwV(fV);
672 REveVectorD forwP(p);
674 Int_t first_point = fPoints.size();
675 Int_t np = first_point;
681 Step(currV, p, forwV, forwP);
682 Update(forwV, forwP);
684 ClosestPointFromVertexToLineSegment(forwV, s, r, rMagInv, forwC);
688 REveVectorD b = r; b.Normalize();
689 Double_t x = forwP.Dot(b);
690 REveVectorD pTPM = forwP - x*b;
691 if (pTPM.Dot(forwC - forwV) < 0)
696 if (IsOutsideBounds(forwV, maxRsq, fMaxZ))
702 fPoints.push_back(forwV);
707 }
while (np < fNMax);
711 ClosestPointBetweenLines(s, r, currV, forwV - currV, v);
714 if (np > first_point)
716 if ((v - currV).Mag() > kStepEps)
718 REveVector last_step = forwV - currV;
719 REveVector delta = v - currV;
720 Double_t step_frac = last_step.Dot(delta) / last_step.Mag2();
725 Float_t orig_max_step = fH.fMaxStep;
726 fH.fMaxStep = step_frac * (forwV - currV).Mag();
727 Update(currV, p, kTRUE, kTRUE);
728 Step(currV, p, forwV, forwP);
731 fPoints.push_back(currV);
733 fH.fMaxStep = orig_max_step;
738 REveVectorD off(v - currV);
739 off *= 1.0f / currV.fT;
740 DistributeOffset(off, first_point, np, p);
746 fPoints.push_back(v);
755 void REveTrackPropagator::DistributeOffset(
const REveVectorD& off, Int_t first_point, Int_t np, REveVectorD& p)
759 REveVectorD lpd0(fPoints[np-1]);
760 lpd0 -= fPoints[np-2];
763 for (Int_t i = first_point; i < np; ++i)
765 fPoints[i] += off * fPoints[i].fT;
768 REveVectorD lpd1(fPoints[np-1]);
769 lpd1 -= fPoints[np-2];
773 tt.SetupFromToVec(lpd0, lpd1);
786 Bool_t REveTrackPropagator::LineToVertex(REveVectorD& v)
788 REveVector4D currV = v;
793 fPoints.push_back(currV);
802 void REveTrackPropagator::LineToBounds(REveVectorD& p)
804 Double_t tZ = 0, tR = 0, tB = 0;
808 tZ = (fMaxZ - fV.fZ) / p.fZ;
810 tZ = - (fMaxZ + fV.fZ) / p.fZ;
815 Double_t a = p.fX*p.fX + p.fY*p.fY;
816 Double_t b = 2.0 * (fV.fX*p.fX + fV.fY*p.fY);
817 Double_t c = fV.fX*fV.fX + fV.fY*fV.fY - fMaxR*fMaxR;
818 Double_t d = b*b - 4.0*a*c;
820 Double_t sqrtD = TMath::Sqrt(d);
821 tR = (-b - sqrtD) / (2.0 * a);
823 tR = (-b + sqrtD) / (2.0 * a);
825 tB = tR < tZ ? tR : tZ;
829 REveVectorD nv(fV.fX + p.fX*tB, fV.fY + p.fY*tB, fV.fZ + p.fZ*tB);
837 Bool_t REveTrackPropagator::HelixIntersectPlane(
const REveVectorD& p,
838 const REveVectorD& point,
839 const REveVectorD& normal,
844 if (fMagFieldObj->IsConst())
845 fH.UpdateHelix(mom, fMagFieldObj->GetFieldD(pos), kFALSE, kFALSE);
847 REveVectorD n(normal);
848 REveVectorD delta = pos - point;
849 Double_t d = delta.Dot(n);
857 REveVector4D pos4(pos);
861 Step(pos4, mom, forwV , forwP);
862 Double_t new_d = (forwV - point).Dot(n);
866 Warning(
"HelixIntersectPlane",
"going away from the plane.");
872 itsect = pos + delta * (d / (d - new_d));
884 Bool_t REveTrackPropagator::LineIntersectPlane(
const REveVectorD& p,
885 const REveVectorD& point,
886 const REveVectorD& normal,
889 REveVectorD pos(fV.fX, fV.fY, fV.fZ);
890 REveVectorD delta = point - pos;
892 Double_t pn = p.Dot(normal);
897 Double_t t = delta.Dot(normal) / pn;
918 Bool_t REveTrackPropagator::IntersectPlane(
const REveVectorD& p,
919 const REveVectorD& point,
920 const REveVectorD& normal,
923 if (fH.fCharge && fMagFieldObj && p.Perp2() > kPtMinSqr)
924 return HelixIntersectPlane(p, point, normal, itsect);
926 return LineIntersectPlane(p, point, normal, itsect);
933 void REveTrackPropagator::ClosestPointFromVertexToLineSegment(
const REveVectorD& v,
934 const REveVectorD& s,
935 const REveVectorD& r,
939 REveVectorD dir = v - s;
940 REveVectorD b1 = r * rMagInv;
943 Double_t dot = dir.Dot(b1);
944 REveVectorD dirI = dot * b1;
946 Double_t facX = dot * rMagInv;
960 Bool_t REveTrackPropagator::ClosestPointBetweenLines(
const REveVectorD& p0,
961 const REveVectorD& u,
962 const REveVectorD& q0,
963 const REveVectorD& v,
966 REveVectorD w0 = p0 -q0;
967 Double_t a = u.Mag2();
968 Double_t b = u.Dot(v);
969 Double_t c = v.Mag2();
970 Double_t d = u.Dot(w0);
971 Double_t e = v.Dot(w0);
973 Double_t x = (b*e - c*d)/(a*c -b*b);
974 Bool_t force = (x < 0 || x > 1);
975 out = p0 + TMath::Range(0., 1., x) * u;
982 void REveTrackPropagator::FillPointSet(REvePointSet* ps)
const
984 Int_t size = TMath::Min(fNMax, (Int_t)fPoints.size());
986 for (Int_t i = 0; i < size; ++i)
988 const REveVector4D& v = fPoints[i];
989 ps->SetNextPoint(v.fX, v.fY, v.fZ);
996 void REveTrackPropagator::RebuildTracks()
998 for (
auto &i: fBackRefs) {
999 auto track =
dynamic_cast<REveTrack *
>(i.first);
1002 track->StampObjProps();
1010 void REveTrackPropagator::SetMagField(Double_t bX, Double_t bY, Double_t bZ)
1012 SetMagFieldObj(
new REveMagFieldConst(bX, bY, bZ));
1018 void REveTrackPropagator::SetMagFieldObj(REveMagField* field, Bool_t own_field)
1020 if (fMagFieldObj && fOwnMagFiledObj)
delete fMagFieldObj;
1022 fMagFieldObj = field;
1023 fOwnMagFiledObj = own_field;
1030 void REveTrackPropagator::PrintMagField(Double_t x, Double_t y, Double_t z)
const
1032 if (fMagFieldObj) fMagFieldObj->PrintField(x, y, z);
1038 void REveTrackPropagator::SetMaxR(Double_t x)
1047 void REveTrackPropagator::SetMaxZ(Double_t x)
1056 void REveTrackPropagator::SetMaxOrbs(Double_t x)
1066 void REveTrackPropagator::SetMinAng(Double_t x)
1068 Warning(
"SetMinAng",
"This method was mis-named, use SetMaxAng() instead!");
1075 Double_t REveTrackPropagator::GetMinAng()
const
1077 Warning(
"GetMinAng",
"This method was mis-named, use GetMaxAng() instead!");
1084 void REveTrackPropagator::SetMaxAng(Double_t x)
1093 void REveTrackPropagator::SetMaxStep(Double_t x)
1102 void REveTrackPropagator::SetDelta(Double_t x)
1111 void REveTrackPropagator::SetFitDaughters(Bool_t x)
1120 void REveTrackPropagator::SetFitReferences(Bool_t x)
1129 void REveTrackPropagator::SetFitDecay(Bool_t x)
1138 void REveTrackPropagator::SetFitLineSegments(Bool_t x)
1140 fFitLineSegments = x;
1147 void REveTrackPropagator::SetFitCluster2Ds(Bool_t x)
1156 void REveTrackPropagator::SetRnrDecay(Bool_t rnr)
1165 void REveTrackPropagator::SetRnrCluster2Ds(Bool_t rnr)
1167 fRnrCluster2Ds = rnr;
1174 void REveTrackPropagator::SetRnrDaughters(Bool_t rnr)
1176 fRnrDaughters = rnr;
1183 void REveTrackPropagator::SetRnrReferences(Bool_t rnr)
1185 fRnrReferences = rnr;
1192 void REveTrackPropagator::SetRnrFV(Bool_t x)
1201 void REveTrackPropagator::SetProjTrackBreaking(UChar_t x)
1203 fProjTrackBreaking = x;
1210 void REveTrackPropagator::SetRnrPTBMarkers(Bool_t x)
1219 void REveTrackPropagator::StepRungeKutta(Double_t step,
1220 Double_t* vect, Double_t* vout)
1244 Double_t h2, h4, f[4];
1245 Double_t a, b, c, ph,ph2;
1246 Double_t secxs[4],secys[4],seczs[4],hxp[3];
1247 Double_t g1, g2, g3, g4, g5, g6, ang2, dxt, dyt, dzt;
1248 Double_t est, at, bt, ct, cba;
1249 Double_t f1, f2, f3, f4, rho, tet, hnorm, hp, rho1, sint, cost;
1260 const Int_t maxit = 500;
1261 const Int_t maxcut = 11;
1263 const Double_t hmin = 1e-4;
1264 const Double_t kdlt = 1e-3;
1265 const Double_t kdlt32 = kdlt/32.;
1266 const Double_t kthird = 1./3.;
1267 const Double_t khalf = 0.5;
1268 const Double_t kec = 2.9979251e-3;
1270 const Double_t kpisqua = 9.86960440109;
1271 const Int_t kix = 0;
1272 const Int_t kiy = 1;
1273 const Int_t kiz = 2;
1274 const Int_t kipx = 3;
1275 const Int_t kipy = 4;
1276 const Int_t kipz = 5;
1285 for(Int_t j = 0; j < 7; j++)
1288 Double_t pinv = kec * fH.fCharge / vect[6];
1295 if (TMath::Abs(h) > TMath::Abs(rest))
1314 secxs[0] = (b * f[2] - c * f[1]) * ph2;
1315 secys[0] = (c * f[0] - a * f[2]) * ph2;
1316 seczs[0] = (a * f[1] - b * f[0]) * ph2;
1317 ang2 = (secxs[0]*secxs[0] + secys[0]*secys[0] + seczs[0]*seczs[0]);
1318 if (ang2 > kpisqua)
break;
1320 dxt = h2 * a + h4 * secxs[0];
1321 dyt = h2 * b + h4 * secys[0];
1322 dzt = h2 * c + h4 * seczs[0];
1328 est = TMath::Abs(dxt) + TMath::Abs(dyt) + TMath::Abs(dzt);
1330 if (ncut++ > maxcut)
break;
1339 fH.fB = fMagFieldObj->GetFieldD(xt, yt, zt);
1348 secxs[1] = (bt * f[2] - ct * f[1]) * ph2;
1349 secys[1] = (ct * f[0] - at * f[2]) * ph2;
1350 seczs[1] = (at * f[1] - bt * f[0]) * ph2;
1354 secxs[2] = (bt * f[2] - ct * f[1]) * ph2;
1355 secys[2] = (ct * f[0] - at * f[2]) * ph2;
1356 seczs[2] = (at * f[1] - bt * f[0]) * ph2;
1357 dxt = h * (a + secxs[2]);
1358 dyt = h * (b + secys[2]);
1359 dzt = h * (c + seczs[2]);
1363 at = a + 2.*secxs[2];
1364 bt = b + 2.*secys[2];
1365 ct = c + 2.*seczs[2];
1367 est = TMath::Abs(dxt)+TMath::Abs(dyt)+TMath::Abs(dzt);
1368 if (est > 2.*TMath::Abs(h)) {
1369 if (ncut++ > maxcut)
break;
1378 fH.fB = fMagFieldObj->GetFieldD(xt, yt, zt);
1383 z = z + (c + (seczs[0] + seczs[1] + seczs[2]) * kthird) * h;
1384 y = y + (b + (secys[0] + secys[1] + secys[2]) * kthird) * h;
1385 x = x + (a + (secxs[0] + secxs[1] + secxs[2]) * kthird) * h;
1387 secxs[3] = (bt*f[2] - ct*f[1])* ph2;
1388 secys[3] = (ct*f[0] - at*f[2])* ph2;
1389 seczs[3] = (at*f[1] - bt*f[0])* ph2;
1390 a = a+(secxs[0]+secxs[3]+2. * (secxs[1]+secxs[2])) * kthird;
1391 b = b+(secys[0]+secys[3]+2. * (secys[1]+secys[2])) * kthird;
1392 c = c+(seczs[0]+seczs[3]+2. * (seczs[1]+seczs[2])) * kthird;
1394 est = TMath::Abs(secxs[0]+secxs[3] - (secxs[1]+secxs[2]))
1395 + TMath::Abs(secys[0]+secys[3] - (secys[1]+secys[2]))
1396 + TMath::Abs(seczs[0]+seczs[3] - (seczs[1]+seczs[2]));
1398 if (est > kdlt && TMath::Abs(h) > hmin) {
1399 if (ncut++ > maxcut)
break;
1406 if (iter++ > maxit)
break;
1411 cba = 1./ TMath::Sqrt(a*a + b*b + c*c);
1419 if (step < 0.) rest = -rest;
1420 if (rest < 1.e-5*TMath::Abs(step))
1422 Float_t dot = (vout[3]*vect[3] + vout[4]*vect[4] + vout[5]*vect[5]);
1423 fH.fPhi += TMath::ACos(dot);
1434 f4 = TMath::Sqrt(f1*f1+f2*f2+f3*f3);
1443 hxp[0] = f2*vect[kipz] - f3*vect[kipy];
1444 hxp[1] = f3*vect[kipx] - f1*vect[kipz];
1445 hxp[2] = f1*vect[kipy] - f2*vect[kipx];
1447 hp = f1*vect[kipx] + f2*vect[kipy] + f3*vect[kipz];
1450 sint = TMath::Sin(tet);
1451 cost = 2.*TMath::Sin(khalf*tet)*TMath::Sin(khalf*tet);
1455 g3 = (tet-sint) * hp*rho1;
1460 vout[kix] = vect[kix] + g1*vect[kipx] + g2*hxp[0] + g3*f1;
1461 vout[kiy] = vect[kiy] + g1*vect[kipy] + g2*hxp[1] + g3*f2;
1462 vout[kiz] = vect[kiz] + g1*vect[kipz] + g2*hxp[2] + g3*f3;
1464 vout[kipx] = vect[kipx] + g4*vect[kipx] + g5*hxp[0] + g6*f1;
1465 vout[kipy] = vect[kipy] + g4*vect[kipy] + g5*hxp[1] + g6*f2;
1466 vout[kipz] = vect[kipz] + g4*vect[kipz] + g5*hxp[2] + g6*f3;