Commit cdb9b7ac authored by frey_m's avatar frey_m
Browse files

This closes issue #136

modified:   Algorithms/NilTracker.h
modified:   Algorithms/ParallelCyclotronTracker.cpp
modified:   Algorithms/ParallelCyclotronTracker.h
modified:   Algorithms/ParallelTTracker.cpp
modified:   Algorithms/ParallelTTracker.h
modified:   Algorithms/ThickTracker.cpp
modified:   Algorithms/ThickTracker.h
modified:   Classic/Algorithms/ThinTracker.cpp
modified:   Classic/Algorithms/ThinTracker.h
modified:   Classic/Algorithms/Tracker.cpp
modified:   Classic/Algorithms/Tracker.h
modified:   Track/TrackRun.cpp
parent 33da909c
......@@ -44,9 +44,9 @@ class NilTracker: public Tracker {
public:
/// Constructor.
explicit NilTracker(const Beamline &beamline,
const PartData &reference,
bool revBeam,
bool revTrack);
const PartData &reference,
bool revBeam,
bool revTrack);
virtual ~NilTracker();
......
This diff is collapsed.
......@@ -76,7 +76,7 @@ public:
// The particle bunch tracked is taken from [b]bunch[/b].
// If [b]revBeam[/b] is true, the beam runs from s = C to s = 0.
// If [b]revTrack[/b] is true, we track against the beam.
explicit ParallelCyclotronTracker(const Beamline &bl, PartBunch &bunch, DataSink &ds,
explicit ParallelCyclotronTracker(const Beamline &bl, PartBunch *bunch, DataSink &ds,
const PartData &data, bool revBeam, bool revTrack, int maxSTEPS, int timeIntegrator);
virtual ~ParallelCyclotronTracker();
......@@ -208,8 +208,6 @@ private:
int LastVisited;
Beamline *itsBeamline;
PartBunch *itsBunch;
DataSink *itsDataSink;
BoundaryGeometry *bgf_m;
......@@ -432,11 +430,11 @@ private:
// Push particles for time h.
// Apply effects of RF Gap Crossings.
// Update time and path length.
// Unit assumptions: [itsBunch->R] = m, [itsBunch->P] = 1, [h] = s, [c] = m/s, [itsBunch->getT()] = s
// Unit assumptions: [itsBunch_m->R] = m, [itsBunch_m->P] = 1, [h] = s, [c] = m/s, [itsBunch_m->getT()] = s
void push(double h);
// Kick particles for time h
// The fields itsBunch->Bf, itsBunch->Ef are used to calculate the forces
// The fields itsBunch_m->Bf, itsBunch_m->Ef are used to calculate the forces
void kick(double h);
// Apply the trilogy half push - kick - half push,
......
......@@ -58,7 +58,6 @@ ParallelTTracker::ParallelTTracker(const Beamline &beamline,
bool revBeam,
bool revTrack):
Tracker(beamline, reference, revBeam, revTrack),
itsBunch_m(NULL),
itsDataSink_m(NULL),
itsOpalBeamline_m(beamline.getOrigin3D(), beamline.getCoordTransformationTo()),
RefPartR_m(0.0),
......@@ -98,7 +97,7 @@ ParallelTTracker::ParallelTTracker(const Beamline &beamline,
}
ParallelTTracker::ParallelTTracker(const Beamline &beamline,
PartBunch &bunch,
PartBunch *bunch,
DataSink &ds,
const PartData &reference,
bool revBeam,
......@@ -107,8 +106,7 @@ ParallelTTracker::ParallelTTracker(const Beamline &beamline,
double zstart,
const std::vector<double> &zstop,
const std::vector<double> &dt):
Tracker(beamline, reference, revBeam, revTrack),
itsBunch_m(&bunch),
Tracker(beamline, bunch, reference, revBeam, revTrack),
itsDataSink_m(&ds),
itsOpalBeamline_m(beamline.getOrigin3D(), beamline.getCoordTransformationTo()),
RefPartR_m(0.0),
......
......@@ -87,7 +87,7 @@ public:
// If [b]revBeam[/b] is true, the beam runs from s = C to s = 0.
// If [b]revTrack[/b] is true, we track against the beam.
explicit ParallelTTracker(const Beamline &bl,
PartBunch &bunch,
PartBunch *bunch,
DataSink &ds,
const PartData &data,
bool revBeam,
......@@ -190,7 +190,6 @@ private:
/******************** STATE VARIABLES ***********************************/
PartBunch *itsBunch_m;
DataSink *itsDataSink_m;
OpalBeamline itsOpalBeamline_m;
......
......@@ -91,7 +91,7 @@ ThickTracker::ThickTracker(const Beamline &beamline,
ThickTracker::ThickTracker(const Beamline &beamline,
const PartBunch &bunch,
PartBunch *bunch,
const PartData &reference,
bool revBeam, bool revTrack):
Tracker(beamline, bunch, reference, revBeam, revTrack)
......@@ -125,11 +125,11 @@ void ThickTracker::visitCorrector(const Corrector &corr) {
if(length != 0.0) scale *= length; // Is this right?!?
const BDipoleField &field = corr.getField();
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
part.px() -= field.getBy() * scale;
part.py() += field.getBx() * scale;
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
// Drift through second half of length.
......@@ -200,8 +200,8 @@ void ThickTracker::visitMultipole(const Multipole &mult) {
As.setTruncOrder(Series::EXACT);
// Use implicit integration to propagate particles.
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
Vector zin;
zin[X] = part.x();
zin[PX] = part.px();
......@@ -254,7 +254,7 @@ void ThickTracker::visitMultipole(const Multipole &mult) {
part.pt() = DBL_MAX;
}
}
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
// Apply exit fringe field.
......@@ -325,8 +325,8 @@ void ThickTracker::visitRBend(const RBend &bend) {
// Use implicit integration to propagate particles.
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
Vector zin, zf;
zin[X] = part.x();
zin[PX] = part.px();
......@@ -385,7 +385,7 @@ void ThickTracker::visitRBend(const RBend &bend) {
part.pt() = DBL_MAX;
}
}
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
if(back_path) {
......@@ -416,13 +416,13 @@ void ThickTracker::visitRFCavity(const RFCavity &as) {
double kin = itsReference.getM() / itsReference.getP();
double peak = flip_s * as.getAmplitude() / itsReference.getP();
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
double pt = (part.pt() + 1.0);
double speed = (c * pt) / sqrt(pt * pt + kin * kin);
double phase = as.getPhase() + (freq * part.t()) / speed;
part.pt() += peak * sin(phase) / pt;
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
// Drift through half length.
......@@ -489,8 +489,8 @@ void ThickTracker::visitSBend(const SBend &bend) {
// Use implicit integration to propagate particles.
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
Vector zin, zf;
zin[X] = part.x();
......@@ -557,7 +557,7 @@ void ThickTracker::visitSBend(const SBend &bend) {
part.pt() = DBL_MAX;
}
}
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
// Apply exit fringe field.
......@@ -581,12 +581,12 @@ void ThickTracker::visitSeparator(const Separator &sep) {
double Ex = scale * sep.getEx();
double Ey = scale * sep.getEy();
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
double pt = 1.0 + part.pt();
part.px() += Ex / pt;
part.py() += Ey / pt;
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
// Drift through second half of length.
......@@ -614,8 +614,8 @@ void ThickTracker::visitSolenoid(const Solenoid &solenoid) {
double refTime = length / itsReference.getBeta();
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
double pt = part.pt() + 1.0;
double px = part.px() + ks * part.y();
double py = part.py() - ks * part.x();
......@@ -636,7 +636,7 @@ void ThickTracker::visitSolenoid(const Solenoid &solenoid) {
part.px() = C * pxt - (S * k) * xt;
part.py() = C * pyt - (S * k) * yt;
part.t() += pt * (refTime / E - length / pz);
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
} else {
applyDrift(length);
......@@ -669,8 +669,8 @@ void ThickTracker::applyEntranceFringe(double angle, double curve,
//Track particles.
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
// Read particle coordinates.
double x = part.x();
double px = part.px();
......@@ -719,7 +719,7 @@ void ThickTracker::applyEntranceFringe(double angle, double curve,
part.t() = t;
part.pt() = pt;
}
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
}
......@@ -738,8 +738,8 @@ void ThickTracker::applyExitFringe(double angle, double curve,
by *= scale;
//Track particles.
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
// Read particle coordinates.
double x = part.x();
double px = part.px();
......@@ -787,7 +787,7 @@ void ThickTracker::applyExitFringe(double angle, double curve,
part.t() = t;
part.pt() = pt;
}
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
}
......
......@@ -82,7 +82,7 @@ public:
// The particle bunch tracked is taken from [b]bunch[/b].
// If [b]revBeam[/b] is true, the beam runs from s = C to s = 0.
// If [b]revTrack[/b] is true, we track against the beam.
explicit ThickTracker(const Beamline &bl, const PartBunch &bunch,
explicit ThickTracker(const Beamline &bl, PartBunch *bunch,
const PartData &data, bool revBeam, bool revTrack);
virtual ~ThickTracker();
......
......@@ -68,7 +68,7 @@ ThinTracker::ThinTracker(const Beamline &beamline, const PartData &reference,
ThinTracker::ThinTracker(const Beamline &beamline,
const PartBunch &bunch,
PartBunch *bunch,
const PartData &reference,
bool revBeam, bool revTrack):
Tracker(beamline, bunch, reference, revBeam, revTrack)
......@@ -114,8 +114,8 @@ void ThinTracker::visitBeamBeam(const BeamBeam &bb) {
if(sx2 == sy2) {
// Limit for sigma(x)^2 = sigma(y)^2.
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
double xs = part.x() - dx;
double ys = part.y() - dy;
......@@ -132,15 +132,15 @@ void ThinTracker::visitBeamBeam(const BeamBeam &bb) {
part.px() += xs * phi;
part.py() += ys * phi;
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
} else {
// Case sigma(x)^2 != sigma(y)^2.
const double r = sqrt(2.0 * std::abs(sx2 - sy2));
double rk = flip_s * flip_B * fk * sqrt(pi) / r;
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
double xs = part.x() - dx;
double ys = part.y() - dy;
......@@ -156,7 +156,7 @@ void ThinTracker::visitBeamBeam(const BeamBeam &bb) {
part.px() += rk * ((xs > 0.0) ? std::imag(W) : - std::imag(W));
part.py() += rk * ((ys > 0.0) ? std::real(W) : - std::real(W));
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
}
}
......@@ -191,11 +191,11 @@ void ThinTracker::visitCorrector(const Corrector &corr) {
itsReference.getQ() * c) / itsReference.getP();
const BDipoleField &field = corr.getField();
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
part.px() -= field.getBy() * scale;
part.py() += field.getBx() * scale;
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
// Drift through second half of length.
......@@ -274,8 +274,8 @@ void ThinTracker::visitRBend(const RBend &bend) {
double scale = (flip_B * itsReference.getQ() * c) / itsReference.getP();
if(length) scale *= length;
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
int order = field.order();
if(order > 0) {
......@@ -295,7 +295,7 @@ void ThinTracker::visitRBend(const RBend &bend) {
part.py() += ky * scale;
part.t() -= angle * x;
}
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
// Drift to out-plane.
......@@ -313,13 +313,13 @@ void ThinTracker::visitRFCavity(const RFCavity &as) {
double peak = flip_s * as.getAmplitude() / itsReference.getP();
double kin = itsReference.getM() / itsReference.getP();
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
double pt = (part.pt() + 1.0);
double speed = (c * pt) / sqrt(pt * pt + kin * kin);
double phase = as.getPhase() + (freq * part.t()) / speed;
part.pt() += peak * sin(phase) / pt;
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
if(length) applyDrift(length / 2.0);
......@@ -347,8 +347,8 @@ void ThinTracker::visitSBend(const SBend &bend) {
double scale = (flip_B * itsReference.getQ() * c) / itsReference.getP();
if(length) scale *= length;
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
int order = field.order();
if(order > 0) {
......@@ -368,7 +368,7 @@ void ThinTracker::visitSBend(const SBend &bend) {
part.py() += ky * scale;
part.t() -= angle * x;
}
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
// Drift to out-plane.
......@@ -386,12 +386,12 @@ void ThinTracker::visitSeparator(const Separator &sep) {
double Ex = scale * sep.getEx();
double Ey = scale * sep.getEy();
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
double pt = 1.0 + part.pt();
part.px() += Ex / pt;
part.py() += Ey / pt;
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
applyDrift(length / 2.0);
......@@ -416,8 +416,8 @@ void ThinTracker::visitSolenoid(const Solenoid &solenoid) {
double kin = itsReference.getM() / itsReference.getP();
double ref = kin * kin;
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
double pt = part.pt() + 1.0;
double px = part.px() + ks * part.y();
......@@ -438,7 +438,7 @@ void ThinTracker::visitSolenoid(const Solenoid &solenoid) {
part.px() = C * pxt - (S * k) * xt;
part.py() = C * pyt - (S * k) * yt;
part.t() += length * (pt * ref - (px * px + py * py + 3.0 * pt * pt * ref) / 2.0);
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
} else {
applyDrift(length);
......@@ -451,8 +451,8 @@ void ThinTracker::applyDrift(double length) {
double kin = itsReference.getM() / itsReference.getP();
double ref = kin * kin;
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
double px = part.px();
double py = part.py();
......@@ -461,6 +461,6 @@ void ThinTracker::applyDrift(double length) {
part.x() += px * lByPz;
part.y() += py * lByPz;
part.t() += length * (pt * ref - (px * px + py * py + 3.0 * pt * pt * ref) / 2.0);
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
}
......@@ -61,7 +61,7 @@ public:
// The particle bunch tracked is taken from [b]bunch[/b].
// If [b]revBeam[/b] is true, the beam runs from s = C to s = 0.
// If [b]revTrack[/b] is true, we track against the beam.
ThinTracker(const Beamline &bl, const PartBunch &bunch,
ThinTracker(const Beamline &bl, PartBunch *bunch,
const PartData &data, bool revBeam, bool revTrack);
virtual ~ThinTracker();
......
......@@ -39,17 +39,17 @@ Tracker::Tracker(const Beamline &beamline, const PartData &reference,
bool backBeam, bool backTrack):
AbstractTracker(beamline, reference, backBeam, backTrack),
itsBeamline_m(beamline),
itsBunch(&reference)
itsBunch_m(nullptr)
{}
Tracker::Tracker(const Beamline &beamline,
const PartBunch &bunch,
PartBunch *bunch,
const PartData &reference,
bool backBeam, bool backTrack):
AbstractTracker(beamline, reference, backBeam, backTrack),
itsBeamline_m(beamline),
itsBunch(bunch)
itsBunch_m(bunch)
{}
......@@ -58,22 +58,22 @@ Tracker::~Tracker()
const PartBunch &Tracker::getBunch() const {
return itsBunch;
return *itsBunch_m;
}
void Tracker::addToBunch(const Particle &part) {
itsBunch.push_back(part);
itsBunch_m->push_back(part);
}
//~ void Tracker::setBunch(const PartBunch &bunch) {
//~ itsBunch = bunch;
//~ itsBunch_m = &bunch;
//~ }
void Tracker::visitComponent(const Component &comp) {
comp.trackBunch(itsBunch, itsReference, back_beam, back_track);
comp.trackBunch(*itsBunch_m, itsReference, back_beam, back_track);
}
......@@ -107,12 +107,12 @@ void Tracker::visitAlignWrapper(const AlignWrapper &wrap) {
void Tracker::visitTrackIntegrator(const TrackIntegrator &i) {
i.trackBunch(itsBunch, itsReference, back_beam, back_track);
i.trackBunch(*itsBunch_m, itsReference, back_beam, back_track);
}
void Tracker::visitMapIntegrator(const MapIntegrator &i) {
i.trackBunch(itsBunch, itsReference, back_beam, back_track);
i.trackBunch(*itsBunch_m, itsReference, back_beam, back_track);
}
......@@ -120,8 +120,8 @@ void Tracker::applyDrift(double length) {
double kin = itsReference.getM() / itsReference.getP();
double refTime = length / itsReference.getBeta();
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
if(part.x() != DBL_MAX) {
double px = part.px();
double py = part.py();
......@@ -131,7 +131,7 @@ void Tracker::applyDrift(double length) {
part.y() += py * lByPz;
part.t() += pt * (refTime / sqrt(pt * pt + kin * kin) - lByPz);
}
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
}
......@@ -141,8 +141,8 @@ void Tracker::applyThinMultipole
int order = field.order();
if(order > 0) {
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
if(part.x() != DBL_MAX) {
double x = part.x();
double y = part.y();
......@@ -159,7 +159,7 @@ void Tracker::applyThinMultipole
part.px() -= kx * scale;
part.py() += ky * scale;
}
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
}
}
......@@ -173,14 +173,14 @@ void Tracker::applyThinSBend
// These substitutions work because As depends on x and y only,
// and not on px or py.
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
FVector<double, 2> z;
z[0] = part.x();
z[1] = part.y();
part.px() -= Fx.evaluate(z);
part.py() -= Fy.evaluate(z);
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
}
......@@ -190,8 +190,8 @@ void Tracker::applyTransform(const Euclid3D &euclid, double refLength) {
double kin = itsReference.getM() / itsReference.getP();
double refTime = refLength / itsReference.getBeta();
for(unsigned int i = 0; i < itsBunch.getLocalNum(); i++) {
Particle part = itsBunch.get_part(i);
for(unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
Particle part = itsBunch_m->get_part(i);
double px = part.px();
double py = part.py();
double pt = part.pt() + 1.0;
......@@ -215,7 +215,7 @@ void Tracker::applyTransform(const Euclid3D &euclid, double refLength) {
part.x() = x2 - sByPz * part.px();
part.y() = y2 - sByPz * part.py();
part.t() += pt * (refTime / E + sByPz);
itsBunch.set_part(part, i);
itsBunch_m->set_part(part, i);
}
}
}
......
......@@ -100,7 +100,7 @@ public:
// The particle bunch is taken from [b]bunch[/b].
// If [b]revBeam[/b] is true, the beam runs from s = C to s = 0.
// If [b]revTrack[/b] is true, we track against the beam.
Tracker(const Beamline &, const PartBunch &bunch,
Tracker(const Beamline &, PartBunch *bunch,
const PartData &, bool backBeam, bool backTrack);
virtual ~Tracker();