openDAQ
Open data acquisition platform
DataDescriptorPtr Class Reference

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

Inherits ObjectPtr< 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
  1. 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.
  1. 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

daq::StringPtr getName () const
 Gets a descriptive name of the signal value. More...
 
daq::ListPtr< daq::IDimension > getDimensions () const
 Gets the list of the descriptor's dimension's. More...
 
daq::SampleType getSampleType () const
 Gets the descriptor's sample type. More...
 
daq::UnitPtr getUnit () const
 Gets the unit of the data in a signal's packets. More...
 
daq::RangePtr getValueRange () const
 Gets the value range of the data in a signal's packets defining the lowest and highest expected values. More...
 
daq::DataRulePtr getRule () const
 Gets the value Data rule. More...
 
daq::StringPtr getOrigin () const
 Gets the absolute origin of a signal value component. More...
 
daq::RatioPtr getTickResolution () const
 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...
 
daq::ListPtr< daq::IDataDescriptor > getStructFields () const
 Gets the fields of the struct, forming a recursive value descriptor definition. More...
 
daq::DictPtr< daq::IString, daq::IString > getMetadata () const
 Gets any extra metadata defined by the data descriptor. More...
 
daq::SizeT getSampleSize () const
 Gets the size of one sample in bytes. More...
 
daq::SizeT getRawSampleSize () const
 Gets the actual sample size in buffer of one sample in bytes. More...
 
daq::ReferenceDomainInfoPtr getReferenceDomainInfo () const
 Gets the Reference Domain Info. More...
 

Member Function Documentation

◆ getDimensions()

daq::ListPtr<daq::IDimension> getDimensions ( ) const
inline

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

Returns
The list of dimensions.

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

◆ getMetadata()

daq::DictPtr<daq::IString, daq::IString> getMetadata ( ) const
inline

Gets any extra metadata defined by the data descriptor.

Returns
Additional metadata of the descriptor as a dictionary.

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

◆ getName()

daq::StringPtr getName ( ) const
inline

Gets a descriptive name of the signal value.

Returns
The name of the signal value.

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

◆ getOrigin()

daq::StringPtr getOrigin ( ) const
inline

Gets the absolute origin of a signal value component.

Returns
The 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()

daq::SizeT getRawSampleSize ( ) const
inline

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()

daq::ReferenceDomainInfoPtr getReferenceDomainInfo ( ) const
inline

Gets the Reference Domain Info.

Returns
The Reference Domain Info.

If set, gives additional information about the reference domain.

◆ getRule()

daq::DataRulePtr getRule ( ) const
inline

Gets the value Data rule.

Returns
The 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()

daq::SizeT getSampleSize ( ) const
inline

Gets the size of one sample in bytes.

Returns
The size of one sample in bytes.

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

◆ getSampleType()

daq::SampleType getSampleType ( ) const
inline

Gets the descriptor's sample type.

Returns
The descriptor's sample type.

◆ getStructFields()

daq::ListPtr<daq::IDataDescriptor> getStructFields ( ) const
inline

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

Returns
The 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()

daq::RatioPtr getTickResolution ( ) const
inline

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.

Returns
The Resolution.

◆ getUnit()

daq::UnitPtr getUnit ( ) const
inline

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

Returns
The unit specified by the descriptor.

◆ getValueRange()

daq::RangePtr getValueRange ( ) const
inline

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

Returns
The value range the signal's data.

The range is not enforced by openDAQ.