14.9. stepsblender

The stepsblender package allows to visualize data recorded in HDF5 files.

14.9.1. stepsblender.load

Visualize STEPS simulations with Blender.

usage: python3 -m stepsblender.load [HDFPath] [-h] [--server server_address] ...

14.9.1.1. Positional Arguments

HDFPath

Path prefix to a STEPS HDF5 file or, if the –server option is used, this should not be provided

14.9.1.2. Named Arguments

--serverpython

Python binary used to launch the data loading server

Default: 'python3'

--blenderPath

Path to the blender executable

Default: 'blender'

--blenderArgs

Path to the blender file that should be used and / or other blender arguments in double quotes

--LinkSpecies.sampleLinkSpecies.links.obj.cast_shadows

Whether the object casts shadows. Possible values: [“ON”, “OFF”] (only for Blender >= 4.2)

--LinkSpecies.sampleLinkSpecies.links.obj.material.alpha

Alpha transparency level

--LinkSpecies.sampleLinkSpecies.links.obj.material.color

An RGBA tuple that should be supplied with quotes e.g. “(0.1, 0.5, 0.1, 1)”

--LinkSpecies.sampleLinkSpecies.links.obj.material.emission

Emission strength

--LinkSpecies.sampleLinkSpecies.links.obj.mesh.bevel_depth

Width of the link, defaults to 0.8 times the species radius

--LinkSpecies.sampleLinkSpecies.specs.obj.cast_shadows

Whether the object casts shadows. Possible values: [“ON”, “OFF”] (only for Blender >= 4.2)

--LinkSpecies.sampleLinkSpecies.specs.obj.material.alpha

Alpha transparency level

--LinkSpecies.sampleLinkSpecies.specs.obj.material.color

An RGBA tuple that should be supplied with quotes e.g. “(0.1, 0.5, 0.1, 1)”

--LinkSpecies.sampleLinkSpecies.specs.obj.material.emission

Emission strength

--LinkSpecies.sampleLinkSpecies.specs.obj.mesh.radius

Radius of the sphere

--LinkSpecies.sampleLinkSpecies.specs.obj.mesh.subdivisions

Number of subdivisions

--Meshes.sampleMesh.cast_shadows

Whether the object casts shadows. Possible values: [“ON”, “OFF”] (only for Blender >= 4.2)

--Meshes.sampleMesh.material.alpha

Alpha transparency level

--Meshes.sampleMesh.material.color

An RGBA tuple that should be supplied with quotes e.g. “(0.1, 0.5, 0.1, 1)”

--Meshes.sampleMesh.material.emission

Emission strength

--Meshes.sampleMesh.mesh.smooth_angle

Angle for smooth shading (in radians)

--Meshes.sampleMesh.surfaceThickness

The thickness of the mesh surface, should be greater than 0 if rafts are present on the surface

--Rafts.sampleRaft.obj.cast_shadows

Whether the object casts shadows. Possible values: [“ON”, “OFF”] (only for Blender >= 4.2)

--Rafts.sampleRaft.obj.material.alpha

Alpha transparency level

--Rafts.sampleRaft.obj.material.color

An RGBA tuple that should be supplied with quotes e.g. “(0.1, 0.5, 0.1, 1)”

--Rafts.sampleRaft.obj.material.emission

Emission strength

--Rafts.sampleRaft.obj.material.outline_color

An RGBA tuple that should be supplied with quotes e.g. “(0.1, 0.5, 0.1, 1)”

--Rafts.sampleRaft.obj.material.outline_frac

Fraction of the raft radius that defines the raft border

--Rafts.sampleRaft.obj.mesh.subdivisions

Number of subdivisions

--Species.sampleSpecies.obj.cast_shadows

Whether the object casts shadows. Possible values: [“ON”, “OFF”] (only for Blender >= 4.2)

--Species.sampleSpecies.obj.material.alpha

Alpha transparency level

--Species.sampleSpecies.obj.material.color

An RGBA tuple that should be supplied with quotes e.g. “(0.1, 0.5, 0.1, 1)”

--Species.sampleSpecies.obj.material.emission

Emission strength

--Species.sampleSpecies.obj.mesh.radius

Radius of the sphere

--Species.sampleSpecies.obj.mesh.subdivisions

Number of subdivisions

--VesiclePaths.sampleVesiclePath.cast_shadows

