diff --git a/core/src/main/java/org/orekit/rugged/api/Rugged.java b/core/src/main/java/org/orekit/rugged/api/Rugged.java
index 7db0011bae46759720f978f417fc32a94c597cb5..b4779345b6a29afbcbfd8c8fb53043affe0d2aff 100644
--- a/core/src/main/java/org/orekit/rugged/api/Rugged.java
+++ b/core/src/main/java/org/orekit/rugged/api/Rugged.java
@@ -66,6 +66,9 @@ public class Rugged {
     /** Maximum number of evaluations. */
     private static final int MAX_EVAL = 50;
 
+    /** Time step for frames transforms interpolations. */
+    private static final double FRAMES_TRANSFORMS_INTERPOLATION_STEP = 0.01;
+
     /** Reference ellipsoid. */
     private final ExtendedEllipsoid ellipsoid;
 
@@ -161,7 +164,8 @@ public class Rugged {
         this.scToBody = new SpacecraftToObservedBody(inertialFrame, ellipsoid.getBodyFrame(),
                                                      minDate, maxDate,
                                                      positionsVelocities, pvInterpolationOrder,
-                                                     quaternions, aInterpolationOrder);
+                                                     quaternions, aInterpolationOrder,
+                                                     FRAMES_TRANSFORMS_INTERPOLATION_STEP);
 
         // intersection algorithm
         this.algorithm = selectAlgorithm(algorithmID, updater, maxCachedTiles);
@@ -273,7 +277,8 @@ public class Rugged {
             this.scToBody = new SpacecraftToObservedBody(inertialFrame, ellipsoid.getBodyFrame(),
                                                          minDate, maxDate,
                                                          positionsVelocities, interpolationOrder,
-                                                         quaternions, interpolationOrder);
+                                                         quaternions, interpolationOrder,
+                                                         FRAMES_TRANSFORMS_INTERPOLATION_STEP);
 
             // intersection algorithm
             this.algorithm = selectAlgorithm(algorithmID, updater, maxCachedTiles);
diff --git a/core/src/main/java/org/orekit/rugged/api/SensorMeanPlaneCrossing.java b/core/src/main/java/org/orekit/rugged/api/SensorMeanPlaneCrossing.java
index 7af3c9a4dd43975873a8a7460c62c17b24c4ca20..7899b8fa8d0f53464d515bdb043d1a5ce6ef703c 100644
--- a/core/src/main/java/org/orekit/rugged/api/SensorMeanPlaneCrossing.java
+++ b/core/src/main/java/org/orekit/rugged/api/SensorMeanPlaneCrossing.java
@@ -16,9 +16,6 @@
  */
 package org.orekit.rugged.api;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
 import org.apache.commons.math3.geometry.euclidean.threed.FieldVector3D;
 import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
@@ -38,11 +35,17 @@ import org.orekit.utils.PVCoordinates;
  */
 class SensorMeanPlaneCrossing {
 
-    /** Transforms sample from observed body frame to inertial frame. */
-    private final List<Transform> bodyToInertial;
+    /** Converter between spacecraft and body. */
+    private final SpacecraftToObservedBody scToBody;
+
+    /** Middle line. */
+    private final double midLine;
 
-    /** Transforms sample from spacecraft frame to inertial frame. */
-    private final List<Transform> scToInertial;
+    /** Body to inertial transform for middle line. */
+    private final Transform midBodyToInert;
+
+    /** Spacecraft to inertial transform for middle line. */
+    private final Transform midScToInert;
 
     /** Minimum line number in the search interval. */
     private final int minLine;
@@ -92,14 +95,12 @@ class SensorMeanPlaneCrossing {
             this.aberrationOfLightCorrection = aberrationOfLightCorrection;
             this.maxEval                     = maxEval;
             this.accuracy                    = accuracy;
+            this.scToBody                    = scToBody;
 
-            bodyToInertial = new ArrayList<Transform>(maxLine - minLine + 1);
-            scToInertial   = new ArrayList<Transform>(maxLine - minLine + 1);
-            for (int line = minLine; line <= maxLine; ++line) {
-                final AbsoluteDate date = sensor.getDate(line);
-                bodyToInertial.add(scToBody.getInertialToBody(date).getInverse());
-                scToInertial.add(scToBody.getScToInertial(date));
-            }
+            this.midLine               = 0.5 * (minLine + maxLine);
+            final AbsoluteDate midDate = sensor.getDate(midLine);
+            this.midBodyToInert        = scToBody.getBodyToInertial(midDate);
+            this.midScToInert          = scToBody.getScToInertial(midDate);
 
         } catch (OrekitException oe) {
             throw new RuggedException(oe, oe.getSpecifier(), oe.getParts());
@@ -174,10 +175,9 @@ class SensorMeanPlaneCrossing {
             // as we know the solution is improved in the second stage of inverse localization.
             // We expect two or three evaluations only. Each new evaluation shows up quickly in
             // the performances as it involves frames conversions
-            final int midIndex    = bodyToInertial.size() / 2;
-            double  crossingLine  = minLine + midIndex;
-            Transform bodyToInert = bodyToInertial.get(midIndex);
-            Transform scToInert   = scToInertial.get(midIndex);
+            double  crossingLine  = midLine;
+            Transform bodyToInert = midBodyToInert;
+            Transform scToInert   = midScToInert;
             boolean atMin         = false;
             boolean atMax         = false;
             for (int i = 0; i < maxEval; ++i) {
@@ -215,10 +215,9 @@ class SensorMeanPlaneCrossing {
                     atMax = false;
                 }
 
-                final int inf = FastMath.max(0, FastMath.min(scToInertial.size() - 2, (int) FastMath.floor(crossingLine)));
                 final AbsoluteDate date = sensor.getDate(crossingLine);
-                bodyToInert = Transform.interpolate(date, false, false, bodyToInertial.subList(inf, inf + 2));
-                scToInert   = Transform.interpolate(date, false, false, scToInertial.subList(inf, inf + 2));
+                bodyToInert = scToBody.getBodyToInertial(date);
+                scToInert   = scToBody.getScToInertial(date);
             }
 
             return null;
diff --git a/core/src/main/java/org/orekit/rugged/utils/SpacecraftToObservedBody.java b/core/src/main/java/org/orekit/rugged/utils/SpacecraftToObservedBody.java
index 0234a1049a855ea01bb5fcdedaa3a8611d49bdcd..70fb4c3894bc67cfb71704aa1b8c3eb95fa8b319 100644
--- a/core/src/main/java/org/orekit/rugged/utils/SpacecraftToObservedBody.java
+++ b/core/src/main/java/org/orekit/rugged/utils/SpacecraftToObservedBody.java
@@ -16,8 +16,10 @@
  */
 package org.orekit.rugged.utils;
 
+import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.commons.math3.util.FastMath;
 import org.orekit.errors.OrekitException;
 import org.orekit.frames.Frame;
 import org.orekit.frames.Transform;
@@ -26,6 +28,7 @@ import org.orekit.rugged.api.RuggedMessages;
 import org.orekit.time.AbsoluteDate;
 import org.orekit.utils.ImmutableTimeStampedCache;
 import org.orekit.utils.TimeStampedAngularCoordinates;
+import org.orekit.utils.TimeStampedCache;
 import org.orekit.utils.TimeStampedPVCoordinates;
 
 /** Provider for observation transforms.
@@ -33,17 +36,17 @@ import org.orekit.utils.TimeStampedPVCoordinates;
  */
 public class SpacecraftToObservedBody {
 
-    /** Inertial frame. */
-    private final Frame inertialFrame;
+    /** Step to use for inertial frame to body frame transforms cache computations. */
+    private final double tStep;
 
-    /** Observed body frame. */
-    private final Frame bodyFrame;
+    /** Transforms sample from observed body frame to inertial frame. */
+    private final List<Transform> bodyToInertial;
 
-    /** Satellite orbits. */
-    private final ImmutableTimeStampedCache<TimeStampedPVCoordinates> positionsVelocities;
+    /** Transforms sample from inertial frame to observed body frame. */
+    private final List<Transform> inertialToBody;
 
-    /** Satellite quaternions. */
-    private final ImmutableTimeStampedCache<TimeStampedAngularCoordinates> quaternions;
+    /** Transforms sample from spacecraft frame to inertial frame. */
+    private final List<Transform> scToInertial;
 
     /** Simple constructor.
      * @param inertialFrame inertial frame
@@ -54,43 +57,74 @@ public class SpacecraftToObservedBody {
      * @param pvInterpolationOrder order to use for position/velocity interpolation
      * @param quaternions satellite quaternions
      * @param aInterpolationOrder order to use for attitude interpolation
+     * @param tStep step to use for inertial frame to body frame transforms cache computations
      * @exception RuggedException if position or attitude samples do not fully cover the
      * [{@code minDate}, {@code maxDate}] search time span
      */
     public SpacecraftToObservedBody(final Frame inertialFrame, final Frame bodyFrame,
                                     final AbsoluteDate minDate, final AbsoluteDate maxDate,
                                     final List<TimeStampedPVCoordinates> positionsVelocities, final int pvInterpolationOrder,
-                                    final List<TimeStampedAngularCoordinates> quaternions, final int aInterpolationOrder)
+                                    final List<TimeStampedAngularCoordinates> quaternions, final int aInterpolationOrder,
+                                    final double tStep)
         throws RuggedException {
-
-        // safety checks
-        final AbsoluteDate minPVDate = positionsVelocities.get(0).getDate();
-        final AbsoluteDate maxPVDate = positionsVelocities.get(positionsVelocities.size() - 1).getDate();
-        if (minDate.compareTo(minPVDate) < 0) {
-            throw new RuggedException(RuggedMessages.OUT_OF_TIME_RANGE, minDate, minPVDate, maxPVDate);
-        }
-        if (maxDate.compareTo(maxPVDate) > 0) {
-            throw new RuggedException(RuggedMessages.OUT_OF_TIME_RANGE, maxDate, minPVDate, maxPVDate);
-        }
-
-        final AbsoluteDate minQDate  = quaternions.get(0).getDate();
-        final AbsoluteDate maxQDate  = quaternions.get(quaternions.size() - 1).getDate();
-        if (minDate.compareTo(minQDate) < 0) {
-            throw new RuggedException(RuggedMessages.OUT_OF_TIME_RANGE, minDate, minQDate, maxQDate);
-        }
-        if (maxDate.compareTo(maxQDate) > 0) {
-            throw new RuggedException(RuggedMessages.OUT_OF_TIME_RANGE, maxDate, minQDate, maxQDate);
+        try {
+            // safety checks
+            final AbsoluteDate minPVDate = positionsVelocities.get(0).getDate();
+            final AbsoluteDate maxPVDate = positionsVelocities.get(positionsVelocities.size() - 1).getDate();
+            if (minDate.compareTo(minPVDate) < 0) {
+                throw new RuggedException(RuggedMessages.OUT_OF_TIME_RANGE, minDate, minPVDate, maxPVDate);
+            }
+            if (maxDate.compareTo(maxPVDate) > 0) {
+                throw new RuggedException(RuggedMessages.OUT_OF_TIME_RANGE, maxDate, minPVDate, maxPVDate);
+            }
+
+            final AbsoluteDate minQDate  = quaternions.get(0).getDate();
+            final AbsoluteDate maxQDate  = quaternions.get(quaternions.size() - 1).getDate();
+            if (minDate.compareTo(minQDate) < 0) {
+                throw new RuggedException(RuggedMessages.OUT_OF_TIME_RANGE, minDate, minQDate, maxQDate);
+            }
+            if (maxDate.compareTo(maxQDate) > 0) {
+                throw new RuggedException(RuggedMessages.OUT_OF_TIME_RANGE, maxDate, minQDate, maxQDate);
+            }
+
+            // set up the cache for position-velocities
+            final TimeStampedCache<TimeStampedPVCoordinates> pvCache =
+                    new ImmutableTimeStampedCache<TimeStampedPVCoordinates>(pvInterpolationOrder, positionsVelocities);
+
+            // set up the cache for attitudes
+            final TimeStampedCache<TimeStampedAngularCoordinates> aCache =
+                    new ImmutableTimeStampedCache<TimeStampedAngularCoordinates>(aInterpolationOrder, quaternions);
+
+            final int n = (int) FastMath.ceil(maxDate.durationFrom(minDate) / tStep);
+            this.tStep          = tStep;
+            this.bodyToInertial = new ArrayList<Transform>(n);
+            this.inertialToBody = new ArrayList<Transform>(n);
+            this.scToInertial   = new ArrayList<Transform>(n);
+            for (AbsoluteDate date = minDate; bodyToInertial.size() < n; date = date.shiftedBy(tStep)) {
+
+                // interpolate position-velocity
+                final TimeStampedPVCoordinates pv =
+                        TimeStampedPVCoordinates.interpolate(date, true, pvCache.getNeighbors(date));
+
+                // interpolate attitude
+                final TimeStampedAngularCoordinates quaternion =
+                        TimeStampedAngularCoordinates.interpolate(date, false, aCache.getNeighbors(date));
+
+                // store transform from spacecraft frame to inertial frame
+                scToInertial.add(new Transform(date,
+                                               new Transform(date, quaternion.revert()),
+                                               new Transform(date, pv)));
+
+                // store transform from body frame to inertial frame
+                final Transform b2i = bodyFrame.getTransformTo(inertialFrame, date);
+                bodyToInertial.add(b2i);
+                inertialToBody.add(b2i.getInverse());
+
+            }
+
+        } catch (OrekitException oe) {
+            throw new RuggedException(oe, oe.getSpecifier(), oe.getParts());
         }
-
-        this.inertialFrame = inertialFrame;
-        this.bodyFrame     = bodyFrame;
-
-        // set up the cache for position-velocities
-        this.positionsVelocities = new ImmutableTimeStampedCache<TimeStampedPVCoordinates>(pvInterpolationOrder, positionsVelocities);
-
-        // set up the cache for attitudes
-        this.quaternions = new ImmutableTimeStampedCache<TimeStampedAngularCoordinates>(aInterpolationOrder, quaternions);
-
     }
 
     /** Get transform from spacecraft to inertial frame.
@@ -100,33 +134,40 @@ public class SpacecraftToObservedBody {
      */
     public Transform getScToInertial(final AbsoluteDate date)
         throws OrekitException {
-
-        // interpolate position-velocity
-        final List<TimeStampedPVCoordinates> sample = positionsVelocities.getNeighbors(date);
-        final TimeStampedPVCoordinates pv = TimeStampedPVCoordinates.interpolate(date, true, sample);
-
-        // interpolate attitude
-        final List<TimeStampedAngularCoordinates> sampleAC = quaternions.getNeighbors(date);
-        final TimeStampedAngularCoordinates quaternion = TimeStampedAngularCoordinates.interpolate(date, false, sampleAC);
-
-        // compute transform from spacecraft frame to inertial frame
-        return new Transform(date,
-                             new Transform(date, quaternion.revert()),
-                             new Transform(date, pv));
-
+        return intepolate(date, scToInertial);
     }
 
-    /** Get transform from inertial frame to body frame.
+    /** Get transform from inertial frame to observed body frame.
      * @param date date of the transform
-     * @return transform from inertial frame to body frame
+     * @return transform from inertial frame to observed body frame
      * @exception OrekitException if frames cannot be computed at date
      */
     public Transform getInertialToBody(final AbsoluteDate date)
         throws OrekitException {
+        return intepolate(date, inertialToBody);
+    }
 
-        // compute transform from inertial frame to body frame
-        return inertialFrame.getTransformTo(bodyFrame, date);
+    /** Get transform from observed body frame to inertial frame.
+     * @param date date of the transform
+     * @return transform from observed body frame to inertial frame
+     * @exception OrekitException if frames cannot be computed at date
+     */
+    public Transform getBodyToInertial(final AbsoluteDate date)
+        throws OrekitException {
+        return intepolate(date, bodyToInertial);
+    }
 
+    /** Interpolate transform.
+     * @param date date of the transform
+     * @param list transforms list to interpolate from
+     * @return interpolated
+     * @exception OrekitException if frames cannot be computed at date
+     */
+    private Transform intepolate(final AbsoluteDate date, final List<Transform> list)
+        throws OrekitException {
+        final double s = date.durationFrom(list.get(0).getDate()) / tStep;
+        final int inf  = FastMath.max(0, FastMath.min(list.size() - 2, (int) FastMath.floor(s)));
+        return Transform.interpolate(date, false, false, list.subList(inf, inf + 2));
     }
 
 }
diff --git a/core/src/test/java/org/orekit/rugged/api/RuggedTest.java b/core/src/test/java/org/orekit/rugged/api/RuggedTest.java
index e5b186f37ab147304be5d4d3fa5a97361fd33715..95e434274d29b7d6ee17ee5aaf9912ac45a0d041 100644
--- a/core/src/test/java/org/orekit/rugged/api/RuggedTest.java
+++ b/core/src/test/java/org/orekit/rugged/api/RuggedTest.java
@@ -375,12 +375,14 @@ public class RuggedTest {
         int firstLine = 0;
         int lastLine  = dimension;
         LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
+        AbsoluteDate minDate = lineSensor.getDate(firstLine);
+        AbsoluteDate maxDate = lineSensor.getDate(lastLine);
 
         Rugged rugged = new Rugged(null, -1, AlgorithmId.IGNORE_DEM_USE_ELLIPSOID,
                                    EllipsoidId.WGS84, InertialFrameId.EME2000, BodyRotatingFrameId.ITRF,
-                                   lineDatation.getDate(firstLine), lineDatation.getDate(lastLine),
-                                   orbitToPV(orbit, earth, lineDatation, firstLine, lastLine, 0.25), 8,
-                                   orbitToQ(orbit, earth, lineDatation, firstLine, lastLine, 0.25), 2);
+                                   minDate, maxDate,
+                                   orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25), 8,
+                                   orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25), 2);
 
         rugged.addLineSensor(lineSensor);
 
@@ -426,12 +428,14 @@ public class RuggedTest {
         int firstLine = 0;
         int lastLine  = dimension;
         LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
+        AbsoluteDate minDate = lineSensor.getDate(firstLine);
+        AbsoluteDate maxDate = lineSensor.getDate(lastLine);
 
         Rugged rugged = new Rugged(null, -1, AlgorithmId.IGNORE_DEM_USE_ELLIPSOID,
                                    EllipsoidId.WGS84, InertialFrameId.EME2000, BodyRotatingFrameId.ITRF,
-                                   lineDatation.getDate(firstLine), lineDatation.getDate(lastLine),
-                                   orbitToPV(orbit, earth, lineDatation, firstLine, lastLine, 0.25), 8,
-                                   orbitToQ(orbit, earth, lineDatation, firstLine, lastLine, 0.25), 2);
+                                   minDate, maxDate,
+                                   orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25), 8,
+                                   orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25), 2);
 
         rugged.addLineSensor(lineSensor);
 
