Examining MDLs Generated by CellBlender

In this tutorial, we will examine some MDL (Model Description Language) files generated by CellBlender. These MDLs are what MCell actually parses. It is possible to use CellBlender without ever having to edit or even look at an MDL. However, this section may be useful if you ever decide to hand-edit your MDL files for any reason.

Examining the Main MDL

For every CellBlender project, you will have a blend file and corresponding directory (note: the directory will only appear once you run a simulation). For instance, if you have a blend file called intro.blend, then you will also have a folder called intro_files. All of the input and output files generated by CellBlender and MCell are stored within this directory (including MDLs, reaction data, and visualization data). To be more specific, they are actually inside a sub-directory called mcell. In this example, they would be in ./intro_files/mcell.

Every project will have a file called Scene.main.mdl, which will look something like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
ITERATIONS = 1000
TIME_STEP = 1e-05

INCLUDE_FILE = "Scene.initialization.mdl"

INCLUDE_FILE = "Scene.molecules.mdl"

INCLUDE_FILE = "Scene.reactions.mdl"

INCLUDE_FILE = "Scene.geometry.mdl"

INSTANTIATE Scene OBJECT
{
  Cube OBJECT Cube {}
  vol1_rel RELEASE_SITE
  {
   SHAPE = Scene.Cube
   MOLECULE = vol1
   NUMBER_TO_RELEASE = 2000
   RELEASE_PROBABILITY = 1
  }
  surf1_rel RELEASE_SITE
  {
   SHAPE = Scene.Cube[top]
   MOLECULE = surf1'
   NUMBER_TO_RELEASE = 2000
   RELEASE_PROBABILITY = 1
  }
}

sprintf(seed,"%05g",SEED)

INCLUDE_FILE = "Scene.viz_output.mdl"

INCLUDE_FILE = "Scene.rxn_output.mdl"

The first two lines are Initialization Commands that we'll cover in the next section.

INCLUDE_FILE commands let you break up MDLs into multiple sections. Examples of this can be seen on lines 4-10 and 33-35. Scene.initialization.mdl contains advanced initialization commands, Scene.molecules.mdl contains molecule definitions, Scene.reactions.mdl contains reaction definitions, Scene.geometry.mdl contains the the vertices and faces that make up our Cube, Scene.viz_output.mdl contains the MCell visualization data output (i.e. what molecule species should be visualized and at what iterations), and Scene.rxn_output.mdl contains the MCell reaction data output (i.e. what molecule species should be counted and where).

In addition to simply including meshes, you also have to INSTANTIATE meshes to make them exist and interact in the simulation, starting on line 12. You can see we're also instantiating another type of object called a RELEASE_SITE, which we'll discuss later in the Release Sites section.

Initialization Commands

At the beginning of the file are the initialization commands, TIME_STEP and ITERATIONS. As the names imply, these commands control how many ITERATIONS the simulation runs for, with each iteration lasting one TIME_STEP (units are seconds).

Notice that ITERATIONS is set to 1000 and TIME_STEP to 1e-5. This means that the simulation will run for 1000 iterations at a time step of 1e-5 seconds (total time: 1000*1e-5=0.01 seconds).

Geometry Files

Your geometry will be stored in Scene.geometry.mdl:

Cube POLYGON_LIST
{
  VERTEX_LIST
  {
    [ 1, 0.999999940395355, -1 ]
    [ 1, -1, -1 ]
    [ -1.00000011920929, -0.999999821186066, -1 ]
    [ -0.999999642372131, 1.00000035762787, -1 ]
    [ 1.00000047683716, 0.999999463558197, 1 ]
    [ 0.999999344348907, -1.00000059604645, 1 ]
    [ -1.00000035762787, -0.999999642372131, 1 ]
    [ -0.999999940395355, 1, 1 ]
  }
  ELEMENT_CONNECTIONS
  {
    [ 0, 1, 2 ]
    [ 4, 7, 5 ]
    [ 0, 4, 1 ]
    [ 1, 5, 2 ]
    [ 2, 6, 7 ]
    [ 4, 0, 3 ]
    [ 3, 0, 2 ]
    [ 4, 5, 1 ]
    [ 5, 6, 2 ]
    [ 3, 2, 7 ]
    [ 7, 4, 3 ]
    [ 7, 6, 5 ]
  }
  DEFINE_SURFACE_REGIONS
  {
    top
    {
      ELEMENT_LIST = [8, 9]
    }
  }
}

