X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=bundles%2Forg.simantics.history%2Fsrc%2Forg%2Fsimantics%2Fhistory%2Fcsv%2FCSVFormatter.java;h=b04e0dd37b37e34d0398855a451cd93cb534d6ff;hb=4a7923add5be874cc352faf9afd0f627794de32e;hp=6cc7a2a6f09a9bf50e1c7f27eeb74651180e1df2;hpb=1ecae6e1ad40507badb8807fb14bb67b4adf199c;p=simantics%2Fplatform.git
diff --git a/bundles/org.simantics.history/src/org/simantics/history/csv/CSVFormatter.java b/bundles/org.simantics.history/src/org/simantics/history/csv/CSVFormatter.java
index 6cc7a2a6f..b04e0dd37 100644
--- a/bundles/org.simantics.history/src/org/simantics/history/csv/CSVFormatter.java
+++ b/bundles/org.simantics.history/src/org/simantics/history/csv/CSVFormatter.java
@@ -38,6 +38,23 @@ import org.simantics.history.util.ValueBand;
*/
public class CSVFormatter {
+ /**
+ * This is the tolerance used to decide whether or not the last data point of
+ * the exported items is included in the exported material or not. If
+ * 0 <= (t - t(lastDataPoint) < {@value #RESAMPLING_END_TIMESTAMP_INCLUSION_TOLERANCE}
+ * is true, then the last exported data point will be
+ * lastDataPoint
, with timestamp t(lastDataPoint)
even
+ * if t > t(lastDataPoint)
.
+ *
+ *
+ * This works around problems where floating point inaccuracy causes a data
+ * point to be left out from the the export when it would be fair for the user
+ * to expect the data to be exported would contain a point with time stamp
+ * 9.999999999999996
when sampling with time-step 1.0
+ * starting from time 0.0
.
+ */
+ private static final double RESAMPLING_END_TIMESTAMP_INCLUSION_TOLERANCE = 1e-13;
+
List- items = new ArrayList
- ();
double from = -Double.MAX_VALUE;
double end = Double.MAX_VALUE;
@@ -329,6 +346,13 @@ public class CSVFormatter {
BigDecimal bigTime = new BigDecimal(String.valueOf(time));
BigDecimal bigTimeStep = new BigDecimal(String.valueOf(timeStep));
+ // Loop kill-switch for the case where timeStep > 0
+ boolean breakAfterNextWrite = false;
+
+// System.out.println("time: " + time);
+// System.out.println("timeStep: " + timeStep);
+// System.out.println("_end: " + Double.toString(_end));
+
for (Item i : items) i.iter.gotoTime(time);
do {
if ( monitor!=null && monitor.isCanceled() ) return;
@@ -394,10 +418,26 @@ public class CSVFormatter {
sb.append( lineFeed );
- // Read next values, and the following times
- if ( timeStep>0.0 ) {
- bigTime = bigTime.add(bigTimeStep);
- time = bigTime.doubleValue();
+ if (breakAfterNextWrite)
+ break;
+
+ // Read next values, and the following times
+ if ( timeStep>0.0 ) {
+ bigTime = bigTime.add(bigTimeStep);
+ time = bigTime.doubleValue();
+
+ // gitlab #529: prevent last data point from getting dropped
+ // due to small imprecisions in re-sampling mode.
+ double diff = time - _end;
+ if (diff > 0 && diff <= RESAMPLING_END_TIMESTAMP_INCLUSION_TOLERANCE) {
+ time = _end;
+ breakAfterNextWrite = true;
+ // Take floating point inaccuracy into account when re-sampling
+ // to prevent the last data point from being left out if there
+ // is small-enough imprecision in the last data point time stamp
+ // to be considered negligible compared to expected stepped time.
+ }
+
} else {
// Get smallest end time that is larger than current time
Double nextTime = null;
@@ -420,6 +460,7 @@ public class CSVFormatter {
if(contains(i, time)) hasMore = true;
}
+ //System.out.println("hasMore @ " + time + " (" + bigTime + ") = " + hasMore);
if(!hasMore) break;
} while (time<=_end);