Overview

A yMMSL file is a YAML file that looks approximately like this:

docs/example.ymmsl
ymmsl_version: v0.1

model:
  name: macro_micro_model
  components:
    macro: my.macro_model
    micro: my.micro_model
  conduits:
    macro.state_out: micro.init_in
    micro.final_out: macro.update_in

settings:
  # Scales
  domain._muscle_grain: 0.01
  domain._muscle_extent: 1.0
  macro._muscle_timestep: 10.0
  macro._muscle_total_time: 1000.0
  micro._muscle_timestep: 0.01
  micro._muscle_total_time: 1.0

  # Global settings
  k: 1.0
  interpolation_method: linear

  # Submodel-specific setting
  micro.d: 2.3

implementations:
  my.macro_model:
    executable: /home/user/model
  my.micro_model:
    modules: gcc openmpi
    execution_model: openmpi
    executable: /home/user/model2

resources:
  macro:
    threads: 1
  micro:
    mpi_processes: 8

checkpoints:
  at_end: true
  simulation_time:
  - every: 50

This file describes a macro-micro coupled simulation model with time-scale separation and domain overlap. It describes both the model itself and an experiment to be run with this model, and contains the minimal information needed for MUSCLE 3 to be able to coordinate model execution. We’ll go into more detail on this file in a moment.

The yMMSL YAML format is supported by the ymmsl-python library, whose documentation you are currently reading. This library lets you read and write yMMSL files, and manipulate their contents using an object-based Python API.

Installation

ymmsl-python is on PyPI, so you can install it using Pip:

pip install ymmsl

or you can add it to your dependencies as usual, e.g. in your setup.py or your requirements.txt, depending on how you’ve set up your project.

Reading yMMSL files

Here is an example of loading a yMMSL file:

from pathlib import Path
import ymmsl

config = ymmsl.load(Path('example.ymmsl'))

This makes config an object of type ymmsl.Configuration, which is the top-level class describing a yMMSL document. More on these objects in the next section. The ymmsl.load() function can also load from an open file or from a string containing YAML data.

If the file is valid YAML, but not recognized as a yMMSL file, the library will raise a ymmsl.RecognitionError with a message describing in detail what is wrong, so that you can easily fix the file.

Note that the ymmsl.load() function uses the safe loading functionality of the underlying YAML library, so you can safely load files from untrusted sources.

Writing yMMSL files

To write a yMMSL file with the contents of a ymmsl.Configuration, we use ymmsl.save:

from pathlib import Path
from ymmsl import Component, Configuration, Model, Settings

model = Model('test_model', [Component('macro')])
settings = Settings(OrderedDict([('test_parameter', 42)]))
config = Configuration(model, settings)

ymmsl.save(config, Path('out.ymmsl'))

Here, we create a model named test_model, containing a single component named macro, and no conduits. For the settings, we create a Settings object, which is a container for an ordered dictionary of settings. Note that normal Python dictionaries are unordered, which is why YAML documents saved from Python are often in a random order and hard to read. We avoid that problem in yMMSL by using an OrderedDict here. You have to pass it a list of tuples, because using dictionary syntax with curly brackets will lose the ordering.

Finally, we combine the model and the settings into a yammsl.Configuration object, which we then save to a file. If you want to have the YAML as a string, use ymmsl.dump() instead.

As the format may develop over time, files are required to carry a version, in this case v0.1, which is currently the only version of yMMSL.

When you read in a yMMSL file as described above, you get a collection of Python objects describing its contents. The next section explains how those work.