Whether the object casts shadows. Possible values: [“ON”, “OFF”] (only for Blender >= 4.2)

--VesiclePaths.sampleVesiclePath.material.alpha

Alpha transparency level

--VesiclePaths.sampleVesiclePath.material.color

An RGBA tuple that should be supplied with quotes e.g. “(0.1, 0.5, 0.1, 1)”

--VesiclePaths.sampleVesiclePath.material.emission

Emission strength

--VesiclePaths.sampleVesiclePath.mesh.path_thickness

Thickness to the path

--Vesicles.sampleVesicle.immobileSpecs

Comma-separated list of species (without spaces) that should not be animated in between saving time points

--Vesicles.sampleVesicle.innerSpecMargin

Outer fraction of the vesicle radius that is free of inner species

--Vesicles.sampleVesicle.obj.cast_shadows

Whether the object casts shadows. Possible values: [“ON”, “OFF”] (only for Blender >= 4.2)

--Vesicles.sampleVesicle.obj.material.alpha

Alpha transparency level

--Vesicles.sampleVesicle.obj.material.color

An RGBA tuple that should be supplied with quotes e.g. “(0.1, 0.5, 0.1, 1)”

--Vesicles.sampleVesicle.obj.material.facing_blend

Gradient of the inner color

--Vesicles.sampleVesicle.obj.material.fresnel_IOR

Fresnel Index Of Refraction

--Vesicles.sampleVesicle.obj.material.fresnel_multiplier

Strength of the outer rim

--Vesicles.sampleVesicle.obj.material.outline_color

An RGBA tuple that should be supplied with quotes e.g. “(0.1, 0.5, 0.1, 1)”

--Vesicles.sampleVesicle.obj.material.shadow_method

Blender shadow method (only for Blender < 4.2)

--Vesicles.sampleVesicle.obj.mesh.subdivisions

Number of subdivisions

--Vesicles.sampleVesicle.pathLinks.obj.cast_shadows

Whether the object casts shadows. Possible values: [“ON”, “OFF”] (only for Blender >= 4.2)

--Vesicles.sampleVesicle.pathLinks.obj.material.alpha

Alpha transparency level

--Vesicles.sampleVesicle.pathLinks.obj.material.color

An RGBA tuple that should be supplied with quotes e.g. “(0.1, 0.5, 0.1, 1)”

--Vesicles.sampleVesicle.pathLinks.obj.material.emission

Emission strength

--Vesicles.sampleVesicle.pathLinks.obj.mesh.bevel_depth

Width of the link, defaults to 0.8 times the species radius

--addSubPatches

Add subparts of patches, like regions of interest, as surface meshes.

--authkey

Authentication key to connect to the data loading server

--background_color

An RGBA tuple that should be supplied with quotes e.g. “(0.1, 0.5, 0.1, 1)” Color of the background

--cycles_shadows

Make global light cast shadows with the cycles render engine

--dbInd

Unique run group identifier, only needed if several run groups exist in the file (see the documentation of steps.API_2.sim.Simulation.toDB)

--exclude

Comma-separated list of regular expressions that controls which STEPS objects are prevented from being loaded in Blender

--ignore_version

Ignore the Blender version checks.

--include

Comma-separated list of regular expressions that controls which STEPS objects get loaded in Blender

--intersectAlgo

Intersection computation algorithm, defaults to “FAST” but uses “EXACT” when rendering to prevent visual bugs, “NONE” to turn it off

--outputPath

Path to which rendered frames should be saved when using the –render option, defaults to working directory

--port

Port to connect to on the data loading server

--rInd

Run index, defaults to -1 (last run in the run group)

--render

Whether the script should launch Blender in background mode and automatically render each frame

--renderEnd

End frame for rendering (exclusive). If -1, will use the end frame from the file

--renderStart

Start frame for rendering. If -1, will use the start frame from the file

--renderStep

Frame step for rendering, allows to skip some frames if it is higher than 1

--scale

Spatial scale factor

--server

Address of the data loading server

--specScaleFactor

Size of species compared to the mean tetrahedron size

--timeInterpFunc.n
--timeScale

Temporal scale factor

Optional arguments that contain dots like e.g. –Species.sampleSpecies.obj.material.color can be used to set the properties of specific STEPS objects in the visualization. The “sampleSpecies” part should be replaced by the STEPS name of the species in order to get a valid argument. For example, one can set the color of species S1 with:

