]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.history/src/org/simantics/history/util/subscription/SamplingFormat.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.history / src / org / simantics / history / util / subscription / SamplingFormat.java
diff --git a/bundles/org.simantics.history/src/org/simantics/history/util/subscription/SamplingFormat.java b/bundles/org.simantics.history/src/org/simantics/history/util/subscription/SamplingFormat.java
new file mode 100644 (file)
index 0000000..a8b2ea6
--- /dev/null
@@ -0,0 +1,243 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.history.util.subscription;\r
+\r
+import java.util.Arrays;\r
+import java.util.Comparator;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.Datatypes;\r
+import org.simantics.databoard.adapter.AdaptException;\r
+import org.simantics.databoard.type.ArrayType;\r
+import org.simantics.databoard.type.Component;\r
+import org.simantics.databoard.type.Datatype;\r
+import org.simantics.databoard.type.NumberType;\r
+import org.simantics.databoard.type.RecordType;\r
+import org.simantics.databoard.util.Bean;\r
+import org.simantics.databoard.util.Limit;\r
+import org.simantics.databoard.util.Range;\r
+\r
+/**\r
+ * This is an utility class for SubscriptionItem.\r
+ * \r
+ * The Simantics Charts samples history data in a specified way. \r
+ * One data source item is recorded into multiple history item, each identified\r
+ * with a named SamplingFormat. This class describes a named sampling format.\r
+ * \r
+ * @author toni.kalajainen@semantum.fi\r
+ */\r
+public class SamplingFormat extends Bean {\r
+       \r
+       public static final SamplingFormat[] EMPTY = new SamplingFormat[0];\r
+       \r
+       public final static Comparator<Bean> INTERVAL_COMPARATOR = new Comparator<Bean>() {\r
+               @Override\r
+               public int compare(Bean o1, Bean o2) {\r
+                       double i1 = (Double) o1.getFieldUnchecked("interval");\r
+                       double i2 = (Double) o2.getFieldUnchecked("interval");\r
+                       boolean nan1 = Double.isNaN( i1 );\r
+                       boolean nan2 = Double.isNaN( i2 );\r
+                       \r
+                       if ( nan1 && nan2 ) return 0;\r
+                       if ( nan1 && !nan2) return -1;\r
+                       if ( !nan1 && nan2) return 1;\r
+                       return i1 == i2 ? 0 : ( i1 < i2 ? -1 : 1 );\r
+               }\r
+       };\r
+       \r
+       public final static Comparator<SamplingFormat> DEADBAND_COMPARATOR = new Comparator<SamplingFormat>() {\r
+               @Override\r
+               public int compare(SamplingFormat o1, SamplingFormat o2) {\r
+                       boolean nan1 = Double.isNaN( o1.deadband );\r
+                       boolean nan2 = Double.isNaN( o2.deadband );\r
+                       \r
+                       if ( nan1 && nan2 ) return 0;\r
+                       if ( nan1 && !nan2) return -1;\r
+                       if ( !nan1 && nan2) return 1;\r
+                       return o1.deadband == o2.deadband ? 0 : ( o1.deadband < o2.deadband ? -1 : 1 );\r
+               }\r
+       };\r
+\r
+       /** Identifier, this value is used for separating the time series files */\r
+       public String formatId;\r
+       \r
+       /** \r
+        * Describes the format of the packed sample. The sample must be a record.\r
+        * The record must have any combination of the following named fields.\r
+        * The field types must one of: byte, integer, long, float, double.\r
+        * \r
+        * time, endTime, value - are mandatory fields.\r
+        * \r
+        *  time      -  Region start time, the time of the 1st included sample\r
+        *  endTime   -  Region end time, the time of the last included sample\r
+        *  \r
+        *  value     -  First value in the region\r
+        *  lastValue -  Last value in the region\r
+        *  avg       -  Average value of all included samples\r
+        *  median    -  Median value of all samples in the region\r
+        *  min       -  Lowest value in the region\r
+        *  max       -  Highest value in the region\r
+        *  \r
+        *  quality   -  0 = Good, -1 = No value\r
+        *  count     -  The number of included samples in the region\r
+        */\r
+       public Datatype format;\r
+\r
+       /** Interval sets the minimum time for a packed sample */\r
+       public double interval = Double.NaN;\r
+\r
+       /** Deadband determines the minimum value change for a packed sample when collecting data */\r
+       public double deadband = Double.NaN;\r
+       \r
+       public SamplingFormat()\r
+       {               \r
+       }\r
+       \r
+       public SamplingFormat(String id, RecordType sampleType, double interval, double deadband)\r
+       {\r
+               this.formatId = id;\r
+               this.format = sampleType;\r
+               this.interval = interval;\r
+               this.deadband = deadband;\r
+       }\r
+       \r
+       // Sampling format templates\r
+       public static SamplingFormat simple, allfields, vector;\r
+       \r
+       public RecordType record() { return (RecordType) format; }\r
+\r
+       static {\r
+               simple = new SamplingFormat();\r
+               simple.formatId = "Simple";\r
+               RecordType format = (RecordType) (simple.format = new RecordType());            \r
+               format.addComponent("time", Datatypes.DOUBLE);\r
+               format.addComponent("endTime", Datatypes.DOUBLE);\r
+               format.addComponent("value", Datatypes.DOUBLE);\r
+               format.addComponent("quality", Datatypes.BYTE);\r
+               simple.interval = Double.NaN;\r
+               simple.deadband = Double.NaN;\r
+               \r
+               allfields = new SamplingFormat();\r
+               allfields.formatId = "Allfields";\r
+               allfields.format = new RecordType();\r
+               format = (RecordType) (allfields.format = new RecordType());            \r
+               format.addComponent("time", Datatypes.DOUBLE);\r
+               format.addComponent("endTime", Datatypes.DOUBLE);\r
+               \r
+               format.addComponent("value", Datatypes.DOUBLE);\r
+               format.addComponent("lastValue", Datatypes.DOUBLE);             \r
+               format.addComponent("min", Datatypes.DOUBLE);\r
+               format.addComponent("max", Datatypes.DOUBLE);\r
+               format.addComponent("avg", Datatypes.DOUBLE);\r
+               format.addComponent("median", Datatypes.DOUBLE);\r
+               \r
+               format.addComponent("quality", Datatypes.BYTE);\r
+               format.addComponent("count", Datatypes.INTEGER);\r
+               allfields.interval = Double.NaN;\r
+               allfields.deadband = Double.NaN;                \r
+               \r
+               vector = new SamplingFormat();\r
+               vector.formatId = "Vector";\r
+               vector.format = new RecordType();\r
+               format = (RecordType) (vector.format = new RecordType());               \r
+               format.addComponent("time", Datatypes.FLOAT);\r
+               format.addComponent("endTime", Datatypes.FLOAT);\r
+               format.addComponent("value", new ArrayType( Datatypes.DOUBLE, Range.between(Limit.inclusive(3), Limit.inclusive(3)) ));\r
+               format.addComponent("count", Datatypes.INTEGER);\r
+               vector.interval = Double.NaN;\r
+               vector.deadband = Double.NaN;\r
+               \r
+       }\r
+               \r
+       @Override\r
+       public boolean equals(Object obj) {\r
+               if ( obj == null ) return false;\r
+               if ( obj == this ) return true;\r
+               if ( obj instanceof SamplingFormat == false ) return false;\r
+               SamplingFormat other = (SamplingFormat) obj;            \r
+//             if ( !doubleEquals(interval, other.interval) || !doubleEquals(deadband, other.deadband) ) return false;\r
+//             return RecordTypeBinding.equals( other.sampleType, sampleType );\r
+               return formatId.equals(other.formatId);\r
+       }\r
+       \r
+       @Override\r
+       public String toString() {\r
+               return "id="+formatId+", "+format +", interval="+interval+", deadband="+deadband;\r
+       }\r
+       \r
+       @Override\r
+       public SamplingFormat clone() {\r
+               try {\r
+                       SamplingFormat result = new SamplingFormat();\r
+                       result.formatId = formatId;\r
+                       result.interval = interval;\r
+                       result.deadband = deadband;\r
+                       result.format = (Datatype) Bindings.getBindingUnchecked( Datatype.class ).clone( format );\r
+                       return result;\r
+               } catch (AdaptException e) {\r
+                       throw new RuntimeException( e );\r
+               }\r
+       }\r
+\r
+       public SamplingFormat clone(double interval, double deadband) {\r
+               try {\r
+                       SamplingFormat result = new SamplingFormat();\r
+                       result.formatId = formatId;\r
+                       result.interval = interval;\r
+                       result.deadband = deadband;\r
+                       result.format = (Datatype) Bindings.getBindingUnchecked( Datatype.class ).clone( format );\r
+                       return result;\r
+               } catch (AdaptException e) {\r
+                       throw new RuntimeException( e );\r
+               }\r
+       }\r
+       \r
+       public SamplingFormat cloneTo(String id, double interval, double deadband) {\r
+               try {\r
+                       SamplingFormat result = new SamplingFormat();\r
+                       result.formatId = id;\r
+                       result.interval = interval;\r
+                       result.deadband = deadband;\r
+                       result.format = (Datatype) Bindings.getBindingUnchecked( Datatype.class ).clone( format );\r
+                       return result;\r
+               } catch (AdaptException e) {\r
+                       throw new RuntimeException( e );\r
+               }\r
+       }\r
+       \r
+       public SamplingFormat setUnit(String unit) {\r
+               for ( int i = 0; i<format.getComponentCount(); i++ ) {\r
+                       Component c = ((RecordType)format).getComponent(i);\r
+                       if ( c.name.equals( "value" ) || \r
+                                       c.name.equals( "min" ) || \r
+                                       c.name.equals( "max" ) || \r
+                                       c.name.equals( "avg" ) ||\r
+                                       c.name.equals( "median" )\r
+                                       ) {\r
+                               if ( c.type instanceof NumberType ) {\r
+                                       NumberType nt = (NumberType) c.type;\r
+                                       nt.setUnit( unit );\r
+                               }\r
+                       }\r
+               }\r
+               return this;\r
+       }\r
+       \r
+       public static void sortByInterval( SamplingFormat[] formats ) {\r
+               Arrays.sort(formats, INTERVAL_COMPARATOR);\r
+       }\r
+       \r
+       public static void sortByDeadband( SamplingFormat[] formats ) {\r
+               Arrays.sort(formats, DEADBAND_COMPARATOR);\r
+       }\r
+       \r
+}\r