openDAQ
Open data acquisition platform
IDataDescriptor Struct Referenceabstract

Describes the data sent by a signal, defining how they are to be interpreted by anyone receiving the signal's packets. More...

+ Inheritance diagram for IDataDescriptor:
+ Collaboration diagram for IDataDescriptor:

Detailed Description

Describes the data sent by a signal, defining how they are to be interpreted by anyone receiving the signal's packets.

The data descriptor provides all information required on how to process data buffers, and how to interpret the data. It contains the following fields:

  • Name: A descriptive name of the data being described. In example, when the values describe the amplitude of spectrum data, the name would be Amplitude.
  • Dimensions: A list of dimensions of the signal. A sample descriptor can have 0 or more dimensions. A signal with 1 dimension has vector data. A signal with 2 dimensions has matrix data, a signal with 0 has a single value for each sample.
  • SampleType: An enum value that specifies the underlying data type (eg. Float64, Int32, String,...)
  • Unit: The unit of the data in the signal's packets.
  • ValueRange: The value range of the data in a signal's packets defining the lowest and highest expected values. The range is not enforced.
  • Rule: The data rule that defines how a signal value is calculated from an implicit initialization value when the rule type is not Explicit.
  • Origin: Defines the starting point of the signal. If set, all values are added to the absolute origin when read.
  • TickResolution: Used to scale signal ticks into their physical unit. In example, a resolution of 1/1000 with the unit being seconds states that a value of 1 correlates to 1 millisecond.
  • PostScaling: Defines a scaling transformation, which should be applied to data carried by the signal's packets when read. If PostScaling is used, the Rule, Resolution, and Origin must not be configured. The SampleType must match the outputDataType of the PostScaling.
  • StructFields: A list of DataDescriptor. The descriptor list is used to define complex data samples. When defined, the sample buffer is laid out so that the data described by the first DataDescriptor is at the start, followed by the data described by the second and so on. If the list is not empty, all descriptor parameters except for Name and Dimensions should not be configured. See below for a explanation of Structure data descriptors.
  • ReferenceDomainInfo: If set, gives the common identifier of one domain group. Signals with the same Reference Domain ID share a common synchronization source (all the signals in a group either come from the same device or are synchronized using a protocol, such as PTP, NTP, IRIG, etc.). Those signals can always be read together, implying that a Multi Reader can be used to read the signals if their sampling rates are compatible.

Dimensions

The list of dimensions determines the rank of values described by the descriptor. In example, if the list contains 1 dimension, the data values are vectors. If it contains 2, the data values are matrices, if 0, the descriptor describes a single value.

When the data is placed into packet buffers, the values are laid out in packet buffers linearly, where each value fills up sizeof(sampleType) * (dimensionSize1 * dimensionSize2 *...) bytes.

Data descriptor objects implement the Struct methods internally and are Core type ctStruct.

Struct fields

A DataDescriptor with the StructFields field filled with other descriptors is used to represent signal data in the form of structures. It allows for custom and complex structures to be described and sent by a signal.

When evaluating a struct descriptor, their struct field values are laid out in the packet buffers in the order they are placed in the structFields list. Eg. a struct with 3 fields, of types [int64_t, float, double] will have a buffer composed of an int64_t value, followed by a float, and lastly a double value.

Note that if the Dimensions field of the DataDescriptor is not empty, struct data can also be of a higher rank (eg. a vector/matrix of structs).

Value calculation

Besides the struct fields and dimensions, the Value descriptor also provides 4 fields which need to be taken into account and calculated when reading packet buffers: Rule, Resolution, Origin, and PostScaling.

Without <tt>PostScaling</tt>

  1. Check and apply Rule:
    • If the rule is explicit, the values of a packet are present in the packet's data buffer
    • If not explicit, the packet's values need to be calculated. To calculate them, take the PacketOffset and SampleCount of the packet. Use the PacketOffset, as well as the index of the sample in a packet to calculate the rule's output value: Value = PacketOffset + Rule(Index). Eg. Value = PacketOffset + Delta * Index + Start
  2. Apply TickResolution:
    • If the TickResolution is set, multiply the value from 1. with the Resolution. This scales the value into the Unit of the value descriptor.
    • If not set, keep the value from 1.
  3. Add Origin:
    • If the Origin is set, take the value from 2. and add it to the Origin. In example, if using the Unix Epoch, a value 1669279690 in seconds would mean Thursday, 24 November 2022 08:48:10 GMT.
    • If not set, keep the value from 2.

