]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.history/src/org/simantics/history/HistorySampler.java
Added another sampling method to HistorySampler
[simantics/platform.git] / bundles / org.simantics.history / src / org / simantics / history / HistorySampler.java
index 7d3440192b238709e0d80c7b2feafdfd75aefb64..61f1f8bef7dfbe3864f0c7539688fecef758c015 100644 (file)
-package org.simantics.history;\r
-\r
-import gnu.trove.list.array.TDoubleArrayList;\r
-\r
-import java.io.IOException;\r
-import java.math.BigDecimal;\r
-\r
-import org.simantics.history.csv.ExportInterpolation;\r
-import org.simantics.history.util.HistoryExportUtil;\r
-import org.simantics.history.util.StreamIterator;\r
-import org.simantics.history.util.ValueBand;\r
-\r
-public class HistorySampler {\r
-    \r
-    public synchronized static TDoubleArrayList sample( HistorySamplerItem item, double from, double end, double timeWindow, double timeStep, boolean resample ) throws HistoryException, IOException {\r
-\r
-       try {\r
-               item.open();\r
-               if(item.collector != null)\r
-                       item.collector.flush();\r
-               return sample(item.iter, from, end, timeWindow, timeStep, resample);\r
-       } finally {\r
-               item.close();\r
-       }\r
-    }\r
-\r
-    public static TDoubleArrayList sample( StreamIterator iter, double from, double end, double timeWindow, double timeStep, boolean resample ) throws HistoryException, IOException {\r
-\r
-       ExportInterpolation numberInterpolation = ExportInterpolation.LINEAR_INTERPOLATION;\r
-\r
-       double startTime = 0.0;\r
-\r
-       TDoubleArrayList result = new TDoubleArrayList();\r
-\r
-       if(iter.isEmpty()) return result;\r
-\r
-       double allFrom = iter.getFirstTime();\r
-       double allEnd = 10e10;//iter.getLastTime();\r
-       \r
-       if(from > (allEnd + timeStep)) {\r
-               from = allEnd-timeWindow;\r
-               end = allEnd;\r
-       }\r
-       \r
-//     System.err.println("sample " + from + " " + end);\r
-//     if(from < 0)\r
-//             System.err.println("fgag");\r
-\r
-       // Prepare time         \r
-       boolean hasAnyValues = allFrom != Double.MAX_VALUE && allEnd != -Double.MAX_VALUE;\r
-\r
-       // Make intersection of actual data range (allFrom, allEnd) and requested data (from, end)\r
-       double _from = Double.MAX_VALUE, _end = -Double.MAX_VALUE;              \r
-       if (hasAnyValues) {\r
-               _from = Math.max(allFrom, from);\r
-               _end = Math.min(allEnd, end);\r
-       }\r
-\r
-       if (!hasAnyValues) {\r
-//             System.err.println("=> no values");\r
-               return result;\r
-       }\r
-\r
-       // Iterate until endTime is met for all variables\r
-       double time = _from;\r
-\r
-       if(!resample) {\r
-\r
-               // 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 \r
-               time = _from;\r
-               timeStep = 0.0;\r
-\r
-       } else {\r
-\r
-               // time = startTime + n*timeStep \r
-\r
-               // Sampling based on given startTime and timeStep\r
-               if(timeStep > 0) {\r
-\r
-                       // Find the first sample time that contains data \r
-                       double n = Math.max(0, Math.ceil((_from-startTime) / timeStep));\r
-                       time = startTime + n*timeStep;\r
-\r
-               } else {\r
-\r
-                       // Start sampling from startTime but make sure that it is not less than _from\r
-                       if(startTime > _from) time = startTime;\r
-\r
-               }\r
-\r
-\r
-       }\r
-\r
-       // Must convert double times to String when initializing BigDecimal.\r
-       // Otherwise BigDecimal will pick up inaccuracies from beyond 15 precise digits\r
-       // thus making a mess of the time step calculations.\r
-\r
-       BigDecimal bigTime = new BigDecimal(String.valueOf(time));\r
-       BigDecimal bigTimeStep = new BigDecimal(String.valueOf(timeStep));\r
-\r
-       //System.err.println("=> goto " + time);\r
-       \r
-       if(!iter.gotoTime(time)) {\r
-               //System.err.println("=> no sample found at " + time);\r
-               return result;\r
-       }\r
-       \r
-       //time = iter.getValueBand().getTimeDouble();\r
-\r
-       boolean ignore = Math.abs(time-from) < 1e-6; \r
-\r
-       do {\r
-               \r
-               //System.err.println("process " + time + " " + iter.getValueBand());\r
-\r
-\r
-\r
-           // Check for valid value\r
-               if ( iter.hasValidValue() ) {\r
-                   \r
-                // Write time\r
-                if(!ignore) {\r
-//                    System.err.println("Add time : " + time);\r
-                    result.add(time);\r
-                }\r
-                // Write value\r
-                       Object value = iter.getValueBand().getValue();\r
-                       //System.err.print("Add value : " + value);\r
-                       if (value instanceof Number) {\r
-                               if (value instanceof Float || value instanceof Double) {\r
-                                       switch (numberInterpolation) {\r
-                                       case PREVIOUS_SAMPLE:\r
-\r
-                                       if(!ignore) {\r
-//                                         System.err.println(" previous .. done!");\r
-                                               result.add(((Number) value).doubleValue());\r
-                                       }\r
-                                       \r
-                                               break;\r
-\r
-                                       case LINEAR_INTERPOLATION:\r
-                                               if (time != iter.getValueBand().getTimeDouble() && iter.hasNext()) {\r
-\r
-                                                       // Interpolate\r
-                                                       int currentIndex = iter.getIndex();\r
-                                                       ValueBand band = iter.getValueBand();\r
-                                                       //double t1 = band.getTimeDouble();\r
-                                                       Number v1 = (Number) value;\r
-                                                       double t12 = band.getEndTimeDouble();\r
-                                                       iter.next();\r
-                                                       double t2 = iter.getValueBand().getTimeDouble();\r
-                                                       Number v2 = (Number) iter.getValueBand().getValue();\r
-                                                       iter.gotoIndex(currentIndex);\r
-\r
-                                                       double vs = v1.doubleValue();\r
-                                                       if(time > t12)\r
-                                                               vs = HistoryExportUtil.biglerp(t12, v1.doubleValue(), t2, v2.doubleValue(), time);\r
-\r
-                                               if(!ignore) {\r
-//                                                 System.err.println(" linear .. done!");\r
-                                                       result.add(vs);\r
-                                               }\r
-\r
-                                               } else {\r
-                                                       // Exact timestamp match, or last sample.\r
-                                                       // Don't interpolate nor extrapolate.\r
-                                               if(!ignore) {\r
-//                                                 System.err.println(" else .. done!");\r
-                                                       result.add(((Number) value).doubleValue());\r
-                                               }\r
-                                               }\r
-                                               break;\r
-                                       default:\r
-                                               throw new UnsupportedOperationException("Unsupported interpolation: " + numberInterpolation);\r
-                                       }\r
-                               } else {\r
-                                       throw new IllegalStateException("Value is not a number " + value);\r
-                               }\r
-                       } else if (value instanceof Boolean) {\r
-                       if(!ignore)\r
-                               result.add( (Boolean)value ? 1.0: 0.0);\r
-                       } else {\r
-                               throw new IllegalStateException("Value is not a number " + value);\r
-                       }\r
-               }\r
-               \r
-               ignore = false;\r
-\r
-               // Read next values, and the following times\r
-               if ( timeStep>0.0 ) {\r
-                       bigTime = bigTime.add(bigTimeStep);\r
-                       time = bigTime.doubleValue();\r
-               } else {\r
-                       // Get smallest end time that is larger than current time\r
-                       Double nextTime = null;\r
-                       //                      System.out.println("time = "+time);\r
-                       if(!iter.hasNext()) break;\r
-                       Double itemNextTime = iter.getNextTime( time );\r
-                       //                              System.err.println("  "+i.label+" nextTime="+itemNextTime);\r
-                       if ( nextTime == null || ( nextTime > itemNextTime && !itemNextTime.equals( time ) ) ) nextTime = itemNextTime; \r
-                       if ( nextTime == null || nextTime.equals( time ) ) break;\r
-                       time = nextTime;\r
-               }\r
-\r
-               boolean hasMore = false;\r
-\r
-               iter.proceedToTime(time);\r
-               if(HistoryExportUtil.contains(iter, time)) hasMore = true;\r
-\r
-               if(!hasMore) break;\r
-\r
-       } while (time<=_end);\r
-\r
-               //System.err.println("=> " + Arrays.toString(result.toArray()));\r
-       \r
-       return result;\r
-\r
-    }\r
-\r
-       \r
-}\r
+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;
+
+    }
+
+       public synchronized static TDoubleArrayList sample(HistorySamplerItem2 item, double end, double timeWindow, int maxSamples, 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();
+                       double pixelsPerSecond = (double) maxSamples / timeWindow;
+                       item.open(pixelsPerSecond);
+                       return sample(item.iter, end, timeWindow, maxSamples, resample);
+               } finally {
+                       item.close();
+               }
+       }
+
+       private static TDoubleArrayList sample(StreamIterator iter, double end, double timeWindow, int maxSamples, boolean resample) throws HistoryException, IOException {
+               //System.out.println("sample: " + end + ", " + timeWindow + ", " + maxSamples + ", " + resample);
+               ExportInterpolation numberInterpolation = ExportInterpolation.LINEAR_INTERPOLATION;
+
+               double timeStep = 0;
+               double startTime = -1e10;
+
+               TDoubleArrayList result = new TDoubleArrayList();
+               if (iter.isEmpty())
+                       return result;
+
+               double allFrom = iter.getFirstTime();
+               double allEnd = iter.getLastTime();
+               //System.out.println("data available [" + allFrom + " .. " + allEnd + "]");
+
+               double from = allEnd-timeWindow;
+               end = allEnd;
+               //System.out.println("sample between [" + from + " .. " + end + "]");
+
+               // Prepare time
+               boolean hasAnyValues = allFrom != Double.MAX_VALUE && allEnd != -Double.MAX_VALUE;
+               if (!hasAnyValues) {
+                       //System.err.println("=> no values");
+                       return result;
+               }
+
+               // Make intersection of actual data range (allFrom, allEnd) and requested data (from, end)
+               double _from = Math.max(allFrom, from);
+               double _end = Math.min(allEnd, end);
+
+               // 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;
+
+       }
+
+}