--Species.S1.obj.material.color "(1, 0, 0, 1)"

But not all parts are required, it is also possible to set the same value with:

--S1.color "(1, 0, 0, 1)"

The class of objects used for visualization can also be changed with a similar syntax. For example, one can visualize membrane potential by using the StateDepMeshMaterial material class:

--Meshes.material.__class__ objects.StateDepMeshMaterial

The class needs to be given with the module it is defined in (here it is objects). Additional parameters for setting the voltage range and colormap are listed in objects.ShaderNodeMathRescale and objects.ShaderNodeColorMap respectively.

A higher degree of control over how data is visualized can be achieved by writing a custom python script instead of calling this command.

For more details, see the documentation of stepsblender.utils.HierarchicalParamReader.

14.9.2. stepsblender.dataloader

Start a data loading server for Blender visualization.

usage: python -m stepsblender.dataloader [-h] [--port PORT]
                                         [--authkey AUTHKEY]
                                         HDFPath

14.9.2.1. Positional Arguments

HDFPath

The path prefix to a STEPS HDF5 file (see the documentation of steps.API_2.saving.HDF5Handler)

14.9.2.2. Named Arguments

--port

Port to connect to on the data loading server

Default: 57395

--authkey

Authentication key to connect to the data loading server

Default: 'STEPSBlender'

14.9.3. stepsblender.utils

class HierarchicalParameters(parameters={})[source]

Class for holding hierarchies of parameters

This class holds several levels of parameter dictionaries and allows the retrieval of parameter values by iterating through levels, starting with the most specific. The hierarchy is built from nested dictionnaries, for example:

parameters = {
    'color': (1, 0, 0, 1),         # Red
    'Species': {
        'color': (0, 1, 0, 1),     # Green
        'radius': 0.01,
        'S1': {
            'radius': 0.02,
            'color': (0, 0, 1, 1), # Blue
        },
    },
}

If these parameters are given to HDF5BlenderLoader, all objects that declared a radius or color attribute in their class (see HierarchicalParamReader), will get a value that depends on their position in the object hierarchy (abridged here):

Loader -----> Species ---> S1 --> mesh     | radius == 0.02
       \              \       \-> material | color  == Blue
        \              \-> S2 --> mesh     | radius == 0.01
         \                    \-> material | color  == Green
          \-> Vesicles --> V1 --> mesh     |
                              \-> material | color  == Red

When retrieving the color value for the material of species S2, we first try to find the most specific value: parameters['Species']['S2']['material']['color'], if this does not exist, we then try parameters['Species']['S2']['color'], then parameters['Species']['color'] which exist in our example, so the color is set to green. For species S1, parameters['Species']['S1']['material']['color'] does not exist but parameters['Species']['S1']['color'] does, the color is thus set to blue.

In addition to specifying hierarchies of parameter values, one can also change the class that will be used to instantiate any object in the hierarchy, for example, to provide a custom material for species of type S2, we would give:

parameters = {
    'S2' : {
        'material': {
            '__class__': MyCustomMaterialClass,
            'myCustomParameter': 5.0,
        },
    },
}

With MyCustomMaterialClass inheriting from BlenderMaterial and having myCustomParameter as class attribute (see HierarchicalParamReader). Note that we did not have to specify the full hierarchy, we skipped the Species object, which means that if we have a link species called S2, the custom material will be applied to it.

Finally, parameter objects that inherit from BlenderWrapper can be loaded from the Blender file by giving the name of the blender object. For example, if we created a material in Blender called 'myCustomMaterial', we could assign it to Species S2 with:

parameters = {
    'S2' : {
        'material': 'myCustomMaterial',
    },
}
class HierarchicalParamReader(parameters=None, **kwargs)[source]

Base class for all classes that can be initialized from hierarchical parameters

The parameter hierarchy mirrors the hierarchy of HierarchicalParamReader objects. Classes that inherit from HierarchicalParamReader should declare the parameters that they require as class attributes. The value of the class attribute will be the default value given to the instance attribute.

Example:

class classA(HierarchicalParamReader):
    val1 = 1.0
    val2 = 'str'

a = classA(parameters={val1: 2})

This code leads to a.val1 == 2 and a.val2 == 'str'.

