Essentials

This section provides an overview of how models are structured in SysIDE Automator as well first step on importing model into Python.

Basic knowledge of SysML v2 is assumed. For those unfamiliar with the language, we recommend reviewing the SysML v2 specification.

Learn about:

Model Import

Importing the model is the first step to working with it in Python.

The easiest way to import a SysML v2 model written in textual notation into Python is to use syside.load_model function. This function returns two important objects:

  1. Model class instance containing all information from model defined by .sysml files, including elements, relationships, and their properties. Each .sysml file becomes an instance of class Document and is stored in Model.user_docs attribute

  2. Diagnostics class instance which contains any non-critical warnings that were found in the model

Example:

import syside

model, diagnostics = syside.load_model(["path_to_model.sysml"])

Note

Standard SysML v2 libraries are also imported when constructing a Model, but they are stored in Model.all_docs rather than Model.user_docs since most users won’t need to access them directly.

Note

If the loaded model contains errors, load_model function will raise an exception. If you need to be able to load a model with errors, you can use try_load_model function instead. In that case, the diagnostics will contain the errors and warnings found in the model.

Elements and Relationships

In SysML v2, a Document is constructed from Element (also known as nodes). An Element is a uniquely identified constituent of a model that can have Relationships with other Elements.

Consider this example:

part wheel{
   part wheel_rim;
   part tyre;
}

Here, we have three unique elements: wheel, wheel_rim, and tyre. In Python, these elements are represented as objects with properties assigned via attributes, such as .name.

Elements can be identified in several ways:

Note that the hierarchy is maintained through relationships. In the example, wheel owns wheel_rim and tyre, representing that the wheel is composed of these parts.

Tip

For deeper exploration of Element and other nodes:

  • Refer to the SysML v2 Language Specification Document

  • Use a Python debugger (e.g., through Visual Studio Code)

  • Utilize syside.sexp to explore model nodes

Element Types

Elements can be of different types and have hierarchical relationships. For example:

part wheel{
   attribute mass;
   action rotate;
}

In this case:

Working with Elements

Let’s explore how to work with elements using a basic example.

Example Model: copy this model into your .sysml file locally.

part wheel{
   part wheel_rim{
       part metal;
       attribute diameter;
       attribute mass = 5;
   }
   part tyre{
       part rubber;
       attribute diameter;
       attribute mass = 10;
   }
   attribute mass = wheel_rim.mass + tyre.mass;
}

Accessing Elements

To iterate over elements of a specific type, adjust the path and the name of the model, and run the code:

import syside

model, diagnostics = syside.load_model(["path_to_model.sysml"])

for element in model.elements(syside.PartUsage):
    print(element.name)

Executing the code above will print the following:

wheel
wheel_rim
tyre
metal
rubber

Working with Values

When assigning something to an Element, the structure will depend on what data type was assigned. The most general way of dealing with this is to use the Compiler to evaluate the expression that was assigned to element:

for attr_element in model.nodes(syside.AttributeUsage):
    if attr_element.name == "mass":
        expression = attr_element.feature_value_expression
        assert expression is not None
        evaluation = syside.Compiler().evaluate(expression)
        if evaluation[1].fatal:
            print(f"Error evaluating {attr_element.name}")
        else:
            value = evaluation[0]
        assert attr_element.owner is not None
        print(f"Mass of {attr_element.owner.name} = {value}")

Note that Compiler.evaluate returns a tuple with two elements: the first is the evaluation result, and the second is the evaluation report. It is good practice to check if the evaluation succeeded before using the result. Executing the code above will print the following:

Mass of wheel = 15
Mass of wheel_rim = 5
Mass of tyre = 10

Note

The Compiler is the most general way of dealing with expression evaluation, since the output is dependent on the expression – in above example it returned a number, but in the case of item driver = John it would return the ReferenceUsage instance of John. At the moment, Compiler supports evaluation of model level evaluable expressions, as defined in the specification.

Next Steps

Now that you understand the basics of SysIDE Automator’s model structure, you can proceed to the First Example section for hands-on example.