@@ -478,6 +482,8 @@ public class RuggedTest {
         int firstLine = 0;
         int lastLine  = dimension;
         LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
+        AbsoluteDate minDate = lineSensor.getDate(firstLine);
+        AbsoluteDate maxDate = lineSensor.getDate(lastLine);
 
         TileUpdater updater =
                 new RandomLandscapeUpdater(0.0, 9000.0, 0.5, 0xf0a401650191f9f6l,
@@ -485,17 +491,17 @@ public class RuggedTest {
 
         Rugged ruggedFull = new Rugged(updater, 8, AlgorithmId.DUVENHAGE,
                                        EllipsoidId.WGS84, InertialFrameId.EME2000, BodyRotatingFrameId.ITRF,
-                                       lineDatation.getDate(firstLine), lineDatation.getDate(lastLine),
-                                       orbitToPV(orbit, earth, lineDatation, firstLine, lastLine, 0.25), 8,
-                                       orbitToQ(orbit, earth, lineDatation, firstLine, lastLine, 0.25), 2);
+                                       minDate, maxDate,
+                                       orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25), 8,
+                                       orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25), 2);
         ruggedFull.addLineSensor(lineSensor);
         GeodeticPoint[] gpWithFlatBodyCorrection = ruggedFull.directLocalization("line", 100);
 
         Rugged ruggedFlat = new Rugged(updater, 8, AlgorithmId.DUVENHAGE_FLAT_BODY,
                                        EllipsoidId.WGS84, InertialFrameId.EME2000, BodyRotatingFrameId.ITRF,
-                                       lineDatation.getDate(firstLine), lineDatation.getDate(lastLine),
-                                       orbitToPV(orbit, earth, lineDatation, firstLine, lastLine, 0.25), 8,
-                                       orbitToQ(orbit, earth, lineDatation, firstLine, lastLine, 0.25), 2);
+                                       minDate, maxDate,
+                                       orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25), 8,
+                                       orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25), 2);
         ruggedFlat.addLineSensor(lineSensor);
         GeodeticPoint[] gpWithoutFlatBodyCorrection = ruggedFlat.directLocalization("line", 100);
 
