Simulation data#

Simulation data files are used to represent sequences of values:

  • they are the outputs of simulation jobs;

  • they can be used in test harnesses:

    • in data source blocks, to feed the input flows of the operator instance to test

    • in oracle blocks, to store expected output values to compare with the actual values in model test execution

This library allows to read and edit simulation data files. Look for simulation data in the Scade One documentation.

Covered features#

  • Support of none values, meaning that the value is not defined at a given cycle:

    • Stimuli operator: a value must be defined at first cycle, for next steps the none type means that a previous value is held.

    • Simulator trace: a none value means that the variable clock is false.

  • Support of all Swan types, imported types (stored as a byte array) and combinations of them (native support of Variants & Groups).

    • Data support: structure, table (when the table size is a static constant), enum, string.

    • Limitations: partial data is not supported. All values of a complex type must be given.

  • The variables are organized as a tree of <scope>/<scope>/…/<variable>, each scope and variable has an optional Swan kind: sensors, inputs, outputs, probes, assume, guarantee and so on.

  • Possibility to specify a repetition of a signal or part of it.

  • Possibility to open an existing file for modification: elements, types and values.

Design principles#

  • The values are stored as their binary representation in memory: no structured representation of composite values.

  • The values sequences are compressed using the zlib data-compression library.

  • The file size has no limit (more than 4 GB): use of 64-bits positions and C APIs for seek in file.

  • The entire file content is not loaded in memory when opening: the data is read in file only on demand.

  • The file content is not entirely rewritten on disk when closing: incremental read and write operations.

Performance#

  • Appending values to an element: no need to read all the values before appending and use of a write cache.

  • Updating element: no move of significant data in file.

Examples#

Simulation data file preview command line#

The pyscadeone Command line interface is used, in combination with the simdata and -show arguments, to preview the content of a data file with .SD extension in a text editor, without opening the Scade One tool or the Signal Editor.

# View content of a .SD file as a text
pyscadeone simdata --show some_file.sd > some_file.txt
notepad some_file.txt # opens the file in notepad, or vi editor and so on

Create a structure type data#

import ansys.scadeone.core.svc.simdata as sd

f = sd.create_file("mySimDataFile.sd") # creates a new simulation data file

t_struct1 = sd.create_struct_type([("f1", sd.Bool), ("f2", sd.Int32)], "p1::tStruct1") # creates a new structure type
e_struct1 = f.add_element("eStruct1", t_struct1) # adds an element to the file
clock1 = False

for i in range(10): # number of cycles
    clock1 = not clock1
    e_struct1.append_value([clock1, i + 14]) # adds values to the element

f.close() # closes the file

Create a variant type data#

import ansys.scadeone.core.svc.simdata as sd

f = sd.create_file("mySimDataFile.sd") # creates a new simulation data file

variant_type2 = sd.create_variant_type([("speedLimitStart", sd.Int32), ("speedLimitEnd", None)], "MyModule::SpeedLimit") # creates a new variant type
variant_type1 = sd.create_variant_type([("tsBool", sd.Bool), ("tsNone", None), ("tsSome", variant_type2)], "MyModule::Variant") # creates a new variant type with an inserted variant subtype
variant_element = f.add_element("inputVariant", variant_type1) # adds an element to the file

variant_element.append_values_sequence([("tsNone")]) # fills with values
variant_element.append_values_sequence([("tsBool", True)])
variant_element.append_values_sequence([("tsSome", ("speedLimitStart", 147))])
variant_element.append_values_sequence([("tsSome", ("speedLimitEnd"))])
variant_element.append_values_sequence([("tsNone")])

f.close() # closes the file

Create a group type data#

A group is a composite type that contains child elements. Each child element can be of any type, including another group. The Simdata representation of a group is a container used to organize related elements together. The Element representing the group has the name of the group itself, but does not hold values; its child elements do.

The group representation is flattened: child elements are represented as individual elements in the simulation data file. Child elements are identified by their path in the group hierarchy, using positions and names.

