diff --git a/src/Algorithms/CMakeLists.txt b/src/Algorithms/CMakeLists.txt
index ebe21b7f4c87d1121ce38d73c3b214b5de43c5d2..25315a638f0f4f9c25a646fbc75a83f304368436 100644
--- a/src/Algorithms/CMakeLists.txt
+++ b/src/Algorithms/CMakeLists.txt
@@ -10,9 +10,10 @@ set (_SRCS
   MPSplitIntegrator.cpp
   MultiBunchHandler.cpp
   OrbitThreader.cpp
-  ParallelTTracker.cpp
   ParallelCyclotronTracker.cpp
   ParallelSliceTracker.cpp
+  ParallelTTracker.cpp
+  StepSizeConfig.cpp
   ThickMapper.cpp
   ThickTracker.cpp
   TransportMapper.cpp
@@ -51,6 +52,7 @@ set (HDRS
     ParallelCyclotronTracker.h
     ParallelSliceTracker.h
     ParallelTTracker.h
+    StepSizeConfig.h
     ThickMapper.h
     ThickTracker.h
     TransportMapper.h
@@ -68,4 +70,4 @@ set (HDRS
     bet/math/svdfit.h
 )
 
-install (FILES ${HDRS} DESTINATION "${CMAKE_INSTALL_PREFIX}/include/Algorithms")
+install (FILES ${HDRS} DESTINATION "${CMAKE_INSTALL_PREFIX}/include/Algorithms")
\ No newline at end of file
diff --git a/src/Algorithms/IndexMap.cpp b/src/Algorithms/IndexMap.cpp
index 317b30e3c1058c4064e312523ea9b64f40d7fae8..4b2e9fc8b35a84fd5cc482f1bc337f323b9fe5e4 100644
--- a/src/Algorithms/IndexMap.cpp
+++ b/src/Algorithms/IndexMap.cpp
@@ -51,7 +51,7 @@ void IndexMap::print(std::ostream &out) const {
 }
 
 IndexMap::value_t IndexMap::query(key_t::first_type s, key_t::second_type ds) {
-    const double lowerLimit = (ds < s? s - ds: 0);
+    const double lowerLimit = s - ds;//(ds < s? s - ds: 0);
     const double upperLimit = std::min(totalPathLength_m, s + ds);
     value_t elementSet;
 
@@ -88,7 +88,11 @@ IndexMap::value_t IndexMap::query(key_t::first_type s, key_t::second_type ds) {
 }
 
 void IndexMap::add(key_t::first_type initialS, key_t::second_type finalS, const value_t &val) {
+    if (initialS > finalS) {
+        std::swap(initialS, finalS);
+    }
     key_t key(initialS, finalS * oneMinusEpsilon_m);
+
     mapRange2Element_m.insert(std::pair<key_t, value_t>(key, val));
     totalPathLength_m = (*mapRange2Element_m.rbegin()).first.second;
 
diff --git a/src/Algorithms/OrbitThreader.cpp b/src/Algorithms/OrbitThreader.cpp
index 99fb846c5e40ba5a1e3e2c3023e7a5a950f6622f..fcc672913610d412a5015f6aebe57bceb5368dc9 100644
--- a/src/Algorithms/OrbitThreader.cpp
+++ b/src/Algorithms/OrbitThreader.cpp
@@ -72,12 +72,12 @@ OrbitThreader::OrbitThreader(const PartData &ref,
             logger_m.open(fileName, std::ios_base::app);
         }
 
-        loggingFrequency_m = std::max(1.0, floor(1e-11 / dt_m + 0.5));
+        loggingFrequency_m = std::max(1.0, floor(1e-11 / std::abs(dt_m) + 0.5));
     } else {
         loggingFrequency_m = std::numeric_limits<size_t>::max();
     }
 
-    dZ_m = std::min(pathLength_m, std::max(0.0, maxDiffZBunch));
+    distTrackBack_m = std::min(pathLength_m, std::max(0.0, maxDiffZBunch));
 }
 
 void OrbitThreader::execute() {
@@ -110,7 +110,9 @@ void OrbitThreader::execute() {
         registerElement(elementSet, initialS,  initialR, initialP);
 
         if (errorFlag_m == HITMATERIAL) {
-            pathLength_m += 1.0;
+            // Shouldn't be reached because reference particle
+            // isn't stopped by collimators
+            pathLength_m += std::copysign(1.0, dt_m);
         }
 
         imap_m.add(initialS, pathLength_m, elementSet);
@@ -144,7 +146,6 @@ void OrbitThreader::integrate(const IndexMap::value_t &activeSet, size_t maxStep
     static size_t step = 0;
     CoordinateSystemTrafo labToBeamline = itsOpalBeamline_m.getCSTrafoLab2Local();
     const double oldPathLength = pathLength_m;
-    double stepLength;
     Vector_t nextR;
     do {
         errorFlag_m = EVERYTHINGFINE;
@@ -211,15 +212,13 @@ void OrbitThreader::integrate(const IndexMap::value_t &activeSet, size_t maxStep
         nextR *= Physics::c * dt_m;
 
         if ((activeSet.size() == 0 && std::abs(pathLength_m - oldPathLength) > maxDrift) ||
-            (activeSet.size() > 0  && pathLength_m > zstop_m)) {
+            (activeSet.size() > 0  && dt_m * pathLength_m > dt_m * zstop_m) ||
+            (pathLength_m < 0.0 && dt_m < 0.0)) {
             errorFlag_m = EOL;
             return;
         }
 
-        stepLength = std::abs(dt_m) * euclidean_norm(p_m) / sqrt(dot(p_m, p_m) + 1) * Physics::c;
-    } while ((dt_m > 0.0 ||
-              euclidean_norm(labToBeamline.transformTo(r_m)) > stepLength)  &&
-             (activeSet == itsOpalBeamline_m.getElements(nextR)));
+    } while (activeSet == itsOpalBeamline_m.getElements(nextR));
 }
 
 bool OrbitThreader::containsCavity(const IndexMap::value_t &activeSet) {
@@ -286,8 +285,8 @@ void OrbitThreader::trackBack(double maxDrift) {
     integrator_m.push(nextR, p_m, dt_m);
     nextR *= Physics::c * dt_m;
 
-    maxDrift = std::min(maxDrift, dZ_m);
-    while (initialPathLength - pathLength_m < dZ_m) {
+    maxDrift = std::min(maxDrift, distTrackBack_m);
+    while (std::abs(initialPathLength - pathLength_m) < distTrackBack_m) {
         auto elementSet = itsOpalBeamline_m.getElements(nextR);
 
         integrate(elementSet, 1000, maxDrift);
@@ -453,7 +452,7 @@ double OrbitThreader::computeMaximalImplicitDrift() {
         }
     }
 
-    maxDrift = std::min(maxIntegSteps_m * dt_m * Physics::c, maxDrift);
+    maxDrift = std::min(maxIntegSteps_m * std::abs(dt_m) * Physics::c, maxDrift);
 
     return maxDrift;
 }
\ No newline at end of file
diff --git a/src/Algorithms/OrbitThreader.h b/src/Algorithms/OrbitThreader.h
index af8247c1eb52b50fd57416ac1a73775afbdc5d5d..010454157a710711b71dace66c0f60fbe9ea34ab 100644
--- a/src/Algorithms/OrbitThreader.h
+++ b/src/Algorithms/OrbitThreader.h
@@ -34,13 +34,23 @@ public:
     IndexMap::value_t getTouchingElements(const std::pair<double, double> &range);
 
 private:
+    /// position of reference particle in lab coordinates
     Vector_t r_m;
+    /// momentum of reference particle
     Vector_t p_m;
+    /// position of reference particle in path length
     double pathLength_m;
-    double dZ_m;
+    /// distance to track back before tracking forward
+    /// (length of bunch but not beyond cathode)
+    double distTrackBack_m;
+    /// the simulated time
     double time_m;
+    /// the time step
     double dt_m;
+
+    /// the number of time steps to track
     const size_t maxIntegSteps_m;
+    /// final position in path length
     const double zstop_m;
 
     OpalBeamline &itsOpalBeamline_m;
diff --git a/src/Algorithms/ParallelTTracker.cpp b/src/Algorithms/ParallelTTracker.cpp
index 486bef3650742cb2d24a8b4f36acf8e381abd0be..380b1ac76c22a62c4f9b9f90e8cf9587fceeba59 100644
--- a/src/Algorithms/ParallelTTracker.cpp
+++ b/src/Algorithms/ParallelTTracker.cpp
@@ -64,10 +64,7 @@ ParallelTTracker::ParallelTTracker(const Beamline &beamline,
     wakeFunction_m(NULL),
     pathLength_m(0.0),
     zstart_m(0.0),
-    zStop_m(),
     dtCurrentTrack_m(0.0),
-    dtAllTracks_m(),
-    localTrackSteps_m(),
     minStepforReBin_m(-1),
     minBinEmitted_m(std::numeric_limits<size_t>::max()),
     repartFreq_m(-1),
@@ -120,16 +117,13 @@ ParallelTTracker::ParallelTTracker(const Beamline &beamline,
     particleMatterStatus_m(false),
     totalParticlesInSimulation_m(0)
 {
-    for (std::vector<unsigned long long>::const_iterator it = maxSteps.begin(); it != maxSteps.end(); ++ it) {
-        localTrackSteps_m.push(*it);
-    }
-    for (std::vector<double>::const_iterator it = dt.begin(); it != dt.end(); ++ it) {
-        dtAllTracks_m.push(*it);
-    }
-    for (std::vector<double>::const_iterator it = zstop.begin(); it != zstop.end(); ++ it) {
-        zStop_m.push(*it);
+    for (unsigned int i = 0; i < zstop.size(); ++ i) {
+        stepSizes_m.push_back(dt[i], zstop[i], maxSteps[i]);
     }
 
+    stepSizes_m.sortAscendingZStop();
+    stepSizes_m.resetIterator();
+
 #ifdef OPAL_DKS
     if (IpplInfo::DKSEnabled)
         setupDKS();
@@ -202,6 +196,8 @@ void ParallelTTracker::execute() {
     const double globalTimeShift = itsBunch_m->weHaveEnergyBins()? OpalData::getInstance()->getGlobalPhaseShift(): 0.0;
     OpalData::getInstance()->setGlobalPhaseShift(0.0);
 
+    // the time step needs to be positive in the setup
+    itsBunch_m->setdT(std::abs(itsBunch_m->getdT()));
     dtCurrentTrack_m = itsBunch_m->getdT();
 
     evenlyDistributeParticles();
@@ -212,20 +208,8 @@ void ParallelTTracker::execute() {
 
     prepareSections();
 
-    std::queue<double> timeStepSizes(dtAllTracks_m);
-    std::queue<unsigned long long> numSteps(localTrackSteps_m);
-    double minTimeStep = timeStepSizes.front();
-    unsigned long long totalNumSteps = 0;
-    while (timeStepSizes.size() > 0) {
-        if (minTimeStep > timeStepSizes.front()) {
-            totalNumSteps = std::ceil(totalNumSteps * minTimeStep / timeStepSizes.front());
-            minTimeStep = timeStepSizes.front();
-        }
-        totalNumSteps += std::ceil(numSteps.front() * timeStepSizes.front() / minTimeStep);
-
-        numSteps.pop();
-        timeStepSizes.pop();
-    }
+    double minTimeStep = stepSizes_m.getMinTimeStep();
+    unsigned long long totalNumSteps = stepSizes_m.getNumStepsFinestResolution();
 
     itsOpalBeamline_m.activateElements();
 
@@ -259,19 +243,29 @@ void ParallelTTracker::execute() {
         }
     }
 
+    stepSizes_m.advanceToPos(zstart_m);
+    if (back_track) {
+        itsBunch_m->setdT(-std::abs(itsBunch_m->getdT()));
+        stepSizes_m.reverseDirection();
+        if (pathLength_m < stepSizes_m.getZStop()) {
+            ++ stepSizes_m;
+        }
+    }
+
     Vector_t rmin(0.0), rmax(0.0);
     if (itsBunch_m->getTotalNum() > 0) {
         itsBunch_m->get_bounds(rmin, rmax);
     }
+
     OrbitThreader oth(itsReference,
                       itsBunch_m->RefPartR_m,
                       itsBunch_m->RefPartP_m,
                       pathLength_m,
                       -rmin(2),
                       itsBunch_m->getT(),
-                      minTimeStep,
+                      (back_track? -minTimeStep: minTimeStep),
                       totalNumSteps,
-                      zStop_m.back() + 2 * rmax(2),
+                      stepSizes_m.getFinalZStop() + 2 * rmax(2),
                       itsOpalBeamline_m);
 
     oth.execute();
@@ -298,7 +292,7 @@ void ParallelTTracker::execute() {
 
     *gmsg << level1
           << "Executing ParallelTTracker, initial dt= " << Util::getTimeString(itsBunch_m->getdT()) << ";\n"
-          << "max integration steps " << getMaxSteps(localTrackSteps_m) << ", next step= " << step << endl;
+          << "max integration steps " << stepSizes_m.getMaxSteps() << ", next step= " << step << endl;
 
     setOptionalVariables();
 
@@ -307,17 +301,20 @@ void ParallelTTracker::execute() {
         allocateDeviceMemory();
 #endif
 
-    // loggingFrequency_m = floor(1e-11/itsBunch_m->getdT() + 0.5);
     globalEOL_m = false;
     wakeStatus_m = false;
     deletedParticles_m = false;
     OpalData::getInstance()->setInPrepState(false);
-    while (localTrackSteps_m.size() > 0) {
-        localTrackSteps_m.front() += step;
-        dtCurrentTrack_m = dtAllTracks_m.front();
-        changeDT();
-
-        for (; step < localTrackSteps_m.front(); ++step) {
+    while (!stepSizes_m.reachedEnd()) {
+        unsigned long long trackSteps = stepSizes_m.getNumSteps() + step;
+        dtCurrentTrack_m = stepSizes_m.getdT();
+        changeDT(back_track);
+
+        for (; step < trackSteps; ++ step) {
+            Vector_t rmin(0.0), rmax(0.0);
+            if (itsBunch_m->getTotalNum() > 0) {
+                itsBunch_m->get_bounds(rmin, rmax);
+            }
 
             timeIntegration1(pusher);
 
@@ -326,9 +323,9 @@ void ParallelTTracker::execute() {
 
             computeSpaceChargeFields(step);
 
-            selectDT();
+            selectDT(back_track);
             emitParticles(step);
-            selectDT();
+            selectDT(back_track);
 
             computeExternalFields(oth);
 
@@ -336,7 +333,8 @@ void ParallelTTracker::execute() {
 
             itsBunch_m->incrementT();
 
-            if (itsBunch_m->getT() > 0.0) {
+            if (itsBunch_m->getT() > 0.0 ||
+                itsBunch_m->getdT() < 0.0) {
                 updateReference(pusher);
             }
 
@@ -344,7 +342,6 @@ void ParallelTTracker::execute() {
                 evenlyDistributeParticles();
                 deletedParticles_m = false;
             }
-
             itsBunch_m->set_sPos(pathLength_m);
 
             if (hasEndOfLineReached()) break;
@@ -356,17 +353,16 @@ void ParallelTTracker::execute() {
             itsBunch_m->incTrackSteps();
 
             double beta = euclidean_norm(itsBunch_m->RefPartP_m / Util::getGamma(itsBunch_m->RefPartP_m));
-            double driftPerTimeStep = itsBunch_m->getdT() * Physics::c * beta;
-            if (std::abs(zStop_m.front() - pathLength_m) < 0.5 * driftPerTimeStep)
-                localTrackSteps_m.front() = step;
+            double driftPerTimeStep = std::abs(itsBunch_m->getdT()) * Physics::c * beta;
+            if (std::abs(stepSizes_m.getZStop() - pathLength_m) < 0.5 * driftPerTimeStep) {
+                break;
+            }
         }
 
         if (globalEOL_m)
             break;
 
-        dtAllTracks_m.pop();
-        localTrackSteps_m.pop();
-        zStop_m.pop();
+        ++ stepSizes_m;
     }
 
     itsBunch_m->set_sPos(pathLength_m);
@@ -465,7 +461,7 @@ void ParallelTTracker::timeIntegration2(BorisPusher & pusher) {
     IpplTimings::stopTimer(timeIntegrationTimer2_m);
 }
 
-void ParallelTTracker::selectDT() {
+void ParallelTTracker::selectDT(bool backTrack) {
 
     if (itsBunch_m->getIfBeamEmitting()) {
         double dt = itsBunch_m->getEmissionDeltaT();
@@ -474,10 +470,13 @@ void ParallelTTracker::selectDT() {
         double dt = dtCurrentTrack_m;
         itsBunch_m->setdT(dt);
     }
+    if (backTrack) {
+        itsBunch_m->setdT(-std::abs(itsBunch_m->getdT()));
+    }
 }
 
-void ParallelTTracker::changeDT() {
-    selectDT();
+void ParallelTTracker::changeDT(bool backTrack) {
+    selectDT(backTrack);
     const unsigned int localNum = itsBunch_m->getLocalNum();
     for (unsigned int i = 0; i < localNum; ++ i) {
         itsBunch_m->dt[i] = itsBunch_m->getdT();
@@ -645,7 +644,7 @@ void ParallelTTracker::computeExternalFields(OrbitThreader &oth) {
 
     if (ne > 0) {
         msg << level1 << "* Deleted " << ne << " particles, "
-            << "remaining " << itsBunch_m->getTotalNum() << " particles" << endl;
+            << "remaining " << totalParticlesInSimulation_m << " particles" << endl;
     }
 }
 
@@ -1054,7 +1053,7 @@ void ParallelTTracker::writePhaseSpace(const long long step, bool psDump, bool s
     if (psDump && (itsBunch_m->getTotalNum() > 0)) {
         // Write fields to .h5 file.
         const size_t localNum = itsBunch_m->getLocalNum();
-        double distToLastStop = zStop_m.back() - pathLength_m;
+        double distToLastStop = stepSizes_m.getFinalZStop() - pathLength_m;
         Vector_t beta = itsBunch_m->RefPartP_m / Util::getGamma(itsBunch_m->RefPartP_m);
         Vector_t driftPerTimeStep = itsBunch_m->getdT() * Physics::c * itsBunch_m->toLabTrafo_m.rotateFrom(beta);
         bool driftToCorrectPosition = std::abs(distToLastStop) < 0.5 * euclidean_norm(driftPerTimeStep);
@@ -1080,7 +1079,7 @@ void ParallelTTracker::writePhaseSpace(const long long step, bool psDump, bool s
                                          Quaternion(1.0, 0.0, 0.0, 0.0));
             itsBunch_m->toLabTrafo_m = itsBunch_m->toLabTrafo_m * update.inverted();
 
-            itsBunch_m->set_sPos(zStop_m.back());
+            itsBunch_m->set_sPos(stepSizes_m.getFinalZStop());
 
             itsBunch_m->calcBeamParameters();
         }
@@ -1111,7 +1110,9 @@ void ParallelTTracker::updateReference(const BorisPusher &pusher) {
 }
 
 void ParallelTTracker::updateReferenceParticle(const BorisPusher &pusher) {
-    const double dt = std::min(itsBunch_m->getT(), itsBunch_m->getdT());
+    const double direction = back_track? -1: 1;
+    const double dt = direction * std::min(itsBunch_m->getT(),
+                                           direction * itsBunch_m->getdT());
     const double scaleFactor = Physics::c * dt;
     Vector_t Ef(0.0), Bf(0.0);
 
@@ -1162,10 +1163,9 @@ void ParallelTTracker::transformBunch(const CoordinateSystemTrafo &trafo) {
 
 void ParallelTTracker::updateRefToLabCSTrafo() {
     Vector_t R = itsBunch_m->toLabTrafo_m.transformFrom(itsBunch_m->RefPartR_m);
-
     Vector_t P = itsBunch_m->toLabTrafo_m.rotateFrom(itsBunch_m->RefPartP_m);
 
-    pathLength_m += euclidean_norm(R);
+    pathLength_m += std::copysign(1, itsBunch_m->getdT()) * euclidean_norm(R);
 
     CoordinateSystemTrafo update(R, getQuaternion(P, Vector_t(0, 0, 1)));
 
@@ -1174,15 +1174,40 @@ void ParallelTTracker::updateRefToLabCSTrafo() {
     itsBunch_m->toLabTrafo_m = itsBunch_m->toLabTrafo_m * update.inverted();
 }
 
+void ParallelTTracker::applyFractionalStep(const BorisPusher &pusher, double tau) {
+    double t = itsBunch_m->getT();
+    t += tau;
+    itsBunch_m->setT(t);
+
+    // the push method below pushes for half a time step. Hence the ref particle
+    // should be pushed for 2 * tau
+    itsBunch_m->RefPartR_m /= (Physics::c * 2 * tau);
+    pusher.push(itsBunch_m->RefPartR_m, itsBunch_m->RefPartP_m, tau);
+    itsBunch_m->RefPartR_m *= (Physics::c * 2 * tau);
+
+    pathLength_m = zstart_m;
+
+    Vector_t R = itsBunch_m->toLabTrafo_m.transformFrom(itsBunch_m->RefPartR_m);
+    Vector_t P = itsBunch_m->toLabTrafo_m.rotateFrom(itsBunch_m->RefPartP_m);
+    CoordinateSystemTrafo update(R, getQuaternion(P, Vector_t(0, 0, 1)));
+    itsBunch_m->toLabTrafo_m = itsBunch_m->toLabTrafo_m * update.inverted();
+}
+
 void ParallelTTracker::findStartPosition(const BorisPusher &pusher) {
 
+    StepSizeConfig stepSizesCopy(stepSizes_m);
+    if (back_track) {
+        stepSizesCopy.shiftZStopLeft(zstart_m);
+    }
+
     double t = 0.0;
     itsBunch_m->setT(t);
 
-    dtCurrentTrack_m = dtAllTracks_m.front();
-    changeDT();
+    dtCurrentTrack_m = stepSizesCopy.getdT();
+    selectDT();
 
-    if (Util::getEnergy(itsBunch_m->RefPartP_m, itsBunch_m->getM()) < 1e-3) {
+    if ((back_track && itsOpalBeamline_m.containsSource()) ||
+        Util::getEnergy(itsBunch_m->RefPartP_m, itsBunch_m->getM()) < 1e-3) {
         double gamma = 0.1 / itsBunch_m->getM() + 1.0;
         double beta = sqrt(1.0 - 1.0 / std::pow(gamma, 2));
         itsBunch_m->RefPartP_m = itsBunch_m->toLabTrafo_m.rotateTo(beta * gamma * Vector_t(0, 0, 1));
@@ -1198,37 +1223,32 @@ void ParallelTTracker::findStartPosition(const BorisPusher &pusher) {
         updateReferenceParticle(pusher);
         pathLength_m += euclidean_norm(itsBunch_m->RefPartR_m - oldR);
 
-        if (pathLength_m > zStop_m.front()) {
-            if (localTrackSteps_m.size() == 0) return;
-
-            dtAllTracks_m.pop();
-            localTrackSteps_m.pop();
-            zStop_m.pop();
-
-            changeDT();
-        }
-
         double speed = euclidean_norm(itsBunch_m->RefPartP_m * Physics::c / Util::getGamma(itsBunch_m->RefPartP_m));
-        if (std::abs(pathLength_m - zstart_m) <=  0.5 * itsBunch_m->getdT() * speed) {
-            double tau = (pathLength_m - zstart_m) / speed;
 
-            t += tau;
-            itsBunch_m->setT(t);
+        if (pathLength_m > stepSizesCopy.getZStop()) {
+            ++ stepSizesCopy;
 
-            itsBunch_m->RefPartR_m /= (Physics::c * tau);
-            pusher.push(itsBunch_m->RefPartR_m, itsBunch_m->RefPartP_m, tau);
-            itsBunch_m->RefPartR_m *= (Physics::c * tau);
+            if (stepSizesCopy.reachedEnd()) {
+                -- stepSizesCopy;
+                double tau = (stepSizesCopy.getZStop() - pathLength_m) / speed;
+                applyFractionalStep(pusher, tau);
 
-            pathLength_m = zstart_m;
+                break;
+            }
 
-            Vector_t R = itsBunch_m->toLabTrafo_m.transformFrom(itsBunch_m->RefPartR_m);
-            Vector_t P = itsBunch_m->toLabTrafo_m.rotateFrom(itsBunch_m->RefPartP_m);
-            CoordinateSystemTrafo update(R, getQuaternion(P, Vector_t(0, 0, 1)));
-            itsBunch_m->toLabTrafo_m = itsBunch_m->toLabTrafo_m * update.inverted();
+            dtCurrentTrack_m = stepSizesCopy.getdT();
+            selectDT();
+        }
 
-            return;
+        if (std::abs(pathLength_m - zstart_m) <=  0.5 * itsBunch_m->getdT() * speed) {
+            double tau = (zstart_m - pathLength_m) / speed;
+            applyFractionalStep(pusher, tau);
+
+            break;
         }
     }
+
+    changeDT();
 }
 
 void ParallelTTracker::autophaseCavities(const BorisPusher &pusher) {
diff --git a/src/Algorithms/ParallelTTracker.h b/src/Algorithms/ParallelTTracker.h
index dc35e2c715accf70afbbc7d4d5e179738b47ff04..c495cf0b98b2749f8c884d39ab87c75aada0c2fd 100644
--- a/src/Algorithms/ParallelTTracker.h
+++ b/src/Algorithms/ParallelTTracker.h
@@ -21,6 +21,7 @@
 #include "Algorithms/Tracker.h"
 #include "Steppers/BorisPusher.h"
 #include "Structure/DataSink.h"
+#include "Algorithms/StepSizeConfig.h"
 
 #include "BasicActions/Option.h"
 #include "Utilities/Options.h"
@@ -62,9 +63,7 @@
 
 #include <list>
 #include <vector>
-#include <queue>
 
-class BorisPusher;
 class ParticleMatterInteractionHandler;
 
 class ParallelTTracker: public Tracker {
@@ -214,14 +213,13 @@ private:
     /// where to start
     double zstart_m;
 
-    /// where to stop
-    std::queue<double> zStop_m;
+    /// stores informations where to change the time step and
+    /// where to stop the simulation,
+    /// the time step sizes and
+    /// the number of time steps with each configuration
+    StepSizeConfig stepSizes_m;
 
     double dtCurrentTrack_m;
-    std::queue<double> dtAllTracks_m;
-
-    /// The maximal number of steps the system is integrated per TRACK
-    std::queue<unsigned long long> localTrackSteps_m;
 
     // This variable controls the minimal number of steps of emission (using bins)
     // before we can merge the bins
@@ -292,8 +290,8 @@ private:
 
     void timeIntegration1(BorisPusher & pusher);
     void timeIntegration2(BorisPusher & pusher);
-    void selectDT();
-    void changeDT();
+    void selectDT(bool backTrack = false);
+    void changeDT(bool backTrack = false);
     void emitParticles(long long step);
     void computeExternalFields(OrbitThreader &oth);
     void computeWakefield(IndexMap::value_t &elements);
@@ -312,12 +310,11 @@ private:
 
     void updateReference(const BorisPusher &pusher);
     void updateRefToLabCSTrafo();
+    void applyFractionalStep(const BorisPusher &pusher, double tau);
     void findStartPosition(const BorisPusher &pusher);
     void autophaseCavities(const BorisPusher &pusher);
 
     void evenlyDistributeParticles();
-
-    static unsigned long long getMaxSteps(std::queue<unsigned long long> numSteps);
 };
 
 inline void ParallelTTracker::visitAlignWrapper(const AlignWrapper &wrap) {
@@ -455,18 +452,6 @@ inline void ParallelTTracker::pushParticles(const BorisPusher &pusher) {
     itsBunch_m->switchOffUnitlessPositions(true);
 }
 
-inline
-unsigned long long ParallelTTracker::getMaxSteps(std::queue<unsigned long long> numSteps) {
-    unsigned long long totalNumSteps = 0;
-
-    while (numSteps.size() > 0) {
-        totalNumSteps += numSteps.front();
-        numSteps.pop();
-    }
-
-    return totalNumSteps;
-}
-
 #ifdef OPAL_DKS
 inline void ParallelTTracker::setupDKS() {
     dksbase = new DKSOPAL;
diff --git a/src/Algorithms/StepSizeConfig.cpp b/src/Algorithms/StepSizeConfig.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f4808a8bf7eac9e7e6dd0892fe141165d2fc57a4
--- /dev/null
+++ b/src/Algorithms/StepSizeConfig.cpp
@@ -0,0 +1,181 @@
+#include "Algorithms/StepSizeConfig.h"
+#include "Utilities/OpalException.h"
+
+#include <algorithm>
+#include <numeric>
+#include <iterator>
+#include <cmath>
+
+void StepSizeConfig::sortAscendingZStop() {
+    configurations_m.sort([] (const entry_t &a,
+                              const entry_t &b) -> bool
+                          {
+                              return std::get<1>(a) < std::get<1>(b);
+                          });
+}
+
+void StepSizeConfig::reverseDirection() {
+    unsigned int posIterator = std::distance(it_m, configurations_m.end()) - 1;
+    configurations_m.reverse();
+    it_m = configurations_m.begin();
+    std::advance(it_m, posIterator);
+}
+
+StepSizeConfig& StepSizeConfig::advanceToPos(double spos) {
+    while (getZStop() < spos && std::next(it_m) != configurations_m.end()) {
+        ++ it_m;
+    }
+
+    return *this;
+}
+
+StepSizeConfig& StepSizeConfig::operator++() {
+    if (reachedEnd()) {
+        throw OpalException("StepSizeConfig::operator++",
+                            "iterator is at end of list of configurations");
+    }
+
+    ++ it_m;
+
+    return *this;
+}
+
+StepSizeConfig& StepSizeConfig::operator--() {
+    if (reachedStart()) {
+        throw OpalException("StepSizeConfig::operator--",
+                            "iterator is at begin of list of configurations");
+    }
+
+    -- it_m;
+
+    return *this;
+}
+
+void StepSizeConfig::shiftZStopRight(double front) {
+    auto it = configurations_m.begin();
+    while (std::get<1>(*it) < front &&
+           std::next(it) != configurations_m.end()) {
+        ++ it;
+    }
+
+    double zstop = std::get<1>(*it);
+    if (zstop < front) return;
+
+    std::get<1>(*it) = front;
+    for (++ it ;
+         it != configurations_m.end();
+         ++ it) {
+        std::swap(zstop, std::get<1>(*it));
+    }
+}
+
+void StepSizeConfig::shiftZStopLeft(double back) {
+    auto it = configurations_m.rbegin();
+    while (std::get<1>(*it) > back &&
+           std::next(it) != configurations_m.rend()) {
+        ++ it;
+    }
+
+    double zstop = std::get<1>(*it);
+    if (zstop > back) return;
+
+    std::get<1>(*it) = back;
+    for (++ it ;
+         it != configurations_m.rend();
+         ++ it) {
+        std::swap(zstop, std::get<1>(*it));
+    }
+}
+
+double StepSizeConfig::getdT() const {
+    if (reachedEnd()) {
+        throw OpalException("StepSizeConfig::getdT",
+                            "iterator is at end of list of configurations");
+    }
+
+    return std::get<0>(*it_m);
+}
+
+double StepSizeConfig::getZStop() const {
+    if (reachedEnd()) {
+        throw OpalException("StepSizeConfig::getZStop",
+                            "iterator is at end of list of configurations");
+    }
+
+    return std::get<1>(*it_m);
+}
+
+unsigned long StepSizeConfig::getNumSteps() const {
+    if (reachedEnd()) {
+        throw OpalException("StepSizeConfig::getNumSteps",
+                            "iterator is at end of list of configurations");
+    }
+
+    return std::get<2>(*it_m);
+}
+
+unsigned long long StepSizeConfig::getMaxSteps() const {
+    unsigned long long maxSteps = 0;
+    for (const auto config: configurations_m) {
+        maxSteps += std::get<2>(config);
+    }
+
+    return maxSteps;
+}
+
+unsigned long long StepSizeConfig::getNumStepsFinestResolution() const {
+    double minTimeStep = std::get<0>(configurations_m.front());
+    unsigned long long totalNumSteps = 0;
+
+    for (const auto config: configurations_m) {
+        const double &dt = std::get<0>(config);
+        const unsigned long &numSteps = std::get<2>(config);
+
+        if (minTimeStep > dt) {
+            totalNumSteps = std::ceil(totalNumSteps * minTimeStep / dt);
+            minTimeStep = dt;
+        }
+
+        totalNumSteps += std::ceil(numSteps * dt / minTimeStep);
+    }
+
+    return totalNumSteps;
+}
+
+double StepSizeConfig::getMinTimeStep() const {
+    double minTimeStep = std::get<0>(configurations_m.front());
+    for (const auto config: configurations_m) {
+        if (minTimeStep > std::get<0>(config)) {
+            minTimeStep = std::get<0>(config);
+        }
+    }
+
+    return minTimeStep;
+}
+
+double StepSizeConfig::getFinalZStop() const {
+    return std::get<1>(configurations_m.back());
+}
+
+void StepSizeConfig::print(Inform &out) const {
+    out << std::scientific << "   "
+        << std::setw(20) << "dt [ns] "
+        << std::setw(20) << "zStop [m] "
+        << std::setw(20) << "num Steps [1]"
+        << endl;
+
+    for (auto it = configurations_m.begin();
+         it != configurations_m.end();
+         ++ it) {
+        if (it_m == it) {
+            out << "-> ";
+        } else {
+            out << "   ";
+        }
+
+        out << std::setw(20) << std::get<0>(*it)
+            << std::setw(20) << std::get<1>(*it)
+            << std::setw(20) << std::get<2>(*it)
+            << endl;
+    }
+}
\ No newline at end of file
diff --git a/src/Algorithms/StepSizeConfig.h b/src/Algorithms/StepSizeConfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..2ece19c7a3e2aacc8aaf9d96ff491cbf69dabe49
--- /dev/null
+++ b/src/Algorithms/StepSizeConfig.h
@@ -0,0 +1,106 @@
+#ifndef STEPSIZECONFIG_H
+#define STEPSIZECONFIG_H
+
+#include "Utility/Inform.h"
+
+#include <list>
+#include <tuple>
+
+class StepSizeConfig {
+public:
+    StepSizeConfig();
+
+    StepSizeConfig(const StepSizeConfig &right);
+
+    void operator=(const StepSizeConfig &) = delete;
+
+    void push_back(double dt,
+                   double zstop,
+                   unsigned long numSteps);
+
+    void sortAscendingZStop();
+
+    void resetIterator();
+
+    bool reachedStart() const;
+
+    bool reachedEnd() const;
+
+    void clear();
+
+    void reverseDirection();
+
+    StepSizeConfig& advanceToPos(double spos);
+
+    StepSizeConfig& operator++();
+
+    StepSizeConfig& operator--();
+
+    void shiftZStopRight(double front);
+    void shiftZStopLeft(double back);
+
+    double getdT() const;
+
+    double getZStop() const;
+
+    unsigned long getNumSteps() const;
+
+    unsigned long long getMaxSteps() const;
+
+    unsigned long long getNumStepsFinestResolution() const;
+
+    double getMinTimeStep() const;
+
+    double getFinalZStop() const;
+
+    void print(Inform &out) const;
+
+private:
+    typedef std::tuple<double, double, unsigned long> entry_t;
+    typedef std::list<entry_t> container_t;
+
+    container_t configurations_m;
+    container_t::iterator it_m;
+};
+
+inline
+StepSizeConfig::StepSizeConfig():
+    configurations_m(),
+    it_m(configurations_m.begin())
+{ }
+
+inline
+StepSizeConfig::StepSizeConfig(const StepSizeConfig &right):
+    configurations_m(right.configurations_m),
+    it_m(configurations_m.begin())
+{ }
+
+inline
+void StepSizeConfig::push_back(double dt,
+                               double zstop,
+                               unsigned long numSteps) {
+    configurations_m.push_back(std::make_tuple(dt, zstop, numSteps));
+}
+
+inline
+void StepSizeConfig::resetIterator() {
+    it_m = configurations_m.begin();
+}
+
+inline
+bool StepSizeConfig::reachedStart() const {
+    return (it_m == configurations_m.begin());
+}
+
+inline
+bool StepSizeConfig::reachedEnd() const {
+    return (it_m == configurations_m.end());
+}
+
+inline
+void StepSizeConfig::clear() {
+    configurations_m.clear();
+    it_m = configurations_m.begin();
+}
+
+#endif
\ No newline at end of file
diff --git a/src/Classic/AbsBeamline/Monitor.cpp b/src/Classic/AbsBeamline/Monitor.cpp
index a460fc7c170c5a40ffb5cc3c453e6575a75e0303..78a8c454b71a2abf2356df6065241813335c5f3f 100644
--- a/src/Classic/AbsBeamline/Monitor.cpp
+++ b/src/Classic/AbsBeamline/Monitor.cpp
@@ -78,7 +78,8 @@ bool Monitor::apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B)
     const double recpgamma = Physics::c * dt / Util::getGamma(P);
     const double middle = 0.5 * getElementLength();
     if (online_m && type_m == SPATIAL) {
-        if (R(2) < middle && R(2) + P(2) * recpgamma > middle) {
+        if (dt * R(2) < dt * middle && // multiply with dt to allow back tracking
+            dt * (R(2) + P(2) * recpgamma) > dt * middle) {
             double frac = (middle - R(2)) / (P(2) * recpgamma);
 
             lossDs_m->addParticle(R + frac * recpgamma * P,
@@ -99,7 +100,8 @@ bool Monitor::applyToReferenceParticle(const Vector_t &R,
         const double recpgamma = Physics::c * dt / Util::getGamma(P);
         const double middle = 0.5 * getElementLength();
 
-        if (R(2) < middle && R(2) + P(2) * recpgamma > middle) {
+        if (dt * R(2) < dt * middle && // multiply with dt to allow back tracking
+            dt * (R(2) + P(2) * recpgamma) > dt * middle) {
             double frac = (middle - R(2)) / (P(2) * recpgamma);
             double time = t + frac * dt;
             Vector_t dR = (0.5 + frac) * P * recpgamma;
@@ -115,7 +117,7 @@ bool Monitor::applyToReferenceParticle(const Vector_t &R,
 
                 for (unsigned int i = 0; i < localNum; ++ i) {
                     const double recpgamma = Physics::c * dt / Util::getGamma(RefPartBunch_m->P[i]);
-                    lossDs_m->addParticle(RefPartBunch_m->R[i] + frac * RefPartBunch_m->P[i] * recpgamma,
+                    lossDs_m->addParticle(RefPartBunch_m->R[i] + frac * RefPartBunch_m->P[i] * recpgamma - halfLength_s,
                                           RefPartBunch_m->P[i], RefPartBunch_m->ID[i],
                                           time, 0);
                 }
diff --git a/src/Classic/AbsBeamline/Source.cpp b/src/Classic/AbsBeamline/Source.cpp
index 1a6cb856d26cec3497f4f0e583d2c9c8f7cce5cf..c96f309137ffe7cd5b5e14a9cb0248ade7bc49af 100644
--- a/src/Classic/AbsBeamline/Source.cpp
+++ b/src/Classic/AbsBeamline/Source.cpp
@@ -14,8 +14,6 @@ extern Inform *gmsg;
 // Class Source
 // ------------------------------------------------------------------------
 
-const std::string Source::defaultDistribution("DISTRIBUTION");
-
 Source::Source():
     Source("")
 {}
@@ -65,26 +63,37 @@ void Source::addKR(int i, double t, Vector_t &K) {
 void Source::addKT(int i, double t, Vector_t &K) {
 }
 
-bool Source::apply(const double &t) {
-    Vector_t externalE = Vector_t(0.0);
-    Vector_t externalB = Vector_t(0.0);
-    beamline_m->getFieldAt(csTrafoGlobal2Local_m.getOrigin(),
-                           Vector_t(0.0),
-                           RefPartBunch_m->getT() + 0.5 * RefPartBunch_m->getdT(),
-                           externalE,
-                           externalB);
-    for (Distribution* dist: distrs_m) {
-        dist->emitParticles(RefPartBunch_m, externalE(2));
+bool Source::apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) {
+    const Vector_t &R = RefPartBunch_m->R[i];
+    const Vector_t &P = RefPartBunch_m->P[i];
+    const double &dt = RefPartBunch_m->dt[i];
+    const double recpgamma = Physics::c * dt / Util::getGamma(P);
+    const double end = getElementLength();
+    if (online_m && dt < 0.0) {
+        if (R(2) > end &&
+            (R(2) + P(2) * recpgamma) < end) {
+            double frac = (end - R(2)) / (P(2) * recpgamma);
+
+            lossDs_m->addParticle(R + frac * recpgamma * P,
+                                  P, RefPartBunch_m->ID[i], t + frac * dt, 0);
+
+            return true;
+        }
     }
 
     return false;
 }
 
 void Source::initialise(PartBunchBase<double, 3> *bunch, double &startField, double &endField) {
-    // Inform msg("Source ", *gmsg);
-    // double zBegin = 0.0, zEnd = 0.0, rBegin = 0.0, rEnd = 0.0;
-
     RefPartBunch_m = bunch;
+    endField = startField;
+    startField -= getElementLength();
+
+    std::string filename = getName();
+    lossDs_m = std::unique_ptr<LossDataSink>(new LossDataSink(filename,
+                                                              !Options::asciidump,
+                                                              getType()));
+
 }
 
 void Source::finalise()
@@ -101,6 +110,7 @@ void Source::goOnline(const double &) {
 
 void Source::goOffline() {
     online_m = false;
+    lossDs_m->save();
 }
 
 void Source::getDimensions(double &zBegin, double &zEnd) const {
@@ -111,16 +121,4 @@ void Source::getDimensions(double &zBegin, double &zEnd) const {
 
 ElementBase::ElementType Source::getType() const {
     return SOURCE;
-}
-
-void Source::setDistribution(std::vector<std::string> distNames) {
-    const size_t numberOfDistributions = distNames.size();
-    if (numberOfDistributions == 0) {
-        distrs_m.push_back(Distribution::find(defaultDistribution));
-    } else {
-        for (std::string name: distNames) {
-            distrs_m.push_back(Distribution::find(name));
-            distrs_m.back()->setNumberOfDistributions(numberOfDistributions);
-        }
-    }
 }
\ No newline at end of file
diff --git a/src/Classic/AbsBeamline/Source.h b/src/Classic/AbsBeamline/Source.h
index e62ea0c329a1caf798c1bb5d2a9ff69600fded52..830eb96546abc174bdab970b0823e7406ce93829 100644
--- a/src/Classic/AbsBeamline/Source.h
+++ b/src/Classic/AbsBeamline/Source.h
@@ -2,7 +2,8 @@
 #define CLASSIC_SOURCE_HH
 
 #include "AbsBeamline/Component.h"
-#include "Distribution/Distribution.h"
+#include "Structure/LossDataSink.h"
+
 class OpalBeamline;
 
 template <class T, unsigned Dim>
@@ -26,8 +27,7 @@ public:
 
     virtual void addKT(int i, double t, Vector_t &K) override;
 
-    using Component::apply;
-    virtual bool apply(const double &t);
+    virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) override;
 
     virtual void initialise(PartBunchBase<double, 3> *bunch, double &startField, double &endField) override;
 
@@ -43,26 +43,15 @@ public:
 
     virtual void getDimensions(double &zBegin, double &zEnd) const override;
 
-    void setDistribution(std::vector<std::string> distNames);
-
-    void setBeamline(OpalBeamline *beamline);
 private:
 
     double ElementEdge_m;
     double startField_m;           /**< startingpoint of field, m*/
     double endField_m;
 
-    std::vector<Distribution*> distrs_m;
+    std::unique_ptr<LossDataSink> lossDs_m;
 
-    OpalBeamline *beamline_m;
     // Not implemented.
     void operator=(const Source &);
-
-    static const std::string defaultDistribution;
 };
-
-inline
-void Source::setBeamline(OpalBeamline *beamline) {
-    beamline_m = beamline;
-}
-#endif // CLASSIC_SOURCE_HH
+#endif // CLASSIC_SOURCE_HH
\ No newline at end of file
diff --git a/src/Classic/Algorithms/PartBunchBase.hpp b/src/Classic/Algorithms/PartBunchBase.hpp
index 3df9b5d0bc5beecc0234897ff3928ada7a0cbece..2c1d57cd69fdcd56772142ee96b5320f51de051b 100644
--- a/src/Classic/Algorithms/PartBunchBase.hpp
+++ b/src/Classic/Algorithms/PartBunchBase.hpp
@@ -1191,7 +1191,7 @@ Vector_t PartBunchBase<T, Dim>::get_pmean() const {
 
 template <class T, unsigned Dim>
 Vector_t PartBunchBase<T, Dim>::get_pmean_Distribution() const {
-    if (dist_m && dist_m->getType() != DistrTypeT::FROMFILE)
+    if (dist_m)// && dist_m->getType() != DistrTypeT::FROMFILE)
         return dist_m->get_pmean();
 
     double gamma = 0.1 / getM() + 1; // set default 0.1 eV
diff --git a/src/Classic/Structure/LossDataSink.cpp b/src/Classic/Structure/LossDataSink.cpp
index 4238a77a977620cfd4bf2944e91d7713dd2ef046..e549fb3ee14fe56bc70f15fa0dfc47aab0bc8d1f 100644
--- a/src/Classic/Structure/LossDataSink.cpp
+++ b/src/Classic/Structure/LossDataSink.cpp
@@ -103,8 +103,14 @@
 
 
 SetStatistics::SetStatistics():
+    element_m(""),
+    spos_m(0.0),
+    refTime_m(0.0),
     tmean_m(0.0),
     trms_m(0.0),
+    nTotal_m(0),
+    RefPartR_m(0.0),
+    RefPartP_m(0.0),
     rmin_m(0.0),
     rmax_m(0.0),
     rmean_m(0.0),
@@ -627,6 +633,7 @@ SetStatistics LossDataSink::computeSetStatistics(unsigned int setIdx) {
     new_reduce(rminmax, 6, std::greater<double>());
 
     if (Ippl::myNode() != 0) return stat;
+    if (plainData[0] == 0.0) return stat;
 
     double *centroid = plainData + 1;
     double *moments = plainData + 7;
diff --git a/src/Classic/Structure/LossDataSink.h b/src/Classic/Structure/LossDataSink.h
index 8f5113130c72a3b205083babec69ed3f86d57e9c..900cb6723e27d28d94679a1d7b98f8d6df966377 100644
--- a/src/Classic/Structure/LossDataSink.h
+++ b/src/Classic/Structure/LossDataSink.h
@@ -182,7 +182,10 @@ std::set<SetStatistics> LossDataSink::computeStatistics(unsigned int numStatisti
     splitSets(numStatistics);
 
     for (unsigned int i = 0; i < numStatistics; ++ i) {
-        stats.insert(computeSetStatistics(i));
+        auto setStats = computeSetStatistics(i);
+        if (setStats.nTotal_m > 0) {
+            stats.insert(setStats);
+        }
     }
 
     return stats;
diff --git a/src/Distribution/Distribution.cpp b/src/Distribution/Distribution.cpp
index efee18c1018fff4889f734db0e61ea2e3d5f2ac2..322b8772bbc38a2287f19875fedcb5b5e5fa0bbe 100644
--- a/src/Distribution/Distribution.cpp
+++ b/src/Distribution/Distribution.cpp
@@ -1328,10 +1328,10 @@ void Distribution::createMatchedGaussDistribution(size_t numberOfParticles, doub
 
     double rguess =
         Attributes::getReal(itsAttr[Attrib::Distribution::RGUESS]);
-    
+
     double denergy = 1000.0 *
         Attributes::getReal(itsAttr[Attrib::Distribution::DENERGY]);
-    
+
     if ( denergy < 0.0 )
         throw OpalException("Distribution:CreateMatchedGaussDistribution()",
                             "DENERGY < 0");
@@ -4401,7 +4401,7 @@ void Distribution::shiftBeam(double &maxTOrZ, double &minTOrZ) {
             maxTOrZ -= maxTOrZ;
         }
 
-    } else {
+    } else if (distrTypeT_m != DistrTypeT::FROMFILE) {
         double avgZ[] = {0.0, 1.0 * tOrZDist_m.size()};
         for (double tOrZ : tOrZDist_m)
             avgZ[0] += tOrZ;
diff --git a/src/Elements/OpalBeamline.cpp b/src/Elements/OpalBeamline.cpp
index 24f3c4c4206d033850740c87aefddb7a33207e29..a852ce7379771a406ecec9330aaaa07d39999a52 100644
--- a/src/Elements/OpalBeamline.cpp
+++ b/src/Elements/OpalBeamline.cpp
@@ -214,58 +214,60 @@ void OpalBeamline::compute3DLattice() {
             }
             (*it).order_m = minOrder;
             std::shared_ptr<Component> element = (*it).getElement();
-            if (element->getType() == ElementBase::SBEND ||
-                element->getType() == ElementBase::RBEND ||
-                element->getType() == ElementBase::RBEND3D) {
-
-                double beginThisPathLength = element->getElementPosition();
-                Vector_t beginThis3D(0, 0, beginThisPathLength - endPriorPathLength);
-                BendBase * bendElement = static_cast<BendBase*>(element.get());
-                double thisLength = bendElement->getChordLength();
-                double bendAngle = bendElement->getBendAngle();
-                double entranceAngle = bendElement->getEntranceAngle();
-                double arcLength = (thisLength * std::abs(bendAngle) / (2 * sin(std::abs(bendAngle) / 2)));
-
-                double rotationAngleAboutZ = bendElement->getRotationAboutZ();
-                Quaternion_t rotationAboutZ(cos(0.5 * rotationAngleAboutZ),
-                                            sin(-0.5 * rotationAngleAboutZ) * Vector_t(0, 0, 1));
-
-                Vector_t effectiveRotationAxis = rotationAboutZ.rotate(Vector_t(0, -1, 0));
-                effectiveRotationAxis /= euclidean_norm(effectiveRotationAxis);
-
-                Quaternion_t rotationAboutAxis(cos(0.5 * bendAngle),
-                                               sin(0.5 * bendAngle) * effectiveRotationAxis);
-                Quaternion_t halfRotationAboutAxis(cos(0.25 * bendAngle),
-                                                   sin(0.25 * bendAngle) * effectiveRotationAxis);
-                Quaternion_t entryFaceRotation(cos(0.5 * entranceAngle),
-                                               sin(0.5 * entranceAngle) * effectiveRotationAxis);
-
-                if (!Options::idealized) {
-                    std::vector<Vector_t> truePath = bendElement->getDesignPath();
-                    Quaternion_t directionExitHardEdge(cos(0.5 * (0.5 * bendAngle - entranceAngle)),
-                                                       sin(0.5 * (0.5 * bendAngle - entranceAngle)) * effectiveRotationAxis);
-                    Vector_t exitHardEdge = thisLength * directionExitHardEdge.rotate(Vector_t(0, 0, 1));
-                    double distanceEntryHETruePath = euclidean_norm(truePath.front());
-                    double distanceExitHETruePath = euclidean_norm(rotationAboutZ.rotate(truePath.back()) - exitHardEdge);
-                    double pathLengthTruePath = (*it).getEnd() - (*it).getStart();
-                    arcLength = pathLengthTruePath - distanceEntryHETruePath - distanceExitHETruePath;
-                }
 
-                Vector_t chord = thisLength * halfRotationAboutAxis.rotate(Vector_t(0, 0, 1));
-                Vector_t endThis3D = beginThis3D + chord;
-                double endThisPathLength = beginThisPathLength + arcLength;
+            if (element->getType() != ElementBase::SBEND &&
+                element->getType() != ElementBase::RBEND &&
+                element->getType() != ElementBase::RBEND3D) {
+                continue;
+            }
+
+            double beginThisPathLength = element->getElementPosition();
+            Vector_t beginThis3D(0, 0, beginThisPathLength - endPriorPathLength);
+            BendBase * bendElement = static_cast<BendBase*>(element.get());
+            double thisLength = bendElement->getChordLength();
+            double bendAngle = bendElement->getBendAngle();
+            double entranceAngle = bendElement->getEntranceAngle();
+            double arcLength = (thisLength * std::abs(bendAngle) / (2 * sin(std::abs(bendAngle) / 2)));
 
-                CoordinateSystemTrafo fromEndLastToBeginThis(beginThis3D,
-                                                             (entryFaceRotation * rotationAboutZ).conjugate());
-                CoordinateSystemTrafo fromEndLastToEndThis(endThis3D,
-                                                           rotationAboutAxis.conjugate());
+            double rotationAngleAboutZ = bendElement->getRotationAboutZ();
+            Quaternion_t rotationAboutZ(cos(0.5 * rotationAngleAboutZ),
+                                        sin(-0.5 * rotationAngleAboutZ) * Vector_t(0, 0, 1));
 
-                (*it).setCoordTransformationTo(fromEndLastToBeginThis * currentCoordTrafo);
+            Vector_t effectiveRotationAxis = rotationAboutZ.rotate(Vector_t(0, -1, 0));
+            effectiveRotationAxis /= euclidean_norm(effectiveRotationAxis);
 
-                currentCoordTrafo = (fromEndLastToEndThis * currentCoordTrafo);
+            Quaternion_t rotationAboutAxis(cos(0.5 * bendAngle),
+                                           sin(0.5 * bendAngle) * effectiveRotationAxis);
+            Quaternion_t halfRotationAboutAxis(cos(0.25 * bendAngle),
+                                               sin(0.25 * bendAngle) * effectiveRotationAxis);
+            Quaternion_t entryFaceRotation(cos(0.5 * entranceAngle),
+                                           sin(0.5 * entranceAngle) * effectiveRotationAxis);
 
-                endPriorPathLength = endThisPathLength;
+            if (!Options::idealized) {
+                std::vector<Vector_t> truePath = bendElement->getDesignPath();
+                Quaternion_t directionExitHardEdge(cos(0.5 * (0.5 * bendAngle - entranceAngle)),
+                                                   sin(0.5 * (0.5 * bendAngle - entranceAngle)) * effectiveRotationAxis);
+                Vector_t exitHardEdge = thisLength * directionExitHardEdge.rotate(Vector_t(0, 0, 1));
+                double distanceEntryHETruePath = euclidean_norm(truePath.front());
+                double distanceExitHETruePath = euclidean_norm(rotationAboutZ.rotate(truePath.back()) - exitHardEdge);
+                double pathLengthTruePath = (*it).getEnd() - (*it).getStart();
+                arcLength = pathLengthTruePath - distanceEntryHETruePath - distanceExitHETruePath;
             }
+
+            Vector_t chord = thisLength * halfRotationAboutAxis.rotate(Vector_t(0, 0, 1));
+            Vector_t endThis3D = beginThis3D + chord;
+            double endThisPathLength = beginThisPathLength + arcLength;
+
+            CoordinateSystemTrafo fromEndLastToBeginThis(beginThis3D,
+                                                         (entryFaceRotation * rotationAboutZ).conjugate());
+            CoordinateSystemTrafo fromEndLastToEndThis(endThis3D,
+                                                       rotationAboutAxis.conjugate());
+
+            (*it).setCoordTransformationTo(fromEndLastToBeginThis * currentCoordTrafo);
+
+            currentCoordTrafo = (fromEndLastToEndThis * currentCoordTrafo);
+
+            endPriorPathLength = endThisPathLength;
         }
     }
 
@@ -283,6 +285,9 @@ void OpalBeamline::compute3DLattice() {
         double thisLength = element->getElementLength();
         Vector_t beginThis3D(0, 0, beginThisPathLength - endPriorPathLength);
 
+        if (element->getType() == ElementBase::SOURCE) {
+            beginThis3D(2) -= thisLength;
+        }
         if (element->getType() == ElementBase::MONITOR) {
             beginThis3D(2) -= 0.5 * thisLength;
         }
@@ -587,4 +592,4 @@ void OpalBeamline::activateElements() {
         (*it).setOn(designEnergy);
         // element->goOnline(designEnergy);
     }
-}
\ No newline at end of file
+}
diff --git a/src/Elements/OpalBeamline.h b/src/Elements/OpalBeamline.h
index 6ef4455d236edb5b56c76f5480af820b39cd47e9..9eced4f53b60d1823f470ddaed92da84f76e3f2e 100644
--- a/src/Elements/OpalBeamline.h
+++ b/src/Elements/OpalBeamline.h
@@ -111,6 +111,15 @@ void OpalBeamline::visit(const T &element, BeamlineVisitor &, PartBunchBase<doub
 template<> inline
 void OpalBeamline::visit<Source>(const Source &element, BeamlineVisitor &, PartBunchBase<double, 3> *bunch) {
     containsSource_m = true;
+    double startField = 0.0;
+    double endField = 0.0;
+    std::shared_ptr<Source> elptr(dynamic_cast<Source *>(element.removeWrappers()->clone()));
+
+    if (elptr->isElementPositionSet())
+        startField = elptr->getElementPosition();
+
+    elptr->initialise(bunch, startField, endField);
+    elements_m.push_back(ClassicField(elptr, startField, endField));
 }
 
 template<> inline
diff --git a/src/Elements/OpalSource.cpp b/src/Elements/OpalSource.cpp
index 330f44d22d661535c8960af47718aafb94ecd6f5..0a912825f8d3d712bf3a3f418c0b01e195fba352 100644
--- a/src/Elements/OpalSource.cpp
+++ b/src/Elements/OpalSource.cpp
@@ -49,13 +49,10 @@ void OpalSource::update() {
 
     SourceRep *sol =
         dynamic_cast<SourceRep *>(getElement()->removeWrappers());
-    double length = Attributes::getReal(itsAttr[LENGTH]);
-    std::vector<std::string> distribution = Attributes::getStringArray(itsAttr[DISTRIBUTION]);
+    double length = 0.05;
 
     sol->setElementLength(length);
 
-    sol->setDistribution(distribution);
-
     // Transmit "unknown" attributes.
     OpalElement::updateUnknown(sol);
 }
\ No newline at end of file
diff --git a/src/Track/TrackRun.cpp b/src/Track/TrackRun.cpp
index 40822dd81f03949678dff62a6dd4e50e4c5657f1..4eafbebd935ec03c19aa38ee314d488f69885f56 100644
--- a/src/Track/TrackRun.cpp
+++ b/src/Track/TrackRun.cpp
@@ -81,6 +81,7 @@ namespace {
         BOUNDARYGEOMETRY, // The boundary geometry
         DISTRIBUTION, // The particle distribution
         MULTIPACTING, // MULTIPACTING flag
+        TRACKBACK,
         SIZE
     };
 }
@@ -125,7 +126,8 @@ TrackRun::TrackRun():
                              ("DISTRIBUTION", "List of particle distributions to be used ");
     itsAttr[MULTIPACTING] = Attributes::makeBool
                             ("MULTIPACTING", "Multipacting flag, default: false. Set true to initialize primary particles according to BoundaryGeometry", false);
-
+    itsAttr[TRACKBACK] = Attributes::makeBool
+        ("TRACKBACK", "Track in reverse direction, default: false", false);
     registerOwnership(AttributeHandler::SUB_COMMAND);
 
     opal = OpalData::getInstance();
@@ -318,19 +320,15 @@ void TrackRun::setupSliceTracker() {
     if (Track::block->bunch->getTotalNum() > 0) {
         double spos = Track::block->zstart;
         auto &zstop = Track::block->zstop;
-        auto &timeStep = Track::block->localTimeSteps;
-        auto &dT = Track::block->dT;
+        auto it = Track::block->dT.begin();
 
         unsigned int i = 0;
         while (i + 1 < zstop.size() && zstop[i + 1] < spos) {
             ++ i;
+            ++ it;
         }
 
-        zstop.erase(zstop.begin(), zstop.begin() + i);
-        timeStep.erase(timeStep.begin(), timeStep.begin() + i);
-        dT.erase(dT.begin(), dT.begin() + i);
-
-        Track::block->bunch->setdT(dT.front());
+        Track::block->bunch->setdT(*it);
     } else {
         Track::block->zstart = 0.0;
     }
@@ -550,19 +548,15 @@ void TrackRun::setupTTracker(){
     if (Track::block->bunch->getTotalNum() > 0) {
         double spos = Track::block->zstart;
         auto &zstop = Track::block->zstop;
-        auto &timeStep = Track::block->localTimeSteps;
-        auto &dT = Track::block->dT;
+        auto it = Track::block->dT.begin();
 
         unsigned int i = 0;
         while (i + 1 < zstop.size() && zstop[i + 1] < spos) {
             ++ i;
+            ++ it;
         }
 
-        zstop.erase(zstop.begin(), zstop.begin() + i);
-        timeStep.erase(timeStep.begin(), timeStep.begin() + i);
-        dT.erase(dT.begin(), dT.begin() + i);
-
-        Track::block->bunch->setdT(dT.front());
+        Track::block->bunch->setdT(*it);
     } else {
         Track::block->zstart = 0.0;
     }
@@ -585,7 +579,7 @@ void TrackRun::setupTTracker(){
                                       *ds,
                                       Track::block->reference,
                                       false,
-                                      false,
+                                      Attributes::getBool(itsAttr[TRACKBACK]),
                                       Track::block->localTimeSteps,
                                       Track::block->zstart,
                                       Track::block->zstop,
diff --git a/tools/emacs/opal.el b/tools/emacs/opal.el
index c2efbfaf467978c7d16ce6514e31da71bfb99466..9bbb23bea007d3d04c7585d03364f3cb382b4100 100644
--- a/tools/emacs/opal.el
+++ b/tools/emacs/opal.el
@@ -138,11 +138,11 @@
   )
   "Highlighting expressions for OPAL mode (seqediting).")
 
-;(concat "\\<" (regexp-opt '("A" "ADD" "AMPLITUDE_MODEL" "ANGLE" "APERTURE" "APVETO" "AT" "AUTOPHASE" "B" "BBOXINCR" "BCFFTZ" "BCFFTT" "BCFFTX" "BCFFTY" "BCURRENT" "BEAM_PHIINIT" "BEAM_PRINIT" "BEAM_RINIT" "BFREQ" "BIRTH_CONTROL" "BMAX" "BOUNDPDESTROYFQ" "BSCALE" "BY" "CALLS" "CATHTEMP" "CENTRE" "CHARGE" "CLASS" "CLEAR" "CMD" "COEFDENOM" "COEFDENOMPHI" "COEFNUM" "COEFNUMPHI" "COLUMN" "CONDUCT" "CONSTRAINTS" "CONST_LENGTH" "CONV_HVOL_PROG" "CORRX" "CORRY" "CORRZ" "CSRDUMP" "CROSSOVER" "CUTOFFLONG" "CUTOFFPX" "CUTOFFPY" "CUTOFFPZ" "CUTOFFR" "CUTOFFX" "CUTOFFY" "CYHARMON" "CZERO" "DESIGNENERGY" "DK1" "DK1S" "DK2" "DK2S" "DKN" "DKNR" "DKS" "DKSR" "DLAG" "DPHI" "DPSI" "DS" "DT" "DTHETA" "DUMP" "DUMP_DAT" "DUMP_FREQ" "DUMP_OFFSPRING" "DVARS" "DVOLT" "DX" "DY" "DZ" "E1" "E2" "EBDUMP" "ECHO" "EKIN" "ELASER" "ELEMEDGE" "ELEMENT" "EMISSIONMODEL" "EMISSIONSTEPS" "EMITTED" "ENABLEHDF5" "ENABLERUTHERFORD" "ENERGY" "ENDSEQUENCE" "END_NORMAL_X" "END_NORMAL_Y" "END_POSITION_X" "END_POSITION_Y" "EPSILON" "ESCALE" "ET" "EVERYSTEP" "EX" "EXPECTED_HYPERVOL" "EXPR" "EY" "FE" "FGEOM" "FIELDMAPDIR" "FIELDMAPDIR" "FILE" "FINT" "FMAPFN" "FNAME" "FORM" "FREQ" "FREQUENCY_MODEL" "FROM" "FSTYPE" "FTOSCAMPLITUDE" "FTOSCPERIODS" "FULL" "GAMMA" "GAP" "GAPWIDTH" "GENE_MUTATION_PROBABILITY" "GEOMETRY" "GREENSF" "H1" "H2" "HAPERT" "HARMON" "HARMONIC_NUMBER" "HGAP" "HKICK" "HYPERVOLREFERENCE" "IDEALIZED" "INITIAL_OPTIMIZATION" "IMAGENAME" "INFO" "INITIALPOPULATION" "INPUT" "INPUTMOUNITS" "INTENSITYCUT" "INTERPL" "IS_CLOSED" "ITSOLVER" "K0" "K0S" "K1" "K1S" "K2" "K2S" "K3" "K3S" "KEYWORD" "KICK" "KN" "KS" "L" "LAG" "LASERPROFFN" "LATTICE_PHIINIT" "LATTICE_RINIT" "LATTICE_THETAINIT" "LENGTH" "LEVEL" "LOGBENDTRAJECTORY" "LOWER" "LOWERBOUND" "MASS" "MATERIAL" "MAXGENERATIONS" "MAXITERS" "MAXR" "MAXSTEPS" "MAXZ" "METHOD" "MINR" "MINZ" "MODE" "MREX" "MREY" "MSCALX" "MSCALY" "MT" "MUTATION_PROBABILITY" "MX" "MY" "NBIN" "NFREQ" "NLEFT" "NO" "NPART" "NPOINTS" "NRIGHT" "NUMCELLS" "NUM_COWORKERS" "NUM_IND_GEN" "NUM_MASTERS" "OBJECTIVES" "OFFSETPX" "OFFSETPY" "OFFSETPZ" "OFFSETT" "OFFSETX" "OFFSETY" "OFFSETZ" "ONE_PILOT_CONVERGE" "OPCHARGE" "OPMASS" "OPYIELD" "ORDER" "ORIENTATION" "ORIGIN" "OUTDIR" "OUTFN" "OUTPUT" "P1" "P2" "P3" "P4" "PARFFTT" "PARFFTX" "PARFFTY" "PARTICLE" "PARTICLEMATTERINTERACTION" "PATTERN" "PC" "PDIS" "PHI" "PHI0" "PHIINIT" "PHIMAX" "PHIMIN" "PLANE" "POLYORDER" "PRECMODE" "PRINIT" "PSDUMPEACHTURN" "PSDUMPFRAME" "PSDUMPFREQ" "PSI" "PTC" "PYMULT" "PZINIT" "PZMULT" "R51" "R52" "R61" "R62" "RADIUS" "RANDOM" "RANGE" "RASTER" "RECOMBINATION_PROBABILITY" "REFER" "REFPOS" "REPARTFREQ" "RESET" "RFFREQ" "RFMAPFN" "RFPHI" "RINIT" "RMAX" "RMIN" "ROTATION" "ROW" "S" "SAMPLINGS" "SCALABLE" "SEED" "SELECTED" "SEQUENCE" "SIGMA" "SIGMAPX" "SIGMAPY" "SIGMAPZ" "SIGMAR" "SIGMAT" "SIGMAX" "SIGMAY" "SIGMAZ" "SIGX" "SIGY" "SIMBIN_CROSSOVER_NU" "SIMTMPDIR" "SLPTC" "SOL_SYNCH" "SPLIT" "SPTDUMPFREQ" "STARTPOPULATION" "STATDUMPFREQ" "STEP" "STEPSPERTURN" "STOP" "STRING" "SUPERPOSE" "SYMMETRY" "T0" "TABLE" "TAU" "TELL" "TEMPLATEDIR" "TFALL" "THETA" "THIN" "THRESHOLD" "TIME" "TIMEINTEGRATOR" "TMULT" "TO" "TOL" "TOLERANCE" "TPULSEFWHM" "TRACE" "TRIMCOILTHRESHOLD" "TRISE" "TURNS" "TYPE" "UPPER" "UPPERBOUND" "VARIABLE" "VERIFY" "VERSION" "VKICK" "VMAX" "VMIN" "VOLT" "W" "WAKEF" "WARN" "WARP" "WEIGHT" "WIDTH" "WRITETOFILE" "X" "XEND" "XMA" "XMULT" "XSIZE" "XSTART" "Y" "YEND" "YMA" "YMULT" "YSIZE" "YSTART" "Z" "Z0" "ZEND" "ZINIT" "ZSTART" "ZSTOP") t) "\\>")
+;(concat "\\<" (regexp-opt '("A" "ADD" "AMPLITUDE_MODEL" "ANGLE" "APERTURE" "APVETO" "AT" "AUTOPHASE" "B" "BBOXINCR" "BCFFTZ" "BCFFTT" "BCFFTX" "BCFFTY" "BCURRENT" "BEAM_PHIINIT" "BEAM_PRINIT" "BEAM_RINIT" "BFREQ" "BIRTH_CONTROL" "BMAX" "BOUNDPDESTROYFQ" "BSCALE" "BY" "CALLS" "CATHTEMP" "CENTRE" "CHARGE" "CLASS" "CLEAR" "CMD" "COEFDENOM" "COEFDENOMPHI" "COEFNUM" "COEFNUMPHI" "COLUMN" "CONDUCT" "CONSTRAINTS" "CONST_LENGTH" "CONV_HVOL_PROG" "CORRX" "CORRY" "CORRZ" "CSRDUMP" "CROSSOVER" "CUTOFFLONG" "CUTOFFPX" "CUTOFFPY" "CUTOFFPZ" "CUTOFFR" "CUTOFFX" "CUTOFFY" "CYHARMON" "CZERO" "DESIGNENERGY" "DK1" "DK1S" "DK2" "DK2S" "DKN" "DKNR" "DKS" "DKSR" "DLAG" "DPHI" "DPSI" "DS" "DT" "DTHETA" "DUMP" "DUMP_DAT" "DUMP_FREQ" "DUMP_OFFSPRING" "DVARS" "DVOLT" "DX" "DY" "DZ" "E1" "E2" "EBDUMP" "ECHO" "EKIN" "ELASER" "ELEMEDGE" "ELEMENT" "EMISSIONMODEL" "EMISSIONSTEPS" "EMITTED" "ENABLEHDF5" "ENABLERUTHERFORD" "ENERGY" "ENDSEQUENCE" "END_NORMAL_X" "END_NORMAL_Y" "END_POSITION_X" "END_POSITION_Y" "EPSILON" "ESCALE" "ET" "EVERYSTEP" "EX" "EXPECTED_HYPERVOL" "EXPR" "EY" "FE" "FGEOM" "FIELDMAPDIR" "FIELDMAPDIR" "FILE" "FINT" "FMAPFN" "FNAME" "FORM" "FREQ" "FREQUENCY_MODEL" "FROM" "FSTYPE" "FTOSCAMPLITUDE" "FTOSCPERIODS" "FULL" "GAMMA" "GAP" "GAPWIDTH" "GENE_MUTATION_PROBABILITY" "GEOMETRY" "GREENSF" "H1" "H2" "HAPERT" "HARMON" "HARMONIC_NUMBER" "HGAP" "HKICK" "HYPERVOLREFERENCE" "IDEALIZED" "INITIAL_OPTIMIZATION" "IMAGENAME" "INFO" "INITIALPOPULATION" "INPUT" "INPUTMOUNITS" "INTENSITYCUT" "INTERPL" "IS_CLOSED" "ITSOLVER" "K0" "K0S" "K1" "K1S" "K2" "K2S" "K3" "K3S" "KEYWORD" "KICK" "KN" "KS" "L" "LAG" "LASERPROFFN" "LATTICE_PHIINIT" "LATTICE_RINIT" "LATTICE_THETAINIT" "LENGTH" "LEVEL" "LOGBENDTRAJECTORY" "LOWER" "LOWERBOUND" "MASS" "MATERIAL" "MAXGENERATIONS" "MAXITERS" "MAXR" "MAXSTEPS" "MAXZ" "METHOD" "MINR" "MINZ" "MODE" "MREX" "MREY" "MSCALX" "MSCALY" "MT" "MUTATION_PROBABILITY" "MX" "MY" "NBIN" "NFREQ" "NLEFT" "NO" "NPART" "NPOINTS" "NRIGHT" "NUMCELLS" "NUM_COWORKERS" "NUM_IND_GEN" "NUM_MASTERS" "OBJECTIVES" "OFFSETPX" "OFFSETPY" "OFFSETPZ" "OFFSETT" "OFFSETX" "OFFSETY" "OFFSETZ" "ONE_PILOT_CONVERGE" "OPCHARGE" "OPMASS" "OPYIELD" "ORDER" "ORIENTATION" "ORIGIN" "OUTDIR" "OUTFN" "OUTPUT" "P1" "P2" "P3" "P4" "PARFFTT" "PARFFTX" "PARFFTY" "PARTICLE" "PARTICLEMATTERINTERACTION" "PATTERN" "PC" "PDIS" "PHI" "PHI0" "PHIINIT" "PHIMAX" "PHIMIN" "PLANE" "POLYORDER" "PRECMODE" "PRINIT" "PSDUMPEACHTURN" "PSDUMPFRAME" "PSDUMPFREQ" "PSI" "PTC" "PYMULT" "PZINIT" "PZMULT" "R51" "R52" "R61" "R62" "RADIUS" "RANDOM" "RANGE" "RASTER" "RECOMBINATION_PROBABILITY" "REFER" "REFPOS" "REPARTFREQ" "RESET" "RFFREQ" "RFMAPFN" "RFPHI" "RINIT" "RMAX" "RMIN" "ROTATION" "ROW" "S" "SAMPLINGS" "SCALABLE" "SEED" "SELECTED" "SEQUENCE" "SIGMA" "SIGMAPX" "SIGMAPY" "SIGMAPZ" "SIGMAR" "SIGMAT" "SIGMAX" "SIGMAY" "SIGMAZ" "SIGX" "SIGY" "SIMBIN_CROSSOVER_NU" "SIMTMPDIR" "SLPTC" "SOL_SYNCH" "SPLIT" "SPTDUMPFREQ" "STARTPOPULATION" "STATDUMPFREQ" "STEP" "STEPSPERTURN" "STOP" "STRING" "SUPERPOSE" "SYMMETRY" "T0" "TABLE" "TAU" "TELL" "TEMPLATEDIR" "TFALL" "THETA" "THIN" "THRESHOLD" "TIME" "TIMEINTEGRATOR" "TMULT" "TO" "TOL" "TOLERANCE" "TPULSEFWHM" "TRACE" "TRACKBACK" "TRIMCOILTHRESHOLD" "TRISE" "TURNS" "TYPE" "UPPER" "UPPERBOUND" "VARIABLE" "VERIFY" "VERSION" "VKICK" "VMAX" "VMIN" "VOLT" "W" "WAKEF" "WARN" "WARP" "WEIGHT" "WIDTH" "WRITETOFILE" "X" "XEND" "XMA" "XMULT" "XSIZE" "XSTART" "Y" "YEND" "YMA" "YMULT" "YSIZE" "YSTART" "Z" "Z0" "ZEND" "ZINIT" "ZSTART" "ZSTOP") t) "\\>")
 
 (defconst opal-font-lock-keywords-parameters
   (list
- '("\\<\\(A\\(?:DD\\|MPLITUDE_MODEL\\|NGLE\\|P\\(?:ERTURE\\|VETO\\)\\|T\\|UTOPHASE\\)\\|B\\(?:BOXINCR\\|C\\(?:FFT[TXYZ]\\|URRENT\\)\\|EAM_\\(?:\\(?:P\\(?:HI\\|R\\)\\|R\\)INIT\\)\\|FREQ\\|IRTH_CONTROL\\|MAX\\|OUNDPDESTROYFQ\\|SCALE\\|Y\\)\\|C\\(?:A\\(?:LLS\\|THTEMP\\)\\|ENTRE\\|HARGE\\|L\\(?:ASS\\|EAR\\)\\|MD\\|O\\(?:EF\\(?:DENOM\\(?:PHI\\)?\\|NUM\\(?:PHI\\)?\\)\\|LUMN\\|N\\(?:DUCT\\|ST\\(?:RAINTS\\|_LENGTH\\)\\|V_HVOL_PROG\\)\\|RR[XYZ]\\)\\|ROSSOVER\\|SRDUMP\\|UTOFF\\(?:LONG\\|P[XYZ]\\|[RXY]\\)\\|YHARMON\\|ZERO\\)\\|D\\(?:ESIGNENERGY\\|K\\(?:1S\\|2S\\|[NS]R\\|[12NS]\\)\\|LAG\\|P\\(?:[HS]I\\)\\|THETA\\|UMP\\(?:_\\(?:DAT\\|FREQ\\|OFFSPRING\\)\\)?\\|V\\(?:ARS\\|OLT\\)\\|[STXYZ]\\)\\|E\\(?:BDUMP\\|CHO\\|KIN\\|L\\(?:ASER\\|EME\\(?:DGE\\|NT\\)\\)\\|MI\\(?:SSION\\(?:MODEL\\|STEPS\\)\\|TTED\\)\\|N\\(?:ABLE\\(?:HDF5\\|RUTHERFORD\\)\\|D\\(?:SEQUENCE\\|_\\(?:NORMAL_[XY]\\|POSITION_[XY]\\)\\)\\|ERGY\\)\\|PSILON\\|SCALE\\|VERYSTEP\\|XP\\(?:ECTED_HYPERVOL\\|R\\)\\|[12TXY]\\)\\|F\\(?:E\\|GEOM\\|I\\(?:ELDMAPDIR\\|LE\\|NT\\)\\|MAPFN\\|NAME\\|ORM\\|R\\(?:EQ\\(?:UENCY_MODEL\\)?\\|OM\\)\\|STYPE\\|TOSC\\(?:AMPLITUDE\\|PERIODS\\)\\|ULL\\)\\|G\\(?:A\\(?:MMA\\|P\\(?:WIDTH\\)?\\)\\|E\\(?:\\(?:NE_MUTATION_PROBABILIT\\|OMETR\\)Y\\)\\|REENSF\\)\\|H\\(?:A\\(?:PERT\\|RMON\\(?:IC_NUMBER\\)?\\)\\|GAP\\|KICK\\|YPERVOLREFERENCE\\|[12]\\)\\|I\\(?:DEALIZED\\|MAGENAME\\|N\\(?:FO\\|ITIAL\\(?:\\(?:POPUL\\|_OPTIMIZ\\)ATION\\)\\|PUT\\(?:MOUNITS\\)?\\|TE\\(?:NSITYCUT\\|RPL\\)\\)\\|S_CLOSED\\|TSOLVER\\)\\|K\\(?:0S\\|1S\\|2S\\|3S\\|EYWORD\\|ICK\\|[0-3NS]\\)\\|L\\(?:A\\(?:G\\|SERPROFFN\\|TTICE_\\(?:\\(?:PHI\\|R\\|THETA\\)INIT\\)\\)\\|E\\(?:NGTH\\|VEL\\)\\|O\\(?:GBENDTRAJECTORY\\|WER\\(?:BOUND\\)?\\)\\)\\|M\\(?:A\\(?:SS\\|TERIAL\\|X\\(?:GENERATIONS\\|ITERS\\|STEPS\\|[RZ]\\)\\)\\|ETHOD\\|IN[RZ]\\|ODE\\|RE[XY]\\|SCAL[XY]\\|UTATION_PROBABILITY\\|[TXY]\\)\\|N\\(?:BIN\\|FREQ\\|LEFT\\|O\\|P\\(?:ART\\|OINTS\\)\\|RIGHT\\|UM\\(?:CELLS\\|_\\(?:COWORKERS\\|IND_GEN\\|MASTERS\\)\\)\\)\\|O\\(?:BJECTIVES\\|FFSET\\(?:P[XYZ]\\|[TXYZ]\\)\\|NE_PILOT_CONVERGE\\|P\\(?:CHARGE\\|MASS\\|YIELD\\)\\|R\\(?:DER\\|I\\(?:\\(?:ENTATIO\\|GI\\)N\\)\\)\\|UT\\(?:DIR\\|FN\\|PUT\\)\\)\\|P\\(?:A\\(?:R\\(?:FFT[TXY]\\|TICLE\\(?:MATTERINTERACTION\\)?\\)\\|TTERN\\)\\|DIS\\|HI\\(?:0\\|INIT\\|M\\(?:AX\\|IN\\)\\)?\\|LANE\\|OLYORDER\\|R\\(?:ECMODE\\|INIT\\)\\|S\\(?:DUMP\\(?:EACHTURN\\|FR\\(?:AME\\|EQ\\)\\)\\|I\\)\\|TC\\|\\(?:YMUL\\|Z\\(?:INI\\|MUL\\)\\)T\\|[1-4C]\\)\\|R\\(?:5[12]\\|6[12]\\|A\\(?:DIUS\\|N\\(?:DOM\\|GE\\)\\|STER\\)\\|E\\(?:COMBINATION_PROBABILITY\\|F\\(?:ER\\|POS\\)\\|PARTFREQ\\|SET\\)\\|F\\(?:FREQ\\|MAPFN\\|PHI\\)\\|INIT\\|M\\(?:AX\\|IN\\)\\|O\\(?:TATION\\|W\\)\\)\\|S\\(?:AMPLINGS\\|CALABLE\\|E\\(?:ED\\|LECTED\\|QUENCE\\)\\|I\\(?:G\\(?:MA\\(?:P[XYZ]\\|[RTXYZ]\\)?\\|[XY]\\)\\|M\\(?:BIN_CROSSOVER_NU\\|TMPDIR\\)\\)\\|LPTC\\|OL_SYNCH\\|P\\(?:LIT\\|TDUMPFREQ\\)\\|T\\(?:A\\(?:RTPOPULATION\\|TDUMPFREQ\\)\\|EP\\(?:SPERTURN\\)?\\|OP\\|RING\\)\\|UPERPOSE\\|YMMETRY\\)\\|T\\(?:A\\(?:BLE\\|U\\)\\|E\\(?:LL\\|MPLATEDIR\\)\\|FALL\\|H\\(?:ETA\\|IN\\|RESHOLD\\)\\|IME\\(?:INTEGRATOR\\)?\\|MULT\\|OL\\(?:ERANCE\\)?\\|PULSEFWHM\\|R\\(?:ACE\\|I\\(?:MCOILTHRESHOLD\\|SE\\)\\)\\|URNS\\|YPE\\|[0O]\\)\\|UPPER\\(?:BOUND\\)?\\|V\\(?:ARIABLE\\|ER\\(?:IFY\\|SION\\)\\|KICK\\|M\\(?:AX\\|IN\\)\\|OLT\\)\\|W\\(?:A\\(?:KEF\\|R[NP]\\)\\|EIGHT\\|IDTH\\|RITETOFILE\\)\\|X\\(?:END\\|M\\(?:A\\|ULT\\)\\|S\\(?:IZE\\|TART\\)\\)\\|Y\\(?:END\\|M\\(?:A\\|ULT\\)\\|S\\(?:IZE\\|TART\\)\\)\\|Z\\(?:0\\|END\\|INIT\\|ST\\(?:ART\\|OP\\)\\)\\|[ABLSW-Z]\\)\\>"
+ '("\\<\\(A\\(?:DD\\|MPLITUDE_MODEL\\|NGLE\\|P\\(?:ERTURE\\|VETO\\)\\|T\\|UTOPHASE\\)\\|B\\(?:BOXINCR\\|C\\(?:FFT[TXYZ]\\|URRENT\\)\\|EAM_\\(?:\\(?:P\\(?:HI\\|R\\)\\|R\\)INIT\\)\\|FREQ\\|IRTH_CONTROL\\|MAX\\|OUNDPDESTROYFQ\\|SCALE\\|Y\\)\\|C\\(?:A\\(?:LLS\\|THTEMP\\)\\|ENTRE\\|HARGE\\|L\\(?:ASS\\|EAR\\)\\|MD\\|O\\(?:EF\\(?:DENOM\\(?:PHI\\)?\\|NUM\\(?:PHI\\)?\\)\\|LUMN\\|N\\(?:DUCT\\|ST\\(?:RAINTS\\|_LENGTH\\)\\|V_HVOL_PROG\\)\\|RR[XYZ]\\)\\|ROSSOVER\\|SRDUMP\\|UTOFF\\(?:LONG\\|P[XYZ]\\|[RXY]\\)\\|YHARMON\\|ZERO\\)\\|D\\(?:ESIGNENERGY\\|K\\(?:1S\\|2S\\|[NS]R\\|[12NS]\\)\\|LAG\\|P\\(?:[HS]I\\)\\|THETA\\|UMP\\(?:_\\(?:DAT\\|FREQ\\|OFFSPRING\\)\\)?\\|V\\(?:ARS\\|OLT\\)\\|[STXYZ]\\)\\|E\\(?:BDUMP\\|CHO\\|KIN\\|L\\(?:ASER\\|EME\\(?:DGE\\|NT\\)\\)\\|MI\\(?:SSION\\(?:MODEL\\|STEPS\\)\\|TTED\\)\\|N\\(?:ABLE\\(?:HDF5\\|RUTHERFORD\\)\\|D\\(?:SEQUENCE\\|_\\(?:NORMAL_[XY]\\|POSITION_[XY]\\)\\)\\|ERGY\\)\\|PSILON\\|SCALE\\|VERYSTEP\\|XP\\(?:ECTED_HYPERVOL\\|R\\)\\|[12TXY]\\)\\|F\\(?:E\\|GEOM\\|I\\(?:ELDMAPDIR\\|LE\\|NT\\)\\|MAPFN\\|NAME\\|ORM\\|R\\(?:EQ\\(?:UENCY_MODEL\\)?\\|OM\\)\\|STYPE\\|TOSC\\(?:AMPLITUDE\\|PERIODS\\)\\|ULL\\)\\|G\\(?:A\\(?:MMA\\|P\\(?:WIDTH\\)?\\)\\|E\\(?:\\(?:NE_MUTATION_PROBABILIT\\|OMETR\\)Y\\)\\|REENSF\\)\\|H\\(?:A\\(?:PERT\\|RMON\\(?:IC_NUMBER\\)?\\)\\|GAP\\|KICK\\|YPERVOLREFERENCE\\|[12]\\)\\|I\\(?:DEALIZED\\|MAGENAME\\|N\\(?:FO\\|ITIAL\\(?:\\(?:POPUL\\|_OPTIMIZ\\)ATION\\)\\|PUT\\(?:MOUNITS\\)?\\|TE\\(?:NSITYCUT\\|RPL\\)\\)\\|S_CLOSED\\|TSOLVER\\)\\|K\\(?:0S\\|1S\\|2S\\|3S\\|EYWORD\\|ICK\\|[0-3NS]\\)\\|L\\(?:A\\(?:G\\|SERPROFFN\\|TTICE_\\(?:\\(?:PHI\\|R\\|THETA\\)INIT\\)\\)\\|E\\(?:NGTH\\|VEL\\)\\|O\\(?:GBENDTRAJECTORY\\|WER\\(?:BOUND\\)?\\)\\)\\|M\\(?:A\\(?:SS\\|TERIAL\\|X\\(?:GENERATIONS\\|ITERS\\|STEPS\\|[RZ]\\)\\)\\|ETHOD\\|IN[RZ]\\|ODE\\|RE[XY]\\|SCAL[XY]\\|UTATION_PROBABILITY\\|[TXY]\\)\\|N\\(?:BIN\\|FREQ\\|LEFT\\|O\\|P\\(?:ART\\|OINTS\\)\\|RIGHT\\|UM\\(?:CELLS\\|_\\(?:COWORKERS\\|IND_GEN\\|MASTERS\\)\\)\\)\\|O\\(?:BJECTIVES\\|FFSET\\(?:P[XYZ]\\|[TXYZ]\\)\\|NE_PILOT_CONVERGE\\|P\\(?:CHARGE\\|MASS\\|YIELD\\)\\|R\\(?:DER\\|I\\(?:\\(?:ENTATIO\\|GI\\)N\\)\\)\\|UT\\(?:DIR\\|FN\\|PUT\\)\\)\\|P\\(?:A\\(?:R\\(?:FFT[TXY]\\|TICLE\\(?:MATTERINTERACTION\\)?\\)\\|TTERN\\)\\|DIS\\|HI\\(?:0\\|INIT\\|M\\(?:AX\\|IN\\)\\)?\\|LANE\\|OLYORDER\\|R\\(?:ECMODE\\|INIT\\)\\|S\\(?:DUMP\\(?:EACHTURN\\|FR\\(?:AME\\|EQ\\)\\)\\|I\\)\\|TC\\|\\(?:YMUL\\|Z\\(?:INI\\|MUL\\)\\)T\\|[1-4C]\\)\\|R\\(?:5[12]\\|6[12]\\|A\\(?:DIUS\\|N\\(?:DOM\\|GE\\)\\|STER\\)\\|E\\(?:COMBINATION_PROBABILITY\\|F\\(?:ER\\|POS\\)\\|PARTFREQ\\|SET\\)\\|F\\(?:FREQ\\|MAPFN\\|PHI\\)\\|INIT\\|M\\(?:AX\\|IN\\)\\|O\\(?:TATION\\|W\\)\\)\\|S\\(?:AMPLINGS\\|CALABLE\\|E\\(?:ED\\|LECTED\\|QUENCE\\)\\|I\\(?:G\\(?:MA\\(?:P[XYZ]\\|[RTXYZ]\\)?\\|[XY]\\)\\|M\\(?:BIN_CROSSOVER_NU\\|TMPDIR\\)\\)\\|LPTC\\|OL_SYNCH\\|P\\(?:LIT\\|TDUMPFREQ\\)\\|T\\(?:A\\(?:RTPOPULATION\\|TDUMPFREQ\\)\\|EP\\(?:SPERTURN\\)?\\|OP\\|RING\\)\\|UPERPOSE\\|YMMETRY\\)\\|T\\(?:A\\(?:BLE\\|U\\)\\|E\\(?:LL\\|MPLATEDIR\\)\\|FALL\\|H\\(?:ETA\\|IN\\|RESHOLD\\)\\|IME\\(?:INTEGRATOR\\)?\\|MULT\\|OL\\(?:ERANCE\\)?\\|PULSEFWHM\\|R\\(?:AC\\(?:E\\|KBACK\\)\\|I\\(?:MCOILTHRESHOLD\\|SE\\)\\)\\|URNS\\|YPE\\|[0O]\\)\\|UPPER\\(?:BOUND\\)?\\|V\\(?:ARIABLE\\|ER\\(?:IFY\\|SION\\)\\|KICK\\|M\\(?:AX\\|IN\\)\\|OLT\\)\\|W\\(?:A\\(?:KEF\\|R[NP]\\)\\|EIGHT\\|IDTH\\|RITETOFILE\\)\\|X\\(?:END\\|M\\(?:A\\|ULT\\)\\|S\\(?:IZE\\|TART\\)\\)\\|Y\\(?:END\\|M\\(?:A\\|ULT\\)\\|S\\(?:IZE\\|TART\\)\\)\\|Z\\(?:0\\|END\\|INIT\\|ST\\(?:ART\\|OP\\)\\)\\|[ABLSW-Z]\\)\\>"
   . font-lock-variable-name-face)
   )
   "Highlighting expressions for OPAL mode (parameters).")
diff --git a/tools/opal2sdds/main.cpp b/tools/opal2sdds/main.cpp
index 0eb589d675d18ac507279ece13892ee527b5f681..ad8e4637c997381dd9c423821ab29f759d106638 100644
--- a/tools/opal2sdds/main.cpp
+++ b/tools/opal2sdds/main.cpp
@@ -37,9 +37,13 @@ enum FORMAT {
 
 typedef h5_file_t file_t;
 
-data_t readStepData(file_t file);
+data_t readStepData(file_t file, bool temporal);
 attributes_t readStepAttributes(file_t file);
-void readH5HutFile(const std::string &fname, size_t step, data_t &data, attributes_t &attr);
+void readH5HutFile(const std::string &fname,
+                   size_t step,
+                   bool temporal,
+                   data_t &data,
+                   attributes_t &attr);
 void convertToElegantUnits(data_t &data);
 void writeSDDSFile(const std::string &fname, const data_t &data, const attributes_t &attr, FORMAT form);
 void printInfo(const std::string &input);
@@ -50,6 +54,7 @@ int main(int argc, char **argv) {
 
     std::string inputFile(""), outputFile("/dev/stdout");
     bool doPrintInfo = false;
+    bool temporal = false;
     int step = -1;
     FORMAT form = ASCII;
 
@@ -75,6 +80,8 @@ int main(int argc, char **argv) {
                 return 0;
             } else if (std::string(argv[i]) == "--info") {
                 doPrintInfo = true;
+            } else if (std::string(argv[i]) == "--temporal") {
+                temporal = true;
             } else {
                 inputFile = std::string(argv[i]);
             }
@@ -94,7 +101,7 @@ int main(int argc, char **argv) {
 
     data_t data;
     attributes_t attr;
-    readH5HutFile(inputFile, step, data, attr);
+    readH5HutFile(inputFile, step, temporal, data, attr);
     convertToElegantUnits(data);
     writeSDDSFile(outputFile, data, attr, form);
 
@@ -106,7 +113,11 @@ void reportOnError(h5_int64_t rc, const char* file, int line) {
         std::cerr << "H5 rc= " << rc << " in " << file << " @ line " << line << std::endl;
 }
 
-void readH5HutFile(const std::string &fname, size_t step, data_t &data, attributes_t &attr) {
+void readH5HutFile(const std::string &fname,
+                   size_t step,
+                   bool temporal,
+                   data_t &data,
+                   attributes_t &attr) {
     h5_prop_t props = H5CreateFileProp ();
     MPI_Comm comm = MPI_COMM_WORLD;
     H5SetPropFileMPIOCollective (props, &comm);
@@ -118,12 +129,12 @@ void readH5HutFile(const std::string &fname, size_t step, data_t &data, attribut
 
     REPORTONERROR(H5SetStep(file, readStep));
 
-    data = readStepData(file);
+    data = readStepData(file, temporal);
     attr = readStepAttributes(file);
     REPORTONERROR(H5CloseFile(file));
 }
 
-data_t readStepData(file_t file) {
+data_t readStepData(file_t file, bool temporal) {
     data_t data;
 
     h5_ssize_t numParticles = H5PartGetNumParticles(file);
@@ -144,11 +155,19 @@ data_t readStepData(file_t file) {
     }
     data.insert(std::make_pair(std::string("y"), dData));
 
-    READDATA(Float64, file, "z", f64buffer);
-    for(long int n = 0; n < numParticles; ++ n) {
-        dData[n] = f64buffer[n];
+    if (temporal) {
+        READDATA(Float64, file, "time", f64buffer);
+        for(long int n = 0; n < numParticles; ++ n) {
+            dData[n] = f64buffer[n];
+        }
+        data.insert(std::make_pair(std::string("time"), dData));
+    } else {
+        READDATA(Float64, file, "z", f64buffer);
+        for(long int n = 0; n < numParticles; ++ n) {
+            dData[n] = f64buffer[n];
+        }
+        data.insert(std::make_pair(std::string("z"), dData));
     }
-    data.insert(std::make_pair(std::string("z"), dData));
 
     READDATA(Float64, file, "px", f64buffer);
     for(long int n = 0; n < numParticles; ++ n) {
@@ -201,22 +220,32 @@ attributes_t readStepAttributes(file_t file) {
 }
 
 void convertToElegantUnits(data_t &data) {
-    const size_t size = data["x"].size();
+    size_t size;
+    bool temporal = false;
+
+    try {
+        size = data["z"].size();
+    } catch (...) {
+        temporal = true;
+        size = data["x"].size();
+    }
 
     for (size_t i = 0; i < size; ++ i) {
         data["px"][i] /= data["pz"][i];
         data["py"][i] /= data["pz"][i];
+        if (temporal) continue;
+
         data["z"][i] /= -299792458.0;
     }
 }
 
 void writeSDDSFile(const std::string &fname, const data_t &data, const attributes_t &attr, FORMAT form) {
-    const std::map<std::string, std::string> nameConversion {{"x", "x"},
-                                                              {"y", "y"},
-                                                              {"t", "z"},
-                                                              {"xp", "px"},
-                                                              {"yp", "py"},
-                                                              {"p", "pz"}};
+    std::map<std::string, std::string> nameConversion {{"x", "x"},
+                                                       {"y", "y"},
+                                                       {"t", "z"},
+                                                       {"xp", "px"},
+                                                       {"yp", "py"},
+                                                       {"p", "pz"}};
     const std::map<std::string, std::string> nameUnits {{"x", "m"},
                                                         {"y", "m"},
                                                         {"t", "s"},
@@ -237,6 +266,13 @@ void writeSDDSFile(const std::string &fname, const data_t &data, const attribute
     char buffer1[64];
     char buffer2[8];
 
+    for (const auto entry: data) {
+        if (entry.first == "time") {
+            nameConversion["t"] = "time";
+            break;
+        }
+    }
+
     strcpy(buffer0, fname.c_str());
     strcpy(buffer1, "extracted OPAL data");
     if (SDDS_InitializeOutput(&SDDS_dataset, form, 1, buffer1, NULL, buffer0 ) != 1) {
@@ -368,6 +404,7 @@ void printUsage(char **argv) {
               << indent << std::setw(width) << std::left << "--binary"                << "= whether SDDS output should be in \n"
               << indent << std::setw(width + 2) << std::left << " "                   <<   "binary format. Default: ASCII\n"
               << indent << std::setw(width) << std::left << "--info"                  << "= printing path length corresponding to step\n"
+              << indent << std::setw(width) << std::left << "--time-of-arrival"       << "= extract and save the time of arrival instead of the longitudinal position\n"
               << indent << std::setw(width) << std::left << "--help"                  << "= this help\n"
               << std::endl;
-}
+}
\ No newline at end of file
diff --git a/tools/sdds2opal/main.cpp b/tools/sdds2opal/main.cpp
index fe8017c6cae27aa1dc07442083ab211062550429..91d7097dedb0c00a0d80430953a7ffb357714ee0 100644
--- a/tools/sdds2opal/main.cpp
+++ b/tools/sdds2opal/main.cpp
@@ -11,11 +11,12 @@
 #include <cstring>
 #include <unistd.h>
 
-std::vector<std::vector<double> > readSDDSFile(std::string fname);
+std::vector<std::vector<double> > readSDDSFile(std::string fname, bool temporal);
 void printUsage(char **argv);
 
 int main(int argc, char **argv) {
     std::string inputFile(""), outputFile("/dev/stdout");
+    bool temporal = false;
 
     if (argc == 1) {
         printUsage(argv);
@@ -30,6 +31,8 @@ int main(int argc, char **argv) {
                 inputFile = std::string(argv[++ i]);
             } else if (std::string(argv[i]) == "--output" && i + 1 < argc) {
                 outputFile = std::string(argv[++ i]);
+            } else if (std::string(argv[i]) == "--temporal") {
+                temporal = true;
             } else if (std::string(argv[i]) == "--help") {
                 printUsage(argv);
                 return 0;
@@ -47,7 +50,7 @@ int main(int argc, char **argv) {
         }
     }
 
-    auto data = readSDDSFile(inputFile);
+    auto data = readSDDSFile(inputFile, temporal);
     std::ofstream out(outputFile);
     out.precision(8);
     out << data.size() << "\n";
@@ -61,7 +64,7 @@ int main(int argc, char **argv) {
     return 0;
 }
 
-std::vector<std::vector<double> > readSDDSFile(std::string fname) {
+std::vector<std::vector<double> > readSDDSFile(std::string fname, bool temporal) {
 
     SDDS_DATASET SDDS_dataset;
     void *columnData;
@@ -122,6 +125,8 @@ std::vector<std::vector<double> > readSDDSFile(std::string fname) {
     for (std::vector<double> &row: fileData) {
         row[1] *= row[5];
         row[3] *= row[5];
+        if (temporal) continue;
+
         row[4] *= -299792458.0;
     }
 
@@ -147,6 +152,7 @@ void printUsage(char **argv) {
               << "Options\n\n"
               << indent << std::setw(width) << std::left << "--input <path to input>" << "= path to input file\n"
               << indent << std::setw(width) << std::left << "--output <file name>"    << "= name of output. If omitted, directed\n"
+              << indent << std::setw(width) << std::left << "--time-of-arrival"       << "= extract and save the time of arrival instead of the longitudinal position\n"
               << indent << std::setw(width + 2)          << " "                       <<   "to stdout\n"
               << indent << std::setw(width) << std::left << "--help"                  << "= this help\n"
               << std::endl;