With <tt>PostScaling</tt>

If PostScaling is set, the Rule must be explicit, while Resolution and Origin must not be configured.

To calculate the value with PostScaling configured, take the values of the packet's data buffer and apply the post scaling to each value in the buffer: Value = PostScaling(Value), eg. Value = Value * Scale + Offset

Public Member Functions

virtual ErrCode INTERFACE_FUNC getName (IString **name)=0
 Gets a descriptive name of the signal value. More...
 
virtual ErrCode INTERFACE_FUNC getDimensions (IList **dimensions)=0
 Gets the list of the descriptor's dimension's. More...
 
virtual ErrCode INTERFACE_FUNC getSampleType (SampleType *sampleType)=0
 Gets the descriptor's sample type. More...
 
virtual ErrCode INTERFACE_FUNC getUnit (IUnit **unit)=0
 Gets the unit of the data in a signal's packets. More...
 
virtual ErrCode INTERFACE_FUNC getValueRange (IRange **range)=0
 Gets the value range of the data in a signal's packets defining the lowest and highest expected values. More...
 
virtual ErrCode INTERFACE_FUNC getRule (IDataRule **rule)=0
 Gets the value Data rule. More...
 
virtual ErrCode INTERFACE_FUNC getOrigin (IString **origin)=0
 Gets the absolute origin of a signal value component. More...
 
virtual ErrCode INTERFACE_FUNC getTickResolution (IRatio **tickResolution)=0
 Gets the Resolution which scales the explicit or implicit value to the physical unit defined in unit. It is defined as domain (usually time) between two consecutive ticks. More...
 
virtual ErrCode INTERFACE_FUNC getStructFields (IList **structFields)=0
 Gets the fields of the struct, forming a recursive value descriptor definition. More...
 
virtual ErrCode INTERFACE_FUNC getMetadata (IDict **metadata)=0
 Gets any extra metadata defined by the data descriptor. More...
 
virtual ErrCode INTERFACE_FUNC getSampleSize (SizeT *sampleSize)=0
 Gets the size of one sample in bytes. More...
 
virtual ErrCode INTERFACE_FUNC getRawSampleSize (SizeT *rawSampleSize)=0
 Gets the actual sample size in buffer of one sample in bytes. More...
 
virtual ErrCode INTERFACE_FUNC getReferenceDomainInfo (IReferenceDomainInfo **referenceDomainInfo)=0
 Gets the Reference Domain Info. More...
 
- Public Member Functions inherited from IBaseObject
virtual ErrCode INTERFACE_FUNC borrowInterface (const IntfID &intfID, void **obj) const =0
 Returns another interface which is supported by the object without incrementing the reference count. More...
 
virtual ErrCode INTERFACE_FUNC dispose ()=0
 Disposes all references held by the object. More...
 
virtual ErrCode INTERFACE_FUNC getHashCode (SizeT *hashCode)=0
 Returns hash code of the object. More...
 
virtual ErrCode INTERFACE_FUNC equals (IBaseObject *other, Bool *equal) const =0
 Compares object to another object for equality. More...
 
virtual ErrCode INTERFACE_FUNC toString (CharPtr *str)=0
 Returns a string representation of the object. More...
 
- Public Member Functions inherited from IUnknown
virtual ErrCode INTERFACE_FUNC queryInterface (const IntfID &intfID, void **obj)=0
 Returns another interface which is supported by the object and increments the reference count. More...
 
virtual int INTERFACE_FUNC addRef ()=0
 Increments the reference count for an interface on an object. More...
 
virtual int INTERFACE_FUNC releaseRef ()=0
 Decrements the reference count for an interface on an object. More...
 

Member Function Documentation

◆ getDimensions()

virtual ErrCode INTERFACE_FUNC getDimensions ( IList **  dimensions)
pure virtual

Gets the list of the descriptor's dimension's.