If the default value is a class that inherits from HierarchicalParamReader, an object from this class will be instantiated and recursively initialized with the HierarchicalParameters object.

By default, all HierarchicalParamReader instances have a parent and nameInParent attributes that will be filled in at instanciation.

Example:

class classB(HierarchicalParamReader):
    objA = classA
    val3 = 5.0

objB = classB(parameters={'objA':{'val1':2}})

This code leads to objA being automatically instantiated with:

objB.objA.parent == objB
objB.objA.nameInParent == 'objA'

When creating an object, one can also pass keyword arguments to the constructors, they will be treated as if they were part of the hierarchical parameters but will have lower priority.

Example:

a = classA(parameters={val1: 2})           # with the `parameters` object only

a = classA(val1=2)                         # Equivalent to previous call

a = classA(parameters={'val1': 3}, val1=2) # val1 will be initialized to 3,
                                           # because it has higher priority

Keyword argument can thus be treated as default values given at the time of instanciation, they will override the default value given in the class declaration, but will be overridden by parameters given in the HierarchicalParameters object.

If the parameter should be of a given class that inherits from HierarchicalParamReader but its default value should be None, the class should be specified through python annotations.

Example:

class classC(HierarchicalParamReader):
    objB: classB = None

c1 = classC(parameters={})                     # Will lead to c1.objB == None

c2 = classC(parameters={'objB': {'val3: 10'}}) # Will lead to c1.objB being an object of
                                               # classB with c1.objB.val3 == 10

Finally, additional annotations about a parameter can be supplied by using typing.Annotated to wrap the type of the parameter.

Example:

class MyClass(HierarchicalParamReader):
    param1: typing.Annotated[int, 'Description of the parameter'] = 42
    param2: typing.Annotated[str, dict(help='Description', metavar='/path/to/file')] = None

class MySubClass(MyClass):
    param1 = 123

Note that subclasses that would want to change the default value of the parameter do not need to re-annotate it.

If a string is given as a second parameter to typing.Annotated, it will be interpreted as the description of the parameter. If a dictionary is given, it will be supplied as keyword arguments to argparse.ArgumentParser.add_argument() in the stepsblender.load module to automatically add the parameter as a command-line argument.

Simple types like int and float will be converted from the string provided as a command-line argument to the correct value, more complex types might require additional implementation, see for example stepsblender.utils.makeCreatableFromStr().

static getAllAnnotations(cls)[source]

Return all annotations from a class and its parents

classmethod using(**kwargs)[source]

Create a subclass of cls that uses the given keyword arguments as attributes / default value

AddBlenderDataSaving(sim, verbose=True, **kwargs)[source]

Add result selectors saving all data that can be visualized in Blender

Parameters:

Usage example:

AddBlenderDataSaving(sim, dt=1e-3)

14.9.4. stepsblender.state

class StateDependentObject(**kwargs)[source]

Base class for objects whose material can change as a funciton of its state

This class can be used in place of BlenderObject to customize the material of the object as a function of the state of the STEPS object.

There are two possible ways to achieve this:
  • Use a small number of materials that are already declared in the Blender file;

  • Programatically customize the material of the object.

The first way is done by setting the setMaterialFunc parameter to a function with the following signature:

def myCustomMatSetFunc(scene, depg, state) -> str

