diff --git a/src/Algorithms/CavityAutophaser.cpp b/src/Algorithms/CavityAutophaser.cpp
index 9fa6b29ecacc0e848295ab56a1fcd8a27e7dc419..11a9d4e9c1e38361cb8ef22f0bbd2c721d8dc592 100644
--- a/src/Algorithms/CavityAutophaser.cpp
+++ b/src/Algorithms/CavityAutophaser.cpp
@@ -19,8 +19,7 @@ CavityAutophaser::CavityAutophaser(const PartData &ref,
     itsCavity_m(cavity)
 {
     double zbegin = 0.0, zend = 0.0;
-    PartBunchBase<double, 3> *fakeBunch = NULL;
-    cavity->initialise(fakeBunch, zbegin, zend);
+    cavity->getDimensions(zbegin, zend);
     initialR_m = Vector_t(0, 0, zbegin);
 }
 
diff --git a/src/Algorithms/OrbitThreader.cpp b/src/Algorithms/OrbitThreader.cpp
index f24dfc1004356e3af2e5cad51f441a9a1445aae8..c340a5374bc007e39c4696c3e2c4df8531019eba 100644
--- a/src/Algorithms/OrbitThreader.cpp
+++ b/src/Algorithms/OrbitThreader.cpp
@@ -31,7 +31,6 @@ OrbitThreader::OrbitThreader(const PartData &ref,
                              double maxDiffZBunch,
                              double t,
                              double dt,
-                             size_t maxIntegSteps,
                              double zstop,
                              OpalBeamline &bl) :
     r_m(r),
@@ -39,7 +38,6 @@ OrbitThreader::OrbitThreader(const PartData &ref,
     pathLength_m(s),
     time_m(t),
     dt_m(dt),
-    maxIntegSteps_m(maxIntegSteps),
     zstop_m(zstop),
     itsOpalBeamline_m(bl),
     errorFlag_m(0),
@@ -82,17 +80,16 @@ OrbitThreader::OrbitThreader(const PartData &ref,
     }
 
     distTrackBack_m = std::min(pathLength_m, std::max(0.0, maxDiffZBunch));
+    computeBoundingBox();
 }
 
 void OrbitThreader::execute() {
     double initialPathLength = pathLength_m;
-    computeMaximalImplicitDrift2();
-    double maxDistance = computeMaximalImplicitDrift();
 
     auto allElements = itsOpalBeamline_m.getElementByType(ElementBase::ANY);
     std::set<std::string> visitedElements;
 
-    trackBack(2 * maxDistance);
+    trackBack();
 
     Vector_t nextR = r_m / (Physics::c * dt_m);
     integrator_m.push(nextR, p_m, dt_m);
@@ -110,7 +107,8 @@ void OrbitThreader::execute() {
         double initialS = pathLength_m;
         Vector_t initialR = r_m;
         Vector_t initialP = p_m;
-        integrate(elementSet, maxIntegSteps_m, 2 * maxDistance);
+        double maxDistance = computeDriftLengthToBoundingBox(elementSet, r_m, p_m);
+        integrate(elementSet, maxDistance);
 
         registerElement(elementSet, initialS,  initialR, initialP);
 
@@ -147,7 +145,7 @@ void OrbitThreader::execute() {
     processElementRegister();
 }
 
-void OrbitThreader::integrate(const IndexMap::value_t &activeSet, size_t /*maxSteps*/, double maxDrift) {
+void OrbitThreader::integrate(const IndexMap::value_t &activeSet, double maxDrift) {
     static size_t step = 0;
     CoordinateSystemTrafo labToBeamline = itsOpalBeamline_m.getCSTrafoLab2Local();
     const double oldPathLength = pathLength_m;
@@ -282,7 +280,7 @@ double OrbitThreader::getMaxDesignEnergy(const IndexMap::value_t &elementSet) co
     return designEnergy;
 }
 
-void OrbitThreader::trackBack(double maxDrift) {
+void OrbitThreader::trackBack() {
     dt_m *= -1;
     double initialPathLength = pathLength_m;
 
@@ -290,11 +288,12 @@ void OrbitThreader::trackBack(double maxDrift) {
     integrator_m.push(nextR, p_m, dt_m);
     nextR *= Physics::c * dt_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);
+        double maxDrift = computeDriftLengthToBoundingBox(elementSet, r_m, -p_m);
+        maxDrift = std::min(maxDrift, distTrackBack_m);
+        integrate(elementSet, maxDrift);
 
         nextR = r_m / (Physics::c * dt_m);
         integrator_m.push(nextR, p_m, dt_m);
@@ -389,7 +388,7 @@ void OrbitThreader::setDesignEnergy(FieldList &allElements, const std::set<std::
     }
 }
 
-void OrbitThreader::computeMaximalImplicitDrift2() {
+void OrbitThreader::computeBoundingBox() {
     FieldList allElements = itsOpalBeamline_m.getElementByType(ElementBase::ANY);
     FieldList::iterator it = allElements.begin();
     const FieldList::iterator end = allElements.end();
@@ -403,76 +402,40 @@ void OrbitThreader::computeMaximalImplicitDrift2() {
         ElementBase::BoundingBox other = it->getBoundingBoxInLabCoords();
         globalBoundingBox_m.getCombinedBoundingBox(other);
     }
-}
-
-double OrbitThreader::computeMaximalImplicitDrift() {
-    FieldList allElements = itsOpalBeamline_m.getElementByType(ElementBase::ANY);
-    double maxDrift = 0.0;
 
-    MarkerRep start("#S");
-    CoordinateSystemTrafo toEdge(r_m, getQuaternion(p_m, Vector_t(0, 0, 1)));
-    start.setElementLength(0.0);
-    start.setCSTrafoGlobal2Local(toEdge);
-    std::shared_ptr<Component> startPtr(static_cast<Marker*>(start.clone()));
-    allElements.push_front(ClassicField(startPtr, 0.0, 0.0));
-
-    FieldList::iterator it = allElements.begin();
-    const FieldList::iterator end = allElements.end();
-    for (; it != end; ++ it) {
-        auto element1 = it->getElement();
-        const auto &toEdge = element1->getCSTrafoGlobal2Local();
-        auto toEnd = element1->getEdgeToEnd() * toEdge;
-        Vector_t end1 = toEnd.transformFrom(Vector_t(0, 0, 0));
-        Vector_t directionEnd = toEnd.rotateFrom(Vector_t(0, 0, 1));
-        if (element1->getType() == ElementBase::RBEND ||
-            element1->getType() == ElementBase::SBEND ||
-            element1->getType() == ElementBase::RBEND3D ) {
-            auto toBegin = element1->getEdgeToBegin() * toEdge;
-
-            BendBase *bend = static_cast<BendBase*>(element1.get());
-            double angleRelativeToFace = bend->getEntranceAngle() - bend->getBendAngle();
-            directionEnd = toBegin.rotateFrom(Vector_t(sin(angleRelativeToFace), 0, cos(angleRelativeToFace)));
-        }
-
-        double minDistanceLocal = std::numeric_limits<double>::max();
-        FieldList::iterator it2 = allElements.begin();
-        for (; it2 != end; ++ it2) {
-            if (it == it2) continue;
-
-            auto element2 = it2->getElement();
-            const auto &toEdge = element2->getCSTrafoGlobal2Local();
-            auto toBegin = element2->getEdgeToBegin() * toEdge;
-            auto toEnd = element2->getEdgeToEnd() * toEdge;
-            Vector_t begin2 = toBegin.transformFrom(Vector_t(0, 0, 0));
-            Vector_t end2 = toEnd.transformFrom(Vector_t(0, 0, 0));
-            Vector_t directionBegin = toBegin.rotateFrom(Vector_t(0, 0, 1));
-            if (element2->getType() == ElementBase::RBEND ||
-                element2->getType() == ElementBase::SBEND ||
-                element2->getType() == ElementBase::RBEND3D ) {
-                BendBase *bend = static_cast<BendBase*>(element2.get());
-                double E1 = bend->getEntranceAngle();
-                directionBegin = toBegin.rotateFrom(Vector_t(sin(E1), 0, cos(E1)));
-            }
-
-
-            double distance = euclidean_norm(begin2 - end1);
-            double directionProjection = dot(directionEnd, directionBegin);
-            bool overlapping = dot(begin2 - end1, directionBegin) < 0.0? true: false;
-
-            if (!overlapping &&
-                directionProjection > 0.999 &&
-                minDistanceLocal > distance) {
-                minDistanceLocal = distance;
-            }
+    Vector_t const& X = globalBoundingBox_m.lowerLeftCorner;
+    Vector_t const& Y = globalBoundingBox_m.upperRightCorner;
+    Vector_t delta = Y - X;
+    Vector_t dX(delta(0), 0, 0), dY(0, delta(1), 0), dZ(0, 0, delta(2));
+    std::vector<Vector_t> corners{X, X + dX, X + dX + dY, X + dY, Y, Y - dX, Y - dX - dY, Y - dY};
+    std::vector<std::vector<unsigned int>> paths{{0, 1, 2, 3}, {4, 5, 6, 7}, {0, 1, 7, 6}, {1, 2, 4, 7}, {2, 3, 5, 4}, {3, 0, 6, 5}};
+
+    std::ofstream out("boundingBox.gpl");
+    std::ofstream traj("trajectories.gpl");
+    for (std::vector<unsigned int> const& path: paths) {
+        for (unsigned int i = 0; i < 5; ++ i) {
+            Vector_t const& point = corners[path[i % 4]];
+            out << point(0) << "\t" << point(1) << "\t" << point(2) << std::endl;
         }
+        out << std::endl;
+    }
+}
 
-        if (maxDrift < minDistanceLocal &&
-            minDistanceLocal != std::numeric_limits<double>::max()) {
-            maxDrift = minDistanceLocal;
+double OrbitThreader::computeDriftLengthToBoundingBox(const std::set<std::shared_ptr<Component>> & elements,
+                                                      const Vector_t & position,
+                                                      const Vector_t & direction) const {
+    if (elements.empty() ||
+        (elements.size() == 1 && (*elements.begin())->getType() == ElementBase::ElementType::DRIFT)) {
+        boost::optional<Vector_t> intersectionPoint = globalBoundingBox_m.getPointOfIntersection(position, direction);
+        double maxDrift = intersectionPoint ? euclidean_norm(intersectionPoint.get() - position): 10.0;
+        if (intersectionPoint) {
+            std::ofstream traj("trajectories.gpl", std::ios::app);
+            traj << position(0) << "\t" << position(1) << "\t" << position(2) << std::endl;
+            traj << intersectionPoint.get()(0) << "\t" << intersectionPoint.get()(1) << "\t" << intersectionPoint.get()(2) << std::endl;
+            traj << std::endl;
         }
+        return maxDrift;
     }
 
-    maxDrift = std::min(maxIntegSteps_m * std::abs(dt_m) * Physics::c, maxDrift);
-
-    return maxDrift;
+    return std::numeric_limits<double>::max();
 }
\ No newline at end of file
diff --git a/src/Algorithms/OrbitThreader.h b/src/Algorithms/OrbitThreader.h
index 09fccd121538487fba4fb8d125be33c91c0e0eb5..c56b4a7a4b9feca0ffeaf993d68b9caab65c1842 100644
--- a/src/Algorithms/OrbitThreader.h
+++ b/src/Algorithms/OrbitThreader.h
@@ -20,7 +20,6 @@ public:
                   double maxDiffZBunch,
                   double t,
                   double dT,
-                  size_t maxIntegSteps,
                   double zstop,
                   OpalBeamline &bl);
 
@@ -48,8 +47,6 @@ private:
     /// 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;
 
@@ -80,8 +77,8 @@ private:
 
     std::multimap<std::string, elementPosition> elementRegistry_m;
 
-    void trackBack(double maxDrift);
-    void integrate(const IndexMap::value_t &activeSet, size_t maxSteps, double maxDrift = 10.0);
+    void trackBack();
+    void integrate(const IndexMap::value_t &activeSet, double maxDrift = 10.0);
     bool containsCavity(const IndexMap::value_t &activeSet);
     void autophaseCavities(const IndexMap::value_t &activeSet, const std::set<std::string> &visitedElements);
     double getMaxDesignEnergy(const IndexMap::value_t &elementSet) const;
@@ -89,8 +86,11 @@ private:
     void registerElement(const IndexMap::value_t &elementSet, double, const Vector_t &r, const Vector_t &p);
     void processElementRegister();
     void setDesignEnergy(FieldList &allElements, const std::set<std::string> &visitedElements);
-    void computeMaximalImplicitDrift2();
-    double computeMaximalImplicitDrift();
+    void computeBoundingBox();
+    // double computeMaximalImplicitDrift();
+    double computeDriftLengthToBoundingBox(const std::set<std::shared_ptr<Component>> & elements,
+                                           const Vector_t & position,
+                                           const Vector_t & direction) const;
 };
 
 inline
diff --git a/src/Algorithms/ParallelTTracker.cpp b/src/Algorithms/ParallelTTracker.cpp
index f38da15e80bd5e36a201c9a9637a7aeaee16c12c..49f56f3e87fbec86534b53c7719095938fa338d9 100644
--- a/src/Algorithms/ParallelTTracker.cpp
+++ b/src/Algorithms/ParallelTTracker.cpp
@@ -193,7 +193,6 @@ void ParallelTTracker::execute() {
     prepareSections();
 
     double minTimeStep = stepSizes_m.getMinTimeStep();
-    unsigned long long totalNumSteps = stepSizes_m.getNumStepsFinestResolution();
 
     itsOpalBeamline_m.activateElements();
 
@@ -248,7 +247,6 @@ void ParallelTTracker::execute() {
                       -rmin(2),
                       itsBunch_m->getT(),
                       (back_track? -minTimeStep: minTimeStep),
-                      totalNumSteps,
                       stepSizes_m.getFinalZStop() + 2 * rmax(2),
                       itsOpalBeamline_m);
 
@@ -1390,4 +1388,4 @@ void ParallelTTracker::evenlyDistributeParticles() {
 // c-basic-offset: 4
 // indent-tabs-mode: nil
 // require-final-newline: nil
-// End:
+// End:
\ No newline at end of file
diff --git a/src/Classic/AbsBeamline/ElementBase.cpp b/src/Classic/AbsBeamline/ElementBase.cpp
index 540d0731c813156f72a8bd7f68bbdbdc9d53ca28..2e7336b231c0a850b43e56f691ffefad2c36e6f4 100644
--- a/src/Classic/AbsBeamline/ElementBase.cpp
+++ b/src/Classic/AbsBeamline/ElementBase.cpp
@@ -348,37 +348,51 @@ bool ElementBase::BoundingBox::isInside(const Vector_t & position) const {
 
 boost::optional<Vector_t>
 ElementBase::BoundingBox::getPointOfIntersection(const Vector_t & position,
-                                                                         const Vector_t & direction) const {
-    Vector_t relativePosition = position - lowerLeftCorner;
+                                                 const Vector_t & direction) const {
+    Vector_t relativePosition = lowerLeftCorner - position;
     Vector_t diagonal = upperRightCorner - lowerLeftCorner;
+    Vector_t normalizedDirection = direction / euclidean_norm(direction);
+    // *gmsg << "position: " << position << "\n"
+    //       << "normalizedDirection: " << normalizedDirection << "\n"
+    //       << "lowerLeftCorner: " << lowerLeftCorner << "\n"
+    //       << "upperRightCorner: " << upperRightCorner << "\n"
+    //       << "diagonal: " << diagonal << endl;
 
-    for (unsigned int i = 0; i < 2; ++ i) {
+    for (int i = -1; i < 2; i += 2) {
         for (unsigned int d = 0; d < 3; ++ d) {
-            double projectedDirection = direction[d];
+            double projectedDirection = normalizedDirection[d];
+            // *gmsg << "\n" << "projectedDirection: " << projectedDirection << "\n";
             if (std::abs(projectedDirection) < 1e-10) {
                 continue;
             }
 
             double distanceNearestPoint = relativePosition[d];
             double tau = distanceNearestPoint / projectedDirection;
+            // *gmsg << "distanceNearestPoint: " << distanceNearestPoint << "\n"
+            //       << "relativePosition: " << relativePosition << "\n"
+            //       << "tau: " << tau << "\n";
             if (tau < 0) {
                 continue;
             }
-            Vector_t intersectionPoint = relativePosition + tau * direction;
+            Vector_t delta = tau * normalizedDirection;
+            Vector_t relativeIntersectionPoint = i * (relativePosition - delta);
 
-            double sign = 1 - 2 * i;
-            if (sign * intersectionPoint[(d + 1) % 3] < 0.0 ||
-                sign * intersectionPoint[(d + 1) % 3] > diagonal[(d + 1) % 3] ||
-                sign * intersectionPoint[(d + 2) % 3] < 0.0 ||
-                sign * intersectionPoint[(d + 2) % 3] > diagonal[(d + 2) % 3]) {
+            // *gmsg << "delta: " << delta << "\n"
+            //       << "relativeIntersectionPoint: " << relativeIntersectionPoint << endl;
+
+            // *gmsg << sign * intersectionPoint[(d + 1) % 3] << "\t" << sign * relativeIntersectionPoint[(d + 2) % 3] << "\t";
+            if (relativeIntersectionPoint[(d + 1) % 3] < 0.0 ||
+                relativeIntersectionPoint[(d + 1) % 3] > diagonal[(d + 1) % 3] ||
+                relativeIntersectionPoint[(d + 2) % 3] < 0.0 ||
+                relativeIntersectionPoint[(d + 2) % 3] > diagonal[(d + 2) % 3]) {
                 continue;
             }
 
-            return position + tau * direction;
+            return position + tau * normalizedDirection;
         }
         relativePosition = upperRightCorner - position;
     }
-
+    // *gmsg << endl;
     return boost::none;
 }
 
diff --git a/src/Classic/AbsBeamline/RFCavity.cpp b/src/Classic/AbsBeamline/RFCavity.cpp
index b8ebb79459043ae993e9c3b3b05712ad5183e541..5f08002c23f702ca573d735971b26e5c847e2fbe 100644
--- a/src/Classic/AbsBeamline/RFCavity.cpp
+++ b/src/Classic/AbsBeamline/RFCavity.cpp
@@ -740,4 +740,4 @@ void RFCavity::getElementDimensions(double &begin,
 // c-basic-offset: 4
 // indent-tabs-mode: nil
 // require-final-newline: nil
-// End:
+// End:
\ No newline at end of file
diff --git a/src/Classic/Fields/Astra1DDynamic_fast.cpp b/src/Classic/Fields/Astra1DDynamic_fast.cpp
index dcfab8e1e462f9c9353a9187764ee346d75b1281..dc57e81a44bfbbbee56d829cfd5cf808909a8ae8 100644
--- a/src/Classic/Fields/Astra1DDynamic_fast.cpp
+++ b/src/Classic/Fields/Astra1DDynamic_fast.cpp
@@ -1,11 +1,13 @@
 #include "Fields/Astra1DDynamic_fast.h"
 #include "Utilities/GeneralClassicException.h"
 #include "Utilities/Util.h"
+#include "Utilities/OpalException.h"
 #include "Physics/Physics.h"
 
 #include <fstream>
 #include <ios>
 
+extern Inform *gmsg;
 Astra1DDynamic_fast::Astra1DDynamic_fast(std::string aFilename):
     Astra1D_fast(aFilename)
 {
@@ -82,11 +84,16 @@ bool Astra1DDynamic_fast::getFieldstrength(const Vector_t &R, Vector_t &E, Vecto
     // do fourier interpolation in z-direction
     const double RR2 = R(0) * R(0) + R(1) * R(1);
 
-    double ez = gsl_spline_eval(onAxisInterpolants_m[0], R(2) - zbegin_m, onAxisAccel_m[0]);
-    double ezp = gsl_spline_eval(onAxisInterpolants_m[1], R(2) - zbegin_m, onAxisAccel_m[1]);
-    double ezpp = gsl_spline_eval(onAxisInterpolants_m[2], R(2) - zbegin_m, onAxisAccel_m[2]);
-    double ezppp = gsl_spline_eval(onAxisInterpolants_m[3], R(2) - zbegin_m, onAxisAccel_m[3]);
-
+    double ez, ezp, ezpp, ezppp;
+    try {
+        ez = gsl_spline_eval(onAxisInterpolants_m[0], R(2) - zbegin_m, onAxisAccel_m[0]);
+        ezp = gsl_spline_eval(onAxisInterpolants_m[1], R(2) - zbegin_m, onAxisAccel_m[1]);
+        ezpp = gsl_spline_eval(onAxisInterpolants_m[2], R(2) - zbegin_m, onAxisAccel_m[2]);
+        ezppp = gsl_spline_eval(onAxisInterpolants_m[3], R(2) - zbegin_m, onAxisAccel_m[3]);
+    } catch (OpalException const& e) {
+        throw OpalException("Astra1DDynamice_fast::getFieldstrength",
+                            "The requested interpolation point, " + std::to_string(R(2)) + " is out of range");
+    }
     // expand the field off-axis
     const double f  = -(ezpp  + ez *  xlrep_m * xlrep_m) / 16.;
     const double fp = -(ezppp + ezp * xlrep_m * xlrep_m) / 16.;
@@ -115,6 +122,7 @@ void Astra1DDynamic_fast::getFieldDimensions(double &zBegin, double &zEnd) const
     zBegin = zbegin_m;
     zEnd = zend_m;
 }
+
 void Astra1DDynamic_fast::getFieldDimensions(double &/*xIni*/, double &/*xFinal*/, double &/*yIni*/, double &/*yFinal*/, double &/*zIni*/, double &/*zFinal*/) const {}
 
 void Astra1DDynamic_fast::swap()
@@ -205,5 +213,4 @@ int Astra1DDynamic_fast::stripFileHeader(std::ifstream &file) {
     interpretLine<double>(file, tmpDouble);
 
     return accuracy;
-}
-
+}
\ No newline at end of file
diff --git a/src/Classic/Fields/Fieldmap.cpp b/src/Classic/Fields/Fieldmap.cpp
index 3a420bfe468bb20c4c0f9b0bf624737ee55b4e45..b8eb3e6b4e75e6c8a58ca56ef90b2d4e931f2ad4 100644
--- a/src/Classic/Fields/Fieldmap.cpp
+++ b/src/Classic/Fields/Fieldmap.cpp
@@ -513,7 +513,7 @@ void Fieldmap::checkMap(unsigned int accuracy,
     if (std::sqrt(error / ezSquare) > 1e-1 || maxDiff > 1e-1 * ezMax) {
         lowResolutionWarning(std::sqrt(error / ezSquare), maxDiff / ezMax);
 
-        throw GeneralClassicException("Astra2DDynamic_fast::readMap()",
+        throw GeneralClassicException("Fieldmap::checkMap",
                                       "Field map can't be reproduced properly with the given number of fourier components");
     }
     if (std::sqrt(error / ezSquare) > 1e-2 || maxDiff > 1e-2 * ezMax) {