Parameters
[out]dimensionsThe list of dimensions.

The number of dimensions defines the rank of the signal's data (eg. Vector, Matrix).

◆ getMetadata()

virtual ErrCode INTERFACE_FUNC getMetadata ( IDict **  metadata)
pure virtual

Gets any extra metadata defined by the data descriptor.

Parameters
[out]metadataAdditional metadata of the descriptor as a dictionary.

All objects in the metadata dictionary must be key value pairs of <String, String>.

◆ getName()

virtual ErrCode INTERFACE_FUNC getName ( IString **  name)
pure virtual

Gets a descriptive name of the signal value.

Parameters
[out]nameThe name of the signal value.

When, for example, describing the amplitude values of spectrum data, the name would be Amplitude.

◆ getOrigin()

virtual ErrCode INTERFACE_FUNC getOrigin ( IString **  origin)
pure virtual

Gets the absolute origin of a signal value component.

Parameters
[out]originThe absolute origin.

An origin can be an arbitrary string that determines the starting point of the signal data. All explicit or implicit values are multiplied by the resolution and added to the origin to obtain absolute data instead of relative.

Most commonly a time reference is used, in which case it should be formatted according to the ISO 8601 standard.

◆ getRawSampleSize()

virtual ErrCode INTERFACE_FUNC getRawSampleSize ( SizeT *  rawSampleSize)
pure virtual

Gets the actual sample size in buffer of one sample in bytes.

Parameters
[out]sampleSizeThe actual size of one sample in buffer in bytes.

The actual size of one sample is calculated on constructor of the data descriptor object. Actual sample size is the sample size that is used in buffer. If the data descriptor includes implicitly generated samples, the actual sample size is less than sample size.

◆ getReferenceDomainInfo()

virtual ErrCode INTERFACE_FUNC getReferenceDomainInfo ( IReferenceDomainInfo **  referenceDomainInfo)
pure virtual

Gets the Reference Domain Info.

Parameters
[out]referenceDomainInfoThe Reference Domain Info.

If set, gives additional information about the reference domain.

◆ getRule()

virtual ErrCode INTERFACE_FUNC getRule ( IDataRule **  rule)
pure virtual

Gets the value Data rule.

Parameters
[out]ruleThe value Data rule.

If explicit, the values will be contained in the packet buffer. Otherwise they are calculated using the offset packet parameter as the input into the rule.

◆ getSampleSize()

virtual ErrCode INTERFACE_FUNC getSampleSize ( SizeT *  sampleSize)
pure virtual

Gets the size of one sample in bytes.

Parameters
[out]sampleSizeThe size of one sample in bytes.

The size of one sample is calculated on constructor of the data descriptor object.

◆ getSampleType()

virtual ErrCode INTERFACE_FUNC getSampleType ( SampleType *  sampleType)
pure virtual

Gets the descriptor's sample type.

Parameters
[out]sampleTypeThe descriptor's sample type.

◆ getStructFields()

virtual ErrCode INTERFACE_FUNC getStructFields ( IList **  structFields)
pure virtual

Gets the fields of the struct, forming a recursive value descriptor definition.

Parameters
[out]structFieldsThe list of data descriptors forming the struct fields.

Contains a list of value descriptors, defining the data layout: the data described by the first DataDescriptor of the list is at the start, followed by the data described by the second and so on.

◆ getTickResolution()

virtual ErrCode INTERFACE_FUNC getTickResolution ( IRatio **  tickResolution)
pure virtual

Gets the Resolution which scales the explicit or implicit value to the physical unit defined in unit. It is defined as domain (usually time) between two consecutive ticks.

Parameters
[out]tickResolutionThe Resolution.

◆ getUnit()

virtual ErrCode INTERFACE_FUNC getUnit ( IUnit **  unit)
pure virtual

Gets the unit of the data in a signal's packets.

Parameters
[out]unitThe unit specified by the descriptor.

◆ getValueRange()

virtual ErrCode INTERFACE_FUNC getValueRange ( IRange **  range)
pure virtual

Gets the value range of the data in a signal's packets defining the lowest and highest expected values.

Parameters
[out]rangeThe value range the signal's data.

The range is not enforced by openDAQ.