Experiment Control

From Developer Documents
Jump to: navigation, search

Experiment control is a software component that controls the process of an experiment. It uses a configuration as input.

History Collector

It is experiment control's responsibility to collect history data. One part of its configuration defines subscription parameters. The end user can define variables from which samples are collected during experiment. Subscription is a group, subscription item is a configuration for a single variable.

 SubscriptionItem = {
     // Name of the subscription item
     name: String,
     // Source data file
     src: Variant,
     // Interval in seconds (optional)
     interval: Optional( Double( unit="s" )),
     // Deadband
     deadband : Optional( Double )
 }

The collected data is stored in experiment's workarea, each subscription item as a file. Experiment Workarea is a directory that contains experiment result files: timeseries and milestones.

Time series is databoard binary file (.dbb), and its type is

TimeSeries = {
    // Value source, typically a String
    source : Variant,
    // All labels
    labels : LocalizedTexts,
    // Subscription params
    params : SubscriptionItem,
    // Time series
    data : Map( 

File name corresponds to the subscription item name with the following encoding:

  S<string>.dbb   String types
                  control characters " : < > | ? * \ / % [0..31] [128..] are escaped with %<hex><hex>
  I<integer>.dbb  Integer types
  L<long>.dbb     Long types
  B<base64>.dbb    All other cases. The value is binary encoded and presented as single line Base64 string.
                  Base64 encoding has Url and filename safe encoding flags enabled.

SampleCollector.png

Samples are captured at real-time from data source, eg. simulation or measuring device, and written to a SampleCollection. SamplingConfiguration is an input to the SampleCollector. It describes how to do sampling. There is a Record for each subscribed variable. Subscription is a describes how and when samples are recorded from a variable.

Samples may be collected:

  • on every step
  • on change
  • on change that exceeds change tolerance dead band
  • at intervals
 type SamplingConfiguration = {
        // Capture events, if true events are captured
        captureEvents : Boolean,

        // Subscribed Variables
        subscriptions : SubscriptionParameters[]
      }
 
 type SubscriptionParameters = {
        variableId : Variant,
        deadband : Optional( Double ),
        interval : Optional( Variant ),
        sampleEveryStep : Boolean
      }

If interval is omited, the variable is sampled at every step (this applies to step wise data sources).

There can be multiple subscriptions for one variable, though they are both written to one record. If sampling from multiple subscriptions create a sample at the same timecode, only one sample is written to the record.

See Dataflows for Simantics layout of data flow components.

Deadband

Deadband.png

Often values too small are irrelevant and to conserve space they can be omited. As the value of variable changes, its values are written to a record. If the difference between variable value and the last recorded value does not meet the dead band, the new value is not written to the record. The first and the last value of a deadband segment is always recorded. When deadband property is enabled, the produced record is in Sparse presentation format.

Deadband2.png

The setting deadband = 0.0 can be used for not-storing redundant samples in the record.


History Archive

History archive is a data warehouse where experiment results are persistently stored. It is network accesible service and managed by end users.

Its datamodel consists of nodes. There is dual structure, a tree hierarchy, and a map for random access.

The identifier is variant. The root id is the Default Value of a Variant type, an empty record :{}. Ids are immutable and unique, two nodes cannot have same identifier. If such is case in the back-end system, a circumventing measure must be used in the implementation. It is typically sufficient, if path is included in the format of the id. Another strategy is to use GUIDs. There are three identification serialization formats for the references: text, binary, url.

 type DataRepository = {
        nodes : Map(Variant, Node)
      }
 type Node = {
        id : Variant,
        labels : LocalizedText,
        children : Variant[],
        value : Optional(Variant)
      }