diff --git a/src/main/java/org/orekit/rugged/api/Rugged.java b/src/main/java/org/orekit/rugged/api/Rugged.java index 3d20e823fdc2e33d244355e4aeb58d1ea6c37ea9..fe9b8dcfd57fe264dc31e1f77f1dc400fe58ce97 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 003018fe84f5ce138c6320e8138b9326648782e6..6484c24a11197458503f5d6902e1332899ef1005 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 b49e7a88d83afad29073a6e10c3b33bad639eb64..acb944807c4543d334dcef5c85d9c48cfe0b014d 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 6aaa151af1031582aa2a89c0101057c97a314c3d..6d0443b8d803cac288cc43d6ae6da4561e875fa2 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 e336fdf758dfeddebc19c1c4961a60d71c175aed..e657479f34b7395dac153d422e033f6ef1eb2356 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 bcdb4c9d6bd06d0d0b4d43f938ca1f1a011615b9..942fb759234fa6ef71a984b6a11e8c20bb236b2e 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 ef8328b8a3441df5496ea0bf5376e99d77eb74e4..c65fd1b2371f9235c7f658925aa77bcfb9f6647e 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 6d0c8e35933336b295e97f8a361605117598af0a..7d5f68fab8a4151c3b88367ce7b60d238eb458aa 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 0ee86683bea24520b2f7ad7846f90255c548fbb8..44b538430d2af4605ef34c71863208528ac7bc29 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 a96ec9daccb97b8261beb2d8d323ba6cfbf4ecf3..b3e5c040e8f8c48a3cb89439fb85ed967c40dd1f 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 8a18f04fffedcce9b6c9155d248075f574b915f9..b927d20a22e3eaaf5541199a0b1c9b75fd0e1d6e 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 7da881a06112197b10025aa6bf0a53690d49ae46..35ae33430a3d11cecff9c95c44374ae535c8c302 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 8a97c80f7faca1b079c1c6f411cf7036b28cb38c..90280718842ca66ec803b808c3786fa2b2293f4e 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 0aaf852d29bf21161090cd2882904fae01119131..900187a721af177d906e4c800cb9b2fa15a4ba76 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 47291ceb469f427b48260d7d36230305b603bb25..fa07bcf5d9d120436e25b35bfa860c8844e95ad4 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 0f0a3c0cefeb3ac24008c3365ec205833fc1a43e..5b89cdbbff214c2a1d2fd36ec685160dbd7c4ed1 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