Suppose one defines a group type in Swan as follows: group MyGroup = (int32, bool, b:((x:float32, y:float32), int32)) in the module interface MyModule. The code to create a simulation data file with this group type is:

import ansys.scadeone.core.svc.simdata as sd

f = sd.create_file("mySimDataFile.sd") # creates a new simulation data file
group_element = f.add_element("inputGroup", group_expr="MyModule::MyGroup")
child_1 = group_element.add_child_element(".(.1)", sd.Int32, sd.ElementKind.GROUP_ITEM)
child_2 = group_element.add_child_element(".(.2)", sd.Bool, sd.ElementKind.GROUP_ITEM)
child_b1_b_1_x = group_element.add_child_element(
    ".(.b.1.x)", sd.Float32, sd.ElementKind.GROUP_ITEM
)
child_b1_b_1_y = group_element.add_child_element(
    ".(.b.1.y)", sd.Float32, sd.ElementKind.GROUP_ITEM
)
child_b1_b_2 = group_element.add_child_element(
    ".(.b.2)", sd.Int32, sd.ElementKind.GROUP_ITEM
)

child_1.append_values_sequence([1, 1, 1, 2, 3, 4])
child_b1_b_1_x.append_values_sequence([0.1, 0.1, 0.1, 0.2, 2.3, 2.4])
child_b1_b_1_y.append_values_sequence([2.5, 2.5, 2.5, 2.6, 2.7, 2.8])
child_b1_b_2.append_values_sequence([10, 11, 12, 12, 12, 12])
child_2.append_values_sequence([False, True, False, True, False, True])

f.close()

The content of the file can be visualized:

$ pyscadeone simdata --show mySimDataFile.sd
*** Elements:
inputGroup:
    GROUP_ITEM .(.1): int32: 1 | 1 | 1 | 2 | 3 | 4 |
    GROUP_ITEM .(.2): bool: false | true | false | true | false | true |
    GROUP_ITEM .(.b.1.x): float32: 0.1 | 0.1 | 0.1 | 0.2 | 2.3 | 2.4 |
    GROUP_ITEM .(.b.1.y): float32: 2.5 | 2.5 | 2.5 | 2.6 | 2.7 | 2.8 |
    GROUP_ITEM .(.b.2): int32: 10 | 11 | 12 | 12 | 12 | 12 |

In the Scade One Signal Editor, the group is represented as:

Signal Editor view of a group type

High-level API#

High-level functions#

The following functions are used to create or open a simulation data file, and to create user types definitions for elements, which can be then be filled with values from Python values.

ansys.scadeone.core.svc.simdata.open_file(file_path: str) FileBase#

Open a simdata file in read-only mode

Parameters:
file_pathstr

path of the file

Returns:
FileBase

The opened file

Raises:
ScadeOneException

file could not be opened

ansys.scadeone.core.svc.simdata.create_file(file_path: str) FileBase#

Create a simdata file

Parameters:
file_pathstr

path of the file

Returns:
FileBase

The created file

Raises:
ScadeOneException

file could not be created

ansys.scadeone.core.svc.simdata.edit_file(file_path: str) FileBase#

Open a simdata file in edit mode

Parameters:
file_pathstr

path of the file

Returns:
FileBase

The opened file

Raises:
ScadeOneException

The file could not be opened

ansys.scadeone.core.svc.simdata.create_array_type(base_type: Type, dims: List[int], name: str = '') ArrayType#

Create a multi dimensional array type

Parameters:
base_typeType

type of array

dimsList[int]

array dimensions

namestr, optional

array name

Returns:
ArrayType

Created array type

Raises:
ScadeOneException

incorrect dimensions, array type could not be created, argument error or none type passed

ansys.scadeone.core.svc.simdata.create_struct_type(fields: List[Tuple], name: str = '') StructType#

Create a structure type

Parameters:
fieldsList[Tuple]

all fields of the structure

namestr, optional

structure name

Returns:
StructType