The first two parameters are passed from the bpy.app.handlers.frame_change_pre callback function (see https://docs.blender.org/api/current/bpy.app.handlers.html). The third parameter contains the state of the object (see table in StateDependentMesh). The function should return a string that is the name of a material in the Blender file.

The second way is done by setting the updateMaterialFunc parameter to a function with the following signature:

def myCustomMatUpdateFunc(scene, depg, material, state) -> None

The first two parameters are identical. The third parameter is the bpy.types.Material object that is attributed to the object and should be modified by the function. The last parameter is the state of the object (see tables in StateDependentMesh).

class StateDependentSeparateObjects(**kwargs)[source]

Base class for state-dependent objects like Vesicles or Rafts

This class can be used in place of SeparateObjects to customize the material of each object as a function of the state of the STEPS object (its position, the species on its surface, etc.).

There are two possible ways to achieve this:
  • Use a small number of materials that are already declared in the Blender file;

  • Programatically customize the material of each object.

The first way is done by setting the setMaterialFunc parameter to a function with the following signature:

def myCustomMatSetFunc(scene, depg, state) -> str

The first two parameters are passed from the bpy.app.handlers.frame_change_pre callback function (see https://docs.blender.org/api/current/bpy.app.handlers.html). The third parameter contains the state of the object (see tables in StateDependentVesicle or StateDependentRaft). The function should return a string that is the name of a material in the Blender file.

The second way is done by setting the updateMaterialFunc parameter to a function with the following signature:

def myCustomMatUpdateFunc(scene, depg, material, state) -> None

The first two parameters are identical. The third parameter is the bpy.types.Material object that is attributed to the object and should be modified by the function. The last parameter is the state of the object (see tables in StateDependentVesicle or StateDependentRaft).

14.9.5. stepsblender.statedep

class StateDependentVesicles(**kwargs)[source]

Subclass of BlenderVesicles that allows to dynamically change material of vesicles

See StateDependentSeparateObjects for information about material set and update functions.

The state parameter given to both functions is a dictionary that contains the following values:

Name

Example

Description

idx

45

Index of the specific vesicle

position

[x, y, z]

3D position of the vesicle in cartesian coordinates

name

'Ves1'

Name of the vesicle type in STEPS

surface_species

{'S1':[
  (r1, theta1, phi1),
  (r2, theta2, phi2),
...], ...}

Dictionary of species name to list of spherical coordinate positions relative to the vesicle

inside_species

{'S1': 10, ...}

Dictionary of species name to count

link_species

{'L1':
  {123: {
    'position': [r, theta, phi]
    'link': 456},
  ...}, ...}

Dictionary of link species name to dictionary of specific link species to 3D position in relative spherical coordinates and corresponding link species

on_path

[x, y, z]

3D position of the path point to which the vesicle is bound. None if not bound

Example:

def redBoundVesicles(scene, depg, material, state):
    bsdf = material.node_tree.nodes['Principled BSDF']
    if 'L1' in state['link_species']:
        bsdf.inputs['Emission Color'].default_value = (1, 0, 0, 1) # Red
    else:
        bsdf.inputs['Emission Color'].default_value = (0, 1, 0, 1) # Green

parameters = {'Ves1': StateDependentVesicles, 'updateMaterialFunc': redBoundVesicles}

loader = HDF5BlenderLoader(parameters=parameters, ...)

This example will display all vesicles that have link species 'L1' on their surface as red and all other vesicles as green.

class StateDependentRafts(**kwargs)[source]

Subclass of BlenderRafts that allows to dynamically change material of rafts

See StateDependentSeparateObjects for information about material set and update functions.

The state parameter given to both functions is a dictionary that contains the following values:

Name

Example

Description

idx

45

Index of the specific raft

position

[x, y, z]

3D position of the raft in cartesian coordinates

name

'Raft1'

Name of the raft type in STEPS

surface_species

{'S1': 0, 'S2':5, ...}

Dictionary of species name to counts

Example:

def redS1Rafts(scene, depg, material, state):
    bsdf = material.node_tree.nodes['Principled BSDF']
    if 'S1' in state['surface_species']:
        bsdf.inputs['Emission Color'].default_value = (1, 0, 0, 1) # Red
    else:
        bsdf.inputs['Emission Color'].default_value = (0, 1, 0, 1) # Green

parameters = {'Raft1': StateDependentRafts, 'updateMaterialFunc': redS1Rafts}

loader = HDF5BlenderLoader(parameters=parameters, ...)

This example will display all rafts that have species 'S1' on their surface as red and all other rafts as green.

class StateDependentMesh(**kwargs)[source]

Subclass of STEPSMeshObject that allows to dynamically change the material of a mesh

See StateDependentObject for information about material set and update functions.

The state parameter given to both functions is a dictionary that contains the following values:

Name

Example

Description

time

0.23

Simulation time

Example:

def meshEmission(scene, depg, material, state):
    bsdf = material.node_tree.nodes['Principled BSDF']

    if 0.001 <= state['time'] < 0.002:
    if 'S1' in state['surface_species']:
        bsdf.inputs['Emission Strength'].default_value = 5
    else:
        bsdf.inputs['Emission Strength'].default_value = 0

parameters = {'Membrane': StateDependentMesh, 'updateMaterialFunc': meshEmission}

loader = HDF5BlenderLoader(parameters=parameters, ...)

This example will increase the mesh emission strength between 1 and 2ms to visually convey e.g. a current injection.