Compact model specification with user-defined types
A proposal for supporting models of synapses and other user-definable component types in NeuroML
Current version: 0.8.2 4-Nov-2011 These pages as a single PDF
LEMS - Low Entropy Model Specification
This proposal consists of:
- A An overview of how types and models are declared
- A set of XML elements for defining and using user-defined types
- A proof-of-concept interpreter for processing and running models built with these elements
- Some examples (left menu) illustrating how elements can be defined and used.
- A summary of the canonical form for a model that corresponds to the elements presented here
- Miscellaneous discussion of the objectives, design issues, benefits and weaknesses of this approach
The best place to start is probably the first example. Anyone familiar with modeling and model specification should be able to read the XML and make out what is going on.
After that, feel free to download the interpreter, run the examples, and try constructing your own.
What it does so far
You can define ComponentTypes (e.g. a "HH channel" or "a bi-exponential synapse") which express the general properties of a particular type of thing that goes in a model. This includes saying what parameters they have, what child elements they are allowed, and how they behave (the equations).
You can then define Components based on these types by supplying values for the parameters and adding any child elements that are required, so, for example, a bi-exponential synapse model with rise time 1ms and decay 5ms would be a component.
ComponentTypes can extend other ComponentTypes to add extra parameters, fix certain values, and otherwise modify their behavior. Components can extend other Components to reuse specified parameter values. There is also a loose notion of abstract types, so a component can accept children with a particular lineage without needing to know exactly what type they are. This can be used, for example, to define cells that accept synaptic connections provided they have a particular signature.
Each ComponentType can have a Behavior element that specifies how it behaves: what the state variables are, the equations that govern them, and what happens when events are sent or received. The interpreter takes a model consisting of type and component elements referenced from a network, builds an instance from them and runs it.
For those familiar with object oriented languages, the ComponentType/Component distinction is close to the normal Class/Instance distinction. When the model is run, the same pattern applies again, with the Components acting as class definitions, with their "instances" actually containing the state variables in the running mode.
The March 2010 NeuroML meeting identified a need to extend the capability within NeuroML for expressing a range of models of synapses. It was decided that the hitherto adopted approach of defining parameterized building blocks to construct models by combining blocks and setting parameters was unlikely to be flexible enough to cope with the needs for synapse models. This is not obvious a-priori, since, for example, the pre NeuroML 2.0 ion channel building blocks are fully adequate to describe the Behavior of a wide range existing channel models. But there appears to be no such commonality in models used for synapses, where the mechanisms used range from highly detailed biochemical models to much more abstract ones.
This work also has antecedents in Catacomb 3, which was essentially a GUI for a component definition system and model builder using a type system similar to that proposed here. Much of the XML processing code used in the interpreter was taken from PSICS which itself currently uses the "building block" approach to model specification. The need for user-defined types has been considered with respect to future PSICS development, and this proposal also reflects potential requirements for PSICS.
Here is the XML for a simple integrate-and-fire cell definition:
<Parameter name="threshold" dimension="voltage" />
<Parameter name="refractoryPeriod" dimension="time" />
<Parameter name="capacitance" dimension="capacitance" />
<Parameter name="vleak" dimension="voltage" />
<Parameter name="gleak" dimension="conductance" />
<Parameter name="current" dimension="current" />
<Parameter name="vreset" dimension="voltage" />
<Parameter name="deltaV" dimension="voltage" />
<Parameter name="v0" dimension="voltage" />
<EventPort name="out" direction="out" />
<EventPort name="in" direction="in" />
<Exposure name="v" dimension="voltage" />
<StateVariable name="v" exposure="v" dimension="voltage" />
<StateAssignment variable="v" value="v0" />
<StateVariable name="tin" dimension="time" />
<StateAssignment variable="tin" value="t" />
<StateAssignment variable="v" value="vreset" />
<OnCondition test="t .gt. tin + refractoryPeriod">
<Transition regime="int" />
<Regime name="int" initial="true">
<TimeDerivative variable="v" value="(current + gleak * (vleak - v)) / capacitance" />
<OnCondition test="v .gt. threshold">
<EventOut port="out" />
<Transition regime="refr" />
<StateAssignment variable="v" value="v + deltaV" />
Once this definition is available, a particular model using this structure can be specified with the following XML:
More complex models will have nested components and other types of parameters, but the basic principle of separating out the equations and parameters for reusable model components, such that the equations are only stated once, remains the same.