The current stable version of NeuroML is v2.1, and can the schema for this be seen here. The following figure, taken from Cannon et al. 2014 ([CGC+14]) shows some of the elements defined in NeuroML version 2 (note: these core elements haven’t changed since that publication).
You can see the complete definitions of NeuroML 2 entities in the following pages. You can also search this documentation for specific entities that you may be using in your NeuroML models.
Examples of files using the NeuroML 2 schema, and some of the elements they use are:
NeuroML elements used
NeuroML files containing the XML representation of the model can be validated to ensure all of the correct tags/attributes are present.
But how do we know how the model is actually meant to use the specified attributes in an element? The schema only says that
thresh, etc. are allowed attributes on
iafCell, but how are these used to calculate the membrane potential? The answer lies in another, lower-level language, called LEMS (Low Entropy Model Specification).
Defining dynamics in LEMS¶
While valid NeuroML entities are contained in the schema, their underlying mathematical structure and composition rules must also be defined. For this, NeuroML version 2 makes use of LEMS (Low Entropy Language Specification).
For an in-depth guide to LEMS, please see the research paper: LEMS: a language for expressing complex biological models in concise and hierarchical form and its use in underpinning NeuroML 2. Documentation on the structure of the LEMS language can be found here.
LEMS is an XML based language originally developed by Robert Cannon for specifying generic models of hybrid dynamical systems. Models defined in LEMS can also be simulated directly through a native interpreter.
ComponentType elements define the behaviour of a specific type of model and specify Parameters, StateVariables, and their Dynamics and Structure can be defined as templates for model elements (e.g. HH ion channels, abstract cells, etc.). The notion of a ComponentType is thus similar to that of a class in object oriented programming.
Components are instances of these types, with specific values of Parameters (e.g. HH squid axon Na+ channel, I&F cell with threshold -60mV, etc.). Components play the same role as objects in object oriented programming.
On the left side of the figure, examples are shown of the (truncated) XML representations of:
(green) a spiking neuron model as described by Izhikevich (2003);
(yellow) a conductance based synapse with a single exponential decay waveform.
On the right, the definition of the structure and dynamics of these elements in the LEMS language is shown. Each element has a corresponding ComponentType definition, describing the parameters (as well as their dimensions, not shown) and the dynamics in terms of state variables and their derivatives, any derived variables, and the behaviour when certain conditions are met or events are received (for example, the emission of a spike after a given threshold is crossed).
NeuroML 2 Component Type definitions in LEMS¶
The standard set of ComponentType definitions for the core NeuroML2 elements are contained in a curated set of files (below) though users are free to define their own ComponentTypes to extend the scope of the language.
<xs:complexType name="Izhikevich2007Cell"> <xs:complexContent> <xs:extension base="BaseCellMembPotCap"> <xs:attribute name="v0" type="Nml2Quantity_voltage" use="required"/> <xs:attribute name="k" type="Nml2Quantity_conductancePerVoltage" use="required"/> <xs:attribute name="vr" type="Nml2Quantity_voltage" use="required"/> <xs:attribute name="vt" type="Nml2Quantity_voltage" use="required"/> <xs:attribute name="vpeak" type="Nml2Quantity_voltage" use="required"/> <xs:attribute name="a" type="Nml2Quantity_pertime" use="required"/> <xs:attribute name="b" type="Nml2Quantity_conductance" use="required"/> <xs:attribute name="c" type="Nml2Quantity_voltage" use="required"/> <xs:attribute name="d" type="Nml2Quantity_current" use="required"/> </xs:extension> </xs:complexContent> </xs:complexType>
Correspondingly, its ComponentType dynamics are defined in the LEMS file, Cells.xml. (Note: you do not need to read the XML LEMS definitions, you can see this information in a well formatted form here in the documentation itself)
<ComponentType name="izhikevich2007Cell" extends="baseCellMembPotCap" description="Cell based on the modified Izhikevich model in Izhikevich 2007, Dynamical systems in neuroscience, MIT Press"> <Parameter name="v0" dimension="voltage"/> <!-- Defined in baseCellMembPotCap: <Parameter name="C" dimension="capacitance"/> --> <Parameter name="k" dimension="conductance_per_voltage"/> <Parameter name="vr" dimension="voltage"/> <Parameter name="vt" dimension="voltage"/> <Parameter name="vpeak" dimension="voltage"/> <Parameter name="a" dimension="per_time"/> <Parameter name="b" dimension="conductance"/> <Parameter name="c" dimension="voltage"/> <Parameter name="d" dimension="current"/> <Attachments name="synapses" type="basePointCurrent"/> <Exposure name="u" dimension="current"/> <Dynamics> <StateVariable name="v" dimension="voltage" exposure="v"/> <StateVariable name="u" dimension="current" exposure="u"/> <DerivedVariable name="iSyn" dimension="current" exposure="iSyn" select="synapses[*]/i" reduce="add" /> <DerivedVariable name="iMemb" dimension="current" exposure="iMemb" value="k * (v-vr) * (v-vt) + iSyn - u"/> <TimeDerivative variable="v" value="iMemb / C"/> <TimeDerivative variable="u" value="a * (b * (v-vr) - u)"/> <OnStart> <StateAssignment variable="v" value="v0"/> <StateAssignment variable="u" value="0"/> </OnStart> <OnCondition test="v .gt. vpeak"> <StateAssignment variable="v" value="c"/> <StateAssignment variable="u" value="u + d"/> <EventOut port="spike"/> </OnCondition> </Dynamics> </ComponentType>
We can define Components of the izhikevich2007Cell ComponentType with the parameters we need. For example, the izhikevich2007Cell neuron model can exhibit different spiking behaviours, so we can define a regular spiking Component, or another Component that exhibits bursting.
<izhikevich2007Cell id="iz2007RS" v0 = "-60mV" C="100 pF" k = "0.7 nS_per_mV" vr = "-60 mV" vt = "-40 mV" vpeak = "35 mV" a = "0.03 per_ms" b = "-2 nS" c = "-50 mV" d = "100 pA"/>
Once these Components are defined in the NeuroML document, we can use Instances of them to create populations and networks, and so on.
You don’t have to write in XML…
A quick reminder that while XML files can be edited in a standard text editor, you generally don’t have to create/update them by hand. This guide goes through the steps of creating an example using the izhikevich2007Cell model in Python using libNeuroML and pyNeuroML
Using LEMS to specify the core of NeuroML version 2 has the following significant advantages:
NeuroML 2 XML files can be used standalone by applications (exported/imported) in the same way as NeuroML v1.x, without reference to the LEMS definitions, easing the transition for v1.x compliant applications
Any NeuroML 2 ComponentType can be extended and will be usable/translatable by any application (e.g. jLEMS) which understands LEMS
The first point above means that a parsing application does not necessarily have to natively read the LEMS type definition for, e.g. an izhikevich2007Cell element: it just has to map the NeuroML element parameters onto its own object model implementing that entity. Ideally, the behaviour should be the same − which could be ascertained by testing against the reference LEMS interpreter implementation (jLEMS).
The second point above means that if an application does support LEMS, it can automatically parse (and generate code for) a wide range of NeuroML 2 cells, channels and synapses, including any new ComponentType derived from these, without having to natively know anything about channels, cell models, etc.