Mesh objects made in Blender become a POLYGON_LIST object in MCell. A POLYGON_LIST object consists of two to three sections in MCell: a VERTEX_LIST, an ELEMENT_CONNECTIONS list, and optionally a DEFINE_SURFACE_REGIONS section. A VERTEX_LIST is exactly what it sounds like, a list of vertices. The ELEMENT_CONNECTIONS list defines the faces of the triangles. Each number in the list is an index to a single vertex defined in the VERTEX_LIST. Each set of three numbers (e.g. [ 0, 1, 2 ]) tells which vertices are connected together to form a single face. DEFINE_SURFACE_REGIONS is optional, unless you want to specify specify surface regions. Each number in the ELEMENT_LIST is an index to a triangle in ELEMENT_CONNECTIONS.

Molecule Definitions

Molecules need to be defined before they are used (as a release site or a reaction) in the MDL.

Open the Scene.molecules.mdl file, and you'll see the following:

DEFINE_MOLECULES
{
  vol1
  {
    DIFFUSION_CONSTANT_3D = 1e-06
  }
  vol2
  {
    DIFFUSION_CONSTANT_3D = 1e-06
  }
  surf1
  {
    DIFFUSION_CONSTANT_2D = 1e-07
  }
}

Molecules that use DIFFUSION_CONSTANT_3D command, like vol1 and vol2, will be volume molecules, meaning that they will exist in solution. Molecules that use DIFFUSION_CONSTANT_2D, like surf1, will be surface molecules, meaning that they exist on a surface. The units of the values assigned to this command (1E-6 and 1E-7 in this instance) are in cm2/s.

Reactions

Molecules that were defined in the previous section can be created and destroyed in a number of different ways using reactions. A reaction is defined in the following manner:

reactant(s) -> product(s) [rate]

This means that reactant(s) are converted into product(s) at a given rate.

There must be one or more molecules on the left hand reactants side. On the right hand products side, you must have zero ( NULL) or more molecules. The units of the rate depend on the type of reaction. [s-1] for unimolecular reactions and [M-1s-1] for bimolecular reactions between two volume molecules or a volume molecule and a surface molecule.

Reaction Directionality

