diff --git a/src/main/java/org/orekit/rugged/api/Rugged.java b/src/main/java/org/orekit/rugged/api/Rugged.java
index 0f17428c2802d3a77c895d947b7964c4d0a9d0f1..3d20e823fdc2e33d244355e4aeb58d1ea6c37ea9 100644
--- a/src/main/java/org/orekit/rugged/api/Rugged.java
+++ b/src/main/java/org/orekit/rugged/api/Rugged.java
@@ -384,21 +384,7 @@ public class Rugged {
         throws RuggedException {
 
         final LineSensor sensor = getLineSensor(sensorName);
-        SensorMeanPlaneCrossing planeCrossing = finders.get(sensorName);
-        if (planeCrossing == null ||
-            planeCrossing.getMinLine() != minLine ||
-            planeCrossing.getMaxLine() != maxLine) {
-
-            // create a new finder for the specified sensor and range
-            planeCrossing = new SensorMeanPlaneCrossing(sensor, scToBody, minLine, maxLine,
-                                                        lightTimeCorrection, aberrationOfLightCorrection,
-                                                        MAX_EVAL, COARSE_INVERSE_LOCATION_ACCURACY);
-
-            // store the finder, in order to reuse it
-            // (and save some computation done in its constructor)
-            finders.put(sensorName, planeCrossing);
-
-        }
+        final SensorMeanPlaneCrossing planeCrossing = getPlaneCrossing(sensorName, minLine, maxLine);
 
         // find approximately the sensor line at which ground point crosses sensor mean plane
         final Vector3D   target = ellipsoid.transform(point);
@@ -449,22 +435,14 @@ public class Rugged {
                                        final int minLine, final int maxLine)
         throws RuggedException {
 
-        final LineSensor sensor = getLineSensor(sensorName);
-        SensorMeanPlaneCrossing planeCrossing = finders.get(sensorName);
-        if (planeCrossing == null ||
-            planeCrossing.getMinLine() != minLine ||
-            planeCrossing.getMaxLine() != maxLine) {
-
-            // create a new finder for the specified sensor and range
-            planeCrossing = new SensorMeanPlaneCrossing(sensor, scToBody, minLine, maxLine,
-                                                        lightTimeCorrection, aberrationOfLightCorrection,
-                                                        MAX_EVAL, COARSE_INVERSE_LOCATION_ACCURACY);
+        DumpManager.dumpInverseLocation(sensorName, point, minLine, maxLine,
+                                        lightTimeCorrection, aberrationOfLightCorrection);
 
-            // store the finder, in order to reuse it
-            // (and save some computation done in its constructor)
-            finders.put(sensorName, planeCrossing);
+        final LineSensor sensor = getLineSensor(sensorName);
+        final SensorMeanPlaneCrossing planeCrossing = getPlaneCrossing(sensorName, minLine, maxLine);
 
-        }
+        DumpManager.dumpSensor(sensor);
+        DumpManager.dumpSensorMeanPlane(planeCrossing);
 
         // find approximately the sensor line at which ground point crosses sensor mean plane
         final Vector3D   target = ellipsoid.transform(point);
@@ -511,8 +489,51 @@ public class Rugged {
                                                  Vector3D.dotProduct(fixedDirection, fixedX));
         final double fixedPixel = lowIndex + alpha / pixelWidth;
 
-        return new SensorPixel(fixedLine, fixedPixel);
+        final SensorPixel result = new SensorPixel(fixedLine, fixedPixel);
+        DumpManager.dumpInverseLocationResult(result);
+        return result;
+
+    }
+
+    /** Get the mean plane crossing finder for a sensor.
+     * @param sensorName name of the line  sensor
+     * @param minLine minimum line number
+     * @param maxLine maximum line number
+     * @return mean plane crossing finder
+     * @exception RuggedException if sensor is unknown
+     */
+    private SensorMeanPlaneCrossing getPlaneCrossing(final String sensorName,
+                                                     final int minLine, final int maxLine)
+        throws RuggedException {
 
+        final LineSensor sensor = getLineSensor(sensorName);
+        SensorMeanPlaneCrossing planeCrossing = finders.get(sensorName);
+        if (planeCrossing == null ||
+            planeCrossing.getMinLine() != minLine ||
+            planeCrossing.getMaxLine() != maxLine) {
+
+            // create a new finder for the specified sensor and range
+            planeCrossing = new SensorMeanPlaneCrossing(sensor, scToBody, minLine, maxLine,
+                                                        lightTimeCorrection, aberrationOfLightCorrection,
+                                                        MAX_EVAL, COARSE_INVERSE_LOCATION_ACCURACY);
+
+            // store the finder, in order to reuse it
+            // (and save some computation done in its constructor)
+            setPlaneCrossing(planeCrossing);
+
+        }
+
+        return planeCrossing;
+
+    }
+
+    /** Set the mean plane crossing finder for a sensor.
+     * @param planeCrossing plane crossing finder
+     * @exception RuggedException if sensor is unknown
+     */
+    private void setPlaneCrossing(final SensorMeanPlaneCrossing planeCrossing)
+        throws RuggedException {
+        finders.put(planeCrossing.getSensor().getName(), planeCrossing);
     }
 
     /** Get transform from spacecraft to inertial frame.
diff --git a/src/main/java/org/orekit/rugged/errors/Dump.java b/src/main/java/org/orekit/rugged/errors/Dump.java
index a24e5ed40928728932976df23d7f2227bd98e786..003018fe84f5ce138c6320e8138b9326648782e6 100644
--- a/src/main/java/org/orekit/rugged/errors/Dump.java
+++ b/src/main/java/org/orekit/rugged/errors/Dump.java
@@ -33,6 +33,9 @@ import org.orekit.frames.FactoryManagedFrame;
 import org.orekit.frames.Frame;
 import org.orekit.frames.Transform;
 import org.orekit.rugged.api.AlgorithmId;
+import org.orekit.rugged.linesensor.LineSensor;
+import org.orekit.rugged.linesensor.SensorMeanPlaneCrossing;
+import org.orekit.rugged.linesensor.SensorPixel;
 import org.orekit.rugged.raster.Tile;
 import org.orekit.rugged.utils.ExtendedEllipsoid;
 import org.orekit.rugged.utils.SpacecraftToObservedBody;
@@ -49,9 +52,15 @@ class Dump {
     /** Dump file. */
     private final PrintWriter writer;
 
-    /** Tiles map. */
+    /** Tiles list. */
     private final List<DumpedTileData> tiles;
 
+    /** Already dumped sensors. */
+    private final List<String> sensors;
+
+    /** Already dumped sensors mean planes. */
+    private final List<String> meanPlanes;
+
     /** Flag for dumped algorithm. */
     private boolean algorithmDumped;
 
@@ -67,6 +76,8 @@ class Dump {
     public Dump(final PrintWriter writer) {
         this.writer          = writer;
         this.tiles           = new ArrayList<DumpedTileData>();
+        this.sensors         = new ArrayList<String>();
+        this.meanPlanes      = new ArrayList<String>();
         this.algorithmDumped = false;
         this.ellipsoidDumped = false;
         this.tranformsDumped = null;
@@ -165,6 +176,36 @@ class Dump {
         }
     }
 
+    /** Dump an inverse location computation.
+     * @param sensorName name of the line  sensor
+     * @param point point to localize
+     * @param minLine minimum line number
+     * @param maxLine maximum line number
+     * @param lightTimeCorrection flag for light time correction
+     * @param aberrationOfLightCorrection flag for aberration of light correction
+     */
+    public void dumpInverseLocation(final String sensorName, final GeodeticPoint point,
+                                    final int minLine, final int maxLine,
+                                    final boolean lightTimeCorrection, final boolean aberrationOfLightCorrection) {
+        writer.format(Locale.US,
+                      "inverse location: sensorName %s latitude %22.15e longitude %22.15e elevation %22.15e minLine %d maxLine %d lightTime %b aberration %b%n",
+                      sensorName,
+                      point.getLatitude(), point.getLongitude(), point.getAltitude(),
+                      minLine, maxLine,
+                      lightTimeCorrection, aberrationOfLightCorrection);
+    }
+
+    /** Dump an inverse location result.
+     * @param pixel resulting sensor pixel
+     */
+    public void dumpInverseLocationResult(final SensorPixel pixel) {
+        if (pixel != null) {
+            writer.format(Locale.US,
+                          "inverse location result: lineNumber %22.15e pixelNumber %22.15e%n",
+                          pixel.getLineNumber(), pixel.getPixelNumber());
+        }
+    }
+
     /** Dump an observation transform transform.
      * @param scToBody provider for observation
      * @param index index of the transform
@@ -198,6 +239,94 @@ class Dump {
         }
     }
 
+    /** Dump a sensor.
+     * @param sensor sensor to dump
+     */
+    public void dumpSensor(final LineSensor sensor) {
+        if (!sensors.contains(sensor.getName())) {
+            writer.format(Locale.US,
+                          "sensor: sensorName %s nbPixels %d position %22.15e %22.15e %22.15e%n",
+                          sensor.getName(), sensor.getNbPixels(),
+                          sensor.getPosition().getX(), sensor.getPosition().getY(), sensor.getPosition().getZ());
+            sensors.add(sensor.getName());
+        }
+    }
+
+    /** Dump a sensor mean plane.
+     * @param meanPlane mean plane associated with sensor
+     * @exception RuggedException if some frames cannot be computed at mid date
+     */
+    public void dumpSensorMeanPlane(final SensorMeanPlaneCrossing meanPlane)
+        throws RuggedException {
+        if (!meanPlanes.contains(meanPlane.getSensor().getName())) {
+            writer.format(Locale.US,
+                          "sensor mean plane: sensorName %s minLine %d maxLine %d maxEval %d accuracy %22.15e normal %22.15e %22.15e %22.15e%n",
+                          meanPlane.getSensor().getName(),
+                          meanPlane.getMinLine(), meanPlane.getMaxLine(),
+                          meanPlane.getMaxEval(), meanPlane.getAccuracy(),
+                          meanPlane.getMeanPlaneNormal().getX(), meanPlane.getMeanPlaneNormal().getY(), meanPlane.getMeanPlaneNormal().getZ());
+
+            // ensure the transforms for mid date are dumped
+            final AbsoluteDate midDate = meanPlane.getSensor().getDate(0.5 * (meanPlane.getMinLine() + meanPlane.getMaxLine()));
+            meanPlane.getScToBody().getBodyToInertial(midDate);
+            meanPlane.getScToBody().getScToInertial(midDate);
+
+            meanPlanes.add(meanPlane.getSensor().getName());
+
+        }
+    }
+
+    /** Dump a sensor LOS.
+     * @param name sensor name
+     * @param date date
+     * @param i pixel index
+     * @param los pixel normalized line-of-sight
+     * @exception RuggedException if date cannot be converted to UTC
+     */
+    public void dumpSensorLOS(final String name, final AbsoluteDate date, final int i, final Vector3D los)
+        throws RuggedException {
+        writer.format(Locale.US,
+                      "sensor LOS: sensorName %s date %s pixelNumber %d => %22.15e %22.15e %22.15e%n",
+                      name, convertDate(date), i, los.getX(), los.getY(), los.getZ());
+    }
+
+    /** Dump a sensor date.
+     * @param name sensor name
+     * @param lineNumber line number
+     * @param date date
+     * @exception RuggedException if date cannot be converted to UTC
+     */
+    public void dumpSensorDate(final String name, final double lineNumber, final AbsoluteDate date)
+        throws RuggedException {
+        writer.format(Locale.US,
+                      "sensor date: sensorName %s lineNumber %22.15e => %s%n",
+                      name, lineNumber, convertDate(date));
+    }
+
+    /** Dump a sensor line.
+     * @param name sensor name
+     * @param date date
+     * @param lineNumber line number
+     * @exception RuggedException if date cannot be converted to UTC
+     */
+    public void dumpSensorLine(final String name, final AbsoluteDate date, final double lineNumber)
+        throws RuggedException {
+        writer.format(Locale.US,
+                      "sensor line: sensorName %s date => %22.15e%n",
+                      name, convertDate(date), lineNumber);
+    }
+
+    /** Dump a sensor rate.
+     * @param name sensor name
+     * @param lineNumber line number
+     * @param rate lines rate
+     */
+    public void dumpSensorRate(final String name, final double lineNumber, final double rate) {
+        writer.format(Locale.US,
+                      "sensor rate: sensorName %s lineNumber %s => %22.15e%n",
+                      name, lineNumber, rate);
+    }
+
     /** Get a frame key or name.
      * @param frame frame to convert
      * @return frame key or name
diff --git a/src/main/java/org/orekit/rugged/errors/DumpManager.java b/src/main/java/org/orekit/rugged/errors/DumpManager.java
index 1d5afe652b5936f600e14b2ce5a40977a9829a0a..b49e7a88d83afad29073a6e10c3b33bad639eb64 100644
--- a/src/main/java/org/orekit/rugged/errors/DumpManager.java
+++ b/src/main/java/org/orekit/rugged/errors/DumpManager.java
@@ -24,6 +24,9 @@ import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
 import org.orekit.bodies.GeodeticPoint;
 import org.orekit.frames.Transform;
 import org.orekit.rugged.api.AlgorithmId;
+import org.orekit.rugged.linesensor.LineSensor;
+import org.orekit.rugged.linesensor.SensorMeanPlaneCrossing;
+import org.orekit.rugged.linesensor.SensorPixel;
 import org.orekit.rugged.raster.Tile;
 import org.orekit.rugged.utils.ExtendedEllipsoid;
 import org.orekit.rugged.utils.SpacecraftToObservedBody;
@@ -157,6 +160,32 @@ public class DumpManager {
         }
     }
 
+    /** Dump an inverse location computation.
+     * @param sensorName name of the line  sensor
+     * @param point point to localize
+     * @param minLine minimum line number
+     * @param maxLine maximum line number
+     * @param lightTimeCorrection flag for light time correction
+     * @param aberrationOfLightCorrection flag for aberration of light correction
+     */
+    public static void dumpInverseLocation(final String sensorName, final GeodeticPoint point,
+                                           final int minLine, final int maxLine,
+                                           final boolean lightTimeCorrection, final boolean aberrationOfLightCorrection) {
+        if (isActive()) {
+            DUMP.get().dumpInverseLocation(sensorName, point, minLine, maxLine,
+                                        lightTimeCorrection, aberrationOfLightCorrection);
+        }
+    }
+
+    /** Dump an inverse location result.
+     * @param pixel resulting sensor pixel
+     */
+    public static void dumpInverseLocationResult(final SensorPixel pixel) {
+        if (isActive()) {
+            DUMP.get().dumpInverseLocationResult(pixel);
+        }
+    }
+
     /** Dump an observation transform transform.
      * @param scToBody provider for observation
      * @param index index of the transform
@@ -172,4 +201,75 @@ public class DumpManager {
         }
     }
 
+    /** Dump a sensor.
+     * @param sensor sensor to dump
+     */
+    public static void dumpSensor(final LineSensor sensor) {
+        if (isActive()) {
+            DUMP.get().dumpSensor(sensor);
+        }
+    }
+
+    /** Dump a sensor mean plane.
+     * @param meanPlane mean plane associated with sensor
+     * @exception RuggedException if some frames cannot be computed at mid date
+     */
+    public static void dumpSensorMeanPlane(final SensorMeanPlaneCrossing meanPlane)
+        throws RuggedException {
+        if (isActive()) {
+            DUMP.get().dumpSensorMeanPlane(meanPlane);
+        }
+    }
+
+    /** Dump a sensor LOS.
+     * @param name sensor name
+     * @param date date
+     * @param i pixel index
+     * @param los pixel normalized line-of-sight
+     * @exception RuggedException if date cannot be converted to UTC
+     */
+    public static void dumpSensorLOS(final String name, final AbsoluteDate date, final int i, final Vector3D los)
+        throws RuggedException {
+        if (isActive()) {
+            DUMP.get().dumpSensorLOS(name, date, i, los);
+        }
+    }
+
+    /** Dump a sensor date.
+     * @param name sensor name
+     * @param lineNumber line number
+     * @param date date
+     * @exception RuggedException if date cannot be converted to UTC
+     */
+    public static void dumpSensorDate(final String name, final double lineNumber, final AbsoluteDate date)
+        throws RuggedException {
+        if (isActive()) {
+            DUMP.get().dumpSensorDate(name, lineNumber, date);
+        }
+    }
+
+    /** Dump a sensor line.
+     * @param name sensor name
+     * @param date date
+     * @param lineNumber line number
+     * @exception RuggedException if date cannot be converted to UTC
+     */
+    public static void dumpSensorLine(final String name, final AbsoluteDate date, final double lineNumber)
+        throws RuggedException {
+        if (isActive()) {
+            DUMP.get().dumpSensorLine(name, date, lineNumber);
+        }
+    }
+
+    /** Dump a sensor rate.
+     * @param name sensor name
+     * @param lineNumber line number
+     * @param rate lines rate
+     */
+    public static void dumpSensorRate(final String name, final double lineNumber, final double rate) {
+        if (isActive()) {
+            DUMP.get().dumpSensorRate(name, lineNumber, rate);
+        }
+    }
+
 }
diff --git a/src/main/java/org/orekit/rugged/errors/DumpReplayer.java b/src/main/java/org/orekit/rugged/errors/DumpReplayer.java
index 589a63f69c208cd0dbe5b200a2ac2aea4594517c..f38f9545a67455d3cf7f46b3250a24d7a9f5afd0 100644
--- a/src/main/java/org/orekit/rugged/errors/DumpReplayer.java
+++ b/src/main/java/org/orekit/rugged/errors/DumpReplayer.java
@@ -24,17 +24,23 @@ import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.ObjectOutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.NavigableMap;
 import java.util.TreeMap;
 
+import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
 import org.apache.commons.math3.exception.util.LocalizedFormats;
+import org.apache.commons.math3.geometry.euclidean.threed.FieldVector3D;
 import org.apache.commons.math3.geometry.euclidean.threed.Rotation;
 import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
 import org.apache.commons.math3.util.FastMath;
 import org.apache.commons.math3.util.OpenIntToDoubleHashMap;
+import org.apache.commons.math3.util.Pair;
 import org.orekit.bodies.GeodeticPoint;
 import org.orekit.bodies.OneAxisEllipsoid;
 import org.orekit.errors.OrekitException;
@@ -45,6 +51,11 @@ import org.orekit.frames.Transform;
 import org.orekit.rugged.api.AlgorithmId;
 import org.orekit.rugged.api.Rugged;
 import org.orekit.rugged.api.RuggedBuilder;
+import org.orekit.rugged.linesensor.LineDatation;
+import org.orekit.rugged.linesensor.LineSensor;
+import org.orekit.rugged.linesensor.SensorMeanPlaneCrossing;
+import org.orekit.rugged.linesensor.SensorPixel;
+import org.orekit.rugged.los.TimeDependentLOS;
 import org.orekit.rugged.raster.TileUpdater;
 import org.orekit.rugged.raster.UpdatableTile;
 import org.orekit.rugged.utils.SpacecraftToObservedBody;
@@ -160,6 +171,36 @@ public class DumpReplayer {
     /** Keyword for longitude index fields. */
     private static final String LON_INDEX = "lonIndex";
 
+    /** Keyword for sensor name. */
+    private static final String SENSOR_NAME = "sensorName";
+
+    /** Keyword for min line. */
+    private static final String MIN_LINE = "minLine";
+
+    /** Keyword for max line. */
+    private static final String MAX_LINE = "maxLine";
+
+    /** Keyword for line number. */
+    private static final String LINE_NUMBER = "lineNumber";
+
+    /** Keyword for number of pixels. */
+    private static final String NB_PIXELS = "nbPixels";
+
+    /** Keyword for pixel number. */
+    private static final String PIXEL_NUMBER = "pixelNumber";
+
+    /** Keyword for max number of evaluations. */
+    private static final String MAX_EVAL = "maxEval";
+
+    /** Keyword for accuracy. */
+    private static final String ACCURACY = "accuracy";
+
+    /** Keyword for normal. */
+    private static final String NORMAL = "normal";
+
+    /** Keyword for return arrow. */
+    private static final String RETURN_ARROW = "=>";
+
     /** Constant elevation for constant elevation algorithm. */
     private double constantElevation;
 
@@ -169,9 +210,12 @@ public class DumpReplayer {
     /** Ellipsoid. */
     private OneAxisEllipsoid ellipsoid;
 
-    /** Tiles map. */
+    /** Tiles list. */
     private final List<ParsedTile> tiles;
 
+    /** Sensors list. */
+    private final List<ParsedSensor> sensors;
+
     /** Interpolator min date. */
     private AbsoluteDate minDate;
 
@@ -205,8 +249,9 @@ public class DumpReplayer {
     /** Simple constructor.
      */
     public DumpReplayer() {
-        tiles = new ArrayList<ParsedTile>();
-        calls = new ArrayList<DumpedCall>();
+        tiles   = new ArrayList<ParsedTile>();
+        sensors = new ArrayList<ParsedSensor>();
+        calls   = new ArrayList<DumpedCall>();
     }
 
     /** Parse a dump file.
@@ -235,6 +280,9 @@ public class DumpReplayer {
         try {
             final RuggedBuilder builder = new RuggedBuilder();
 
+            if (algorithmId == null) {
+                algorithmId = AlgorithmId.IGNORE_DEM_USE_ELLIPSOID;
+            }
             builder.setAlgorithm(algorithmId);
             if (algorithmId == AlgorithmId.CONSTANT_ELEVATION_OVER_ELLIPSOID) {
                 builder.setConstantElevation(constantElevation);
@@ -291,20 +339,63 @@ public class DumpReplayer {
 
             // we use Rugged transforms reloading mechanism to ensure the spacecraft
             // to body transforms will be the same as the ones dumped
-            final SpacecraftToObservedBody sc2Body =
+            final SpacecraftToObservedBody scToBody =
                     new SpacecraftToObservedBody(inertialFrame, ellipsoid.getBodyFrame(),
                                                  minDate, maxDate, tStep, tolerance,
                                                  b2iList, s2iList);
             final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-            new ObjectOutputStream(bos).writeObject(sc2Body);
+            new ObjectOutputStream(bos).writeObject(scToBody);
             final ByteArrayInputStream  bis = new ByteArrayInputStream(bos.toByteArray());
             builder.setTrajectoryAndTimeSpan(bis);
 
-            return builder.build();
+            final List<SensorMeanPlaneCrossing> planeCrossings = new ArrayList<SensorMeanPlaneCrossing>();
+            for (final ParsedSensor parsedSensor : sensors) {
+                final LineSensor sensor = new LineSensor(parsedSensor.name,
+                                                         parsedSensor,
+                                                         parsedSensor.position,
+                                                         parsedSensor);
+                if (parsedSensor.meanPlane != null) {
+                    planeCrossings.add(new SensorMeanPlaneCrossing(sensor, scToBody,
+                                                                   parsedSensor.meanPlane.minLine,
+                                                                   parsedSensor.meanPlane.maxLine,
+                                                                   lightTimeCorrection, aberrationOfLightCorrection,
+                                                                   parsedSensor.meanPlane.maxEval,
+                                                                   parsedSensor.meanPlane.accuracy,
+                                                                   parsedSensor.meanPlane.normal));
+                }
+                builder.addLineSensor(sensor);
+            }
+
+            final Rugged rugged = builder.build();
+
+            final Method setPlaneCrossing = Rugged.class.getDeclaredMethod("setPlaneCrossing",
+                                                                           SensorMeanPlaneCrossing.class);
+            setPlaneCrossing.setAccessible(true);
+            for (final SensorMeanPlaneCrossing planeCrossing : planeCrossings) {
+                setPlaneCrossing.invoke(rugged, planeCrossing);
+            }
+
+            return rugged;
 
         } catch (IOException ioe) {
             throw new RuggedException(ioe, LocalizedFormats.SIMPLE_MESSAGE, ioe.getLocalizedMessage());
+        } catch (SecurityException e) {
+            // this should never happen
+            throw RuggedException.createInternalError(e);
+        } catch (NoSuchMethodException e) {
+            // this should never happen
+            throw RuggedException.createInternalError(e);
+        } catch (IllegalArgumentException e) {
+            // this should never happen
+            throw RuggedException.createInternalError(e);
+        } catch (IllegalAccessException e) {
+            // this should never happen
+            throw RuggedException.createInternalError(e);
+        } catch (InvocationTargetException e) {
+            // this should never happen
+            throw RuggedException.createInternalError(e);
         }
+
     }
 
     /** Execute all dumped calls.
@@ -630,6 +721,254 @@ public class DumpReplayer {
                                           name, l, file.getAbsolutePath(), line);
             }
 
+        },
+
+        /** Parser for inverse location calls dump lines. */
+        INVERSE_LOCATION() {
+
+            /** {@inheritDoc} */
+            @Override
+            public void parse(final int l, final File file, final String line, final String[] fields, final DumpReplayer global)
+                throws RuggedException {
+                if (fields.length < 16 ||
+                        !fields[0].equals(SENSOR_NAME) ||
+                        !fields[2].equals(LATITUDE) || !fields[4].equals(LONGITUDE) || !fields[6].equals(ELEVATION) ||
+                        !fields[8].equals(MIN_LINE) || !fields[10].equals(MAX_LINE) ||
+                        !fields[12].equals(LIGHT_TIME) || !fields[14].equals(ABERRATION)) {
+                    throw new RuggedException(RuggedMessages.CANNOT_PARSE_LINE, l, file, line);
+                }
+                final String sensorName = fields[1];
+                final GeodeticPoint point = new GeodeticPoint(Double.parseDouble(fields[3]),
+                                                              Double.parseDouble(fields[5]),
+                                                              Double.parseDouble(fields[7]));
+                final int minLine = Integer.parseInt(fields[9]);
+                final int maxLine = Integer.parseInt(fields[11]);
+                if (global.calls.isEmpty()) {
+                    global.lightTimeCorrection         = Boolean.parseBoolean(fields[11]);
+                    global.aberrationOfLightCorrection = Boolean.parseBoolean(fields[13]);
+                } else {
+                    if (global.lightTimeCorrection != Boolean.parseBoolean(fields[11])) {
+                        throw new RuggedException(RuggedMessages.LIGHT_TIME_CORRECTION_REDEFINED,
+                                                  l, file.getAbsolutePath(), line);
+                    }
+                    if (global.aberrationOfLightCorrection != Boolean.parseBoolean(fields[13])) {
+                        throw new RuggedException(RuggedMessages.ABERRATION_OF_LIGHT_CORRECTION_REDEFINED,
+                                                  l, file.getAbsolutePath(), line);
+                    }
+                }
+                global.calls.add(new DumpedCall() {
+
+                    /** {@inheritDoc} */
+                    @Override
+                    public Object execute(final Rugged rugged) throws RuggedException {
+                        return rugged.inverseLocation(sensorName, point, minLine, maxLine);
+                    }
+
+                });
+            }
+
+        },
+
+        /** Parser for inverse location result dump lines. */
+        INVERSE_LOCATION_RESULT() {
+
+            /** {@inheritDoc} */
+            @Override
+            public void parse(final int l, final File file, final String line, final String[] fields, final DumpReplayer global)
+                throws RuggedException {
+                if (fields.length < 4 || !fields[0].equals(LINE_NUMBER) || !fields[2].equals(PIXEL_NUMBER)) {
+                    throw new RuggedException(RuggedMessages.CANNOT_PARSE_LINE, l, file, line);
+                }
+                final SensorPixel sp = new SensorPixel(Double.parseDouble(fields[1]),
+                                                       Double.parseDouble(fields[3]));
+                final DumpedCall last = global.calls.get(global.calls.size() - 1);
+                last.expected = sp;
+            }
+
+        },
+
+        /** Parser for sensor dump lines. */
+        SENSOR() {
+
+            /** {@inheritDoc} */
+            @Override
+            public void parse(final int l, final File file, final String line, final String[] fields, final DumpReplayer global)
+                throws RuggedException {
+                if (fields.length < 8 || !fields[0].equals(SENSOR_NAME) ||
+                    !fields[2].equals(NB_PIXELS) || !fields[4].equals(POSITION)) {
+                    throw new RuggedException(RuggedMessages.CANNOT_PARSE_LINE, l, file, line);
+                }
+                final String   sensorName = fields[1];
+                final int      nbPixels   = Integer.parseInt(fields[3]);
+                final Vector3D position   = new Vector3D(Double.parseDouble(fields[5]),
+                                                         Double.parseDouble(fields[6]),
+                                                         Double.parseDouble(fields[7]));
+                for (final ParsedSensor sensor : global.sensors) {
+                    if (sensor.name.equals(sensorName)) {
+                        throw new RuggedException(RuggedMessages.SENSOR_ALREADY_DEFINED,
+                                                  sensorName, l, file.getAbsolutePath(), line);
+                    }
+                }
+                global.sensors.add(new ParsedSensor(sensorName, nbPixels, position));
+            }
+
+        },
+
+        /** Parser for sensor mean plane dump lines. */
+        SENSOR_MEAN_PLANE() {
+
+            /** {@inheritDoc} */
+            @Override
+            public void parse(final int l, final File file, final String line, final String[] fields, final DumpReplayer global)
+                throws RuggedException {
+                if (fields.length < 14 || !fields[0].equals(SENSOR_NAME) ||
+                    !fields[2].equals(MIN_LINE) || !fields[4].equals(MAX_LINE) ||
+                    !fields[6].equals(MAX_EVAL) || !fields[8].equals(ACCURACY) ||
+                    !fields[10].equals(NORMAL)) {
+                    throw new RuggedException(RuggedMessages.CANNOT_PARSE_LINE, l, file, line);
+                }
+                final String   sensorName = fields[1];
+                final int      minLine    = Integer.parseInt(fields[3]);
+                final int      maxLine    = Integer.parseInt(fields[5]);
+                final int      maxEval    = Integer.parseInt(fields[7]);
+                final double   accuracy   = Double.parseDouble(fields[9]);
+                final Vector3D normal     = new Vector3D(Double.parseDouble(fields[11]),
+                                                         Double.parseDouble(fields[12]),
+                                                         Double.parseDouble(fields[13]));
+                for (final ParsedSensor sensor : global.sensors) {
+                    if (sensor.name.equals(sensorName)) {
+                        sensor.meanPlane = new ParsedMeanPlane(minLine, maxLine, maxEval, accuracy, normal);
+                        return;
+                    }
+                }
+
+                throw new RuggedException(RuggedMessages.UNKNOWN_SENSOR, sensorName);
+
+            }
+
+        },
+
+        /** Parser for sensor LOS dump lines. */
+        SENSOR_LOS() {
+
+            /** {@inheritDoc} */
+            @Override
+            public void parse(final int l, final File file, final String line, final String[] fields, final DumpReplayer global)
+                throws RuggedException {
+                try {
+                    if (fields.length < 10 || !fields[0].equals(SENSOR_NAME) ||
+                            !fields[2].equals(DATE) || !fields[4].equals(PIXEL_NUMBER) ||
+                            !fields[6].equals(RETURN_ARROW)) {
+                        throw new RuggedException(RuggedMessages.CANNOT_PARSE_LINE, l, file, line);
+                    }
+                    final String       sensorName  = fields[1];
+                    final AbsoluteDate date        = new AbsoluteDate(fields[3], TimeScalesFactory.getUTC());
+                    final int          pixelNumber = Integer.parseInt(fields[5]);
+                    final Vector3D     los         = new Vector3D(Double.parseDouble(fields[7]),
+                                                                  Double.parseDouble(fields[8]),
+                                                                  Double.parseDouble(fields[9]));
+                    for (final ParsedSensor sensor : global.sensors) {
+                        if (sensor.name.equals(sensorName)) {
+                            sensor.setLOS(date, pixelNumber, los);
+                            return;
+                        }
+                    }
+
+                    throw new RuggedException(RuggedMessages.UNKNOWN_SENSOR, sensorName);
+                } catch (OrekitException oe) {
+                    throw new RuggedException(oe, oe.getSpecifier(), oe.getParts());
+                }
+            }
+
+        },
+
+        /** Parser for sensor date dump lines. */
+        SENSOR_DATE() {
+
+            /** {@inheritDoc} */
+            @Override
+            public void parse(final int l, final File file, final String line, final String[] fields, final DumpReplayer global)
+                throws RuggedException {
+                try {
+                    if (fields.length < 5 || !fields[0].equals(SENSOR_NAME) ||
+                        !fields[2].equals(LINE_NUMBER) || !fields[4].equals(RETURN_ARROW)) {
+                        throw new RuggedException(RuggedMessages.CANNOT_PARSE_LINE, l, file, line);
+                    }
+                    final String       sensorName  = fields[1];
+                    final double       lineNumber  = Double.parseDouble(fields[3]);
+                    final AbsoluteDate date        = new AbsoluteDate(fields[5], TimeScalesFactory.getUTC());
+                    for (final ParsedSensor sensor : global.sensors) {
+                        if (sensor.name.equals(sensorName)) {
+                            sensor.setDatation(lineNumber, date);
+                            return;
+                        }
+                    }
+
+                    throw new RuggedException(RuggedMessages.UNKNOWN_SENSOR, sensorName);
+                } catch (OrekitException oe) {
+                    throw new RuggedException(oe, oe.getSpecifier(), oe.getParts());
+                }
+
+            }
+
+        },
+
+        /** Parser for sensor line dump lines. */
+        SENSOR_LINE() {
+
+            /** {@inheritDoc} */
+            @Override
+            public void parse(final int l, final File file, final String line, final String[] fields, final DumpReplayer global)
+                throws RuggedException {
+                try {
+                    if (fields.length < 10 || !fields[0].equals(SENSOR_NAME) ||
+                            !fields[2].equals(LINE_NUMBER) || !fields[4].equals(RETURN_ARROW)) {
+                        throw new RuggedException(RuggedMessages.CANNOT_PARSE_LINE, l, file, line);
+                    }
+                    final String       sensorName  = fields[1];
+                    final AbsoluteDate date        = new AbsoluteDate(fields[3], TimeScalesFactory.getUTC());
+                    final double       lineNumber  = Double.parseDouble(fields[5]);
+                    for (final ParsedSensor sensor : global.sensors) {
+                        if (sensor.name.equals(sensorName)) {
+                            sensor.setDatation(lineNumber, date);
+                            return;
+                        }
+                    }
+
+                    throw new RuggedException(RuggedMessages.UNKNOWN_SENSOR, sensorName);
+                } catch (OrekitException oe) {
+                    throw new RuggedException(oe, oe.getSpecifier(), oe.getParts());
+                }
+
+            }
+
+        },
+
+        /** Parser for sensor rate dump lines. */
+        SENSOR_RATE() {
+
+            /** {@inheritDoc} */
+            @Override
+            public void parse(final int l, final File file, final String line, final String[] fields, final DumpReplayer global)
+                throws RuggedException {
+                if (fields.length < 5 || !fields[0].equals(SENSOR_NAME) ||
+                    !fields[2].equals(LINE_NUMBER) || !fields[4].equals(RETURN_ARROW)) {
+                    throw new RuggedException(RuggedMessages.CANNOT_PARSE_LINE, l, file, line);
+                }
+                final String       sensorName  = fields[1];
+                final double       lineNumber  = Double.parseDouble(fields[3]);
+                final double       rate  = Double.parseDouble(fields[5]);
+                for (final ParsedSensor sensor : global.sensors) {
+                    if (sensor.name.equals(sensorName)) {
+                        sensor.setRate(lineNumber, rate);
+                        return;
+                    }
+                }
+
+                throw new RuggedException(RuggedMessages.UNKNOWN_SENSOR, sensorName);
+
+            }
+
         };
 
         /** Parse a line.
@@ -652,7 +991,7 @@ public class DumpReplayer {
                 final String parsedKey = line.substring(0, colon).trim().replaceAll(" ", "_").toUpperCase();
                 try {
                     final LineParser parser = LineParser.valueOf(parsedKey);
-                    parser.parse(colon, file, line, line.substring(colon + 1).trim().split("\\s+"), global);
+                    parser.parse(l, file, line, line.substring(colon + 1).trim().split("\\s+"), global);
                 } catch (IllegalArgumentException iae) {
                     throw new RuggedException(RuggedMessages.CANNOT_PARSE_LINE, l, file, line);
                 }
@@ -761,6 +1100,201 @@ public class DumpReplayer {
 
     }
 
+    /** Local class for handling already parsed sensor data. */
+    private static class ParsedSensor implements LineDatation, TimeDependentLOS {
+
+        /** Name of the sensor. */
+        private final String name;
+
+        /** Number of pixels. */
+        private final int nbPixels;
+
+        /** Position. */
+        private final Vector3D position;
+
+        /** Mean plane crossing finder. */
+        private ParsedMeanPlane meanPlane;
+
+        /** LOS map. */
+        private final Map<Integer, List<Pair<AbsoluteDate, Vector3D>>> losMap;
+
+        /** Datation. */
+        private final List<Pair<Double, AbsoluteDate>> datation;
+
+        /** Rate. */
+        private final List<Pair<Double, Double>> rates;
+
+        /** simple constructor.
+         * @param name name of the sensor
+         * @param nbPixels number of pixels
+         * @param position position
+         */
+        public ParsedSensor(final String name, final int nbPixels, final Vector3D position) {
+            this.name     = name;
+            this.nbPixels = nbPixels;
+            this.position = position;
+            this.losMap   = new HashMap<Integer, List<Pair<AbsoluteDate, Vector3D>>>();
+            this.datation = new ArrayList<Pair<Double, AbsoluteDate>>();
+            this.rates    = new ArrayList<Pair<Double, Double>>();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public int getNbEstimatedParameters() {
+            return 0;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void getEstimatedParameters(final double[] parameters, final int start, final int length)
+            throws RuggedException {
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void setEstimatedParameters(final double[] parameters, final int start, final int length)
+            throws RuggedException {
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public int getNbPixels() {
+            return nbPixels;
+        }
+
+        /** Set a los direction.
+         * @param date date
+         * @param pixelNumber number of the pixel
+         * @param los los direction
+         */
+        public void setLOS(final AbsoluteDate date, final int pixelNumber, final Vector3D los) {
+            List<Pair<AbsoluteDate, Vector3D>> list = losMap.get(pixelNumber);
+            if (list == null) {
+                list = new ArrayList<Pair<AbsoluteDate, Vector3D>>();
+                losMap.put(pixelNumber, list);
+            }
+            list.add(new Pair<AbsoluteDate, Vector3D>(date, los));
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public Vector3D getLOS(final int index, final AbsoluteDate date) {
+            final List<Pair<AbsoluteDate, Vector3D>> list = losMap.get(index);
+            if (list == null) {
+                throw RuggedException.createInternalError(null);
+            }
+            int selected = 0;
+            for (int i = 0; i < list.size(); ++i) {
+                if (FastMath.abs(list.get(i).getFirst().durationFrom(date)) <
+                    FastMath.abs(list.get(selected).getFirst().durationFrom(date))) {
+                    selected = i;
+                }
+            }
+            return list.get(selected).getSecond();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public FieldVector3D<DerivativeStructure> getLOS(final int index, final AbsoluteDate date, final double[] parameters) {
+            final Vector3D los = getLOS(index, date);
+            return new FieldVector3D<DerivativeStructure>(new DerivativeStructure(parameters.length, 1, los.getX()),
+                                                          new DerivativeStructure(parameters.length, 1, los.getY()),
+                                                          new DerivativeStructure(parameters.length, 1, los.getZ()));
+        }
+
+        /** Set a datation pair.
+         * @param lineNumber line number
+         * @param date date
+         */
+        public void setDatation(final double lineNumber, final AbsoluteDate date) {
+            datation.add(new Pair<Double, AbsoluteDate>(lineNumber, date));
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public AbsoluteDate getDate(final double lineNumber) {
+            int selected = 0;
+            for (int i = 0; i < datation.size(); ++i) {
+                if (FastMath.abs(datation.get(i).getFirst()        - lineNumber) <
+                    FastMath.abs(datation.get(selected).getFirst() - lineNumber)) {
+                    selected = i;
+                }
+            }
+            return datation.get(selected).getSecond();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public double getLine(final AbsoluteDate date) {
+            int selected = 0;
+            for (int i = 0; i < datation.size(); ++i) {
+                if (FastMath.abs(datation.get(i).getSecond().durationFrom(date)) <
+                    FastMath.abs(datation.get(selected).getSecond().durationFrom(date))) {
+                    selected = i;
+                }
+            }
+            return datation.get(selected).getFirst();
+        }
+
+        /** Set a rate.
+         * @param lineNumber line number
+         * @param rate lines rate
+         */
+        public void setRate(final double lineNumber, final double rate) {
+            rates.add(new Pair<Double, Double>(lineNumber, rate));
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public double getRate(final double lineNumber) {
+            int selected = 0;
+            for (int i = 0; i < rates.size(); ++i) {
+                if (FastMath.abs(rates.get(i).getFirst()        - lineNumber) <
+                    FastMath.abs(rates.get(selected).getFirst() - lineNumber)) {
+                    selected = i;
+                }
+            }
+            return rates.get(selected).getSecond();
+        }
+
+    }
+
+    /** Local class for handling already parsed mean plane data. */
+    private static class ParsedMeanPlane {
+
+        /** Min line. */
+        private final int minLine;
+
+        /** Max line. */
+        private final int maxLine;
+
+        /** Maximum number of evaluations. */
+        private final int maxEval;
+
+        /** Accuracy to use for finding crossing line number. */
+        private final double accuracy;
+
+        /** Mean plane normal. */
+        private final Vector3D normal;
+
+        /** simple constructor.
+         * @param minLine min line
+         * @param maxLine max line
+         * @param maxEval maximum number of evaluations
+         * @param accuracy accuracy to use for finding crossing line number
+         * @param normal mean plane normal
+         */
+        public ParsedMeanPlane(final int minLine, final int maxLine,
+                               final int maxEval, final double accuracy, final Vector3D normal) {
+            this.minLine  = minLine;
+            this.maxLine  = maxLine;
+            this.maxEval  = maxEval;
+            this.accuracy = accuracy;
+            this.normal   = normal;
+        }
+
+    }
+
     /** Local interface for dumped calls. */
     private abstract static class DumpedCall {
 
diff --git a/src/main/java/org/orekit/rugged/errors/RuggedExceptionWrapper.java b/src/main/java/org/orekit/rugged/errors/RuggedExceptionWrapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..6d006135f7d095e2d3972a4f152d8de554a8de41
--- /dev/null
+++ b/src/main/java/org/orekit/rugged/errors/RuggedExceptionWrapper.java
@@ -0,0 +1,53 @@
+/* Copyright 2013-2015 CS Systèmes d'Information
+ * Licensed to CS Systèmes d'Information (CS) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * CS licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.orekit.rugged.errors;
+
+/** This class allows to wrap {@link RuggedException} instances in {@code RuntimeException}.
+ * <p>Wrapping {@link RuggedException} instances is useful when a low level method throws
+ * one such exception and this method must be called from another one which does not allow
+ * this exception. Typical examples are propagation methods that are used inside Apache
+ * Commons optimizers, integrators or solvers.</p>
+ * <p>
+ * This class is heavily based on Orekit {@link org.orekit.errors.OrekitException},
+ * which is distributed under the terms of the Apache License V2.
+ * </p>
+ * @author Luc Maisonobe
+ */
+public class RuggedExceptionWrapper extends RuntimeException {
+
+    /** serializable UID. */
+    private static final long serialVersionUID = 20150224L;
+
+    /** Underlying Orekit exception. */
+    private final RuggedException wrappedException;
+
+    /** Simple constructor.
+     * @param wrappedException Orekit exception to wrap
+     */
+    public RuggedExceptionWrapper(final RuggedException wrappedException) {
+        super(wrappedException);
+        this.wrappedException = wrappedException;
+    }
+
+    /** Get the wrapped exception.
+     * @return wrapped exception
+     */
+    public RuggedException getException() {
+        return wrappedException;
+    }
+
+}
diff --git a/src/main/java/org/orekit/rugged/errors/RuggedMessages.java b/src/main/java/org/orekit/rugged/errors/RuggedMessages.java
index e657479f34b7395dac153d422e033f6ef1eb2356..e336fdf758dfeddebc19c1c4961a60d71c175aed 100644
--- a/src/main/java/org/orekit/rugged/errors/RuggedMessages.java
+++ b/src/main/java/org/orekit/rugged/errors/RuggedMessages.java
@@ -74,7 +74,8 @@ public enum RuggedMessages implements Localizable {
     LIGHT_TIME_CORRECTION_REDEFINED("light time correction redefined, line {0}, file {1}: {2}"),
     ABERRATION_OF_LIGHT_CORRECTION_REDEFINED("aberration of light correction redefined, line {0}, file {1}: {2}"),
     TILE_ALREADY_DEFINED("tile {0} already defined, line {1}, file {2}: {3}"),
-    UNKNOWN_TILE("unknown tile {0}, line {1}, file {2}: {3}");
+    UNKNOWN_TILE("unknown tile {0}, line {1}, file {2}: {3}"),
+    SENSOR_ALREADY_DEFINED("sensor {0} already defined, line {1}, file {2}: {3}");
 
     // CHECKSTYLE: resume JavadocVariable check
 
diff --git a/src/main/java/org/orekit/rugged/linesensor/LineSensor.java b/src/main/java/org/orekit/rugged/linesensor/LineSensor.java
index abcd16ec827c69df7fe86665c9d99577e64534e4..bcdb4c9d6bd06d0d0b4d43f938ca1f1a011615b9 100644
--- a/src/main/java/org/orekit/rugged/linesensor/LineSensor.java
+++ b/src/main/java/org/orekit/rugged/linesensor/LineSensor.java
@@ -17,6 +17,8 @@
 package org.orekit.rugged.linesensor;
 
 import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
+import org.orekit.rugged.errors.DumpManager;
+import org.orekit.rugged.errors.RuggedException;
 import org.orekit.rugged.los.TimeDependentLOS;
 import org.orekit.time.AbsoluteDate;
 
@@ -72,25 +74,37 @@ public class LineSensor {
      * @param date current date
      * @param i pixel index (must be between 0 and {@link #getNbPixels()} - 1
      * @return pixel normalized line-of-sight
+     * @exception RuggedException if date cannot be handled
      */
-    public Vector3D getLos(final AbsoluteDate date, final int i) {
-        return los.getLOS(i, date);
+    public Vector3D getLos(final AbsoluteDate date, final int i)
+        throws RuggedException {
+        final Vector3D l = los.getLOS(i, date);
+        DumpManager.dumpSensorLOS(name, date, i, l);
+        return l;
     }
 
     /** Get the date.
      * @param lineNumber line number
      * @return date corresponding to line number
+     * @exception RuggedException if date cannot be handled
      */
-    public AbsoluteDate getDate(final double lineNumber) {
-        return datationModel.getDate(lineNumber);
+    public AbsoluteDate getDate(final double lineNumber)
+        throws RuggedException {
+        final AbsoluteDate date = datationModel.getDate(lineNumber);
+        DumpManager.dumpSensorDate(name, lineNumber, date);
+        return date;
     }
 
     /** Get the line number.
      * @param date date
      * @return line number corresponding to date
+     * @exception RuggedException if date cannot be handled
      */
-    public double getLine(final AbsoluteDate date) {
-        return datationModel.getLine(date);
+    public double getLine(final AbsoluteDate date)
+        throws RuggedException {
+        final double lineNumber = datationModel.getLine(date);
+        DumpManager.dumpSensorLine(name, date, lineNumber);
+        return lineNumber;
     }
 
     /** Get the rate of lines scanning.
@@ -98,7 +112,9 @@ public class LineSensor {
      * @return rate of lines scanning (lines / seconds)
      */
     public double getRate(final double lineNumber) {
-        return datationModel.getRate(lineNumber);
+        final double rate = datationModel.getRate(lineNumber);
+        DumpManager.dumpSensorRate(name, lineNumber, rate);
+        return rate;
     }
 
     /** Get the sensor position.
diff --git a/src/main/java/org/orekit/rugged/linesensor/SensorMeanPlaneCrossing.java b/src/main/java/org/orekit/rugged/linesensor/SensorMeanPlaneCrossing.java
index e4f8cfb1b54760348fd5756dfc950fe0fd5d8350..ce2d0659dd0bda4f73986feaf092e782a61fb6d3 100644
--- a/src/main/java/org/orekit/rugged/linesensor/SensorMeanPlaneCrossing.java
+++ b/src/main/java/org/orekit/rugged/linesensor/SensorMeanPlaneCrossing.java
@@ -92,6 +92,30 @@ public class SensorMeanPlaneCrossing {
                                    final boolean aberrationOfLightCorrection,
                                    final int maxEval, final double accuracy)
         throws RuggedException {
+        this(sensor, scToBody, minLine, maxLine, lightTimeCorrection, aberrationOfLightCorrection,
+             maxEval, accuracy, computeMeanPlaneNormal(sensor, minLine, maxLine));
+    }
+
+    /** Simple constructor.
+     * @param sensor sensor to consider
+     * @param scToBody converter between spacecraft and body
+     * @param minLine minimum line number
+     * @param maxLine maximum line number
+     * @param lightTimeCorrection flag for light time correction
+     * @param aberrationOfLightCorrection flag for aberration of light correction.
+     * @param maxEval maximum number of evaluations
+     * @param accuracy accuracy to use for finding crossing line number
+     * @param meanPlaneNormal mean plane normal
+     * @exception RuggedException if some frame conversion fails
+     */
+    public SensorMeanPlaneCrossing(final LineSensor sensor,
+                                   final SpacecraftToObservedBody scToBody,
+                                   final int minLine, final int maxLine,
+                                   final boolean lightTimeCorrection,
+                                   final boolean aberrationOfLightCorrection,
+                                   final int maxEval, final double accuracy,
+                                   final Vector3D meanPlaneNormal)
+        throws RuggedException {
 
         this.sensor                      = sensor;
         this.minLine                     = minLine;
@@ -107,19 +131,25 @@ public class SensorMeanPlaneCrossing {
         this.midBodyToInert              = scToBody.getBodyToInertial(midDate);
         this.midScToInert                = scToBody.getScToInertial(midDate);
 
-        this.meanPlaneNormal             = computeMeanPlaneNormal(midDate);
+        this.meanPlaneNormal             = meanPlaneNormal;
 
     }
 
     /** Compute the plane containing origin that best fits viewing directions point cloud.
-     * @param midDate middle date
+     * @param sensor line sensor
+     * @param minLine minimum line number
+     * @param maxLine maximum line number
      * <p>
      * The normal is oriented such that traversing pixels in increasing indices
      * order corresponds to trigonometric order (i.e. counterclockwise).
      * </p>
      * @return normal of the mean plane
+     * @exception RuggedException if mid date cannot be handled
      */
-    private Vector3D computeMeanPlaneNormal(final AbsoluteDate midDate) {
+    private static Vector3D computeMeanPlaneNormal(final LineSensor sensor, final int minLine, final int maxLine)
+        throws RuggedException {
+
+        final AbsoluteDate midDate = sensor.getDate(0.5 * (minLine + maxLine));
 
         // build a centered data matrix
         // (for each viewing direction, we add both the direction and its
@@ -154,6 +184,20 @@ public class SensorMeanPlaneCrossing {
 
     }
 
+    /** Get the underlying sensor.
+     * @return underlying sensor
+     */
+    public LineSensor getSensor() {
+        return sensor;
+    }
+
+    /** Get converter between spacecraft and body.
+     * @return converter between spacecraft and body
+     */
+    public SpacecraftToObservedBody getScToBody() {
+        return scToBody;
+    }
+
     /** Get the minimum line number in the search interval.
      * @return minimum line number in the search interval
      */
@@ -168,6 +212,20 @@ public class SensorMeanPlaneCrossing {
         return maxLine;
     }
 
+    /** Get the maximum number of evaluations.
+     * @return maximum number of evaluations
+     */
+    public int getMaxEval() {
+        return maxEval;
+    }
+
+    /** Get the accuracy to use for finding crossing line number.
+     * @return accuracy to use for finding crossing line number
+     */
+    public double getAccuracy() {
+        return accuracy;
+    }
+
     /** Get the mean plane normal.
      * <p>
      * The normal is oriented such traversing pixels in increasing indices
diff --git a/src/main/java/org/orekit/rugged/linesensor/SensorPixelCrossing.java b/src/main/java/org/orekit/rugged/linesensor/SensorPixelCrossing.java
index ca95673d5106b69871ffb7a7643e4db495d2371d..0e972175d6a342c1d7aceed783217a5823df741f 100644
--- a/src/main/java/org/orekit/rugged/linesensor/SensorPixelCrossing.java
+++ b/src/main/java/org/orekit/rugged/linesensor/SensorPixelCrossing.java
@@ -23,8 +23,8 @@ import org.apache.commons.math3.exception.NoBracketingException;
 import org.apache.commons.math3.exception.TooManyEvaluationsException;
 import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
 import org.apache.commons.math3.util.FastMath;
-import org.orekit.errors.OrekitExceptionWrapper;
 import org.orekit.rugged.errors.RuggedException;
+import org.orekit.rugged.errors.RuggedExceptionWrapper;
 import org.orekit.time.AbsoluteDate;
 
 /** Class devoted to locate where ground point crosses a sensor line.
@@ -79,8 +79,12 @@ public class SensorPixelCrossing {
             final UnivariateFunction f = new UnivariateFunction() {
                 /** {@inheritDoc} */
                 @Override
-                public double value(final double x) throws OrekitExceptionWrapper {
-                    return Vector3D.angle(cross, getLOS(date, x)) - 0.5 * FastMath.PI;
+                public double value(final double x) throws RuggedExceptionWrapper {
+                    try {
+                        return Vector3D.angle(cross, getLOS(date, x)) - 0.5 * FastMath.PI;
+                    } catch (RuggedException re) {
+                        throw new RuggedExceptionWrapper(re);
+                    }
                 }
             };
 
@@ -94,6 +98,8 @@ public class SensorPixelCrossing {
             return Double.NaN;
         } catch (TooManyEvaluationsException tmee) {
             throw new RuggedException(tmee);
+        } catch (RuggedExceptionWrapper rew) {
+            throw rew.getException();
         }
     }
 
@@ -101,8 +107,10 @@ public class SensorPixelCrossing {
      * @param date current date
      * @param x pixel index
      * @return interpolated direction for specified index
+     * @exception RuggedException if date cannot be handled
      */
-    private Vector3D getLOS(final AbsoluteDate date, final double x) {
+    private Vector3D getLOS(final AbsoluteDate date, final double x)
+        throws RuggedException {
 
         // find surrounding pixels
         final int iInf = FastMath.max(0, FastMath.min(sensor.getNbPixels() - 2, (int) FastMath.floor(x)));
diff --git a/src/main/java/org/orekit/rugged/utils/ExtendedEllipsoid.java b/src/main/java/org/orekit/rugged/utils/ExtendedEllipsoid.java
index 3ead84ed71b421ff9193652721e710e201ae6802..af7906f27865a1a6d89c9e2aab12de3e48e398d6 100644
--- a/src/main/java/org/orekit/rugged/utils/ExtendedEllipsoid.java
+++ b/src/main/java/org/orekit/rugged/utils/ExtendedEllipsoid.java
@@ -58,6 +58,21 @@ public class ExtendedEllipsoid extends OneAxisEllipsoid {
         b2 = b * b;
     }
 
+    /** {@inheritDoc} */
+    @Override
+    public Vector3D transform(final GeodeticPoint point) {
+        DumpManager.dumpEllipsoid(this);
+        return super.transform(point);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public GeodeticPoint transform(final Vector3D point, final Frame frame, final AbsoluteDate date)
+        throws OrekitException {
+        DumpManager.dumpEllipsoid(this);
+        return super.transform(point, frame, date);
+    }
+
     /** Get point at some latitude along a pixel line of sight.
      * @param position cell position (in body frame)
      * @param los pixel line-of-sight, not necessarily normalized (in body frame)
@@ -247,8 +262,6 @@ public class ExtendedEllipsoid extends OneAxisEllipsoid {
      */
     public Vector3D convertLos(final GeodeticPoint point, final Vector3D los) {
 
-        DumpManager.dumpEllipsoid(this);
-
         // Cartesian coordinates of the topocentric frame origin
         final Vector3D p3D = transform(point);
 
@@ -282,8 +295,6 @@ public class ExtendedEllipsoid extends OneAxisEllipsoid {
         throws RuggedException {
         try {
 
-            DumpManager.dumpEllipsoid(this);
-
             // switch to geodetic coordinates using primary point as reference
             final GeodeticPoint point = transform(primary, getBodyFrame(), null);
             final Vector3D      los   = secondary.subtract(primary);
@@ -308,7 +319,6 @@ public class ExtendedEllipsoid extends OneAxisEllipsoid {
     public NormalizedGeodeticPoint transform(final Vector3D point, final Frame frame, final AbsoluteDate date,
                                              final double centralLongitude)
         throws OrekitException {
-        DumpManager.dumpEllipsoid(this);
         final GeodeticPoint gp = transform(point, frame, date);
         return new NormalizedGeodeticPoint(gp.getLatitude(), gp.getLongitude(), gp.getAltitude(),
                                            centralLongitude);
diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8
index c65fd1b2371f9235c7f658925aa77bcfb9f6647e..ef8328b8a3441df5496ea0bf5376e99d77eb74e4 100644
--- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8
+++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8
@@ -72,3 +72,6 @@ TILE_ALREADY_DEFINED = <MISSING TRANSLATION>
 
 # unknown tile {0}, line {1}, file {2}: {3}
 UNKNOWN_TILE = <MISSING TRANSLATION>
+
+# sensor {0} already defined, line {1}, file {2}: {3}
+SENSOR_ALREADY_DEFINED = <MISSING TRANSLATION>
diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8
index c7925f9cb3a5f311cc0d62eccc3ea3922e00268d..6d0c8e35933336b295e97f8a361605117598af0a 100644
--- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8
+++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8
@@ -72,3 +72,6 @@ TILE_ALREADY_DEFINED = tile {0} already defined, line {1}, file {2}: {3}
 
 # unknown tile {0}, line {1}, file {2}: {3}
 UNKNOWN_TILE = unknown tile {0}, line {1}, file {2}: {3}
+
+# sensor {0} already defined, line {1}, file {2}: {3}
+SENSOR_ALREADY_DEFINED = sensor {0} already defined, line {1}, file {2}: {3}
diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8
index 44b538430d2af4605ef34c71863208528ac7bc29..0ee86683bea24520b2f7ad7846f90255c548fbb8 100644
--- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8
+++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8
@@ -72,3 +72,6 @@ TILE_ALREADY_DEFINED = <MISSING TRANSLATION>
 
 # unknown tile {0}, line {1}, file {2}: {3}
 UNKNOWN_TILE = <MISSING TRANSLATION>
+
+# sensor {0} already defined, line {1}, file {2}: {3}
+SENSOR_ALREADY_DEFINED = <MISSING TRANSLATION>
diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8
index f86ddc6403d497c790006d52cc005b87503fefce..a96ec9daccb97b8261beb2d8d323ba6cfbf4ecf3 100644
--- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8
+++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8
@@ -72,3 +72,6 @@ TILE_ALREADY_DEFINED = tuile {0} déjà définie ligne {1} du fichier {2}: {3}
 
 # unknown tile {0}, line {1}, file {2}: {3}
 UNKNOWN_TILE = tuile {0} inconnue ligne {1} du fichier {2}: {3}
+
+# sensor {0} already defined, line {1}, file {2}: {3}
+SENSOR_ALREADY_DEFINED = capteur {0} déjà défini ligne {1} du fichier {2}: {3}
diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8
index fc9f5b237c52cf30d3b7121dcb13cfae7625540e..8a18f04fffedcce9b6c9155d248075f574b915f9 100644
--- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8
+++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8
@@ -72,3 +72,6 @@ TILE_ALREADY_DEFINED = <MISSING TRANSLATION>
 
 # unknown tile {0}, line {1}, file {2}: {3}
 UNKNOWN_TILE = <MISSING TRANSLATION>
+
+# sensor {0} already defined, line {1}, file {2}: {3}
+SENSOR_ALREADY_DEFINED = <MISSING TRANSLATION>
diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8
index 73426284fe2a0f4ad101ef1247c77fa035da7993..7da881a06112197b10025aa6bf0a53690d49ae46 100644
--- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8
+++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8
@@ -72,3 +72,6 @@ TILE_ALREADY_DEFINED = <MISSING TRANSLATION>
 
 # unknown tile {0}, line {1}, file {2}: {3}
 UNKNOWN_TILE = <MISSING TRANSLATION>
+
+# sensor {0} already defined, line {1}, file {2}: {3}
+SENSOR_ALREADY_DEFINED = <MISSING TRANSLATION>
diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_no.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_no.utf8
index 90280718842ca66ec803b808c3786fa2b2293f4e..8a97c80f7faca1b079c1c6f411cf7036b28cb38c 100644
--- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_no.utf8
+++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_no.utf8
@@ -72,3 +72,6 @@ TILE_ALREADY_DEFINED = <MISSING TRANSLATION>
 
 # unknown tile {0}, line {1}, file {2}: {3}
 UNKNOWN_TILE = <MISSING TRANSLATION>
+
+# sensor {0} already defined, line {1}, file {2}: {3}
+SENSOR_ALREADY_DEFINED = <MISSING TRANSLATION>
diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8
index 900187a721af177d906e4c800cb9b2fa15a4ba76..0aaf852d29bf21161090cd2882904fae01119131 100644
--- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8
+++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8
@@ -72,3 +72,6 @@ TILE_ALREADY_DEFINED = <MISSING TRANSLATION>
 
 # unknown tile {0}, line {1}, file {2}: {3}
 UNKNOWN_TILE = <MISSING TRANSLATION>
+
+# sensor {0} already defined, line {1}, file {2}: {3}
+SENSOR_ALREADY_DEFINED = <MISSING TRANSLATION>
diff --git a/src/test/java/org/orekit/rugged/errors/DumpReplayerTest.java b/src/test/java/org/orekit/rugged/errors/DumpReplayerTest.java
index c628d18052a0a319967020f5076d0e2779c10f82..8a87d185682a0b152c5a27d3e818c9d3b2cc1f46 100644
--- a/src/test/java/org/orekit/rugged/errors/DumpReplayerTest.java
+++ b/src/test/java/org/orekit/rugged/errors/DumpReplayerTest.java
@@ -29,6 +29,7 @@ import org.orekit.data.DataProvidersManager;
 import org.orekit.data.DirectoryCrawler;
 import org.orekit.errors.OrekitException;
 import org.orekit.rugged.api.Rugged;
+import org.orekit.rugged.linesensor.SensorPixel;
 
 public class DumpReplayerTest {
 
@@ -55,4 +56,26 @@ public class DumpReplayerTest {
 
     }
 
+    @Test
+    public void testInverseLoc01() throws URISyntaxException, IOException, OrekitException, RuggedException {
+
+        String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
+        DataProvidersManager.getInstance().addProvider(new DirectoryCrawler(new File(orekitPath)));
+
+        String dumpPath = getClass().getClassLoader().getResource("replay/replay-inverse-loc-01.txt").toURI().getPath();
+        DumpReplayer replayer = new DumpReplayer();
+        replayer.parse(new File(dumpPath));
+        Rugged rugged = replayer.createRugged();
+        DumpReplayer.Result[] results = replayer.execute(rugged);
+
+        Assert.assertEquals(1, results.length);
+        for (final DumpReplayer.Result result : results) {
+            SensorPixel expectedSP = (SensorPixel) result.getExpected();
+            SensorPixel replayedSP = (SensorPixel) result.getReplayed();
+            Assert.assertEquals(expectedSP.getLineNumber(),  replayedSP.getLineNumber(),  1.0e-6);
+            Assert.assertEquals(expectedSP.getPixelNumber(), replayedSP.getPixelNumber(), 1.0e-6);
+        }
+
+    }
+
 }
diff --git a/src/test/java/org/orekit/rugged/errors/RuggedMessagesTest.java b/src/test/java/org/orekit/rugged/errors/RuggedMessagesTest.java
index fa07bcf5d9d120436e25b35bfa860c8844e95ad4..47291ceb469f427b48260d7d36230305b603bb25 100644
--- a/src/test/java/org/orekit/rugged/errors/RuggedMessagesTest.java
+++ b/src/test/java/org/orekit/rugged/errors/RuggedMessagesTest.java
@@ -30,7 +30,7 @@ public class RuggedMessagesTest {
 
     @Test
     public void testMessageNumber() {
-        Assert.assertEquals(25, RuggedMessages.values().length);
+        Assert.assertEquals(26, RuggedMessages.values().length);
     }
 
     @Test
diff --git a/src/test/resources/replay/replay-inverse-loc-01.txt b/src/test/resources/replay/replay-inverse-loc-01.txt
new file mode 100644
index 0000000000000000000000000000000000000000..51981332641f61410a42e4f3ab026925d2e2abb5
--- /dev/null
+++ b/src/test/resources/replay/replay-inverse-loc-01.txt
@@ -0,0 +1,37 @@
+# Rugged library dump file, created on 2015-02-24T16:50:12Z
+# all units are SI units (m, m/s, rad ...)
+DEM tile: t0 latMin -4.014257279586958e-01 latStep  6.817692390602850e-05 latRows 257 lonMin  2.495820830351891e+00 lonStep  6.817692390602850e-05 lonCols 257
+DEM cell: t0 latIndex 192 lonIndex 0 elevation -6.124011631478857e+02
+DEM cell: t0 latIndex 128 lonIndex 128 elevation  3.151327114467009e+03
+DEM cell: t0 latIndex 122 lonIndex 99 elevation  1.778606495649060e+03
+DEM cell: t0 latIndex 122 lonIndex 100 elevation  1.809481571226391e+03
+DEM cell: t0 latIndex 123 lonIndex 99 elevation  1.772149770526270e+03
+DEM cell: t0 latIndex 123 lonIndex 100 elevation  1.804520334312959e+03
+inverse location: sensorName line latitude -3.930524233859007e-01 longitude  2.502596047891660e+00 elevation  1.785429914217195e+03 minLine 0 maxLine 2000 lightTime true aberration true
+sensor: sensorName line nbPixels 2000 position  1.500000000000000e+00  0.000000000000000e+00 -2.000000000000000e-01
+sensor mean plane: sensorName line minLine 0 maxLine 2000 maxEval 50 accuracy  1.000000000000000e-02 normal  1.000000000000000e+00  0.000000000000000e+00  0.000000000000000e+00
+sensor date: sensorName line lineNumber  1.000000000000000e+03 => 2012-01-01T12:30:00.00000000000000Z
+span: minDate 2012-01-01T12:29:57.50000000000000Z maxDate 2012-01-01T12:30:02.50000000000000Z tStep  1.000000000000000e-03 tolerance  5.000000000000000e+00 inertialFrame EME2000
+transform: index 2500 body r -8.085963389171905e-01 -3.465415132416125e-04  4.896468952533137e-04 -5.883634938068593e-01 Ω -8.740475534355122e-08  1.215132763920864e-09 -7.292109805268457e-05 ΩDot -1.642299174832679e-16  8.973031065665686e-17  1.983408395824453e-19 spacecraft p  1.384770770635060e+04  3.157810312896036e+03 -7.179504513258174e+06 v -3.180198832979256e+01 -6.779040795561070e+00  8.276861119339028e+00 a -9.324121873999545e-01 -8.319728238691058e+00  1.345786832372742e-03 r -6.828948903548651e-01  4.142451171315383e-01 -3.878489660867486e-01  4.600312284675194e-01 Ω -1.009782076972198e-03  1.982726233227751e-04  1.647740165426390e-04 ΩDot -3.649972672343429e-07  2.007836645730816e-07 -1.257082123046451e-06
+ellipsoid: ae  6.378137000000000e+06 f  3.352810664747481e-03 frame ITRF_CIO_CONV_2010_SIMPLE_EOP
+sensor rate: sensorName line lineNumber 1000.0 =>  6.666666666666666e+02
+sensor date: sensorName line lineNumber  1.753125119831697e+03 => 2012-01-01T12:30:01.12968767974755Z
+transform: index 3630 body r -8.086205790715331e-01 -3.465213511527127e-04  4.896611176157392e-04 -5.883301787746077e-01 Ω -8.740475552913246e-08  1.215132865316382e-09 -7.292109805268537e-05 ΩDot -1.642303315278223e-16  8.973086775113133e-17  1.983413459365331e-19 spacecraft p  1.381161686138390e+04  3.149035127746873e+03 -7.179495156850004e+06 v -3.198309695268937e+01 -7.869713919215563e+00  8.283718407079078e+00 a -9.313885738644379e-01 -8.324782304826440e+00  1.354189237138481e-03 r -6.826577475060918e-01  4.145470548488056e-01 -3.882264160785311e-01  4.597927673908209e-01 Ω -1.009835304084986e-03  1.983572786405474e-04  1.645625945551068e-04 ΩDot -3.648903522451360e-07  2.009701619867746e-07 -1.257044812963575e-06
+sensor rate: sensorName line lineNumber 1753.125119831697 =>  6.666666666666666e+02
+sensor date: sensorName line lineNumber  1.753079999999987e+03 => 2012-01-01T12:30:01.12961999999998Z
+sensor rate: sensorName line lineNumber 1753.0799999999872 =>  6.666666666666666e+02
+sensor date: sensorName line lineNumber  1.753079999999987e+03 => 2012-01-01T12:30:01.12961999999998Z
+sensor LOS: sensorName line date 2012-01-01T12:30:01.12961999999998Z pixelNumber 999 =>  0.000000000000000e+00 -7.660363365669057e-01  6.427972705753770e-01
+sensor LOS: sensorName line date 2012-01-01T12:30:01.12961999999998Z pixelNumber 1000 =>  0.000000000000000e+00 -7.660525495492120e-01  6.427779486954669e-01
+sensor LOS: sensorName line date 2012-01-01T12:30:01.12961999999998Z pixelNumber 0 =>  0.000000000000000e+00 -7.495978631423039e-01  6.618935288794506e-01
+sensor LOS: sensorName line date 2012-01-01T12:30:01.12961999999998Z pixelNumber 1 =>  0.000000000000000e+00 -7.496145577932898e-01  6.618746216198131e-01
+sensor LOS: sensorName line date 2012-01-01T12:30:01.12961999999998Z pixelNumber 16 =>  0.000000000000000e+00 -7.498649203239307e-01  6.615909622021642e-01
+sensor LOS: sensorName line date 2012-01-01T12:30:01.12961999999998Z pixelNumber 17 =>  0.000000000000000e+00 -7.498816073432156e-01  6.615720482066600e-01
+sensor LOS: sensorName line date 2012-01-01T12:30:01.12961999999998Z pixelNumber 17 =>  0.000000000000000e+00 -7.498816073432156e-01  6.615720482066600e-01
+sensor LOS: sensorName line date 2012-01-01T12:30:01.12961999999998Z pixelNumber 18 =>  0.000000000000000e+00 -7.498982938854290e-01  6.615531337902669e-01
+sensor LOS: sensorName line date 2012-01-01T12:30:01.12961999999998Z pixelNumber 17 =>  0.000000000000000e+00 -7.498816073432156e-01  6.615720482066600e-01
+sensor LOS: sensorName line date 2012-01-01T12:30:01.12961999999998Z pixelNumber 18 =>  0.000000000000000e+00 -7.498982938854290e-01  6.615531337902669e-01
+sensor date: sensorName line lineNumber  1.753080000000047e+03 => 2012-01-01T12:30:01.12962000000007Z
+sensor LOS: sensorName line date 2012-01-01T12:30:01.12962000000007Z pixelNumber 17 =>  0.000000000000000e+00 -7.498816073432156e-01  6.615720482066600e-01
+sensor LOS: sensorName line date 2012-01-01T12:30:01.12962000000007Z pixelNumber 18 =>  0.000000000000000e+00 -7.498982938854290e-01  6.615531337902669e-01
+inverse location result: lineNumber  1.753080000000047e+03 pixelNumber  1.700000000063574e+01