#include "TEveTrackPropagator.h"
#include "TEveTrack.h"
#include "TMath.h"
#include <cassert>
void TEveTrackPropagator::Helix_t::Step(TEveVector4& v, TEveVector& p)
{
v.fX += (p.fX*fSin - p.fY*(1 - fCos))/fA + fXoff;
v.fY += (p.fY*fSin + p.fX*(1 - fCos))/fA + fYoff;
v.fZ += fLam*TMath::Abs(fR*fPhiStep);
v.fT += fTimeStep;
const Float_t pxt = p.fX*fCos - p.fY*fSin;
const Float_t pyt = p.fY*fCos + p.fX*fSin;
p.fX = pxt;
p.fY = pyt;
}
void TEveTrackPropagator::Helix_t::StepVertex(const TEveVector4& v, const TEveVector& p,
TEveVector4& forw)
{
forw.fX = v.fX + (p.fX*fSin - p.fY*(1 - fCos))/fA + fXoff;
forw.fY = v.fY + (p.fY*fSin + p.fX*(1 - fCos))/fA + fYoff;
forw.fZ = v.fZ + fLam*TMath::Abs(fR*fPhiStep);
forw.fT = v.fT + fTimeStep;
}
ClassImp(TEveTrackPropagator)
Float_t TEveTrackPropagator::fgDefMagField = 0.5;
const Float_t TEveTrackPropagator::fgkB2C = 0.299792458e-2;
TEveTrackPropagator TEveTrackPropagator::fgDefStyle;
TEveTrackPropagator::TEveTrackPropagator() :
TObject(),
TEveRefBackPtr(),
fMagField(fgDefMagField),
fMaxR (350),
fMaxZ (450),
fMaxOrbs (0.5),
fMinAng (45),
fDelta (0.1),
fEditPathMarks (kTRUE),
fFitDaughters (kTRUE),
fFitReferences (kTRUE),
fFitDecay (kTRUE),
fFitCluster2Ds (kTRUE),
fRnrDaughters (kTRUE),
fRnrReferences (kTRUE),
fRnrDecay (kTRUE),
fRnrFV (kFALSE),
fPMAtt(),
fFVAtt(),
fCharge (0),
fVelocity (0.0f),
fV (),
fN (0),
fNLast (0),
fNMax (4096)
{
}
void TEveTrackPropagator::InitTrack(TEveVector &v, TEveVector &p,
Float_t beta, Int_t charge)
{
fV.fX = v.fX;
fV.fY = v.fY;
fV.fZ = v.fZ;
fV.fT = 0;
fPoints.push_back(fV);
fVelocity = TMath::C()*beta;
fCharge = charge;
InitHelix(p);
}
void TEveTrackPropagator::ResetTrack()
{
fPoints.clear();
fN = 0;
fNLast = 0;
}
Bool_t TEveTrackPropagator::GoToVertex(TEveVector& v, TEveVector& p)
{
Bool_t hit;
if (fCharge != 0 && TMath::Abs(fMagField) > 1e-5 && p.Perp2() > 1e-12)
hit = HelixToVertex(v, p);
else
hit = LineToVertex(v);
return hit;
}
void TEveTrackPropagator::GoToBounds(TEveVector& p)
{
if (fCharge != 0 && TMath::Abs(fMagField) > 1e-5 && p.Perp2() > 1e-12)
HelixToBounds(p);
else
LineToBounds(p);
}
void TEveTrackPropagator::InitHelix(const TEveVector& p)
{
if (fCharge)
{
using namespace TMath;
Float_t pT = p.Perp();
fH.fA = fgkB2C * fMagField * fCharge;
fH.fLam = p.fZ / pT;
fH.fR = pT / fH.fA;
fH.fPhiStep = fMinAng * DegToRad();
if (fDelta < Abs(fH.fR))
{
Float_t ang = 2*ACos(1 - fDelta/Abs(fH.fR));
if (ang < fH.fPhiStep) fH.fPhiStep = ang;
}
if (fH.fA < 0) fH.fPhiStep *= -1;
fH.fTimeStep = 0.01 * Abs(fH.fR*fH.fPhiStep)*Sqrt(1+(fH.fLam*fH.fLam))/fVelocity;
fH.fSin = Sin(fH.fPhiStep);
fH.fCos = Cos(fH.fPhiStep);
}
}
void TEveTrackPropagator::SetNumOfSteps()
{
using namespace TMath;
Int_t newCount = Int_t(fMaxOrbs*TwoPi()/Abs(fH.fPhiStep));
Float_t nz;
if (fH.fLam > 0) {
nz = ( fMaxZ - fV.fZ) / (fH.fLam*Abs(fH.fR*fH.fPhiStep));
} else {
nz = (-fMaxZ - fV.fZ) / (fH.fLam*Abs(fH.fR*fH.fPhiStep));
}
if (nz < newCount) newCount = Int_t(nz + 1);
fNLast = fN + newCount;
}
void TEveTrackPropagator::HelixToBounds(TEveVector& p)
{
InitHelix(p);
SetNumOfSteps();
if (fN < fNLast)
{
Bool_t crosR = kFALSE;
if (fV.Perp() < fMaxR + TMath::Abs(fH.fR))
crosR = true;
Float_t maxR2 = fMaxR * fMaxR;
TEveVector4 forw;
while (fN < fNLast)
{
fH.StepVertex(fV, p, forw);
if (crosR && forw.Perp2() > maxR2)
{
Float_t t = (fMaxR - fV.R()) / (forw.R() - fV.R());
if (t < 0 || t > 1)
{
Warning("TEveTrackPropagator::HelixToBounds",
"In MaxR crossing expected t>=0 && t<=1: t=%f, r1=%f, r2=%f, MaxR=%f.",
t, fV.R(), forw.R(), fMaxR);
return;
}
fPoints.push_back(fV + (forw-fV)*t);
++fN;
return;
}
if (TMath::Abs(forw.fZ) > fMaxZ)
{
Float_t t = (fMaxZ - TMath::Abs(fV.fZ)) / TMath::Abs((forw.fZ - fV.fZ));
if (t < 0 || t > 1)
{
Warning("TEveTrackPropagator::HelixToBounds",
"In MaxZ crossing expected t>=0 && t<=1: t=%f, z1=%f, z2=%f, MaxZ=%f.",
t, fV.fZ, forw.fZ, fMaxZ);
return;
}
fPoints.push_back(fV + (forw-fV)*t);
++fN;
return;
}
fH.Step(fV, p); fPoints.push_back(fV); ++fN;
}
return;
}
}
Bool_t TEveTrackPropagator::HelixToVertex(TEveVector& v, TEveVector& p)
{
InitHelix(p);
SetNumOfSteps();
Float_t p0x = p.fX, p0y = p.fY;
Float_t zs = fH.fLam*TMath::Abs(fH.fR*fH.fPhiStep);
Float_t maxrsq = fMaxR * fMaxR;
Float_t fnsteps = (v.fZ - fV.fZ)/zs;
Int_t nsteps = Int_t((v.fZ - fV.fZ)/zs);
Float_t sinf = TMath::Sin(fnsteps*fH.fPhiStep);
Float_t cosf = TMath::Cos(fnsteps*fH.fPhiStep);
nsteps = TMath::Min(nsteps, fNLast - fN);
{
if (nsteps > 0)
{
Float_t xf = fV.fX + (p.fX*sinf - p.fY*(1 - cosf)) / fH.fA;
Float_t yf = fV.fY + (p.fY*sinf + p.fX*(1 - cosf)) / fH.fA;
fH.fXoff = (v.fX - xf) / fnsteps;
fH.fYoff = (v.fY - yf) / fnsteps;
TEveVector4 forw;
for (Int_t l=0; l<nsteps; l++)
{
fH.StepVertex(fV, p, forw);
if (fV.Perp2() > maxrsq || TMath::Abs(fV.fZ) > fMaxZ)
return kFALSE;
fH.Step(fV, p); fPoints.push_back(fV);
++fN;
}
}
fV.fT += TMath::Sqrt((fV.fX-v.fX)*(fV.fX-v.fX) +
(fV.fY-v.fY)*(fV.fY-v.fY) +
(fV.fZ-v.fZ)*(fV.fZ-v.fZ)) / fVelocity;
fV.fX = v.fX; fV.fY = v.fY; fV.fZ = v.fZ;
fPoints.push_back(fV);
++fN;
}
{
Float_t cosr = TMath::Cos((fnsteps-nsteps)*fH.fPhiStep);
Float_t sinr = TMath::Sin((fnsteps-nsteps)*fH.fPhiStep);
Float_t pxt = p.fX*cosr - p.fY*sinr;
Float_t pyt = p.fY*cosr + p.fX*sinr;
p.fX = pxt;
p.fY = pyt;
}
{
Float_t pxf = (p0x*cosf - p0y*sinf)/TMath::Abs(fH.fA) + fH.fXoff/fH.fPhiStep;
Float_t pyf = (p0y*cosf + p0x*sinf)/TMath::Abs(fH.fA) + fH.fYoff/fH.fPhiStep;
Float_t fac = TMath::Sqrt((p0x*p0x + p0y*p0y) / (pxf*pxf + pyf*pyf));
p.fX = fac*pxf;
p.fY = fac*pyf;
}
return kTRUE;
}
Bool_t TEveTrackPropagator::LineToVertex(TEveVector& v)
{
fV.fT += TMath::Sqrt((fV.fX-v.fX)*(fV.fX-v.fX) +
(fV.fY-v.fY)*(fV.fY-v.fY) +
(fV.fZ-v.fZ)*(fV.fZ-v.fZ)) / fVelocity;
fV.fX = v.fX;
fV.fY = v.fY;
fV.fZ = v.fZ;
fPoints.push_back(fV);
return kTRUE;
}
void TEveTrackPropagator::LineToBounds(TEveVector& p)
{
Float_t tZ = 0, tR = 0, tB = 0;
if (p.fZ > 0) {
tZ = (fMaxZ - fV.fZ)/p.fZ;
}
else if (p.fZ < 0 ) {
tZ = (-1)*(fMaxZ + fV.fZ)/p.fZ;
}
Double_t a = p.fX*p.fX + p.fY*p.fY;
Double_t b = 2*(fV.fX*p.fX + fV.fY*p.fY);
Double_t c = fV.fX*fV.fX + fV.fY*fV.fY - fMaxR*fMaxR;
Double_t d = b*b - 4*a*c;
if (d >= 0) {
Double_t sqrtD=TMath::Sqrt(d);
tR = ( -b - sqrtD )/(2*a);
if (tR < 0) {
tR = ( -b + sqrtD )/(2*a);
}
tB = tR < tZ ? tR : tZ;
} else {
tB = tZ;
}
TEveVector nv(fV.fX + p.fX*tB, fV.fY + p.fY*tB, fV.fZ+ p.fZ*tB);
LineToVertex(nv);
}
Bool_t TEveTrackPropagator::HelixIntersectPlane(const TEveVector& p,
const TEveVector& point,
const TEveVector& normal,
TEveVector& itsect)
{
InitHelix(p);
SetNumOfSteps();
TEveVector pos(fV);
TEveVector mom(p);
TEveVector n(normal);
TEveVector delta = pos - point;
Float_t d = delta.Dot(n);
if (d > 0) {
n.NegateXYZ();
d = -d;
}
TEveVector4 pos4(pos);
while (1)
{
fH.Step(pos4, mom);
TEveVector new_pos = pos4;
Float_t new_d = (new_pos - point).Dot(n);
if (new_d < d) {
Warning("TEveTrackPropagator::HelixIntersectPlane", "going away from the plane.");
return kFALSE;
}
if (new_d > 0) {
delta = new_pos - pos;
itsect = pos + delta * (d / (d - new_d));
return kTRUE;
}
pos = new_pos;
}
}
Bool_t TEveTrackPropagator::LineIntersectPlane(const TEveVector& p,
const TEveVector& point,
const TEveVector& normal,
TEveVector& itsect)
{
TEveVector pos(fV.fX, fV.fY, fV.fZ);
TEveVector delta = pos - point;
Float_t d = delta.Dot(normal);
if (d == 0) {
itsect = pos;
return kTRUE;
}
Float_t t = (p.Dot(normal)) / d;
if (t < 0) {
return kFALSE;
} else {
itsect = pos + p*t;
return kTRUE;
}
}
Bool_t TEveTrackPropagator::IntersectPlane(const TEveVector& p,
const TEveVector& point,
const TEveVector& normal,
TEveVector& itsect)
{
if (fCharge != 0 && TMath::Abs(fMagField) > 1e-5 && p.Perp2() > 1e-12)
return HelixIntersectPlane(p, point, normal, itsect);
else
return LineIntersectPlane(p, point, normal, itsect);
}
void TEveTrackPropagator::FillPointSet(TEvePointSet* ps) const
{
Int_t size = TMath::Min(fNMax, (Int_t)fPoints.size());
ps->Reset(size);
for (Int_t i = 0; i < size; ++i)
{
const TEveVector4& v = fPoints[i];
ps->SetNextPoint(v.fX, v.fY, v.fZ);
}
}
void TEveTrackPropagator::RebuildTracks()
{
TEveTrack* track;
std::list<TEveElement*>::iterator i = fBackRefs.begin();
while (i != fBackRefs.end())
{
track = dynamic_cast<TEveTrack*>(*i);
track->MakeTrack();
track->ElementChanged();
++i;
}
}
void TEveTrackPropagator::SetMagField(Float_t x)
{
fMagField = x;
RebuildTracks();
}
void TEveTrackPropagator::SetMaxR(Float_t x)
{
fMaxR = x;
RebuildTracks();
}
void TEveTrackPropagator::SetMaxZ(Float_t x)
{
fMaxZ = x;
RebuildTracks();
}
void TEveTrackPropagator::SetMaxOrbs(Float_t x)
{
fMaxOrbs = x;
RebuildTracks();
}
void TEveTrackPropagator::SetMinAng(Float_t x)
{
fMinAng = x;
RebuildTracks();
}
void TEveTrackPropagator::SetDelta(Float_t x)
{
fDelta = x;
RebuildTracks();
}
void TEveTrackPropagator::SetFitDaughters(Bool_t x)
{
fFitDaughters = x;
RebuildTracks();
}
void TEveTrackPropagator::SetFitReferences(Bool_t x)
{
fFitReferences = x;
RebuildTracks();
}
void TEveTrackPropagator::SetFitDecay(Bool_t x)
{
fFitDecay = x;
RebuildTracks();
}
void TEveTrackPropagator::SetFitCluster2Ds(Bool_t x)
{
fFitCluster2Ds = x;
RebuildTracks();
}
void TEveTrackPropagator::SetRnrDecay(Bool_t rnr)
{
fRnrDecay = rnr;
RebuildTracks();
}
void TEveTrackPropagator::SetRnrCluster2Ds(Bool_t rnr)
{
fRnrCluster2Ds = rnr;
RebuildTracks();
}
void TEveTrackPropagator::SetRnrDaughters(Bool_t rnr)
{
fRnrDaughters = rnr;
RebuildTracks();
}
void TEveTrackPropagator::SetRnrReferences(Bool_t rnr)
{
fRnrReferences = rnr;
RebuildTracks();
}
Last change: Wed Jun 25 08:38:28 2008
Last generated: 2008-06-25 08:38
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.