@@ -512,14 +518,15 @@ public class RuggedTest {
     }
 
     // the following test is disabled by default
-    // it is only used to check timings, and also creates a large (30M) temporary file
+    // it is only used to check timings, and also creates a large (38M) temporary file
     @Test
     @Ignore
     public void testInverseLocalizationTiming()
         throws RuggedException, OrekitException, URISyntaxException {
 
-        long t0 = System.currentTimeMillis();
-        int dimension = 2000;
+        long t0       = System.currentTimeMillis();
+        int dimension = 1000;
+        int nbSensors = 5;
 
         String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
         DataProvidersManager.getInstance().addProvider(new DirectoryCrawler(new File(path)));
@@ -528,19 +535,26 @@ public class RuggedTest {
 
         AbsoluteDate crossing = new AbsoluteDate("2012-01-01T12:30:00.000", TimeScalesFactory.getUTC());
 
-        // one line sensor
-        // position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
-        // los: swath in the (YZ) plane, looking at 50° roll, 2.6" per pixel
-        Vector3D position = new Vector3D(1.5, 0, -0.2);
-        List<Vector3D> los = createLOS(new Rotation(Vector3D.PLUS_I, FastMath.toRadians(50.0)).applyTo(Vector3D.PLUS_K),
-                                       Vector3D.PLUS_I,
-                                       FastMath.toRadians(dimension * 2.6 / 3600.0), dimension);
+        List<LineSensor> sensors = new ArrayList<LineSensor>();
+        for (int i = 0; i < nbSensors; ++i) {
+            // one line sensor
+            // position: 1.5m in front (+X) and 20 cm above (-Z) of the S/C center of mass
+            // los: swath in the (YZ) plane, looking roughly at 50° roll (sensor-dependent), 2.6" per pixel
+            Vector3D position = new Vector3D(1.5, 0, -0.2);
+            List<Vector3D> los = createLOS(new Rotation(Vector3D.PLUS_I,
+                                                        FastMath.toRadians(50.0 - 0.001 * i)).applyTo(Vector3D.PLUS_K),
+                                           Vector3D.PLUS_I,
+                                           FastMath.toRadians(dimension * 2.6 / 3600.0), dimension);
+
+            // linear datation model: at reference time we get roughly middle line, and the rate is one line every 1.5ms
+            LineDatation lineDatation = new LinearLineDatation(crossing, i + dimension / 2, 1.0 / 1.5e-3);
+            sensors.add(new LineSensor("line-" + i, lineDatation, position, los));
+        }
 
-        // linear datation model: at reference time we get line 100, and the rate is one line every 1.5ms
-        LineDatation lineDatation = new LinearLineDatation(crossing, dimension / 2, 1.0 / 1.5e-3);
         int firstLine = 0;
         int lastLine  = dimension;
-        LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
+        AbsoluteDate minDate = sensors.get(0).getDate(firstLine).shiftedBy(-1.0);
+        AbsoluteDate maxDate = sensors.get(sensors.size() - 1).getDate(lastLine).shiftedBy(+1.0);
 
         TileUpdater updater =
                 new RandomLandscapeUpdater(0.0, 9000.0, 0.5, 0xf0a401650191f9f6l,
@@ -548,40 +562,44 @@ public class RuggedTest {
 
         Rugged rugged = new Rugged(updater, 8, AlgorithmId.DUVENHAGE,
                                    EllipsoidId.WGS84, InertialFrameId.EME2000, BodyRotatingFrameId.ITRF,
-                                   lineDatation.getDate(firstLine), lineDatation.getDate(lastLine),
-                                   orbitToPV(orbit, earth, lineDatation, firstLine, lastLine, 0.25), 8,
-                                   orbitToQ(orbit, earth, lineDatation, firstLine, lastLine, 0.25), 2);
+                                   minDate, maxDate,
+                                   orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25), 8,
+                                   orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25), 2);
         rugged.setLightTimeCorrection(true);
         rugged.setAberrationOfLightCorrection(true);
-        rugged.addLineSensor(lineSensor);
+        for (LineSensor lineSensor : sensors) {
+            rugged.addLineSensor(lineSensor);
+        }
 
         double lat0  = FastMath.toRadians(-22.9);
         double lon0  = FastMath.toRadians(142.4);
         double delta = FastMath.toRadians(0.5);
 
         try {
-            int              size   = dimension * dimension * 2 * Integer.SIZE / 8;
+            int              size   = nbSensors * dimension * dimension * 2 * Integer.SIZE / 8;
             RandomAccessFile out    = new RandomAccessFile(tempFolder.newFile(), "rw");
             MappedByteBuffer buffer = out.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, size);
 
             long t1 = System.currentTimeMillis();
             int goodPixels = 0;
             int badPixels  = 0;
-            for (int i = 0; i < dimension; ++i) {
-                double latitude  = lat0 + (i * delta) / dimension;
-                for (int j = 0; j < dimension; ++j) {
-                    double longitude = lon0 + (j * delta) / dimension;
-                    SensorPixel sp = rugged.inverseLocalization("line", latitude, longitude, 0, dimension);
-                    if (sp == null) {
-                        ++badPixels;
-                        buffer.putInt(-1);
-                        buffer.putInt(-1);
-                    } else {
-                        ++goodPixels;
-                        final int lineCode  = (int) FastMath.rint(FastMath.scalb(sp.getLineNumber(),  16));
-                        final int pixelCode = (int) FastMath.rint(FastMath.scalb(sp.getPixelNumber(), 16));
-                        buffer.putInt(lineCode);
-                        buffer.putInt(pixelCode);
+            for (final LineSensor lineSensor : sensors) {
+                for (int i = 0; i < dimension; ++i) {
+                    double latitude  = lat0 + (i * delta) / dimension;
+                    for (int j = 0; j < dimension; ++j) {
+                        double longitude = lon0 + (j * delta) / dimension;
+                        SensorPixel sp = rugged.inverseLocalization(lineSensor.getName(), latitude, longitude, 0, dimension);
+                        if (sp == null) {
+                            ++badPixels;
+                            buffer.putInt(-1);
+                            buffer.putInt(-1);
+                        } else {
+                            ++goodPixels;
+                            final int lineCode  = (int) FastMath.rint(FastMath.scalb(sp.getLineNumber(),  16));
+                            final int pixelCode = (int) FastMath.rint(FastMath.scalb(sp.getPixelNumber(), 16));
+                            buffer.putInt(lineCode);
+                            buffer.putInt(pixelCode);
+                        }
                     }
                 }
             }
@@ -590,10 +608,10 @@ public class RuggedTest {
             out.close();
             int sizeM = size / (1024 * 1024);
             System.out.format(Locale.US,
-                              "%n%n%5dx%5d:%n" +
+                              "%n%n%5dx%5d, %d sensors:%n" +
                               "  Orekit initialization and DEM creation   : %5.1fs%n" +
                               "  inverse localization and %3dM grid writing: %5.1fs (%.1f px/s, %.1f%% covered)%n",
-                              dimension, dimension,
+                              dimension, dimension, nbSensors,
                               1.0e-3 *(t1 - t0), sizeM, 1.0e-3 *(t2 - t1),
                               (badPixels + goodPixels) / (1.0e-3 * (t2 - t1)),
                               (100.0 * goodPixels) / (goodPixels + badPixels));
@@ -691,20 +709,20 @@ public class RuggedTest {
 
         GeodeticPoint point1 = new GeodeticPoint(0.7053784581520293, -1.7354535645320581, 691.856741468848);
         SensorPixel sensorPixel1 = rugged.inverseLocalization(lineSensor.getName(), point1, 1, 131328);
-        Assert.assertEquals(   2.0147269, sensorPixel1.getLineNumber(), 1.0e-6);
-        Assert.assertEquals(   2.0927144, sensorPixel1.getPixelNumber(), 1.0e-6);
+        Assert.assertEquals(   2.01472, sensorPixel1.getLineNumber(), 1.0e-5);
+        Assert.assertEquals(   2.09271, sensorPixel1.getPixelNumber(), 1.0e-5);
         GeodeticPoint point2 = new GeodeticPoint(0.704463899881073, -1.7303503789334154, 648.9200602492216);
         SensorPixel sensorPixel2 = rugged.inverseLocalization(lineSensor.getName(), point2, 1, 131328);
-        Assert.assertEquals(   2.0218406, sensorPixel2.getLineNumber(), 1.0e-6);
-        Assert.assertEquals(  29.5300850, sensorPixel2.getPixelNumber(), 1.0e-6);
+        Assert.assertEquals(   2.02184, sensorPixel2.getLineNumber(), 1.0e-5);
+        Assert.assertEquals(  29.53008, sensorPixel2.getPixelNumber(), 1.0e-5);
         GeodeticPoint point3 = new GeodeticPoint(0.7009593480939814, -1.7314283804521957, 588.3075485689468);
         SensorPixel sensorPixel3 = rugged.inverseLocalization(lineSensor.getName(), point3, 1, 131328);
-        Assert.assertEquals(2305.2617453, sensorPixel3.getLineNumber(),  1.0e-6);
-        Assert.assertEquals(  28.1838132, sensorPixel3.getPixelNumber(), 1.0e-6);
+        Assert.assertEquals(2305.26174, sensorPixel3.getLineNumber(),  1.0e-5);
+        Assert.assertEquals(  28.18381, sensorPixel3.getPixelNumber(), 1.0e-5);
         GeodeticPoint point4 = new GeodeticPoint(0.7018731669637096, -1.73651769725183, 611.2759403696498);
         SensorPixel sensorPixel4 = rugged.inverseLocalization(lineSensor.getName(), point4, 1, 131328);
-        Assert.assertEquals(2305.2550610, sensorPixel4.getLineNumber(), 1.0e-6);
-        Assert.assertEquals(   1.5444731, sensorPixel4.getPixelNumber(), 1.0e-6);
+        Assert.assertEquals(2305.25506, sensorPixel4.getLineNumber(), 1.0e-5);
+        Assert.assertEquals(   1.54447, sensorPixel4.getPixelNumber(), 1.0e-5);
 
     }
 
@@ -794,6 +812,8 @@ public class RuggedTest {
         int firstLine = 0;
         int lastLine  = dimension;
         LineSensor lineSensor = new LineSensor("line", lineDatation, position, los);
+        AbsoluteDate minDate = lineSensor.getDate(firstLine).shiftedBy(-1.0);
+        AbsoluteDate maxDate = lineSensor.getDate(lastLine).shiftedBy(+1.0);
 
         TileUpdater updater =
                 new RandomLandscapeUpdater(0.0, 9000.0, 0.5, 0xf0a401650191f9f6l,
@@ -801,9 +821,9 @@ public class RuggedTest {
 
         Rugged rugged = new Rugged(updater, 8, AlgorithmId.DUVENHAGE,
                                    EllipsoidId.WGS84, InertialFrameId.EME2000, BodyRotatingFrameId.ITRF,
-                                   lineDatation.getDate(firstLine), lineDatation.getDate(lastLine),
-                                   orbitToPV(orbit, earth, lineDatation, firstLine, lastLine, 0.25), 8,
-                                   orbitToQ(orbit, earth, lineDatation, firstLine, lastLine, 0.25), 2);
+                                   minDate, maxDate,
+                                   orbitToPV(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25), 8,
+                                   orbitToQ(orbit, earth, minDate.shiftedBy(-1.0), maxDate.shiftedBy(+1.0), 0.25), 2);
         rugged.setLightTimeCorrection(lightTimeCorrection);
         rugged.setAberrationOfLightCorrection(aberrationOfLightCorrection);
         rugged.addLineSensor(lineSensor);
@@ -914,12 +934,12 @@ public class RuggedTest {
     }
 
     private List<TimeStampedPVCoordinates> orbitToPV(Orbit orbit, BodyShape earth,
-                                                     LineDatation lineDatation, int firstLine, int lastLine,
+                                                     AbsoluteDate minDate, AbsoluteDate maxDate,
                                                      double step)
         throws PropagationException {
         Propagator propagator = new KeplerianPropagator(orbit);
         propagator.setAttitudeProvider(new YawCompensation(new NadirPointing(earth)));
-        propagator.propagate(lineDatation.getDate(firstLine).shiftedBy(-1.0));
+        propagator.propagate(minDate);
         final List<TimeStampedPVCoordinates> list = new ArrayList<TimeStampedPVCoordinates>();
         propagator.setMasterMode(step, new OrekitFixedStepHandler() {
             public void init(SpacecraftState s0, AbsoluteDate t) {
@@ -930,17 +950,17 @@ public class RuggedTest {
                                                       currentState.getPVCoordinates().getVelocity()));
             }
         });
-        propagator.propagate(lineDatation.getDate(lastLine).shiftedBy(+1.0));
+        propagator.propagate(maxDate);
         return list;
     }
 
     private List<TimeStampedAngularCoordinates> orbitToQ(Orbit orbit, BodyShape earth,
-                                                         LineDatation lineDatation, int firstLine, int lastLine,
+                                                         AbsoluteDate minDate, AbsoluteDate maxDate,
                                                          double step)
         throws PropagationException {
         Propagator propagator = new KeplerianPropagator(orbit);
         propagator.setAttitudeProvider(new YawCompensation(new NadirPointing(earth)));
-        propagator.propagate(lineDatation.getDate(firstLine).shiftedBy(-1.0));
+        propagator.propagate(minDate);
         final List<TimeStampedAngularCoordinates> list = new ArrayList<TimeStampedAngularCoordinates>();
         propagator.setMasterMode(step, new OrekitFixedStepHandler() {
             public void init(SpacecraftState s0, AbsoluteDate t) {
@@ -951,7 +971,7 @@ public class RuggedTest {
                                                            Vector3D.ZERO));
             }
         });
-        propagator.propagate(lineDatation.getDate(lastLine).shiftedBy(+1.0));
+        propagator.propagate(maxDate);
         return list;
     }