NeuroML Logo
Home | Projects | Publications | Downloads | Links | Contacts
Introduction to the Development Kit

Fred Howell
Updated April 2005

This package is a sample Java implementation of a parser and generator of NeuroML. It includes suggested definitions of NeuroML, and is intended to make it simple to define new object models. The features of this implementation are:

  • XML is automatically generated from a Java object tree
  • an object tree can be automatically generated from an XML file
  • new features can be added to NeuroML without ever having to change the XML parser or generator

The XMLIn/Out features can actually be used with any data model defined using simplified java classes - within NeuroML are a number of definitions for models of channels, compartmental neurons and networks, but other tools can define their own schemas or extend existing ones.

Why do I need a development kit? Why can't I use DOM or SAX?

The standard XML parsers available from (e.g. Apache, IBM, MS) implement the "DOM" (document object model) or SAX (event based interfaces). Both of these are low level interfaces providing applications with access to the contents of any XML file. But you still need to write the code to interface between DOM or SAX and your internal representation - DOM gives you objects of type "element" and "attribute" rather than objects of type "neuron" or "ionchannel".

The NeuroML development kit provides a more sophisticated level of parsing, layered on top of the low level DOM/SAX parsers - it provides an application with an instantated object tree using that application's class definitions (a similar approach to the Castor project, or the XML serialisation of JDK1.5, or tyhe JAXB project).

How does it work?

We are currently using a simplified form of Java classes to define the schema and vocabulary of NeuroML. There is a set of Java classes which define NeuroML. The XML parser/generator uses Java reflection on these classes to write out the public fields in XML format, so if a channel were defined as:

// Class definitions (define the schema for NeuroML)
public class Channel {
  public int numStates;
}
public class Cell {
  public Channel nachan;
  public Channel kchan;
}
// Example NeuroML file
<neuroml class="Cell">
  <nachan numStates="3" />
  <kchan numStates="2" />
</neuroml>

The following code makes an instance of a cell and writes it out as XML:

// Test code...
static void main() {
  Cell c = new Cell();
  c.nachan.numStates=123;
  c.kchan.numStates=456;
  XMLOut.toString( c ); // Writes XML to stdout
}

And the following code reads in a NeuroML file and instantiates an object tree:

  Cell tree = (Cell) XMLIn.loadXML("test.xml");
This relies on the JDOM parser provided by www.jdom.org
  • The interface is defined as a set of Java classes, with automatic read/write from XML.
  • This makes modifying the NeuroML spec very easy - all that is needed is to change the set of class definitions, and XMLOut.toString( Object ) and XMLIn.loadXML( filename ) will still work.
  • A simulation/database/data analysis program can now use these data structures directly and never needs to write its own XML parser/generator.

How does this relate to XML Schemas, DTDs, and UML?

The set of java classes performs the function of an XML Schema which we can generate automatically - this is useful for checking the validity of XML files (and for XML tools which support Schema such as XML Spy). The format is also interchangeable with UML for documentation.

Java Datatypes / Mapping to XML

Each public field of a class maps to either an XML <element> if the field is a complex object, or an attribute if it can be expressed in a simple string. There is currently support for a restricted set of datatypes in the classes which specify NeuroML:

Basic Datatypes

The basic datatypes below correspond to the following XML:

class Test {
  public boolean w; 
  public int x;     
  public double dx; 
  public String y;  
  public DValue z;  
}

The unusual one here is DValue which is a double value with units. Currently all numbers in NeuroML have to have a reference to units.

This maps to NeuroML of the format:

<neuroml class="Test" w="true" x="123" dx="123.34" y="hello" z="1.234uS">
</neuroml>
Minimal Type Information in Instance Documents

The type information (whether fields are integers, strings, or of a particular class) is held in the Schema (as XML-Schema or as a set of Java class definitions) rather than in instance documents (i.e. there are no elements like <int>). The XML elements are the field names of the parent class - except for the top element which is <neuroml> and for members of a set which use a singular form of the set's name.

The exception to this is when type information is unavoidable in the instance documents, e.g. when there is a derived version of a field, or for the top level class of a neuroml document (which could be a user's class). In this case there needs to be a class="MyTestClass" attribute to make it unambiguous.

The Top Level Element

The top level element of a neuroml file is defined to be <neuroml> with a class="TestClass" attribute to specify the class of the top level object.

Objects

Public fields of a class have to be one of:

int
boolean
double
String
DValue
IntArray
StringArray
DoubleArray
Set
Ref
(or other neuroml Object)
class MyKindOfChannel {
  public String ch1 = "Na";
  public String ch2 = "K";
}

class Test {
  public MyKindOfChannel chan = new MyKindOfChannel();
}
<neuroml class="Test">
  <chan ch1="Na" ch2="K"/>
</neuroml>  
Collective Datatypes

Sets
class Test {
  public Set states = new Set("State");
}
and this generates the XML:-
   <states>
     <state name="S1">
       <... here goes the complex content of a state>
     </state>
     <state name="S2"/>
     <state name="S3"/>
     <state name="S4"/>
   </states>   

Note that the element used for members of the set is always the name of the set's field (in this case states turned into a singular form (by chopping off the "s").

Arrays
class Test {
  DoubleArray numbers = new DoubleArray();
  StringArray ionnames = new StringArray();
  IntArray ionvalencies = new IntArray(); 
}

A compact notation is allowed for arrays of basic datatypes:

<neuroml class="Test">
    <numbers length="23">
1.0     2.0     3.0     4.0     5.0     6.0     7.0     5.0     4.0     3.0
2.0     1.0     3.0     5.0     56.0    6.0     4.0     3.0     43.0    5.0
65.0    5.0     50.0
    </numbers>   
    <ionnames length="5" >
Na      K       Ca      Cl      CaComplex
    </ionnames>
    <ionvalencies length="5" >
1       1       2       -1      -2
    </ionvalencies>
<neuroml>
References to Objects

As well as objects, we define a Ref type, which is a reference to an object, coded as a string name. In effect this is a serializable pointer.

class MyObj {
  public int x;
}

class Test {
  public Set myobjs = new Set("MyObj");
  public Ref myref = new Ref("MyObj");

  public Test() {
     myobjs.addElement( new MyObj("elem1") );
     myobjs.addElement( new MyObj("elem2") );

     r.setTargetName("elem1"); // dereferencing this can be done using Namespace.deRef()
  }
}

In XML the reference will appear as:

<neuroml class="Test" myref="elem1">
  <myobjs>
    <myobj name="elem1" x="123"/>
    <myobj name="elem2" x="456"/>
  </myobjs>
</neuroml>

A utility for naming/dereferencing the target name is provided by the neuroml.util.Namespace class.

Code structure

See the javadoc documentation.

The System Class - NeuromlSys

There is a static "system" class provided with the development kit which provides useful functions:

  • Namespaces
  • loadXML / toFile (NeuroML file %lt;--> object tree)
  • deRef / addRef (Deal with (de)referencing object names <--> objects
Examples and Demos

A number of examples using the kit are in the demo/basic/* directory. The makefile includes a number of targets for reading, writing XML and generating XML Schema versions of the classes.



Last updated: August 2008