Introduction to PyMIF 1.0

The MIF 2.x (MIF/Tcl) formats discussed in the previous sections prescribe an OOMMF micromagnetic simulation in terms of its constitutive objects (Oxs_Ext elements representing energies and fields, problem geometry, system evolution, inputs and outputs) laid out and assembled by Tcl script executed by a Tcl interpreter embedded inside the Oxs solver. In practice, this means that MIF 2.x files are actual Tcl scripts extended with a handful of pre-defined Tcl procs such as Specify, Destination, and Schedule.

The concept behind the PyMIF 1.0 (MIF/Python) format is similar, but with Python replacing Tcl, and pre-defined Python functions instead of Tcl procs. The extension functions currently supported include Destination, Parameter, RandomSeed, Specify, Schedule and SetOptions. Each of these behave in the same manner as their namesake in MIF/Tcl (cf. MIF 2.1 and MIF 2.2 extension command sections) but with call signatures distinguished by differences between Tcl and Python language syntax. For example,

Destination table mmDataTable
Schedule DataTable table Step 5
in MIF/Tcl becomes
Destination('table', 'mmDataTable')
Schedule('DataTable', 'table', 'Step', 5)
in MIF/Python. A number of example MIF/Python files are included with the OOMMF distribution in the the directory oommf/app/oxs/examples_py/.

The Specify and SetOptions commands, however, have a somewhat less transparent translation. These commands take name + value pairs as imports. In MIF/Tcl these are handled as Tcl lists with an even number of elements. In MIF/Python the name + value pairs are represented by dictionaries. For example

SetOptions {
   basename acsample
   scalar_output_format "%.12g"
}
in MIF/Tcl is
SetOptions({'basename'    : 'acsample'},
   'scalar_output_format' : '%.12g'})
in MIF/Python. There is a slight twist with Specify, where the MIF/Tcl syntax
Specify Oxs_UniformExchange:uexch {
  A  13e-12
}
sets the class and instance name as a separate first parameter, followed by the name + value pair list. In the MIF/Python Specify call these are rolled into the dictionary argument:
Specify({'class' : 'Oxs_UniformExchange', 'instance' : 'uexch',
   'A' : 13e-12
})

A more complex example involving sub-lists is

Parameter cellsize 10                ;# Cell size in nm
set cellsize [expr {$cellsize*1e-9}] ;# Convert to meters
Specify Oxs_RectangularMesh:mesh [subst {
  cellsize {$cellsize $cellsize $cellsize}
  atlas :atlas
}]
This MIF/Tcl script becomes
Parameter('cellsize', 10)   # Cell size in nm
cellsize *= 1e-9            # Convert to meters
Specify({'class' : 'Oxs_RectangularMesh', 'instance' : 'mesh',
   'cellsize' : [cellsize, cellsize, cellsize],
   'atlas' : ':atlas'
})
in MIF/Python. Note in particular how the Tcl list
{$cellsize $cellsize $cellsize}
is replaced with the corresponding Python list object
[cellsize, cellsize, cellsize]

Despite the similarities, MIF/Tcl and MIF/Python 1.0 have a significant functional difference in that the latter is not processed by a Python interpreter embedded in Oxs, but is rather converted from PyMIF to MIF/Tcl by a standalone Python executable running the mifpy2tcl.py script. The Oxs executables Oxsii and Boxsi run mifpy2tcl.py on the fly as needed to process PyMIF scripts, but mifpy2tcl.py can also be run outside of Oxs. This allows one to preview and modify the MIF/Tcl version before feeding it back to Oxs for native processing.

The downside of this is that the Python processing is completed before the Oxs simulation proper begins, so it is not possible to have Python routines active inside an OOMMF simulation. This is particularly noticeable in simulations that leverage a Tcl proc to provide a time varying field pulse, such as the MIF/Tcl examples acsample.mif and pulse.mif. The work-around provided by MIF/Python 1.0 is a wrapper function, TclCode, that accepts Tcl script as a string which is passed verbatim from the MIF/Python file to the MIF/Tcl conversion. For example, the PyMIF content

TclCode(”'
proc SineField { total_time } {
   set amp 8e4
   set freq 5e9
   set Hx [expr {$amp*sin($freq*$total_time)}]
   set dHx [expr {$amp*$freq*cos($freq*$total_time)}]
   return [list $Hx 0 0 $dHx 0 0]
}
”')
Specify({'class' : 'Oxs_ScriptUZeeman',
         'script_args' : 'total_time',
         'script' : 'SineField'})
is converted into
proc SineField { total_time } {
   set amp 8e4
   set freq 5e9
   set Hx [expr {$amp*sin($freq*$total_time)}]
   set dHx [expr {$amp*$freq*cos($freq*$total_time)}]
   return [list $Hx 0 0 $dHx 0 0]
}
Specify Oxs_ScriptUZeeman {
 script_args total_time
 script SineField
}
for MIF/Tcl.

Performing variable substitutions within the TclCode string at the PyMIF script level, perhaps to support command line Parameters, is complicated by syntax collisions between Tcl and Python, particularly involving curly braces ({, }). The Python string.Template class can be employed to bypass this obstacle. See the acsample_py.mif example file in oommf/app/oxs/examples_py/ for specifics.

Note: PyMIF files are passed to a Python engine for evaluation in the same manner as other Python .py scripts, and should be treated in a like manner.


OOMMF Documentation Team
September 30, 2025