The created structure type

Raises:
ScadeOneException

structure type could not be created, arguments are invalid, or field names duplicate

ansys.scadeone.core.svc.simdata.create_enum_type(values: List[str], name: str = '') EnumType#

Create an enumeration type

Parameters:
valuesList[str]

values of the enumeration type

namestr, optional

name of enumeration type

Returns:
EnumType

Created enumeration type

Raises:
ScadeOneException

could not create enumeration type, create a value of passed argument or invalid arguments in creation

ansys.scadeone.core.svc.simdata.create_variant_type(constructors: List[Tuple], name: str = '') VariantType#

Create a variant type

Parameters:
constructorsList[Tuple]

constructors of the variant type

namestr, optional

name of variant type

Returns:
VariantType

Created variant type

Raises:
ScadeOneException

variant type could not be created, invalid arguments or duplicate constructor names

ansys.scadeone.core.svc.simdata.create_imported_type(mem_size: int, name: str = '') ImportedType#

Create an imported type

Parameters:
mem_sizeint

memory size

namestr, optional

imported type name

Returns:
ImportedType

Created imported type

Raises:
ScadeOneException

could not create imported type, argument type error or argument type error

High-level classes#

Following classes are used to manipulate simulation data files and their content:

class ansys.scadeone.core.svc.simdata.File(file_id: int)#

Bases: FileBase

Simdata files class

add_element(name: str, sd_type: Type | None = None, kind: SdeKind = SdeKind.NONE, group_expr: str = '') ElementBase#

Create and add an element to file

Parameters:
namestr

element name

sd_typeType, optional

type of element

kindElementKind, optional

kind of element

group_exprstr, optional

group expression of element

Returns:
ElementBase

The new element that was added to file

close() None#

Close a file

Raises:
ScadeOneException

Could not close file or file was not opened

get_version() str#

Get the file version

Returns:
str

Version number

remove_element(element: Element) None#

Delete an element from file

Parameters:
elementElement

element to delete

Raises:
ScadeOneException

element of wrong type or could not be found or deleted

class ansys.scadeone.core.svc.simdata.Element(file: FileBase, elem_id: int, name: str, sd_type: Type | None, kind: SdeKind, group_expr: str | None, parent: ElementBase | None)#

Bases: ElementBase

Class for simdata elements

add_child_element(name: str, sd_type: Type | None = None, kind: SdeKind = SdeKind.NONE, group_expr: str | None = '') ElementBase#

Add a child to element

Parameters:
namestr

child element name

sd_typeType, optional

child element type

kindElementKind, optional

child element kind

group_exprstr, optional

child element group expression

Returns:
ElementBase

Created child element

append_nones_sequence(count: int) None#

Create and append a sequence of ‘none’

Parameters:
countint

number of Nones to add

Raises:
ScadeOneException

invalid count, cannot create or append nones sequence

append_value(py_value: Any) None#

Add a value to an element or appends to the last sequence of values if any.

Parameters:
py_valueAny

value that has a type corresponding to the element

Raises:
ScadeOneException

value is invalid or could not be added

append_values_sequence(py_values: List[Any], repeat_factor: int = 1) None#

Create and append a new sequence of ‘values’ with repeat factor. Do not use repeat factor for array and structure types. Do not use this for structure or array types that already have any value, use append_value() instead in such case.

Parameters:
py_valuesList[Any]

list of value(s) to add

repeat_factorint, optional

number of times to add, by default 1 (no repeat), do not use with non scalar values

Raises:
ScadeOneException

Invalid repeat, none contained in values, invalid values, cannot create or append values sequence, used repeat factor for array or structure types

clear_values() None#

Clear all values of element

Raises:
ScadeOneException

values could not be cleared

get_last_sequence() c_void_p | None#

Get the last sequence

read_values(start: int | None = None, n: int | None = None) Iterator[Value]#

Read element values

Parameters:
startint, optional

start index for reading, beginning if not specified

nint, optional

number of values to read, runs until end if not specified