Surface molecules have a TOP and a BOTTOM, so we need a way to differentiate between reactions that happen on one side versus the other. Commas (,), ticks ('), and semi-colons (;) serve this purpose. For detailed information on this reaction syntax, please refer to this pdf. Let's look at the relatively simple example we have created in Scene.reactions.mdl:

DEFINE_REACTIONS
{
  vol1' + surf1, -> surf1, + vol2, [1e+08]
}

Read this next section carefully, as some people find this syntax confusing at first. If a volume molecule and a surface molecule have their orientations opposed (i.e. a tick and a comma), then the volume molecule interacts with the BOTTOM of the surface molecule. If a volume molecule and a surface molecule have their orientations aligned (i.e. two ticks or two commas), then the volume molecule interacts with the TOP of the surface molecule.

For this reaction, vol1 and surf1 are opposed (a comma and a tick), and vol2 and surf1 are aligned (two commas). This means that vol1 will react with the BOTTOM of surf1, creating vol2 at the TOP of surf1. Since vol1 is not on the products side, it is destroyed when it reacts with surf1. Conversely, surf1 is on both the reactant and product side, so it will not be destroyed from the reaction.

The directionality of these ticks and commas are relative, which means that we could flip the signs and get the same result, like this:

DEFINE_REACTIONS
{
  vol1, + surf1' -> surf1' + vol2' [1e+08]
}

Release Sites

Let's examine the INSTANTIATE section of Scene.main.mdl more closely:

INSTANTIATE Scene OBJECT
{
  Cube OBJECT Cube {}
  vol1_rel RELEASE_SITE
  {
   SHAPE = Scene.Cube
   MOLECULE = vol1
   NUMBER_TO_RELEASE = 2000
   RELEASE_PROBABILITY = 1
  }
  surf1_rel RELEASE_SITE
  {
   SHAPE = Scene.Cube[top]
   MOLECULE = surf1'
   NUMBER_TO_RELEASE = 2000
   RELEASE_PROBABILITY = 1
  }
}

This section creates two release sites, one called vol1_rel and the other surf1_rel. Each release site can take a number of different commands.

The SHAPE of the release determines what object (or region of an object) that molecules are released onto or into. You can also use some predefined shapes, like CUBIC or SPHERICAL, but we won't cover that here.

MOLECULE determines what molecule is released. If it is a surface molecule, an orientation is also specified This is similar to what's described in Reaction Directionality, but it is not relative. A tick means that the TOP of the molecule is aligned with the FRONT of the surface, and a comma means that the TOP is aligned with the BACK of the surface.

NUMBER_TO_RELEASE gives an absolute number of molecules to be released. Alternatively, one could define a CONCENTRATION (for volume molecules) or DENSITY (for surface molecules).

These two release sites together will release 2000 vol1 molecules randomly throughout the inside of Scene.Cube and also 2000 surf1 molecules randomly on the top surface region of Scene.Cube. Also, the TOP of surf1 will be aligned with the FRONT of the surface.

Visualization Data

Open the file called Scene.viz_output.mdl with the following text in it:

VIZ_OUTPUT
{
  MODE = CELLBLENDER
  FILENAME = "./viz_data/seed_" & seed & "/Scene"
  MOLECULES
  {
    NAME_LIST {vol1 vol2 surf1}
    ITERATION_NUMBERS {ALL_DATA @ ALL_ITERATIONS}
  }
}

The VIZ_OUTPUT section specifies what visualization data to export and at what time values. Right now, it is set to export everything at all iterations.

Reaction Data

Now, create a file called Scene.rxn_output.mdl:

REACTION_DATA_OUTPUT
{
  STEP=1e-05
  {COUNT[surf1,WORLD]}=> "./react_data/seed_" & seed & "/surf1.World.dat"
  {COUNT[vol1,WORLD]}=> "./react_data/seed_" & seed & "/vol1.World.dat"
  {COUNT[vol2,WORLD]}=> "./react_data/seed_" & seed & "/vol2.World.dat"
}

The STEP command tells MCell how often it should write out reaction data.

The brackets after the COUNT command tell MCell what molecule to count and where to count it. For instance the first COUNT statement tells it to count all of the vol1 molecules in the WORLD (the entire simulation). Alternatively, you could specify that it only count those found in/on an object/region (e.g. [vol1,Scene.Cube])

The file listed after the arrow symbol (=>) tells it where to save it.

Examine the Log Data

CellBlender should have created two log files with names similar to this:

log.2013-05-07_16:29_1.txt.
log.2013-05-07_16:29_2.txt.

If you do not see these files, it means an error was encountered. By default, errors are printed to the command line, but they can also be saved just like the log files (e.g. error.2013-05-07_16:29_2.txt.) in the Run Simulation panel. Note that this includes the date, time, and seed value. If you open the file, you will see the following:

MCell 3.1 (revision 998/2012-08-29 16:46:46 -0700)
  Running on jacob-PRO114978 at Wed May  8 12:19:26 2013

  Copyright (C) 2006 - 2010 by
    Pittsburgh Supercomputing Center, Carnegie Mellon University and
    The Salk Institute for Biological Studies

MCell initializing simulation...
MCell[0]: random sequence 1
Defining molecules with the following theoretical average diffusion distances:
  l_r_bar=0.0713649646 um for vol1
  l_r_bar=0.0713649646 um for vol2
  l_r_bar=0.0560499122 um for surf1


Reaction probabilities generated for the following reactions:
    Probability 9.3073e-01 set for surf1{-1} + vol1{1} -> surf1{-1} vol2{-1}

Creating geometry (this may take some time)
MCell: world bounding box in microns =
         [ -1.00000036 -1.0000006 -1 ] [ 1.00000048 1.00000036 1 ]
Creating 125 subvolumes (5,5,5 per axis).
Creating 1 memory partitions (1,1,1 per axis).
Instantiating objects...
Creating walls...
Creating edges...
Running simulation.
Releasing 2000 molecules vol1 ...  Released 2000 vol1 from "Scene.vol1_rel" at iteration 0.
Releasing 2000 molecules surf1 ...  Released 2000 surf1 from "Scene.surf1_rel" at iteration 0.
Iterations: 0 of 1000
Iterations: 100 of 1000  (459.781 iter/sec)
Iterations: 200 of 1000  (459.844 iter/sec)
Iterations: 300 of 1000  (461.076 iter/sec)
Iterations: 400 of 1000  (446.614 iter/sec)
Iterations: 500 of 1000  (318.155 iter/sec)
Iterations: 600 of 1000  (462.592 iter/sec)
Iterations: 700 of 1000  (463.891 iter/sec)
Iterations: 800 of 1000  (439.014 iter/sec)
Iterations: 900 of 1000  (457.831 iter/sec)
Iterations: 1000 of 1000  (454.612 iter/sec)
Exiting run loop.
iterations = 1000 ; elapsed time = 0.01 seconds
Average diffusion jump was 1.00 timesteps

Total number of random number use: 8850744
Total number of ray-subvolume intersection tests: 2319051
Total number of ray-polygon intersection tests: 6016068
Total number of ray-polygon intersections: 97381
Initialization CPU time = 0.048000 (user) and 0.004000 (system)
Simulation CPU time = 2.064000 (user) and 0.120000 (system)
Total wall clock time = 2 seconds
Done running.

This file contains potentially useful information, such as reaction probabilities, the number of molecules released, and how many iterations are completed per second.