X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.history%2Fsrc%2Forg%2Fsimantics%2Fhistory%2FHistorySampler.java;h=1c45a220fcf005ac80bf0e2b92f9c988127987fc;hb=fbe4ffbf25e0b35dcbd51f11b50e740bfe4c593d;hp=7d3440192b238709e0d80c7b2feafdfd75aefb64;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.history/src/org/simantics/history/HistorySampler.java b/bundles/org.simantics.history/src/org/simantics/history/HistorySampler.java index 7d3440192..1c45a220f 100644 --- a/bundles/org.simantics.history/src/org/simantics/history/HistorySampler.java +++ b/bundles/org.simantics.history/src/org/simantics/history/HistorySampler.java @@ -1,221 +1,230 @@ -package org.simantics.history; - -import gnu.trove.list.array.TDoubleArrayList; - -import java.io.IOException; -import java.math.BigDecimal; - -import org.simantics.history.csv.ExportInterpolation; -import org.simantics.history.util.HistoryExportUtil; -import org.simantics.history.util.StreamIterator; -import org.simantics.history.util.ValueBand; - -public class HistorySampler { - - public synchronized static TDoubleArrayList sample( HistorySamplerItem item, double from, double end, double timeWindow, double timeStep, boolean resample ) throws HistoryException, IOException { - - try { - item.open(); - if(item.collector != null) - item.collector.flush(); - return sample(item.iter, from, end, timeWindow, timeStep, resample); - } finally { - item.close(); - } - } - - public static TDoubleArrayList sample( StreamIterator iter, double from, double end, double timeWindow, double timeStep, boolean resample ) throws HistoryException, IOException { - - ExportInterpolation numberInterpolation = ExportInterpolation.LINEAR_INTERPOLATION; - - double startTime = 0.0; - - TDoubleArrayList result = new TDoubleArrayList(); - - if(iter.isEmpty()) return result; - - double allFrom = iter.getFirstTime(); - double allEnd = 10e10;//iter.getLastTime(); - - if(from > (allEnd + timeStep)) { - from = allEnd-timeWindow; - end = allEnd; - } - -// System.err.println("sample " + from + " " + end); -// if(from < 0) -// System.err.println("fgag"); - - // Prepare time - boolean hasAnyValues = allFrom != Double.MAX_VALUE && allEnd != -Double.MAX_VALUE; - - // Make intersection of actual data range (allFrom, allEnd) and requested data (from, end) - double _from = Double.MAX_VALUE, _end = -Double.MAX_VALUE; - if (hasAnyValues) { - _from = Math.max(allFrom, from); - _end = Math.min(allEnd, end); - } - - if (!hasAnyValues) { -// System.err.println("=> no values"); - return result; - } - - // Iterate until endTime is met for all variables - double time = _from; - - if(!resample) { - - // If resample is false then all samples are reported as is. The code achieves this by setting startTime to _from and timeStep to 0.0 - time = _from; - timeStep = 0.0; - - } else { - - // time = startTime + n*timeStep - - // Sampling based on given startTime and timeStep - if(timeStep > 0) { - - // Find the first sample time that contains data - double n = Math.max(0, Math.ceil((_from-startTime) / timeStep)); - time = startTime + n*timeStep; - - } else { - - // Start sampling from startTime but make sure that it is not less than _from - if(startTime > _from) time = startTime; - - } - - - } - - // Must convert double times to String when initializing BigDecimal. - // Otherwise BigDecimal will pick up inaccuracies from beyond 15 precise digits - // thus making a mess of the time step calculations. - - BigDecimal bigTime = new BigDecimal(String.valueOf(time)); - BigDecimal bigTimeStep = new BigDecimal(String.valueOf(timeStep)); - - //System.err.println("=> goto " + time); - - if(!iter.gotoTime(time)) { - //System.err.println("=> no sample found at " + time); - return result; - } - - //time = iter.getValueBand().getTimeDouble(); - - boolean ignore = Math.abs(time-from) < 1e-6; - - do { - - //System.err.println("process " + time + " " + iter.getValueBand()); - - - - // Check for valid value - if ( iter.hasValidValue() ) { - - // Write time - if(!ignore) { -// System.err.println("Add time : " + time); - result.add(time); - } - // Write value - Object value = iter.getValueBand().getValue(); - //System.err.print("Add value : " + value); - if (value instanceof Number) { - if (value instanceof Float || value instanceof Double) { - switch (numberInterpolation) { - case PREVIOUS_SAMPLE: - - if(!ignore) { -// System.err.println(" previous .. done!"); - result.add(((Number) value).doubleValue()); - } - - break; - - case LINEAR_INTERPOLATION: - if (time != iter.getValueBand().getTimeDouble() && iter.hasNext()) { - - // Interpolate - int currentIndex = iter.getIndex(); - ValueBand band = iter.getValueBand(); - //double t1 = band.getTimeDouble(); - Number v1 = (Number) value; - double t12 = band.getEndTimeDouble(); - iter.next(); - double t2 = iter.getValueBand().getTimeDouble(); - Number v2 = (Number) iter.getValueBand().getValue(); - iter.gotoIndex(currentIndex); - - double vs = v1.doubleValue(); - if(time > t12) - vs = HistoryExportUtil.biglerp(t12, v1.doubleValue(), t2, v2.doubleValue(), time); - - if(!ignore) { -// System.err.println(" linear .. done!"); - result.add(vs); - } - - } else { - // Exact timestamp match, or last sample. - // Don't interpolate nor extrapolate. - if(!ignore) { -// System.err.println(" else .. done!"); - result.add(((Number) value).doubleValue()); - } - } - break; - default: - throw new UnsupportedOperationException("Unsupported interpolation: " + numberInterpolation); - } - } else { - throw new IllegalStateException("Value is not a number " + value); - } - } else if (value instanceof Boolean) { - if(!ignore) - result.add( (Boolean)value ? 1.0: 0.0); - } else { - throw new IllegalStateException("Value is not a number " + value); - } - } - - ignore = false; - - // Read next values, and the following times - if ( timeStep>0.0 ) { - bigTime = bigTime.add(bigTimeStep); - time = bigTime.doubleValue(); - } else { - // Get smallest end time that is larger than current time - Double nextTime = null; - // System.out.println("time = "+time); - if(!iter.hasNext()) break; - Double itemNextTime = iter.getNextTime( time ); - // System.err.println(" "+i.label+" nextTime="+itemNextTime); - if ( nextTime == null || ( nextTime > itemNextTime && !itemNextTime.equals( time ) ) ) nextTime = itemNextTime; - if ( nextTime == null || nextTime.equals( time ) ) break; - time = nextTime; - } - - boolean hasMore = false; - - iter.proceedToTime(time); - if(HistoryExportUtil.contains(iter, time)) hasMore = true; - - if(!hasMore) break; - - } while (time<=_end); - - //System.err.println("=> " + Arrays.toString(result.toArray())); - - return result; - - } - - -} +package org.simantics.history; + +import gnu.trove.list.array.TDoubleArrayList; + +import java.io.IOException; +import java.math.BigDecimal; + +import org.simantics.history.csv.ExportInterpolation; +import org.simantics.history.util.HistoryExportUtil; +import org.simantics.history.util.StreamIterator; +import org.simantics.history.util.ValueBand; + +public class HistorySampler { + + public synchronized static TDoubleArrayList sample( HistorySamplerItem item, double from, double end, double timeWindow, double timeStep, boolean resample ) throws HistoryException, IOException { + + try { + // If there is something pending at this point, flush before opening for read + if(item.collector != null) + item.collector.flush(); + item.open(); + return sample(item.iter, from, end, timeWindow, timeStep, resample); + } finally { + item.close(); + } + } + + public static TDoubleArrayList sample( StreamIterator iter, double from, double end, double timeWindow, double timeStep, boolean resample ) throws HistoryException, IOException { + return sample(iter, from, end, timeWindow, timeStep, resample, 0.0); + } + + public static TDoubleArrayList sample( StreamIterator iter, double from, double end, double timeWindow, double timeStep, boolean resample, Double sampleFrom ) throws HistoryException, IOException { + + ExportInterpolation numberInterpolation = ExportInterpolation.LINEAR_INTERPOLATION; + + double startTime = from; + if(sampleFrom != null) { + // This option can be used do define the offset of sampling. Samples will be sampleFrom + n * timeStep + startTime = sampleFrom; + } + + TDoubleArrayList result = new TDoubleArrayList(); + + if(iter.isEmpty()) return result; + + double allFrom = iter.getFirstTime(); + double allEnd = 10e10;//iter.getLastTime(); + + if(from > (allEnd + timeStep)) { + from = allEnd-timeWindow; + end = allEnd; + } + +// System.err.println("sample " + from + " " + end); +// if(from < 0) +// System.err.println("fgag"); + + // Prepare time + boolean hasAnyValues = allFrom != Double.MAX_VALUE && allEnd != -Double.MAX_VALUE; + + // Make intersection of actual data range (allFrom, allEnd) and requested data (from, end) + double _from = Double.MAX_VALUE, _end = -Double.MAX_VALUE; + if (hasAnyValues) { + _from = Math.max(allFrom, from); + _end = Math.min(allEnd, end); + } + + if (!hasAnyValues) { +// System.err.println("=> no values"); + return result; + } + + // Iterate until endTime is met for all variables + double time = _from; + + if(!resample) { + + // If resample is false then all samples are reported as is. The code achieves this by setting startTime to _from and timeStep to 0.0 + time = _from; + timeStep = 0.0; + + } else { + + // time = startTime + n*timeStep + + // Sampling based on given startTime and timeStep + if(timeStep > 0) { + + // Find the first sample time that contains data + double n = Math.max(0, Math.ceil((_from-startTime) / timeStep)); + time = startTime + n*timeStep; + + } else { + + // Start sampling from startTime but make sure that it is not less than _from + if(startTime > _from) time = startTime; + + } + + + } + + // Must convert double times to String when initializing BigDecimal. + // Otherwise BigDecimal will pick up inaccuracies from beyond 15 precise digits + // thus making a mess of the time step calculations. + + BigDecimal bigTime = new BigDecimal(String.valueOf(time)); + BigDecimal bigTimeStep = new BigDecimal(String.valueOf(timeStep)); + + //System.err.println("=> goto " + time); + + if(!iter.gotoTime(time)) { + //System.err.println("=> no sample found at " + time); + return result; + } + + //time = iter.getValueBand().getTimeDouble(); + + boolean ignore = Math.abs(time-from) < 1e-6; + + do { + + //System.err.println("process " + time + " " + iter.getValueBand()); + + + + // Check for valid value + if ( iter.hasValidValue() ) { + + // Write time + if(!ignore) { +// System.err.println("Add time : " + time); + result.add(time); + } + // Write value + Object value = iter.getValueBand().getValue(); + //System.err.print("Add value : " + value); + if (value instanceof Number) { + if (value instanceof Float || value instanceof Double) { + switch (numberInterpolation) { + case PREVIOUS_SAMPLE: + + if(!ignore) { +// System.err.println(" previous .. done!"); + result.add(((Number) value).doubleValue()); + } + + break; + + case LINEAR_INTERPOLATION: + if (time != iter.getValueBand().getTimeDouble() && iter.hasNext()) { + + // Interpolate + int currentIndex = iter.getIndex(); + ValueBand band = iter.getValueBand(); + //double t1 = band.getTimeDouble(); + Number v1 = (Number) value; + double t12 = band.getEndTimeDouble(); + iter.next(); + double t2 = iter.getValueBand().getTimeDouble(); + Number v2 = (Number) iter.getValueBand().getValue(); + iter.gotoIndex(currentIndex); + + double vs = v1.doubleValue(); + if(time > t12) + vs = HistoryExportUtil.biglerp(t12, v1.doubleValue(), t2, v2.doubleValue(), time); + + if(!ignore) { +// System.err.println(" linear .. done!"); + result.add(vs); + } + + } else { + // Exact timestamp match, or last sample. + // Don't interpolate nor extrapolate. + if(!ignore) { +// System.err.println(" else .. done!"); + result.add(((Number) value).doubleValue()); + } + } + break; + default: + throw new UnsupportedOperationException("Unsupported interpolation: " + numberInterpolation); + } + } else { + throw new IllegalStateException("Value is not a number " + value); + } + } else if (value instanceof Boolean) { + if(!ignore) + result.add( (Boolean)value ? 1.0: 0.0); + } else { + throw new IllegalStateException("Value is not a number " + value); + } + } + + ignore = false; + + // Read next values, and the following times + if ( timeStep>0.0 ) { + bigTime = bigTime.add(bigTimeStep); + time = bigTime.doubleValue(); + } else { + // Get smallest end time that is larger than current time + Double nextTime = null; + // System.out.println("time = "+time); + if(!iter.hasNext()) break; + Double itemNextTime = iter.getNextTime( time ); + // System.err.println(" "+i.label+" nextTime="+itemNextTime); + if ( nextTime == null || ( nextTime > itemNextTime && !itemNextTime.equals( time ) ) ) nextTime = itemNextTime; + if ( nextTime == null || nextTime.equals( time ) ) break; + time = nextTime; + } + + boolean hasMore = false; + + iter.proceedToTime(time); + if(HistoryExportUtil.contains(iter, time)) hasMore = true; + + if(!hasMore) break; + + } while (time<=_end); + + //System.err.println("=> " + Arrays.toString(result.toArray())); + + return result; + + } + + +}