Yields:
Iterator[Value]

each value read

Raises:
ScadeOneException

invalid number of values to read, cannot seek element index

remove_child_element(element: Element) None#

Remove a child from element

Parameters:
elementElement

element to remove

Raises:
ScadeOneException

child is not an element, was not found or could not be removed

Type definitions#

Simulation values have types, defined in Swan language. Types can be predefined (native) or user-defined. In the latter case, the type must be created before creating an element of this type.

Values are passed to the API as Python values, and converted to the proper binary representation of the Swan type. Scalar types are mapped to Python built-in types, composite types are mapped to Python lists or tuples. For arrays one can use numpy.array() function.

Predefined types#

Predefined swan types that shall be used for creation of simple elements or user types definitions

Swan type

SD Type

char

Char

bool

Bool

int8

Int8

int16

Int16

int32

Int32

int64

Int64

uint8

UInt8

uint16

UInt16

uint32

UInt32

uint64

UInt64

float32

Float32

float64

Float64

Example of using a predefined type (float 32 here) for new element and a custom user type:

import ansys.scadeone.core.svc.simdata as sd

my_file = sd.create_file("mySimDataFile.sd")
# Predefined type
my_element1 = my_file.add_element("myElement", sd.Float32)
# User defined type: 2D array of float32
my_array_type = sd.create_array_type(sd.Float32, [3, 4], "my2DArrayType")
my_element2 = my_file.add_element("my2DArrayElement", my_array_type)

Type-related classes#

class ansys.scadeone.core.svc.simdata.defs.ArrayType(type_id: int, base_type: Type, dims: List[int], name: str = '')#

Bases: Type

Multidimensional array type

property base_type: Type#

Base type of array elements

property dims: List[int]#

Array dimensions as list of integers for multidimensional arrays

property name: str#

Type name

property type_id: int#

Type identifier in the simulation data file

class ansys.scadeone.core.svc.simdata.defs.EnumType(type_id: int, base_type: PredefinedType, values: List[EnumTypeValue], name: str = '')#

Bases: Type

Enumeration type defined with enumeration values

property base_type: PredefinedType#

Base type of enumeration values

property name: str#

Type name

property type_id: int#

Type identifier in the simulation data file

property values: List[EnumTypeValue]#

Enumeration values, with their names and integer values

class ansys.scadeone.core.svc.simdata.defs.EnumTypeValue(name: str, int_value: int)#

Bases: object

Enumeration type value

property int_value: int#

Enumeration value integer value

property name: str#

Enumeration value name

class ansys.scadeone.core.svc.simdata.defs.EnumValue(name: str)#

Bases: Value

Values for enumeration types

class ansys.scadeone.core.svc.simdata.defs.ImportedType(type_id: int, mem_size: int, is_vsize: bool = False, pfn_vsize_get_bytes_size: ~ctypes.CFUNCTYPE.<locals>.CFunctionType | None = None, pfn_vsize_to_bytes: ~ctypes.CFUNCTYPE.<locals>.CFunctionType | None = None, name: str = '')#

Bases: Type

Imported Types (stored as byte arrays)

property mem_size: int#

Memory size in bytes for fixed-size imported types

property name: str#

Type name

property type_id: int#

Type identifier in the simulation data file

class ansys.scadeone.core.svc.simdata.defs.ImportedValue(bytes_data)#

Bases: Value

Values for imported types

class ansys.scadeone.core.svc.simdata.defs.ListValue(values: List[Value])#

Bases: Value

Values for list types

class ansys.scadeone.core.svc.simdata.defs.NoneValue#

Bases: Value

None Values

class ansys.scadeone.core.svc.simdata.defs.PredefinedBoolValue(value: c_ubyte)#

Bases: PredefinedValue

Values for predefined type boolean

class ansys.scadeone.core.svc.simdata.defs.PredefinedCharValue(value: c_ubyte)#

Bases: PredefinedValue

Values for predefined type char

