From a3ea007a9a8c9f07b13b54e7516f750b76a2b8cd Mon Sep 17 00:00:00 2001 From: Luc Maisonobe <luc@orekit.org> Date: Wed, 25 Feb 2015 15:33:08 +0100 Subject: [PATCH] Improved inverse loc dump. We should now avoid dumping the same data several time (in sensors LOS, datation and rate), and we use linear interpolation on replay between the dumped LOS, datation and rates. --- .../java/org/orekit/rugged/api/Rugged.java | 5 +- .../java/org/orekit/rugged/errors/Dump.java | 242 +++++++++++----- .../org/orekit/rugged/errors/DumpManager.java | 50 +--- .../orekit/rugged/errors/DumpReplayer.java | 274 +++++++++++------- .../orekit/rugged/errors/RuggedMessages.java | 3 +- .../orekit/rugged/linesensor/LineSensor.java | 8 +- .../org/orekit/rugged/RuggedMessages_de.utf8 | 3 - .../org/orekit/rugged/RuggedMessages_en.utf8 | 2 - .../org/orekit/rugged/RuggedMessages_es.utf8 | 3 - .../org/orekit/rugged/RuggedMessages_fr.utf8 | 2 - .../org/orekit/rugged/RuggedMessages_gl.utf8 | 2 - .../org/orekit/rugged/RuggedMessages_it.utf8 | 2 - .../org/orekit/rugged/RuggedMessages_no.utf8 | 3 - .../org/orekit/rugged/RuggedMessages_ro.utf8 | 3 - .../rugged/errors/RuggedMessagesTest.java | 2 +- .../replay/replay-inverse-loc-01.txt | 42 ++- 16 files changed, 377 insertions(+), 269 deletions(-) diff --git a/src/main/java/org/orekit/rugged/api/Rugged.java b/src/main/java/org/orekit/rugged/api/Rugged.java index 3d20e823..fe9b8dcf 100644 --- a/src/main/java/org/orekit/rugged/api/Rugged.java +++ b/src/main/java/org/orekit/rugged/api/Rugged.java @@ -435,13 +435,12 @@ public class Rugged { final int minLine, final int maxLine) throws RuggedException { - DumpManager.dumpInverseLocation(sensorName, point, minLine, maxLine, + final LineSensor sensor = getLineSensor(sensorName); + DumpManager.dumpInverseLocation(sensor, point, minLine, maxLine, lightTimeCorrection, aberrationOfLightCorrection); - 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 diff --git a/src/main/java/org/orekit/rugged/errors/Dump.java b/src/main/java/org/orekit/rugged/errors/Dump.java index 003018fe..6484c24a 100644 --- a/src/main/java/org/orekit/rugged/errors/Dump.java +++ b/src/main/java/org/orekit/rugged/errors/Dump.java @@ -19,14 +19,17 @@ package org.orekit.rugged.errors; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Calendar; +import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.TimeZone; 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.errors.OrekitException; import org.orekit.frames.FactoryManagedFrame; @@ -56,10 +59,7 @@ class Dump { private final List<DumpedTileData> tiles; /** Already dumped sensors. */ - private final List<String> sensors; - - /** Already dumped sensors mean planes. */ - private final List<String> meanPlanes; + private final List<DumpedSensorData> sensors; /** Flag for dumped algorithm. */ private boolean algorithmDumped; @@ -76,8 +76,7 @@ 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.sensors = new ArrayList<DumpedSensorData>(); this.algorithmDumped = false; this.ellipsoidDumped = false; this.tranformsDumped = null; @@ -177,19 +176,20 @@ class Dump { } /** Dump an inverse location computation. - * @param sensorName name of the line sensor + * @param sensor 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, + public void dumpInverseLocation(final LineSensor sensor, final GeodeticPoint point, final int minLine, final int maxLine, final boolean lightTimeCorrection, final boolean aberrationOfLightCorrection) { + DumpedSensorData ds = getSensorData(sensor); 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, + ds.getDumpName(), point.getLatitude(), point.getLongitude(), point.getAltitude(), minLine, maxLine, lightTimeCorrection, aberrationOfLightCorrection); @@ -239,92 +239,45 @@ 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()); - - } + getSensorData(meanPlane.getSensor()).setMeanPlane(meanPlane); } /** Dump a sensor LOS. - * @param name sensor name + * @param sensor sensor * @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) + public void dumpSensorLOS(final LineSensor sensor, 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()); + getSensorData(sensor).setLOS(date, i, los); } - /** Dump a sensor date. - * @param name sensor name + /** Dump a sensor datation. + * @param sensor sensor * @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) + public void dumpSensorDatation(final LineSensor sensor, 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); + getSensorData(sensor).setDatation(lineNumber, date); } /** Dump a sensor rate. - * @param name sensor name + * @param sensor sensor * @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); + public void dumpSensorRate(final LineSensor sensor, final double lineNumber, final double rate) { + getSensorData(sensor).setRate(lineNumber, rate); } /** Get a frame key or name. @@ -367,6 +320,25 @@ class Dump { } + /** Get sensor data. + * @param sensor sensor + */ + private DumpedSensorData getSensorData(final LineSensor sensor) { + + for (final DumpedSensorData dumpedSensorData : sensors) { + if (sensor == dumpedSensorData.getSensor()) { + // the sensor is already known + return dumpedSensorData; + } + } + + // it is the first time we encounter this sensor, we need to dump its data + final DumpedSensorData dumpedSensorData = new DumpedSensorData("s" + sensors.size(), sensor); + sensors.add(dumpedSensorData); + return dumpedSensorData; + + } + /** Convert a date to string with high accuracy. * @param date computation date * @return converted date @@ -470,4 +442,140 @@ class Dump { } + /** Local class for handling already dumped sensor data. */ + private class DumpedSensorData { + + /** Name of the dump. */ + private final String dumpName; + + /** Dumped sensor sensor. */ + private final LineSensor sensor; + + /** 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; + + /** Mean plane finder. */ + private SensorMeanPlaneCrossing meanPlane; + + /** Simple constructor. + * @param dumpName name of the sensor dump (not the name of the sensor itself, for confidentiality reasons) + * @param sensor dumped sensor + */ + public DumpedSensorData(final String dumpName, final LineSensor sensor) { + this.dumpName = dumpName; + this.sensor = sensor; + this.losMap = new HashMap<Integer, List<Pair<AbsoluteDate, Vector3D>>>(); + this.datation = new ArrayList<Pair<Double, AbsoluteDate>>(); + this.rates = new ArrayList<Pair<Double, Double>>(); + writer.format(Locale.US, + "sensor: sensorName %s nbPixels %d position %22.15e %22.15e %22.15e%n", + dumpName, sensor.getNbPixels(), + sensor.getPosition().getX(), sensor.getPosition().getY(), sensor.getPosition().getZ()); + } + + /** Get the anonymized dump sensor name. + * @return dump sensorname + */ + public String getDumpName() { + return dumpName; + } + + /** Get dumped sensor. + * @return dumped sensor + */ + public LineSensor getSensor() { + return sensor; + } + + /** Set the mean plane finder. + * @param meanPlane mean plane finder + * @exception RuggedException if frames cannot be computed at mid date + */ + public void setMeanPlane(final SensorMeanPlaneCrossing meanPlane) throws RuggedException { + if (this.meanPlane == null) { + this.meanPlane = meanPlane; + 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", + dumpName, + 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); + + } + } + + /** Set a los direction. + * @param date date + * @param pixelNumber number of the pixel + * @param los los direction + * @exception RuggedException if date cannot be converted to UTC + */ + public void setLOS(final AbsoluteDate date, final int pixelNumber, final Vector3D los) + throws RuggedException { + List<Pair<AbsoluteDate, Vector3D>> list = losMap.get(pixelNumber); + if (list == null) { + list = new ArrayList<Pair<AbsoluteDate, Vector3D>>(); + losMap.put(pixelNumber, list); + } + for (final Pair<AbsoluteDate, Vector3D> alreadyDumped : list) { + if (FastMath.abs(date.durationFrom(alreadyDumped.getFirst())) < 1.0e-12 && + Vector3D.angle(los, alreadyDumped.getSecond()) < 1.0e-12) { + return; + } + } + list.add(new Pair<AbsoluteDate, Vector3D>(date, los)); + writer.format(Locale.US, + "sensor LOS: sensorName %s date %s pixelNumber %d los %22.15e %22.15e %22.15e%n", + dumpName, convertDate(date), pixelNumber, los.getX(), los.getY(), los.getZ()); + } + + /** Set a datation pair. + * @param lineNumber line number + * @param date date + * @exception RuggedException if date cannot be converted to UTC + */ + public void setDatation(final double lineNumber, final AbsoluteDate date) + throws RuggedException { + for (final Pair<Double, AbsoluteDate> alreadyDumped : datation) { + if (FastMath.abs(date.durationFrom(alreadyDumped.getSecond())) < 1.0e-12 && + FastMath.abs(lineNumber - alreadyDumped.getFirst()) < 1.0e-12) { + return; + } + } + datation.add(new Pair<Double, AbsoluteDate>(lineNumber, date)); + writer.format(Locale.US, + "sensor datation: sensorName %s lineNumber %22.15e date %s%n", + dumpName, lineNumber, convertDate(date)); + } + + /** Set a rate. + * @param lineNumber line number + * @param rate lines rate + */ + public void setRate(final double lineNumber, final double rate) { + for (final Pair<Double, Double> alreadyDumped : rates) { + if (FastMath.abs(rate - alreadyDumped.getSecond()) < 1.0e-12 && + FastMath.abs(lineNumber - alreadyDumped.getFirst()) < 1.0e-12) { + return; + } + } + rates.add(new Pair<Double, Double>(lineNumber, rate)); + writer.format(Locale.US, + "sensor rate: sensorName %s lineNumber %22.15e rate %22.15e%n", + dumpName, lineNumber, rate); + } + + } + } diff --git a/src/main/java/org/orekit/rugged/errors/DumpManager.java b/src/main/java/org/orekit/rugged/errors/DumpManager.java index b49e7a88..acb94480 100644 --- a/src/main/java/org/orekit/rugged/errors/DumpManager.java +++ b/src/main/java/org/orekit/rugged/errors/DumpManager.java @@ -161,19 +161,19 @@ public class DumpManager { } /** Dump an inverse location computation. - * @param sensorName name of the line sensor + * @param sensor 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, + public static void dumpInverseLocation(final LineSensor sensor, 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.get().dumpInverseLocation(sensor, point, minLine, maxLine, + lightTimeCorrection, aberrationOfLightCorrection); } } @@ -201,15 +201,6 @@ 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 @@ -222,53 +213,40 @@ public class DumpManager { } /** Dump a sensor LOS. - * @param name sensor name + * @param sensor sensor * @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) + public static void dumpSensorLOS(final LineSensor sensor, final AbsoluteDate date, final int i, final Vector3D los) throws RuggedException { if (isActive()) { - DUMP.get().dumpSensorLOS(name, date, i, los); + DUMP.get().dumpSensorLOS(sensor, date, i, los); } } - /** Dump a sensor date. - * @param name sensor name + /** Dump a sensor datation. + * @param sensor sensor * @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) + public static void dumpSensorDatation(final LineSensor sensor, final double lineNumber, final AbsoluteDate date) throws RuggedException { if (isActive()) { - DUMP.get().dumpSensorLine(name, date, lineNumber); + DUMP.get().dumpSensorDatation(sensor, lineNumber, date); } } /** Dump a sensor rate. - * @param name sensor name + * @param sensor sensor * @param lineNumber line number * @param rate lines rate */ - public static void dumpSensorRate(final String name, final double lineNumber, final double rate) { + public static void dumpSensorRate(final LineSensor sensor, final double lineNumber, final double rate) { if (isActive()) { - DUMP.get().dumpSensorRate(name, lineNumber, rate); + DUMP.get().dumpSensorRate(sensor, 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 6aaa151a..6d0443b8 100644 --- a/src/main/java/org/orekit/rugged/errors/DumpReplayer.java +++ b/src/main/java/org/orekit/rugged/errors/DumpReplayer.java @@ -198,8 +198,8 @@ public class DumpReplayer { /** Keyword for normal. */ private static final String NORMAL = "normal"; - /** Keyword for return arrow. */ - private static final String RETURN_ARROW = "=>"; + /** Keyword for rate. */ + private static final String RATE = "rate"; /** Constant elevation for constant elevation algorithm. */ private double constantElevation; @@ -398,6 +398,21 @@ public class DumpReplayer { } + /** Get a sensor by name. + * @param name sensor name + * @return parsed sensor + */ + private ParsedSensor getSensor(final String name) { + for (final ParsedSensor sensor : sensors) { + if (sensor.name.equals(name)) { + return sensor; + } + } + ParsedSensor sensor = new ParsedSensor(name); + sensors.add(sensor); + return sensor; + } + /** Execute all dumped calls. * <p> * The dumped calls correspond to computation methods like direct or inverse @@ -798,18 +813,11 @@ public class DumpReplayer { !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)); + final ParsedSensor sensor = global.getSensor(fields[1]); + sensor.setNbPixels(Integer.parseInt(fields[3])); + sensor.setPosition(new Vector3D(Double.parseDouble(fields[5]), + Double.parseDouble(fields[6]), + Double.parseDouble(fields[7]))); } }, @@ -835,14 +843,7 @@ public class DumpReplayer { 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); + global.getSensor(sensorName).setMeanPlane(new ParsedMeanPlane(minLine, maxLine, maxEval, accuracy, normal)); } @@ -858,7 +859,7 @@ public class DumpReplayer { try { if (fields.length < 10 || !fields[0].equals(SENSOR_NAME) || !fields[2].equals(DATE) || !fields[4].equals(PIXEL_NUMBER) || - !fields[6].equals(RETURN_ARROW)) { + !fields[6].equals(LOS)) { throw new RuggedException(RuggedMessages.CANNOT_PARSE_LINE, l, file, line); } final String sensorName = fields[1]; @@ -867,14 +868,8 @@ public class DumpReplayer { 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; - } - } + global.getSensor(sensorName).setLOS(date, pixelNumber, los); - throw new RuggedException(RuggedMessages.UNKNOWN_SENSOR, sensorName); } catch (OrekitException oe) { throw new RuggedException(oe, oe.getSpecifier(), oe.getParts()); } @@ -882,8 +877,8 @@ public class DumpReplayer { }, - /** Parser for sensor date dump lines. */ - SENSOR_DATE() { + /** Parser for sensor datation dump lines. */ + SENSOR_DATATION() { /** {@inheritDoc} */ @Override @@ -891,51 +886,14 @@ public class DumpReplayer { throws RuggedException { try { if (fields.length < 5 || !fields[0].equals(SENSOR_NAME) || - !fields[2].equals(LINE_NUMBER) || !fields[4].equals(RETURN_ARROW)) { + !fields[2].equals(LINE_NUMBER) || !fields[4].equals(DATE)) { 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()); - } - - } - - }, + global.getSensor(sensorName).setDatation(lineNumber, date); - /** 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()); } @@ -952,20 +910,13 @@ public class DumpReplayer { 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)) { + !fields[2].equals(LINE_NUMBER) || !fields[4].equals(RATE)) { 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); + global.getSensor(sensorName).setRate(lineNumber, rate); } @@ -1107,10 +1058,10 @@ public class DumpReplayer { private final String name; /** Number of pixels. */ - private final int nbPixels; + private int nbPixels; /** Position. */ - private final Vector3D position; + private Vector3D position; /** Mean plane crossing finder. */ private ParsedMeanPlane meanPlane; @@ -1129,10 +1080,8 @@ public class DumpReplayer { * @param nbPixels number of pixels * @param position position */ - public ParsedSensor(final String name, final int nbPixels, final Vector3D position) { + public ParsedSensor(final String name) { 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>>(); @@ -1156,6 +1105,27 @@ public class DumpReplayer { throws RuggedException { } + /** Set the mean place finder. + * @param meanPlane mean plane finder + */ + public void setMeanPlane(final ParsedMeanPlane meanPlane) { + this.meanPlane = meanPlane; + } + + /** Set the position. + * @param position position + */ + public void setPosition(final Vector3D position) { + this.position = position; + } + + /** Set the number of pixels. + * @param nbPixels number of pixels + */ + public void setNbPixels(final int nbPixels) { + this.nbPixels = nbPixels; + } + /** {@inheritDoc} */ @Override public int getNbPixels() { @@ -1173,7 +1143,15 @@ public class DumpReplayer { list = new ArrayList<Pair<AbsoluteDate, Vector3D>>(); losMap.put(pixelNumber, list); } - list.add(new Pair<AbsoluteDate, Vector3D>(date, los)); + // find insertion index to have LOS sorted chronologically + int index = 0; + while (index < list.size()) { + if (list.get(index).getFirst().compareTo(date) > 0) { + break; + } + ++index; + } + list.add(index, new Pair<AbsoluteDate, Vector3D>(date, los)); } /** {@inheritDoc} */ @@ -1183,14 +1161,28 @@ public class DumpReplayer { 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; + + if (list.size() < 2) { + return list.get(0).getSecond(); + } + + // find entries bracketing the the date + int sup = 0; + while (sup < list.size() - 1) { + if (list.get(sup).getFirst().compareTo(date) >= 0) { + break; } + ++sup; } - return list.get(selected).getSecond(); + final int inf = (sup == 0) ? sup++ : (sup - 1); + + final AbsoluteDate dInf = list.get(inf).getFirst(); + final Vector3D lInf = list.get(inf).getSecond(); + final AbsoluteDate dSup = list.get(sup).getFirst(); + final Vector3D lSup = list.get(sup).getSecond(); + final double alpha = date.durationFrom(dInf) / dSup.durationFrom(dInf); + return new Vector3D(alpha, lSup, 1 - alpha, lInf); + } /** {@inheritDoc} */ @@ -1207,33 +1199,69 @@ public class DumpReplayer { * @param date date */ public void setDatation(final double lineNumber, final AbsoluteDate date) { - datation.add(new Pair<Double, AbsoluteDate>(lineNumber, date)); + // find insertion index to have datations sorted chronologically + int index = 0; + while (index < datation.size()) { + if (datation.get(index).getSecond().compareTo(date) > 0) { + break; + } + ++index; + } + datation.add(index, 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; + + if (datation.size() < 2) { + return datation.get(0).getSecond(); + } + + // find entries bracketing the line number + int sup = 0; + while (sup < datation.size() - 1) { + if (datation.get(sup).getFirst() >= lineNumber) { + break; } + ++sup; } - return datation.get(selected).getSecond(); + final int inf = (sup == 0) ? sup++ : (sup - 1); + + final double lInf = datation.get(inf).getFirst(); + final AbsoluteDate dInf = datation.get(inf).getSecond(); + final double lSup = datation.get(sup).getFirst(); + final AbsoluteDate dSup = datation.get(sup).getSecond(); + final double alpha = (lineNumber - lInf) / (lSup - lInf); + return dInf.shiftedBy(alpha * dSup.durationFrom(dInf)); + } /** {@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; + + if (datation.size() < 2) { + return datation.get(0).getFirst(); + } + + // find entries bracketing the date + int sup = 0; + while (sup < datation.size() - 1) { + if (datation.get(sup).getSecond().compareTo(date) >= 0) { + break; } + ++sup; } - return datation.get(selected).getFirst(); + final int inf = (sup == 0) ? sup++ : (sup - 1); + + final double lInf = datation.get(inf).getFirst(); + final AbsoluteDate dInf = datation.get(inf).getSecond(); + final double lSup = datation.get(sup).getFirst(); + final AbsoluteDate dSup = datation.get(sup).getSecond(); + final double alpha = date.durationFrom(dInf) / dSup.durationFrom(dInf); + return alpha * lSup + (1 - alpha) * lInf; + } /** Set a rate. @@ -1241,20 +1269,42 @@ public class DumpReplayer { * @param rate lines rate */ public void setRate(final double lineNumber, final double rate) { - rates.add(new Pair<Double, Double>(lineNumber, rate)); + // find insertion index to have rates sorted by line numbers + int index = 0; + while (index < rates.size()) { + if (rates.get(index).getFirst() > lineNumber) { + break; + } + ++index; + } + rates.add(index, 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; + + if (rates.size() < 2) { + return rates.get(0).getSecond(); + } + + // find entries bracketing the line number + int sup = 0; + while (sup < rates.size() - 1) { + if (rates.get(sup).getFirst() >= lineNumber) { + break; } + ++sup; } - return rates.get(selected).getSecond(); + final int inf = (sup == 0) ? sup++ : (sup - 1); + + final double lInf = rates.get(inf).getFirst(); + final double rInf = rates.get(inf).getSecond(); + final double lSup = rates.get(sup).getFirst(); + final double rSup = rates.get(sup).getSecond(); + final double alpha = (lineNumber - lInf) / (lSup - lInf); + return alpha * rSup + (1 - alpha) * rInf; + } } diff --git a/src/main/java/org/orekit/rugged/errors/RuggedMessages.java b/src/main/java/org/orekit/rugged/errors/RuggedMessages.java index e336fdf7..e657479f 100644 --- a/src/main/java/org/orekit/rugged/errors/RuggedMessages.java +++ b/src/main/java/org/orekit/rugged/errors/RuggedMessages.java @@ -74,8 +74,7 @@ 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}"), - SENSOR_ALREADY_DEFINED("sensor {0} already defined, line {1}, file {2}: {3}"); + UNKNOWN_TILE("unknown tile {0}, 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 bcdb4c9d..942fb759 100644 --- a/src/main/java/org/orekit/rugged/linesensor/LineSensor.java +++ b/src/main/java/org/orekit/rugged/linesensor/LineSensor.java @@ -79,7 +79,7 @@ public class LineSensor { public Vector3D getLos(final AbsoluteDate date, final int i) throws RuggedException { final Vector3D l = los.getLOS(i, date); - DumpManager.dumpSensorLOS(name, date, i, l); + DumpManager.dumpSensorLOS(this, date, i, l); return l; } @@ -91,7 +91,7 @@ public class LineSensor { public AbsoluteDate getDate(final double lineNumber) throws RuggedException { final AbsoluteDate date = datationModel.getDate(lineNumber); - DumpManager.dumpSensorDate(name, lineNumber, date); + DumpManager.dumpSensorDatation(this, lineNumber, date); return date; } @@ -103,7 +103,7 @@ public class LineSensor { public double getLine(final AbsoluteDate date) throws RuggedException { final double lineNumber = datationModel.getLine(date); - DumpManager.dumpSensorLine(name, date, lineNumber); + DumpManager.dumpSensorDatation(this, lineNumber, date); return lineNumber; } @@ -113,7 +113,7 @@ public class LineSensor { */ public double getRate(final double lineNumber) { final double rate = datationModel.getRate(lineNumber); - DumpManager.dumpSensorRate(name, lineNumber, rate); + DumpManager.dumpSensorRate(this, lineNumber, rate); return rate; } 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 ef8328b8..c65fd1b2 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8 @@ -72,6 +72,3 @@ 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 6d0c8e35..7d5f68fa 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8 @@ -73,5 +73,3 @@ 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 0ee86683..44b53843 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8 @@ -72,6 +72,3 @@ 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 a96ec9da..b3e5c040 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8 @@ -73,5 +73,3 @@ 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 8a18f04f..b927d20a 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8 @@ -73,5 +73,3 @@ 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 7da881a0..35ae3343 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8 @@ -73,5 +73,3 @@ 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 8a97c80f..90280718 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_no.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_no.utf8 @@ -72,6 +72,3 @@ 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 0aaf852d..900187a7 100644 --- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8 +++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8 @@ -72,6 +72,3 @@ 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/RuggedMessagesTest.java b/src/test/java/org/orekit/rugged/errors/RuggedMessagesTest.java index 47291ceb..fa07bcf5 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(26, RuggedMessages.values().length); + Assert.assertEquals(25, 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 index 0f0a3c0c..5b89cdbb 100644 --- a/src/test/resources/replay/replay-inverse-loc-01.txt +++ b/src/test/resources/replay/replay-inverse-loc-01.txt @@ -1,4 +1,4 @@ -# Rugged library dump file, created on 2015-02-25T08:35:47Z +# Rugged library dump file, created on 2015-02-25T14:11:26Z # all units are SI units (m, m/s, rad ...) algorithm: DUVENHAGE DEM tile: t0 latMin -4.014257279586958e-01 latStep 6.817692390602850e-05 latRows 257 lonMin 2.495820830351891e+00 lonStep 6.817692390602850e-05 lonCols 257 @@ -8,31 +8,25 @@ 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 +inverse location: sensorName s0 latitude -3.930524233859007e-01 longitude 2.502596047891660e+00 elevation 1.785429914217195e+03 minLine 0 maxLine 2000 lightTime true aberration true +sensor: sensorName s0 nbPixels 2000 position 1.500000000000000e+00 0.000000000000000e+00 -2.000000000000000e-01 +sensor mean plane: sensorName s0 minLine 0 maxLine 2000 maxEval 50 accuracy 1.000000000000000e-02 normal 1.000000000000000e+00 0.000000000000000e+00 0.000000000000000e+00 +sensor datation: sensorName s0 lineNumber 1.000000000000000e+03 date 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.465415132416124e-04 4.896468952533136e-04 -5.883634938068593e-01 Ω -8.740475534355121e-08 1.215132763920863e-09 -7.292109805268457e-05 ΩDot -1.642299174832473e-16 8.973031065833714e-17 1.983408395826415e-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 +sensor rate: sensorName s0 lineNumber 1.000000000000000e+03 rate 6.666666666666666e+02 +sensor datation: sensorName s0 lineNumber 1.753125119831697e+03 date 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.215132865316375e-09 -7.292109805268537e-05 ΩDot -1.642303315278493e-16 8.973086775115428e-17 1.983413459366029e-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 +sensor rate: sensorName s0 lineNumber 1.753125119831697e+03 rate 6.666666666666666e+02 +sensor datation: sensorName s0 lineNumber 1.753079999999987e+03 date 2012-01-01T12:30:01.12961999999998Z +sensor rate: sensorName s0 lineNumber 1.753079999999987e+03 rate 6.666666666666666e+02 +sensor LOS: sensorName s0 date 2012-01-01T12:30:01.12961999999998Z pixelNumber 999 los 0.000000000000000e+00 -7.660363365669057e-01 6.427972705753770e-01 +sensor LOS: sensorName s0 date 2012-01-01T12:30:01.12961999999998Z pixelNumber 1000 los 0.000000000000000e+00 -7.660525495492120e-01 6.427779486954669e-01 +sensor LOS: sensorName s0 date 2012-01-01T12:30:01.12961999999998Z pixelNumber 0 los 0.000000000000000e+00 -7.495978631423039e-01 6.618935288794506e-01 +sensor LOS: sensorName s0 date 2012-01-01T12:30:01.12961999999998Z pixelNumber 1 los 0.000000000000000e+00 -7.496145577932898e-01 6.618746216198131e-01 +sensor LOS: sensorName s0 date 2012-01-01T12:30:01.12961999999998Z pixelNumber 16 los 0.000000000000000e+00 -7.498649203239307e-01 6.615909622021642e-01 +sensor LOS: sensorName s0 date 2012-01-01T12:30:01.12961999999998Z pixelNumber 17 los 0.000000000000000e+00 -7.498816073432156e-01 6.615720482066600e-01 +sensor LOS: sensorName s0 date 2012-01-01T12:30:01.12961999999998Z pixelNumber 18 los 0.000000000000000e+00 -7.498982938854290e-01 6.615531337902669e-01 +sensor datation: sensorName s0 lineNumber 1.753080000000047e+03 date 2012-01-01T12:30:01.12962000000007Z inverse location result: lineNumber 1.753080000000047e+03 pixelNumber 1.700000000063574e+01 -- GitLab