|
|
Projects: NeuroML Standards Validator NDKit Additional Tools |
Introduction to the Development Kit
Fred Howell 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:
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
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 - NeuromlSysThere is a static "system" class provided with the development kit which provides useful functions:
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 |