#include "TEveTrackPropagator.h"
#include "TEveTrack.h"
#include "TMath.h"
#include <cassert>
void TEveTrackPropagator::Helix_t::Step(Vertex4D_t& 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;
Float_t pxt = p.fX*fCos - p.fY*fSin;
Float_t pyt = p.fY*fCos + p.fX*fSin;
p.fX = pxt;
p.fY = pyt;
}
void TEveTrackPropagator::Helix_t::StepVertex(const Vertex4D_t& v, const TEveVector& p,
Vertex4D_t& 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(kFALSE),
fFitDaughters (kTRUE),
fFitReferences (kTRUE),
fFitDecay (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;
if (fCharge)
{
using namespace TMath;
Float_t pT = p.Perp();
fH.fA = fgkB2C * fMagField * charge;
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::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::SetNumOfSteps()
{
using namespace TMath;
fNLast = 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 < fNLast) fNLast = Int_t(nz + 1);
}
void TEveTrackPropagator::HelixToBounds(TEveVector& p)
{
SetNumOfSteps();
if (fNLast > 0)
{
Bool_t crosR = kFALSE;
if (fV.Perp() < fMaxR + TMath::Abs(fH.fR))
crosR = true;
Float_t maxR2 = fMaxR * fMaxR;
Vertex4D_t forw;
while (fN < fNLast)
{
fH.StepVertex(fV, p, forw);
if (crosR && forw.Perp2() > maxR2)
{
Float_t t = (fMaxR - fV.R()) / (forw.R() - fV.R());
assert(t >= 0 && t <= 1);
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));
assert(t >= 0 && t <= 1);
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)
{
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;
Vertex4D_t 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);
}
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 Vertex4D_t& 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::SetRnrDecay(Bool_t rnr)
{
fRnrDecay = rnr;
RebuildTracks();
}
void TEveTrackPropagator::SetRnrDaughters(Bool_t rnr)
{
fRnrDaughters = rnr;
RebuildTracks();
}
void TEveTrackPropagator::SetRnrReferences(Bool_t rnr)
{
fRnrReferences = rnr;
RebuildTracks();
}
Last update: Thu Jan 17 08:49:35 2008
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.