class ansys.scadeone.core.svc.simdata.defs.PredefinedFloat32Value(value: c_float)#

Bases: PredefinedValue

Values for predefined type float 32

class ansys.scadeone.core.svc.simdata.defs.PredefinedFloat64Value(value: c_double)#

Bases: PredefinedValue

Values for predefined type float 64

class ansys.scadeone.core.svc.simdata.defs.PredefinedInt16Value(value: c_short)#

Bases: PredefinedValue

Values for predefined type int 16

class ansys.scadeone.core.svc.simdata.defs.PredefinedInt32Value(value: c_int)#

Bases: PredefinedValue

Values for predefined type int 32

class ansys.scadeone.core.svc.simdata.defs.PredefinedInt64Value(value: c_long)#

Bases: PredefinedValue

Values for predefined type int 64

class ansys.scadeone.core.svc.simdata.defs.PredefinedInt8Value(value: c_byte)#

Bases: PredefinedValue

Values for predefined type int 8

class ansys.scadeone.core.svc.simdata.defs.PredefinedType(type_id: int)#

Bases: Type

Predefined Swan types are not stored in file. They have hard-coded identifiers that can be used in user types definitions.

property name: str#

Type name

property type_id: int#

Type identifier in the simulation data file

class ansys.scadeone.core.svc.simdata.defs.PredefinedUInt16Value(value: c_ushort)#

Bases: PredefinedValue

Values for predefined type unsigned int 16

class ansys.scadeone.core.svc.simdata.defs.PredefinedUInt32Value(value: c_uint)#

Bases: PredefinedValue

Values for predefined type unsigned int 32

class ansys.scadeone.core.svc.simdata.defs.PredefinedUInt64Value(value: c_ulong)#

Bases: PredefinedValue

Values for predefined type unsigned int 64

class ansys.scadeone.core.svc.simdata.defs.PredefinedUInt8Value(value: c_ubyte)#

Bases: PredefinedValue

Values for predefined type unsigned int 8

class ansys.scadeone.core.svc.simdata.defs.PredefinedValue#

Bases: Value

Values for predefined Swan Types

class ansys.scadeone.core.svc.simdata.defs.StructType(type_id: int, fields: List[StructTypeField], name: str = '')#

Bases: Type

Structure type defined with structure type fields

property fields: List[StructTypeField]#

Structure fields

property name: str#

Type name

property type_id: int#

Type identifier in the simulation data file

class ansys.scadeone.core.svc.simdata.defs.StructTypeField(name: str, offset: int, sd_type: Type)#

Bases: object

Structure type’s fields

property name: str#

Field name

property sd_type: Type#

Field type

class ansys.scadeone.core.svc.simdata.defs.Type(type_id: int, name: str = '')#

Bases: object

Represents an abstract data type.

property name: str#

Type name

property type_id: int#

Type identifier in the simulation data file

class ansys.scadeone.core.svc.simdata.defs.UntypedVariantConstructorValue#

Bases: Value

No value to return for untyped variant constructor

class ansys.scadeone.core.svc.simdata.defs.Value#

Bases: object

Interface for all element types values that shall provide a readable string representation. Derived classes shall implement __str__() method.

class ansys.scadeone.core.svc.simdata.defs.VariantType(type_id: int, constructors: List[VariantTypeConstructor], name: str = '')#

Bases: Type

Variant type defined with variant type constructors

find_constructor(name: str) VariantTypeConstructor | None#

Find variant constructor by name

property constructors: List[VariantTypeConstructor]#

Variant constructors for each possible value of the variant

property name: str#

Type name

property type_id: int#

Type identifier in the simulation data file

class ansys.scadeone.core.svc.simdata.defs.VariantTypeConstructor(name: str, value_type: Type | None)#

Bases: object

Variant type constructor

property name: str#

Variant constructor name

property value_type: Type | None#

Variant constructor value type

class ansys.scadeone.core.svc.simdata.defs.VariantValue(name: str, value: Value | None)#

Bases: Value

Values for variant types