Repository: NeuroML/NeuroMLlite (language: python)

Issue:
Attrs to development



Discussion / hints:

Fix patch:
diff --git a/README.md b/README.md
index 0b51171..17ddcd8 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
 [![Twitter Follow](https://img.shields.io/twitter/follow/NeuroML?style=social)](https://twitter.com/NeuroML)
 
 
-Work in progress. This will develop in to a framework for more portable, concise network specifications which will form an important part of [NeuroML v3](https://docs.neuroml.org/NeuroMLOrg/History.html#the-future).
+NeuroMLlite is in active development. This will evolve into a framework for more portable, concise network specifications which will form an important part of [NeuroML v3](https://docs.neuroml.org/NeuroMLOrg/History.html#the-future).
 
 For some more background to this package see here: https://github.com/NeuroML/NetworkShorthand.
 
diff --git a/docs/NeuroMLlite_specification.json b/docs/NeuroMLlite_specification.json
index 0103e2a..c824a72 100644
--- a/docs/NeuroMLlite_specification.json
+++ b/docs/NeuroMLlite_specification.json
@@ -1,9 +1,21 @@
 {
-    "version": "NeuroMLlite v0.4.4",
+    "version": "NeuroMLlite v0.5.1",
     "specification": {
         "Network": {
-            "definition": "A Network containing multiple _Population_s, connected by _Projection_s and receiving _Input_s",
+            "definition": "A Network containing multiple Population's, connected by Projection's and receiving Input's",
             "allowed_parameters": {
+                "notes": {
+                    "type": "str",
+                    "description": ""
+                },
+                "id": {
+                    "type": "str",
+                    "description": "Unique identifier for the Network"
+                },
+                "parameters": {
+                    "type": "Any",
+                    "description": "Dictionary of global parameters for the network"
+                },
                 "version": {
                     "type": "str",
                     "description": "Information on verson of NeuroMLlite"
@@ -16,68 +28,74 @@
                     "type": "float",
                     "description": "Temperature at which to run network (float in deg C)"
                 },
-                "parameters": {
-                    "type": "dict",
-                    "description": "Dictionary of global parameters for the network"
-                },
                 "network_reader": {
                     "type": "NetworkReader",
                     "description": "A class which can read in a network (e.g. from a structured format)"
-                },
-                "id": {
-                    "type": "str",
-                    "description": "Unique ID of element"
-                },
-                "notes": {
-                    "type": "str",
-                    "description": "Human readable notes"
                 }
             },
             "allowed_children": {
                 "cells": {
                     "type": "Cell",
-                    "description": "The _Cell_s which can be present in _Population_s"
+                    "description": "The Cells which can be present in Populations"
                 },
                 "synapses": {
                     "type": "Synapse",
-                    "description": "The _Synapse_ definitions which are used in _Projection_s"
+                    "description": "The Synapse definitions which are used in Projections"
                 },
                 "input_sources": {
                     "type": "InputSource",
-                    "description": "The _InputSource_ definitions which define the types of stimulus which can be applied in _Input_s"
+                    "description": "The InputSource definitions which define the types of stimulus which can be applied in Inputs"
                 },
                 "regions": {
                     "type": "RectangularRegion",
-                    "description": "The _Regions_ in which _Population_s get placed"
+                    "description": "The Regions in which Populations get placed."
                 },
                 "populations": {
                     "type": "Population",
-                    "description": "The _Population_s of _Cell_s making up this network..."
+                    "description": "The Populations of Cells making up this network ..."
                 },
                 "projections": {
                     "type": "Projection",
-                    "description": "The _Projection_s between _Population_s"
+                    "description": "The Projections between Populations"
                 },
                 "inputs": {
                     "type": "Input",
-                    "description": "The inputs to apply to the elements of _Population_s"
+                    "description": "The inputs to apply to the elements of Populations"
                 }
             }
         },
         "NetworkReader": {
+            "definition": "A NetworkReader definition.",
             "allowed_parameters": {
+                "notes": {
+                    "type": "str",
+                    "description": ""
+                },
                 "type": {
                     "type": "str",
                     "description": "The type of NetworkReader"
                 },
                 "parameters": {
-                    "type": "dict",
+                    "type": "Any",
                     "description": "Dictionary of parameters for the NetworkReader"
                 }
             }
         },
         "Cell": {
+            "definition": "A Cell definition.",
             "allowed_parameters": {
+                "notes": {
+                    "type": "str",
+                    "description": ""
+                },
+                "id": {
+                    "type": "str",
+                    "description": "Unique identifier for this Cell"
+                },
+                "parameters": {
+                    "type": "Any",
+                    "description": "Dictionary of parameters for the cell"
+                },
                 "neuroml2_source_file": {
                     "type": "str",
                     "description": "File name of NeuroML2 file defining the cell"
@@ -101,23 +119,24 @@
                 "bindsnet_node": {
                     "type": "str",
                     "description": "Name of standard BindsNET node"
-                },
-                "parameters": {
-                    "type": "dict",
-                    "description": "Dictionary of parameters for the cell"
-                },
-                "id": {
-                    "type": "str",
-                    "description": "Unique ID of element"
-                },
-                "notes": {
-                    "type": "str",
-                    "description": "Human readable notes"
                 }
             }
         },
         "Synapse": {
+            "definition": "A Synapse definition.",
             "allowed_parameters": {
+                "notes": {
+                    "type": "str",
+                    "description": ""
+                },
+                "id": {
+                    "type": "str",
+                    "description": "Unique identifier for this Synapse"
+                },
+                "parameters": {
+                    "type": "Any",
+                    "description": "Dictionary of parameters for the synapse"
+                },
                 "neuroml2_source_file": {
                     "type": "str",
                     "description": "File name of NeuroML2 file defining the synapse"
@@ -128,132 +147,128 @@
                 },
                 "pynn_synapse_type": {
                     "type": "str",
-                    "description": "Options: \"curr_exp\", \"curr_alpha\", \"cond_exp\", \"cond_alpha\"."
+                    "description": "The pynn synapse type. Valid values are: \"curr_exp\", \"curr_alpha\", \"cond_exp\", \"cond_alpha\"."
                 },
                 "pynn_receptor_type": {
                     "type": "str",
-                    "description": "Either \"excitatory\" or \"inhibitory\"."
-                },
-                "parameters": {
-                    "type": "dict",
-                    "description": "Dictionary of parameters for the synapse"
-                },
-                "id": {
-                    "type": "str",
-                    "description": "Unique ID of element"
-                },
-                "notes": {
-                    "type": "str",
-                    "description": "Human readable notes"
+                    "description": "The pynn receptor type. Valid values are: \"excitatory\", \"inhibitory\"."
                 }
             }
         },
         "InputSource": {
+            "definition": "An InputSource definition.",
             "allowed_parameters": {
-                "neuroml2_source_file": {
+                "notes": {
                     "type": "str",
-                    "description": "File name of NeuroML2 file"
+                    "description": ""
                 },
-                "lems_source_file": {
+                "id": {
                     "type": "str",
-                    "description": "File name of LEMS file"
+                    "description": "Unique identifier for this InputSource"
                 },
-                "neuroml2_input": {
-                    "type": "str",
-                    "description": "Name of standard NeuroML2 input"
+                "parameters": {
+                    "type": "Any",
+                    "description": "Dictionary of parameters for the InputSource"
                 },
-                "pynn_input": {
+                "neuroml2_source_file": {
                     "type": "str",
-                    "description": "Name of standard PyNN input"
+                    "description": "File name of NeuroML2 file defining the input source"
                 },
-                "parameters": {
-                    "type": "dict",
-                    "description": "Dictionary of parameters for the InputSource"
+                "neuroml2_input": {
+                    "type": "str",
+                    "description": "Name of standard NeuroML2 input"
                 },
-                "id": {
+                "lems_source_file": {
                     "type": "str",
-                    "description": "Unique ID of element"
+                    "description": "File name of LEMS file defining the input source"
                 },
-                "notes": {
+                "pynn_input": {
                     "type": "str",
-                    "description": "Human readable notes"
+                    "description": "Name of PyNN input"
                 }
             }
         },
         "RectangularRegion": {
+            "definition": "A RectangularRegion definition.",
             "allowed_parameters": {
+                "notes": {
+                    "type": "str",
+                    "description": ""
+                },
+                "id": {
+                    "type": "str",
+                    "description": "Unique identifier for this rectangular region."
+                },
                 "x": {
                     "type": "float",
-                    "description": "x coordinate of corner"
+                    "description": "x coordinate of corner of region"
                 },
                 "y": {
                     "type": "float",
-                    "description": "y coordinate of corner"
+                    "description": "y coordinate of corner of region"
                 },
                 "z": {
                     "type": "float",
-                    "description": "z coordinate of corner"
+                    "description": "z coordinate of corner of region"
                 },
                 "width": {
                     "type": "float",
-                    "description": "Width of rectangular region"
+                    "description": "width of the rectangular region"
                 },
                 "height": {
                     "type": "float",
-                    "description": "Height of rectangular region"
+                    "description": "height of the rectangular region"
                 },
                 "depth": {
                     "type": "float",
-                    "description": "Depth of rectangular region"
-                },
-                "id": {
-                    "type": "str",
-                    "description": "Unique ID of element"
-                },
-                "notes": {
-                    "type": "str",
-                    "description": "Human readable notes"
+                    "description": "depth of the rectangular region"
                 }
             }
         },
         "Population": {
+            "definition": "A Population definition.",
             "allowed_parameters": {
+                "notes": {
+                    "type": "str",
+                    "description": ""
+                },
+                "id": {
+                    "type": "str",
+                    "description": "Unique identifier for this Population"
+                },
                 "size": {
-                    "type": "EvaluableExpression",
-                    "description": "Size of population"
+                    "type": "Union[EvaluableExpression, T, VT, ndarray, int, float, str]",
+                    "description": "The size of the population."
                 },
                 "component": {
                     "type": "str",
-                    "description": "Type of _Cell_ to use in population"
+                    "description": "The type of Cell to use in this population."
                 },
                 "properties": {
-                    "type": "dict",
-                    "description": "Dictionary of properties (metadata) for the population"
+                    "type": "Any",
+                    "description": "A dictionary of properties (metadata) for this population."
                 },
                 "random_layout": {
                     "type": "RandomLayout",
-                    "description": "Layout in random _Region_"
+                    "description": "Layout in the random RectangularRegion."
                 },
                 "relative_layout": {
                     "type": "RelativeLayout",
-                    "description": "Position relative to _Region_."
+                    "description": "Position relative to RectangularRegion."
                 },
                 "single_location": {
                     "type": "SingleLocation",
-                    "description": "Explicit location of the one _Cell_ in the population"
-                },
-                "id": {
-                    "type": "str",
-                    "description": "Unique ID of element"
-                },
-                "notes": {
-                    "type": "str",
-                    "description": "Human readable notes"
+                    "description": "Explicit location of the one Cell in the population"
                 }
             }
         },
         "RandomLayout": {
+            "definition": "A RandomLayout definition.",
             "allowed_parameters": {
+                "notes": {
+                    "type": "str",
+                    "description": ""
+                },
                 "region": {
                     "type": "str",
                     "description": "Region in which to place population"
@@ -261,62 +276,86 @@
             }
         },
         "RelativeLayout": {
+            "definition": "A RelativeLayout definition.",
             "allowed_parameters": {
+                "notes": {
+                    "type": "str",
+                    "description": ""
+                },
                 "region": {
                     "type": "str",
-                    "description": "The _Region_ relative to which population should be positioned"
+                    "description": "The Region relative to which population should be positioned."
                 },
                 "x": {
                     "type": "float",
-                    "description": "x position relative to x coordinate of _Region_"
+                    "description": "x position relative to x coordinate of Region"
                 },
                 "y": {
                     "type": "float",
-                    "description": "y position relative to y coordinate of _Region_"
+                    "description": "y position relative to y coordinate of Region"
                 },
                 "z": {
                     "type": "float",
-                    "description": "z position relative to z coordinate of _Region_"
+                    "description": "z position relative to z coordinate of Region"
                 }
             }
         },
         "SingleLocation": {
+            "definition": "A SingleLocation definition.",
             "allowed_parameters": {
+                "notes": {
+                    "type": "str",
+                    "description": ""
+                },
                 "location": {
                     "type": "Location",
-                    "description": "The location of the single _Cell_"
+                    "description": "Location of the single Cell."
                 }
             }
         },
         "Location": {
+            "definition": "A Location definition.",
             "allowed_parameters": {
+                "notes": {
+                    "type": "str",
+                    "description": ""
+                },
                 "x": {
                     "type": "float",
-                    "description": "x coordinate"
+                    "description": "x coordinate of location"
                 },
                 "y": {
                     "type": "float",
-                    "description": "y coordinate"
+                    "description": "y coordinate of location"
                 },
                 "z": {
                     "type": "float",
-                    "description": "z coordinate"
+                    "description": "z coordinate of location"
                 }
             }
         },
         "Projection": {
+            "definition": "A Projection definition.",
             "allowed_parameters": {
+                "notes": {
+                    "type": "str",
+                    "description": ""
+                },
+                "id": {
+                    "type": "str",
+                    "description": "Unique identifier for this Projection"
+                },
                 "presynaptic": {
                     "type": "str",
-                    "description": "Presynaptic _Population_"
+                    "description": "Presynaptic Population"
                 },
                 "postsynaptic": {
                     "type": "str",
-                    "description": "Postsynaptic _Population_"
+                    "description": "Postsynaptic Population"
                 },
                 "synapse": {
                     "type": "str",
-                    "description": "Which _Synapse_ to use"
+                    "description": "Which Synapse to use"
                 },
                 "pre_synapse": {
                     "type": "str",
@@ -324,14 +363,14 @@
                 },
                 "type": {
                     "type": "str",
-                    "description": "type of projection: projection (default; standard chemical, event triggered), electricalProjection (for gap junctions) or continuousProjection (for analogue/graded synapses)"
+                    "description": "type of projection: projection (default; standard chemical, event triggered), electricalProjection\n(for gap junctions) or continuousProjection (for analogue/graded synapses)"
                 },
                 "delay": {
-                    "type": "EvaluableExpression",
+                    "type": "Union[EvaluableExpression, T, VT, ndarray, int, float, str]",
                     "description": "Delay to use (default: 0)"
                 },
                 "weight": {
-                    "type": "EvaluableExpression",
+                    "type": "Union[EvaluableExpression, T, VT, ndarray, int, float, str]",
                     "description": "Weight to use (default: 1)"
                 },
                 "random_connectivity": {
@@ -340,43 +379,60 @@
                 },
                 "convergent_connectivity": {
                     "type": "ConvergentConnectivity",
-                    "description": "Use ConvergentConnectivity"
+                    "description": "Use convergent connectivity"
                 },
                 "one_to_one_connector": {
                     "type": "OneToOneConnector",
                     "description": "Connect cell index i in pre pop to cell index i in post pop for all i"
-                },
-                "id": {
-                    "type": "str",
-                    "description": "Unique ID of element"
-                },
-                "notes": {
-                    "type": "str",
-                    "description": "Human readable notes"
                 }
             }
         },
         "RandomConnectivity": {
+            "definition": "A RandomConnectivity definition.",
             "allowed_parameters": {
+                "notes": {
+                    "type": "str",
+                    "description": ""
+                },
                 "probability": {
-                    "type": "EvaluableExpression",
-                    "description": "Random probability of connection"
+                    "type": "Union[EvaluableExpression, T, VT, ndarray, int, float, str]",
+                    "description": "Random probability of connection."
                 }
             }
         },
         "ConvergentConnectivity": {
+            "definition": "A ConvergentConnectivity definition.",
             "allowed_parameters": {
+                "notes": {
+                    "type": "str",
+                    "description": ""
+                },
                 "num_per_post": {
                     "type": "float",
-                    "description": "Number per post synaptic neuron"
+                    "description": "Number per post-synaptic neuron."
                 }
             }
         },
         "OneToOneConnector": {
-            "allowed_parameters": {}
+            "definition": "A OneToOneConnector definition.",
+            "allowed_parameters": {
+                "notes": {
+                    "type": "str",
+                    "description": ""
+                }
+            }
         },
         "Input": {
+            "definition": "An Input definition.",
             "allowed_parameters": {
+                "notes": {
+                    "type": "str",
+                    "description": ""
+                },
+                "id": {
+                    "type": "str",
+                    "description": "Unique identifier for this Input"
+                },
                 "input_source": {
                     "type": "str",
                     "description": "Type of input to use in population"
@@ -386,32 +442,24 @@
                     "description": "Population to target"
                 },
                 "cell_ids": {
-                    "type": "EvaluableExpression",
-                    "description": "Specific ids of _Cell_s to apply this input to (cannot be used with percentage)"
+                    "type": "Union[EvaluableExpression, T, VT, ndarray, int, float, str]",
+                    "description": "Specific ids of _Cell_s to apply this input to (cannot be used with percentage"
                 },
                 "percentage": {
                     "type": "float",
-                    "description": "Percentage of _Cell_s to apply this input to (cannot be used with cell_ids)"
+                    "description": "Percentage of Cells to apply input to"
                 },
                 "number_per_cell": {
-                    "type": "EvaluableExpression",
-                    "description": "Number of individual inputs per selected _Cell_ (default: 1)"
+                    "type": "Union[EvaluableExpression, T, VT, ndarray, int, float, str]",
+                    "description": "Number of individual inputs per selected Cell (default: 1)"
                 },
                 "segment_ids": {
-                    "type": "EvaluableExpression",
+                    "type": "Union[EvaluableExpression, T, VT, ndarray, int, float, str]",
                     "description": "Which segments to target (default: [0])"
                 },
                 "weight": {
-                    "type": "EvaluableExpression",
+                    "type": "Union[EvaluableExpression, T, VT, ndarray, int, float, str]",
                     "description": "Weight to use (default: 1)"
-                },
-                "id": {
-                    "type": "str",
-                    "description": "Unique ID of element"
-                },
-                "notes": {
-                    "type": "str",
-                    "description": "Human readable notes"
                 }
             }
         }
diff --git a/docs/NeuroMLlite_specification.yaml b/docs/NeuroMLlite_specification.yaml
index 40b6118..c36097e 100644
--- a/docs/NeuroMLlite_specification.yaml
+++ b/docs/NeuroMLlite_specification.yaml
@@ -1,9 +1,18 @@
-version: NeuroMLlite v0.4.4
+version: NeuroMLlite v0.5.1
 specification:
     Network:
-        definition: A Network containing multiple _Population_s, connected by _Projection_s
-            and receiving _Input_s
+        definition: A Network containing multiple Population's, connected by Projection's
+            and receiving Input's
         allowed_parameters:
+            notes:
+                type: str
+                description: ''
+            id:
+                type: str
+                description: Unique identifier for the Network
+            parameters:
+                type: Any
+                description: Dictionary of global parameters for the network
             version:
                 type: str
                 description: Information on verson of NeuroMLlite
@@ -13,52 +22,57 @@ specification:
             temperature:
                 type: float
                 description: Temperature at which to run network (float in deg C)
-            parameters:
-                type: dict
-                description: Dictionary of global parameters for the network
             network_reader:
                 type: NetworkReader
                 description: A class which can read in a network (e.g. from a structured
                     format)
-            id:
-                type: str
-                description: Unique ID of element
-            notes:
-                type: str
-                description: Human readable notes
         allowed_children:
             cells:
                 type: Cell
-                description: The _Cell_s which can be present in _Population_s
+                description: The Cells which can be present in Populations
             synapses:
                 type: Synapse
-                description: The _Synapse_ definitions which are used in _Projection_s
+                description: The Synapse definitions which are used in Projections
             input_sources:
                 type: InputSource
-                description: The _InputSource_ definitions which define the types
-                    of stimulus which can be applied in _Input_s
+                description: The InputSource definitions which define the types of
+                    stimulus which can be applied in Inputs
             regions:
                 type: RectangularRegion
-                description: The _Regions_ in which _Population_s get placed
+                description: The Regions in which Populations get placed.
             populations:
                 type: Population
-                description: The _Population_s of _Cell_s making up this network...
+                description: The Populations of Cells making up this network ...
             projections:
                 type: Projection
-                description: The _Projection_s between _Population_s
+                description: The Projections between Populations
             inputs:
                 type: Input
-                description: The inputs to apply to the elements of _Population_s
+                description: The inputs to apply to the elements of Populations
     NetworkReader:
+        definition: A NetworkReader definition.
         allowed_parameters:
+            notes:
+                type: str
+                description: ''
             type:
                 type: str
                 description: The type of NetworkReader
             parameters:
-                type: dict
+                type: Any
                 description: Dictionary of parameters for the NetworkReader
     Cell:
+        definition: A Cell definition.
         allowed_parameters:
+            notes:
+                type: str
+                description: ''
+            id:
+                type: str
+                description: Unique identifier for this Cell
+            parameters:
+                type: Any
+                description: Dictionary of parameters for the cell
             neuroml2_source_file:
                 type: str
                 description: File name of NeuroML2 file defining the cell
@@ -77,17 +91,18 @@ specification:
             bindsnet_node:
                 type: str
                 description: Name of standard BindsNET node
-            parameters:
-                type: dict
-                description: Dictionary of parameters for the cell
-            id:
-                type: str
-                description: Unique ID of element
-            notes:
-                type: str
-                description: Human readable notes
     Synapse:
+        definition: A Synapse definition.
         allowed_parameters:
+            notes:
+                type: str
+                description: ''
+            id:
+                type: str
+                description: Unique identifier for this Synapse
+            parameters:
+                type: Any
+                description: Dictionary of parameters for the synapse
             neuroml2_source_file:
                 type: str
                 description: File name of NeuroML2 file defining the synapse
@@ -96,140 +111,159 @@ specification:
                 description: File name of LEMS file defining the synapse
             pynn_synapse_type:
                 type: str
-                description: 'Options: "curr_exp", "curr_alpha", "cond_exp", "cond_alpha".'
+                description: 'The pynn synapse type. Valid values are: "curr_exp",
+                    "curr_alpha", "cond_exp", "cond_alpha".'
             pynn_receptor_type:
                 type: str
-                description: Either "excitatory" or "inhibitory".
-            parameters:
-                type: dict
-                description: Dictionary of parameters for the synapse
-            id:
-                type: str
-                description: Unique ID of element
-            notes:
-                type: str
-                description: Human readable notes
+                description: 'The pynn receptor type. Valid values are: "excitatory",
+                    "inhibitory".'
     InputSource:
+        definition: An InputSource definition.
         allowed_parameters:
-            neuroml2_source_file:
+            notes:
                 type: str
-                description: File name of NeuroML2 file
-            lems_source_file:
+                description: ''
+            id:
+                type: str
+                description: Unique identifier for this InputSource
+            parameters:
+                type: Any
+                description: Dictionary of parameters for the InputSource
+            neuroml2_source_file:
                 type: str
-                description: File name of LEMS file
+                description: File name of NeuroML2 file defining the input source
             neuroml2_input:
                 type: str
                 description: Name of standard NeuroML2 input
-            pynn_input:
-                type: str
-                description: Name of standard PyNN input
-            parameters:
-                type: dict
-                description: Dictionary of parameters for the InputSource
-            id:
+            lems_source_file:
                 type: str
-                description: Unique ID of element
-            notes:
+                description: File name of LEMS file defining the input source
+            pynn_input:
                 type: str
-                description: Human readable notes
+                description: Name of PyNN input
     RectangularRegion:
+        definition: A RectangularRegion definition.
         allowed_parameters:
+            notes:
+                type: str
+                description: ''
+            id:
+                type: str
+                description: Unique identifier for this rectangular region.
             x:
                 type: float
-                description: x coordinate of corner
+                description: x coordinate of corner of region
             y:
                 type: float
-                description: y coordinate of corner
+                description: y coordinate of corner of region
             z:
                 type: float
-                description: z coordinate of corner
+                description: z coordinate of corner of region
             width:
                 type: float
-                description: Width of rectangular region
+                description: width of the rectangular region
             height:
                 type: float
-                description: Height of rectangular region
+                description: height of the rectangular region
             depth:
                 type: float
-                description: Depth of rectangular region
-            id:
-                type: str
-                description: Unique ID of element
-            notes:
-                type: str
-                description: Human readable notes
+                description: depth of the rectangular region
     Population:
+        definition: A Population definition.
         allowed_parameters:
+            notes:
+                type: str
+                description: ''
+            id:
+                type: str
+                description: Unique identifier for this Population
             size:
-                type: EvaluableExpression
-                description: Size of population
+                type: Union[EvaluableExpression, T, VT, ndarray, int, float, str]
+                description: The size of the population.
             component:
                 type: str
-                description: Type of _Cell_ to use in population
+                description: The type of Cell to use in this population.
             properties:
-                type: dict
-                description: Dictionary of properties (metadata) for the population
+                type: Any
+                description: A dictionary of properties (metadata) for this population.
             random_layout:
                 type: RandomLayout
-                description: Layout in random _Region_
+                description: Layout in the random RectangularRegion.
             relative_layout:
                 type: RelativeLayout
-                description: Position relative to _Region_.
+                description: Position relative to RectangularRegion.
             single_location:
                 type: SingleLocation
-                description: Explicit location of the one _Cell_ in the population
-            id:
-                type: str
-                description: Unique ID of element
-            notes:
-                type: str
-                description: Human readable notes
+                description: Explicit location of the one Cell in the population
     RandomLayout:
+        definition: A RandomLayout definition.
         allowed_parameters:
+            notes:
+                type: str
+                description: ''
             region:
                 type: str
                 description: Region in which to place population
     RelativeLayout:
+        definition: A RelativeLayout definition.
         allowed_parameters:
+            notes:
+                type: str
+                description: ''
             region:
                 type: str
-                description: The _Region_ relative to which population should be positioned
+                description: The Region relative to which population should be positioned.
             x:
                 type: float
-                description: x position relative to x coordinate of _Region_
+                description: x position relative to x coordinate of Region
             y:
                 type: float
-                description: y position relative to y coordinate of _Region_
+                description: y position relative to y coordinate of Region
             z:
                 type: float
-                description: z position relative to z coordinate of _Region_
+                description: z position relative to z coordinate of Region
     SingleLocation:
+        definition: A SingleLocation definition.
         allowed_parameters:
+            notes:
+                type: str
+                description: ''
             location:
                 type: Location
-                description: The location of the single _Cell_
+                description: Location of the single Cell.
     Location:
+        definition: A Location definition.
         allowed_parameters:
+            notes:
+                type: str
+                description: ''
             x:
                 type: float
-                description: x coordinate
+                description: x coordinate of location
             y:
                 type: float
-                description: y coordinate
+                description: y coordinate of location
             z:
                 type: float
-                description: z coordinate
+                description: z coordinate of location
     Projection:
+        definition: A Projection definition.
         allowed_parameters:
+            notes:
+                type: str
+                description: ''
+            id:
+                type: str
+                description: Unique identifier for this Projection
             presynaptic:
                 type: str
-                description: Presynaptic _Population_
+                description: Presynaptic Population
             postsynaptic:
                 type: str
-                description: Postsynaptic _Population_
+                description: Postsynaptic Population
             synapse:
                 type: str
-                description: Which _Synapse_ to use
+                description: Which Synapse to use
             pre_synapse:
                 type: str
                 description: 'For continuous connections, what presynaptic component
@@ -237,44 +271,59 @@ specification:
             type:
                 type: str
                 description: 'type of projection: projection (default; standard chemical,
-                    event triggered), electricalProjection (for gap junctions) or
-                    continuousProjection (for analogue/graded synapses)'
+                    event triggered), electricalProjection
+
+                    (for gap junctions) or continuousProjection (for analogue/graded
+                    synapses)'
             delay:
-                type: EvaluableExpression
+                type: Union[EvaluableExpression, T, VT, ndarray, int, float, str]
                 description: 'Delay to use (default: 0)'
             weight:
-                type: EvaluableExpression
+                type: Union[EvaluableExpression, T, VT, ndarray, int, float, str]
                 description: 'Weight to use (default: 1)'
             random_connectivity:
                 type: RandomConnectivity
                 description: Use random connectivity
             convergent_connectivity:
                 type: ConvergentConnectivity
-                description: Use ConvergentConnectivity
+                description: Use convergent connectivity
             one_to_one_connector:
                 type: OneToOneConnector
                 description: Connect cell index i in pre pop to cell index i in post
                     pop for all i
-            id:
-                type: str
-                description: Unique ID of element
-            notes:
-                type: str
-                description: Human readable notes
     RandomConnectivity:
+        definition: A RandomConnectivity definition.
         allowed_parameters:
+            notes:
+                type: str
+                description: ''
             probability:
-                type: EvaluableExpression
-                description: Random probability of connection
+                type: Union[EvaluableExpression, T, VT, ndarray, int, float, str]
+                description: Random probability of connection.
     ConvergentConnectivity:
+        definition: A ConvergentConnectivity definition.
         allowed_parameters:
+            notes:
+                type: str
+                description: ''
             num_per_post:
                 type: float
-                description: Number per post synaptic neuron
+                description: Number per post-synaptic neuron.
     OneToOneConnector:
-        allowed_parameters: {}
+        definition: A OneToOneConnector definition.
+        allowed_parameters:
+            notes:
+                type: str
+                description: ''
     Input:
+        definition: An Input definition.
         allowed_parameters:
+            notes:
+                type: str
+                description: ''
+            id:
+                type: str
+                description: Unique identifier for this Input
             input_source:
                 type: str
                 description: Type of input to use in population
@@ -282,26 +331,19 @@ specification:
                 type: str
                 description: Population to target
             cell_ids:
-                type: EvaluableExpression
+                type: Union[EvaluableExpression, T, VT, ndarray, int, float, str]
                 description: Specific ids of _Cell_s to apply this input to (cannot
-                    be used with percentage)
+                    be used with percentage
             percentage:
                 type: float
-                description: Percentage of _Cell_s to apply this input to (cannot
-                    be used with cell_ids)
+                description: Percentage of Cells to apply input to
             number_per_cell:
-                type: EvaluableExpression
-                description: 'Number of individual inputs per selected _Cell_ (default:
+                type: Union[EvaluableExpression, T, VT, ndarray, int, float, str]
+                description: 'Number of individual inputs per selected Cell (default:
                     1)'
             segment_ids:
-                type: EvaluableExpression
+                type: Union[EvaluableExpression, T, VT, ndarray, int, float, str]
                 description: 'Which segments to target (default: [0])'
             weight:
-                type: EvaluableExpression
+                type: Union[EvaluableExpression, T, VT, ndarray, int, float, str]
                 description: 'Weight to use (default: 1)'
-            id:
-                type: str
-                description: Unique ID of element
-            notes:
-                type: str
-                description: Human readable notes
diff --git a/docs/README.md b/docs/README.md
index a260bcf..5d4b529 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,624 +1,785 @@
-# Specification of NeuroMLlite v0.4.4
+# Specification of NeuroMLlite v0.5.1
 **Note: the NeuroMLlite specification is still in development! Subject to change...**
 
 ## Network
-
-A Network containing multiple <a href="#population">Population</a>s, connected by <a href="#projection">Projection</a>s and receiving <a href="#input">Input</a>s
+A Network containing multiple Population's, connected by Projection's and receiving Input's
 
 ### Allowed parameters
 <table>
+  <tr>
+    <td><b>notes</b></td>
+    <td>str</td>
+    <td><i></i></td>
+ </tr>
+
+
+  <tr>
+    <td><b>id</b></td>
+    <td>str</td>
+    <td><i>Unique identifier for the Network</i></td>
+ </tr>
+
+
+  <tr>
+    <td><b>parameters</b></td>
+    <td>Any</td>
+    <td><i>Dictionary of global parameters for the network</i></td>
+ </tr>
+
+
   <tr>
     <td><b>version</b></td>
     <td>str</td>
     <td><i>Information on verson of NeuroMLlite</i></td>
-  </tr>
+ </tr>
+
 
   <tr>
     <td><b>seed</b></td>
     <td>int</td>
     <td><i>Seed for random number generator used when building network</i></td>
-  </tr>
+ </tr>
+
 
   <tr>
     <td><b>temperature</b></td>
     <td>float</td>
     <td><i>Temperature at which to run network (float in deg C)</i></td>
-  </tr>
+ </tr>
 
-  <tr>
-    <td><b>parameters</b></td>
-    <td>dict</td>
-    <td><i>Dictionary of global parameters for the network</i></td>
-  </tr>
 
   <tr>
     <td><b>network_reader</b></td>
     <td><a href="#networkreader">NetworkReader</a></td>
     <td><i>A class which can read in a network (e.g. from a structured format)</i></td>
-  </tr>
+ </tr>
 
-  <tr>
-    <td><b>id</b></td>
-    <td>str</td>
-    <td><i>Unique ID of element</i></td>
-  </tr>
-
-  <tr>
-    <td><b>notes</b></td>
-    <td>str</td>
-    <td><i>Human readable notes</i></td>
-  </tr>
 
 </table>
 
-#### Allowed children
-
+### Allowed children
 <table>
   <tr>
     <td><b>cells</b></td>
     <td><a href="#cell">Cell</a></td>
-    <td><i>The <a href="#cell">Cell</a>s which can be present in <a href="#population">Population</a>s</i></td>
+    <td><i>The Cells which can be present in Populations</i></td>
   </tr>
 
+
   <tr>
     <td><b>synapses</b></td>
     <td><a href="#synapse">Synapse</a></td>
-    <td><i>The <a href="#synapse">Synapse</a> definitions which are used in <a href="#projection">Projection</a>s</i></td>
+    <td><i>The Synapse definitions which are used in Projections</i></td>
   </tr>
 
+
   <tr>
     <td><b>input_sources</b></td>
     <td><a href="#inputsource">InputSource</a></td>
-    <td><i>The <a href="#inputsource">InputSource</a> definitions which define the types of stimulus which can be applied in <a href="#input">Input</a>s</i></td>
+    <td><i>The InputSource definitions which define the types of stimulus which can be applied in Inputs</i></td>
   </tr>
 
+
   <tr>
     <td><b>regions</b></td>
     <td><a href="#rectangularregion">RectangularRegion</a></td>
-    <td><i>The <a href="#regions">Regions</a> in which <a href="#population">Population</a>s get placed</i></td>
+    <td><i>The Regions in which Populations get placed.</i></td>
   </tr>
 
+
   <tr>
     <td><b>populations</b></td>
     <td><a href="#population">Population</a></td>
-    <td><i>The <a href="#population">Population</a>s of <a href="#cell">Cell</a>s making up this network...</i></td>
+    <td><i>The Populations of Cells making up this network ...</i></td>
   </tr>
 
+
   <tr>
     <td><b>projections</b></td>
     <td><a href="#projection">Projection</a></td>
-    <td><i>The <a href="#projection">Projection</a>s between <a href="#population">Population</a>s</i></td>
+    <td><i>The Projections between Populations</i></td>
   </tr>
 
+
   <tr>
     <td><b>inputs</b></td>
     <td><a href="#input">Input</a></td>
-    <td><i>The inputs to apply to the elements of <a href="#population">Population</a>s</i></td>
+    <td><i>The inputs to apply to the elements of Populations</i></td>
   </tr>
 
+
 </table>
 
 ## NetworkReader
+A NetworkReader definition.
 
 ### Allowed parameters
 <table>
+  <tr>
+    <td><b>notes</b></td>
+    <td>str</td>
+    <td><i></i></td>
+ </tr>
+
+
   <tr>
     <td><b>type</b></td>
     <td>str</td>
     <td><i>The type of NetworkReader</i></td>
-  </tr>
+ </tr>
+
 
   <tr>
     <td><b>parameters</b></td>
-    <td>dict</td>
+    <td>Any</td>
     <td><i>Dictionary of parameters for the NetworkReader</i></td>
-  </tr>
+ </tr>
+
 
 </table>
 
 ## Cell
+A Cell definition.
 
 ### Allowed parameters
 <table>
+  <tr>
+    <td><b>notes</b></td>
+    <td>str</td>
+    <td><i></i></td>
+ </tr>
+
+
+  <tr>
+    <td><b>id</b></td>
+    <td>str</td>
+    <td><i>Unique identifier for this Cell</i></td>
+ </tr>
+
+
+  <tr>
+    <td><b>parameters</b></td>
+    <td>Any</td>
+    <td><i>Dictionary of parameters for the cell</i></td>
+ </tr>
+
+
   <tr>
     <td><b>neuroml2_source_file</b></td>
     <td>str</td>
     <td><i>File name of NeuroML2 file defining the cell</i></td>
-  </tr>
+ </tr>
+
 
   <tr>
     <td><b>lems_source_file</b></td>
     <td>str</td>
     <td><i>File name of LEMS file defining the cell</i></td>
-  </tr>
+ </tr>
+
 
   <tr>
     <td><b>neuroml2_cell</b></td>
     <td>str</td>
     <td><i>Name of standard NeuroML2 cell type</i></td>
-  </tr>
+ </tr>
+
 
   <tr>
     <td><b>pynn_cell</b></td>
     <td>str</td>
     <td><i>Name of standard PyNN cell type</i></td>
-  </tr>
+ </tr>
+
 
   <tr>
     <td><b>arbor_cell</b></td>
     <td>str</td>
     <td><i>Name of standard Arbor cell type</i></td>
-  </tr>
+ </tr>
+
 
   <tr>
     <td><b>bindsnet_node</b></td>
     <td>str</td>
     <td><i>Name of standard BindsNET node</i></td>
-  </tr>
+ </tr>
 
-  <tr>
-    <td><b>parameters</b></td>
-    <td>dict</td>
-    <td><i>Dictionary of parameters for the cell</i></td>
-  </tr>
 
+</table>
+
+## Synapse
+A Synapse definition.
+
+### Allowed parameters
+<table>
   <tr>
-    <td><b>id</b></td>
+    <td><b>notes</b></td>
     <td>str</td>
-    <td><i>Unique ID of element</i></td>
-  </tr>
+    <td><i></i></td>
+ </tr>
+
 
   <tr>
-    <td><b>notes</b></td>
+    <td><b>id</b></td>
     <td>str</td>
-    <td><i>Human readable notes</i></td>
-  </tr>
+    <td><i>Unique identifier for this Synapse</i></td>
+ </tr>
 
-</table>
 
-## Synapse
+  <tr>
+    <td><b>parameters</b></td>
+    <td>Any</td>
+    <td><i>Dictionary of parameters for the synapse</i></td>
+ </tr>
+
 
-### Allowed parameters
-<table>
   <tr>
     <td><b>neuroml2_source_file</b></td>
     <td>str</td>
     <td><i>File name of NeuroML2 file defining the synapse</i></td>
-  </tr>
+ </tr>
+
 
   <tr>
     <td><b>lems_source_file</b></td>
     <td>str</td>
     <td><i>File name of LEMS file defining the synapse</i></td>
-  </tr>
+ </tr>
+
 
   <tr>
     <td><b>pynn_synapse_type</b></td>
     <td>str</td>
-    <td><i>Options: "curr_exp", "curr_alpha", "cond_exp", "cond_alpha".</i></td>
-  </tr>
+    <td><i>The pynn synapse type. Valid values are: "curr_exp", "curr_alpha", "cond_exp", "cond_alpha".</i></td>
+ </tr>
+
 
   <tr>
     <td><b>pynn_receptor_type</b></td>
     <td>str</td>
-    <td><i>Either "excitatory" or "inhibitory".</i></td>
-  </tr>
+    <td><i>The pynn receptor type. Valid values are: "excitatory", "inhibitory".</i></td>
+ </tr>
 
-  <tr>
-    <td><b>parameters</b></td>
-    <td>dict</td>
-    <td><i>Dictionary of parameters for the synapse</i></td>
-  </tr>
 
+</table>
+
+## InputSource
+An InputSource definition.
+
+### Allowed parameters
+<table>
   <tr>
-    <td><b>id</b></td>
+    <td><b>notes</b></td>
     <td>str</td>
-    <td><i>Unique ID of element</i></td>
-  </tr>
+    <td><i></i></td>
+ </tr>
+
 
   <tr>
-    <td><b>notes</b></td>
+    <td><b>id</b></td>
     <td>str</td>
-    <td><i>Human readable notes</i></td>
-  </tr>
+    <td><i>Unique identifier for this InputSource</i></td>
+ </tr>
 
-</table>
 
-## InputSource
+  <tr>
+    <td><b>parameters</b></td>
+    <td>Any</td>
+    <td><i>Dictionary of parameters for the InputSource</i></td>
+ </tr>
+
 
-### Allowed parameters
-<table>
   <tr>
     <td><b>neuroml2_source_file</b></td>
     <td>str</td>
-    <td><i>File name of NeuroML2 file</i></td>
-  </tr>
+    <td><i>File name of NeuroML2 file defining the input source</i></td>
+ </tr>
 
-  <tr>
-    <td><b>lems_source_file</b></td>
-    <td>str</td>
-    <td><i>File name of LEMS file</i></td>
-  </tr>
 
   <tr>
     <td><b>neuroml2_input</b></td>
     <td>str</td>
     <td><i>Name of standard NeuroML2 input</i></td>
-  </tr>
+ </tr>
+
 
   <tr>
-    <td><b>pynn_input</b></td>
+    <td><b>lems_source_file</b></td>
     <td>str</td>
-    <td><i>Name of standard PyNN input</i></td>
-  </tr>
+    <td><i>File name of LEMS file defining the input source</i></td>
+ </tr>
 
-  <tr>
-    <td><b>parameters</b></td>
-    <td>dict</td>
-    <td><i>Dictionary of parameters for the InputSource</i></td>
-  </tr>
 
   <tr>
-    <td><b>id</b></td>
+    <td><b>pynn_input</b></td>
     <td>str</td>
-    <td><i>Unique ID of element</i></td>
-  </tr>
+    <td><i>Name of PyNN input</i></td>
+ </tr>
 
-  <tr>
-    <td><b>notes</b></td>
-    <td>str</td>
-    <td><i>Human readable notes</i></td>
-  </tr>
 
 </table>
 
 ## RectangularRegion
+A RectangularRegion definition.
 
 ### Allowed parameters
 <table>
+  <tr>
+    <td><b>notes</b></td>
+    <td>str</td>
+    <td><i></i></td>
+ </tr>
+
+
+  <tr>
+    <td><b>id</b></td>
+    <td>str</td>
+    <td><i>Unique identifier for this rectangular region.</i></td>
+ </tr>
+
+
   <tr>
     <td><b>x</b></td>
     <td>float</td>
-    <td><i>x coordinate of corner</i></td>
-  </tr>
+    <td><i>x coordinate of corner of region</i></td>
+ </tr>
+
 
   <tr>
     <td><b>y</b></td>
     <td>float</td>
-    <td><i>y coordinate of corner</i></td>
-  </tr>
+    <td><i>y coordinate of corner of region</i></td>
+ </tr>
+
 
   <tr>
     <td><b>z</b></td>
     <td>float</td>
-    <td><i>z coordinate of corner</i></td>
-  </tr>
+    <td><i>z coordinate of corner of region</i></td>
+ </tr>
+
 
   <tr>
     <td><b>width</b></td>
     <td>float</td>
-    <td><i>Width of rectangular region</i></td>
-  </tr>
+    <td><i>width of the rectangular region</i></td>
+ </tr>
+
 
   <tr>
     <td><b>height</b></td>
     <td>float</td>
-    <td><i>Height of rectangular region</i></td>
-  </tr>
+    <td><i>height of the rectangular region</i></td>
+ </tr>
+
 
   <tr>
     <td><b>depth</b></td>
     <td>float</td>
-    <td><i>Depth of rectangular region</i></td>
-  </tr>
+    <td><i>depth of the rectangular region</i></td>
+ </tr>
 
-  <tr>
-    <td><b>id</b></td>
-    <td>str</td>
-    <td><i>Unique ID of element</i></td>
-  </tr>
-
-  <tr>
-    <td><b>notes</b></td>
-    <td>str</td>
-    <td><i>Human readable notes</i></td>
-  </tr>
 
 </table>
 
 ## Population
+A Population definition.
 
 ### Allowed parameters
 <table>
+  <tr>
+    <td><b>notes</b></td>
+    <td>str</td>
+    <td><i></i></td>
+ </tr>
+
+
+  <tr>
+    <td><b>id</b></td>
+    <td>str</td>
+    <td><i>Unique identifier for this Population</i></td>
+ </tr>
+
+
   <tr>
     <td><b>size</b></td>
-    <td>EvaluableExpression</td>
-    <td><i>Size of population</i></td>
-  </tr>
+    <td>Union[EvaluableExpression, T, VT, ndarray, int, float, str]</td>
+    <td><i>The size of the population.</i></td>
+ </tr>
+
 
   <tr>
     <td><b>component</b></td>
     <td>str</td>
-    <td><i>Type of <a href="#cell">Cell</a> to use in population</i></td>
-  </tr>
+    <td><i>The type of Cell to use in this population.</i></td>
+ </tr>
+
 
   <tr>
     <td><b>properties</b></td>
-    <td>dict</td>
-    <td><i>Dictionary of properties (metadata) for the population</i></td>
-  </tr>
+    <td>Any</td>
+    <td><i>A dictionary of properties (metadata) for this population.</i></td>
+ </tr>
+
 
   <tr>
     <td><b>random_layout</b></td>
     <td><a href="#randomlayout">RandomLayout</a></td>
-    <td><i>Layout in random <a href="#region">Region</a></i></td>
-  </tr>
+    <td><i>Layout in the random RectangularRegion.</i></td>
+ </tr>
+
 
   <tr>
     <td><b>relative_layout</b></td>
     <td><a href="#relativelayout">RelativeLayout</a></td>
-    <td><i>Position relative to <a href="#region">Region</a>.</i></td>
-  </tr>
+    <td><i>Position relative to RectangularRegion.</i></td>
+ </tr>
+
 
   <tr>
     <td><b>single_location</b></td>
     <td><a href="#singlelocation">SingleLocation</a></td>
-    <td><i>Explicit location of the one <a href="#cell">Cell</a> in the population</i></td>
-  </tr>
+    <td><i>Explicit location of the one Cell in the population</i></td>
+ </tr>
 
-  <tr>
-    <td><b>id</b></td>
-    <td>str</td>
-    <td><i>Unique ID of element</i></td>
-  </tr>
-
-  <tr>
-    <td><b>notes</b></td>
-    <td>str</td>
-    <td><i>Human readable notes</i></td>
-  </tr>
 
 </table>
 
 ## RandomLayout
+A RandomLayout definition.
 
 ### Allowed parameters
 <table>
+  <tr>
+    <td><b>notes</b></td>
+    <td>str</td>
+    <td><i></i></td>
+ </tr>
+
+
   <tr>
     <td><b>region</b></td>
     <td>str</td>
     <td><i>Region in which to place population</i></td>
-  </tr>
+ </tr>
+
 
 </table>
 
 ## RelativeLayout
+A RelativeLayout definition.
 
 ### Allowed parameters
 <table>
+  <tr>
+    <td><b>notes</b></td>
+    <td>str</td>
+    <td><i></i></td>
+ </tr>
+
+
   <tr>
     <td><b>region</b></td>
     <td>str</td>
-    <td><i>The <a href="#region">Region</a> relative to which population should be positioned</i></td>
-  </tr>
+    <td><i>The Region relative to which population should be positioned.</i></td>
+ </tr>
+
 
   <tr>
     <td><b>x</b></td>
     <td>float</td>
-    <td><i>x position relative to x coordinate of <a href="#region">Region</a></i></td>
-  </tr>
+    <td><i>x position relative to x coordinate of Region</i></td>
+ </tr>
+
 
   <tr>
     <td><b>y</b></td>
     <td>float</td>
-    <td><i>y position relative to y coordinate of <a href="#region">Region</a></i></td>
-  </tr>
+    <td><i>y position relative to y coordinate of Region</i></td>
+ </tr>
+
 
   <tr>
     <td><b>z</b></td>
     <td>float</td>
-    <td><i>z position relative to z coordinate of <a href="#region">Region</a></i></td>
-  </tr>
+    <td><i>z position relative to z coordinate of Region</i></td>
+ </tr>
+
 
 </table>
 
 ## SingleLocation
+A SingleLocation definition.
 
 ### Allowed parameters
 <table>
+  <tr>
+    <td><b>notes</b></td>
+    <td>str</td>
+    <td><i></i></td>
+ </tr>
+
+
   <tr>
     <td><b>location</b></td>
     <td><a href="#location">Location</a></td>
-    <td><i>The location of the single <a href="#cell">Cell</a></i></td>
-  </tr>
+    <td><i>Location of the single Cell.</i></td>
+ </tr>
+
 
 </table>
 
 ## Location
+A Location definition.
 
 ### Allowed parameters
 <table>
+  <tr>
+    <td><b>notes</b></td>
+    <td>str</td>
+    <td><i></i></td>
+ </tr>
+
+
   <tr>
     <td><b>x</b></td>
     <td>float</td>
-    <td><i>x coordinate</i></td>
-  </tr>
+    <td><i>x coordinate of location</i></td>
+ </tr>
+
 
   <tr>
     <td><b>y</b></td>
     <td>float</td>
-    <td><i>y coordinate</i></td>
-  </tr>
+    <td><i>y coordinate of location</i></td>
+ </tr>
+
 
   <tr>
     <td><b>z</b></td>
     <td>float</td>
-    <td><i>z coordinate</i></td>
-  </tr>
+    <td><i>z coordinate of location</i></td>
+ </tr>
+
 
 </table>
 
 ## Projection
+A Projection definition.
 
 ### Allowed parameters
 <table>
+  <tr>
+    <td><b>notes</b></td>
+    <td>str</td>
+    <td><i></i></td>
+ </tr>
+
+
+  <tr>
+    <td><b>id</b></td>
+    <td>str</td>
+    <td><i>Unique identifier for this Projection</i></td>
+ </tr>
+
+
   <tr>
     <td><b>presynaptic</b></td>
     <td>str</td>
-    <td><i>Presynaptic <a href="#population">Population</a></i></td>
-  </tr>
+    <td><i>Presynaptic Population</i></td>
+ </tr>
+
 
   <tr>
     <td><b>postsynaptic</b></td>
     <td>str</td>
-    <td><i>Postsynaptic <a href="#population">Population</a></i></td>
-  </tr>
+    <td><i>Postsynaptic Population</i></td>
+ </tr>
+
 
   <tr>
     <td><b>synapse</b></td>
     <td>str</td>
-    <td><i>Which <a href="#synapse">Synapse</a> to use</i></td>
-  </tr>
+    <td><i>Which Synapse to use</i></td>
+ </tr>
+
 
   <tr>
     <td><b>pre_synapse</b></td>
     <td>str</td>
     <td><i>For continuous connections, what presynaptic component to use (default: silent analog synapse)</i></td>
-  </tr>
+ </tr>
+
 
   <tr>
     <td><b>type</b></td>
     <td>str</td>
-    <td><i>type of projection: projection (default; standard chemical, event triggered), electricalProjection (for gap junctions) or continuousProjection (for analogue/graded synapses)</i></td>
-  </tr>
+    <td><i>type of projection: projection (default; standard chemical, event triggered), electricalProjection
+(for gap junctions) or continuousProjection (for analogue/graded synapses)</i></td>
+ </tr>
+
 
   <tr>
     <td><b>delay</b></td>
-    <td>EvaluableExpression</td>
+    <td>Union[EvaluableExpression, T, VT, ndarray, int, float, str]</td>
     <td><i>Delay to use (default: 0)</i></td>
-  </tr>
+ </tr>
+
 
   <tr>
     <td><b>weight</b></td>
-    <td>EvaluableExpression</td>
+    <td>Union[EvaluableExpression, T, VT, ndarray, int, float, str]</td>
     <td><i>Weight to use (default: 1)</i></td>
-  </tr>
+ </tr>
+
 
   <tr>
     <td><b>random_connectivity</b></td>
     <td><a href="#randomconnectivity">RandomConnectivity</a></td>
     <td><i>Use random connectivity</i></td>
-  </tr>
+ </tr>
+
 
   <tr>
     <td><b>convergent_connectivity</b></td>
     <td><a href="#convergentconnectivity">ConvergentConnectivity</a></td>
-    <td><i>Use ConvergentConnectivity</i></td>
-  </tr>
+    <td><i>Use convergent connectivity</i></td>
+ </tr>
+
 
   <tr>
     <td><b>one_to_one_connector</b></td>
     <td><a href="#onetooneconnector">OneToOneConnector</a></td>
     <td><i>Connect cell index i in pre pop to cell index i in post pop for all i</i></td>
-  </tr>
+ </tr>
 
-  <tr>
-    <td><b>id</b></td>
-    <td>str</td>
-    <td><i>Unique ID of element</i></td>
-  </tr>
-
-  <tr>
-    <td><b>notes</b></td>
-    <td>str</td>
-    <td><i>Human readable notes</i></td>
-  </tr>
 
 </table>
 
 ## RandomConnectivity
+A RandomConnectivity definition.
 
 ### Allowed parameters
 <table>
+  <tr>
+    <td><b>notes</b></td>
+    <td>str</td>
+    <td><i></i></td>
+ </tr>
+
+
   <tr>
     <td><b>probability</b></td>
-    <td>EvaluableExpression</td>
-    <td><i>Random probability of connection</i></td>
-  </tr>
+    <td>Union[EvaluableExpression, T, VT, ndarray, int, float, str]</td>
+    <td><i>Random probability of connection.</i></td>
+ </tr>
+
 
 </table>
 
 ## ConvergentConnectivity
+A ConvergentConnectivity definition.
 
 ### Allowed parameters
 <table>
+  <tr>
+    <td><b>notes</b></td>
+    <td>str</td>
+    <td><i></i></td>
+ </tr>
+
+
   <tr>
     <td><b>num_per_post</b></td>
     <td>float</td>
-    <td><i>Number per post synaptic neuron</i></td>
-  </tr>
+    <td><i>Number per post-synaptic neuron.</i></td>
+ </tr>
+
 
 </table>
 
 ## OneToOneConnector
+A OneToOneConnector definition.
+
+### Allowed parameters
+<table>
+  <tr>
+    <td><b>notes</b></td>
+    <td>str</td>
+    <td><i></i></td>
+ </tr>
+
+
+</table>
 
 ## Input
+An Input definition.
 
 ### Allowed parameters
 <table>
+  <tr>
+    <td><b>notes</b></td>
+    <td>str</td>
+    <td><i></i></td>
+ </tr>
+
+
+  <tr>
+    <td><b>id</b></td>
+    <td>str</td>
+    <td><i>Unique identifier for this Input</i></td>
+ </tr>
+
+
   <tr>
     <td><b>input_source</b></td>
     <td>str</td>
     <td><i>Type of input to use in population</i></td>
-  </tr>
+ </tr>
+
 
   <tr>
     <td><b>population</b></td>
     <td>str</td>
     <td><i>Population to target</i></td>
-  </tr>
+ </tr>
+
 
   <tr>
     <td><b>cell_ids</b></td>
-    <td>EvaluableExpression</td>
-    <td><i>Specific ids of <a href="#cell">Cell</a>s to apply this input to (cannot be used with percentage)</i></td>
-  </tr>
+    <td>Union[EvaluableExpression, T, VT, ndarray, int, float, str]</td>
+    <td><i>Specific ids of <a href="#cell">Cell</a>s to apply this input to (cannot be used with percentage</i></td>
+ </tr>
+
 
   <tr>
     <td><b>percentage</b></td>
     <td>float</td>
-    <td><i>Percentage of <a href="#cell">Cell</a>s to apply this input to (cannot be used with cell<a href="#ids)">ids)</a></i></td>
-  </tr>
+    <td><i>Percentage of Cells to apply input to</i></td>
+ </tr>
+
 
   <tr>
     <td><b>number_per_cell</b></td>
-    <td>EvaluableExpression</td>
-    <td><i>Number of individual inputs per selected <a href="#cell">Cell</a> (default: 1)</i></td>
-  </tr>
+    <td>Union[EvaluableExpression, T, VT, ndarray, int, float, str]</td>
+    <td><i>Number of individual inputs per selected Cell (default: 1)</i></td>
+ </tr>
+
 
   <tr>
     <td><b>segment_ids</b></td>
-    <td>EvaluableExpression</td>
+    <td>Union[EvaluableExpression, T, VT, ndarray, int, float, str]</td>
     <td><i>Which segments to target (default: [0])</i></td>
-  </tr>
+ </tr>
+
 
   <tr>
     <td><b>weight</b></td>
-    <td>EvaluableExpression</td>
+    <td>Union[EvaluableExpression, T, VT, ndarray, int, float, str]</td>
     <td><i>Weight to use (default: 1)</i></td>
-  </tr>
-
-  <tr>
-    <td><b>id</b></td>
-    <td>str</td>
-    <td><i>Unique ID of element</i></td>
-  </tr>
+ </tr>
 
-  <tr>
-    <td><b>notes</b></td>
-    <td>str</td>
-    <td><i>Human readable notes</i></td>
-  </tr>
 
 </table>
 
diff --git a/examples/BBP_5percent.json b/examples/BBP_5percent.json
index 20bdab9..aed2df1 100644
--- a/examples/BBP_5percent.json
+++ b/examples/BBP_5percent.json
@@ -1,22 +1,6 @@
 {
     "BBP_5percent": {
-        "version": "NeuroMLlite v0.4.4",
-        "network_reader": {
-            "type": "BBPConnectomeReader",
-            "parameters": {
-                "id": "BBP_5percent",
-                "filename": "test_files/cons_locs_pathways_mc0_Column.h5",
-                "percentage_cells_per_pop": 5,
-                "DEFAULT_CELL_ID": "hhcell",
-                "cell_info": {
-                    "hhcell": {
-                        "hhcell": {
-                            "neuroml2_source_file": "test_files/hhcell.cell.nml"
-                        }
-                    }
-                }
-            }
-        },
+        "version": "NeuroMLlite v0.5.1",
         "notes": "A network with the Blue Brain Project connectivity data (%s% of total cells)",
         "cells": {
             "hhcell": {
@@ -42,6 +26,21 @@
                 "population": "L4_PC",
                 "percentage": 80.0
             }
+        },
+        "network_reader": {
+            "type": "BBPConnectomeReader",
+            "parameters": {
+                "id": "BBP_5percent",
+                "filename": "test_files/cons_locs_pathways_mc0_Column.h5",
+                "percentage_cells_per_pop": 5,
+                "DEFAULT_CELL_ID": "hhcell",
+                "cell_info": {
+                    "hhcell": {
+                        "id": "hhcell",
+                        "neuroml2_source_file": "test_files/hhcell.cell.nml"
+                    }
+                }
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/examples/BBP_5percent.net.nml b/examples/BBP_5percent.net.nml
index 4ad713c..d4bb31c 100644
--- a/examples/BBP_5percent.net.nml
+++ b/examples/BBP_5percent.net.nml
@@ -1,11 +1,11 @@
 <neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.2.xsd" id="BBP_5percent">
-    <notes>Network read in from BBP connectome: /Users/padraig/NeuroMLlite/examples/test_files/cons_locs_pathways_mc0_Column.h5</notes>
+    <notes>Network read in from BBP connectome: /home/padraig/NeuroMLlite/examples/test_files/cons_locs_pathways_mc0_Column.h5</notes>
     <include href="test_files/inputs.nml"/>
     <include href="test_files/hhcell.cell.nml"/>
     <include href="test_files/ampa.synapse.nml"/>
     <include href="test_files/gaba.synapse.nml"/>
     <network id="BBP_5percent">
-        <notes>Network read in from BBP connectome: /Users/padraig/NeuroMLlite/examples/test_files/cons_locs_pathways_mc0_Column.h5</notes>
+        <notes>Network read in from BBP connectome: /home/padraig/NeuroMLlite/examples/test_files/cons_locs_pathways_mc0_Column.h5</notes>
         <population id="L1_DAC" component="hhcell" size="2" type="populationList">
             <property tag="radius" value="5"/>
             <property tag="type" value="I"/>
diff --git a/examples/Example10.py b/examples/Example10.py
index 46077f0..4be82ed 100644
--- a/examples/Example10.py
+++ b/examples/Example10.py
@@ -40,7 +40,7 @@
     network=new_file,
     duration="1e4",
     dt="1",
-    recordVariables={"x": {"all": "*"}, "y": {"all": "*"}, "z": {"all": "*"}},
+    record_variables={"x": {"all": "*"}, "y": {"all": "*"}, "z": {"all": "*"}},
     plots2D={
         "X-Y": {"x_axis": "lorenzPop[0]/x", "y_axis": "lorenzPop[0]/y"},
         "Y-Z": {"x_axis": "lorenzPop[0]/y", "y_axis": "lorenzPop[0]/z"},
diff --git a/examples/Example10_Lorenz.json b/examples/Example10_Lorenz.json
index a598371..79b90b9 100644
--- a/examples/Example10_Lorenz.json
+++ b/examples/Example10_Lorenz.json
@@ -1,6 +1,7 @@
 {
     "Example10_Lorenz": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
+        "notes": "Example 10: Lorenz",
         "parameters": {
             "N": 1,
             "sigma": 10,
@@ -10,10 +11,8 @@
             "y0": 1.0,
             "z0": 1.0
         },
-        "notes": "Example 10: Lorenz",
         "cells": {
             "lorenzCell": {
-                "lems_source_file": "test_files/Lorenz1963.xml",
                 "parameters": {
                     "sigma": "sigma",
                     "b": "b",
@@ -21,7 +20,8 @@
                     "x0": "x0",
                     "y0": "y0",
                     "z0": "z0"
-                }
+                },
+                "lems_source_file": "test_files/Lorenz1963.xml"
             }
         },
         "populations": {
diff --git a/examples/Example10_Lorenz.mdf.yaml b/examples/Example10_Lorenz.mdf.yaml
index 9988e0d..618c1e4 100644
--- a/examples/Example10_Lorenz.mdf.yaml
+++ b/examples/Example10_Lorenz.mdf.yaml
@@ -37,10 +37,12 @@ Example10_Lorenz:
                             value: y
                         z:
                             value: z
-                    notes: "Cell: [Cell (lorenzCell), lems_source_file = test_files/Lorenz1963.xml,\
-                        \ parameters = {'sigma': 'sigma', 'b': 'b', 'r': 'r', 'x0':\
-                        \ 'x0', 'y0': 'y0', 'z0': 'z0'}] is defined in test_files/Lorenz1963.xml\
-                        \ and in Lems is: Component, id: lorenzCell, type: lorenz,\n\
-                        \   parameters: {'sigma': '10', 'b': '2.67', 'r': '28', 'x0':\
-                        \ '1.0', 'y0': '1.0', 'z0': '1.0'}\n   parent: None\n"
+                    notes: "Cell: [Cell(notes=None, id='lorenzCell', parameters={'sigma':\
+                        \ 'sigma', 'b': 'b', 'r': 'r', 'x0': 'x0', 'y0': 'y0', 'z0':\
+                        \ 'z0'}, neuroml2_source_file=None, lems_source_file='test_files/Lorenz1963.xml',\
+                        \ neuroml2_cell=None, pynn_cell=None, arbor_cell=None, bindsnet_node=None)]\
+                        \ is defined in test_files/Lorenz1963.xml and in Lems is:\
+                        \ Component, id: lorenzCell, type: lorenz,\n   parameters:\
+                        \ {'sigma': '10', 'b': '2.67', 'r': '28', 'x0': '1.0', 'y0':\
+                        \ '1.0', 'z0': '1.0'}\n   parent: None\n"
             edges: {}
diff --git a/examples/Example11.py b/examples/Example11.py
index c76f3b0..c69a88e 100644
--- a/examples/Example11.py
+++ b/examples/Example11.py
@@ -98,12 +98,12 @@
     network=new_file,
     duration="1000",
     dt="0.01",
-    recordTraces={"all": "*"},
-    recordVariables={
+    record_traces={"all": "*"},
+    record_variables={
         "synapses:%s:0/g" % ampaSyn.id: {"pop1": "*"},
         "synapses:%s:0/g" % nmdaSyn.id: {"pop1": "*"},
     },
-    recordSpikes={"pop0": "*"},
+    record_spikes={"pop0": "*"},
 )
 
 sim.to_json_file()
diff --git a/examples/Example11_Synapses.json b/examples/Example11_Synapses.json
index fe2cf36..f41b366 100644
--- a/examples/Example11_Synapses.json
+++ b/examples/Example11_Synapses.json
@@ -1,11 +1,11 @@
 {
     "Example11_Synapses": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
+        "notes": "Example 11: synaptic properties",
         "parameters": {
             "input_amp": 0.23,
             "weight": 1.01
         },
-        "notes": "Example 11: synaptic properties",
         "cells": {
             "iafCell0": {
                 "neuroml2_source_file": "test_files/iaf.cell.nml"
@@ -21,12 +21,12 @@
         },
         "input_sources": {
             "i_clamp": {
-                "pynn_input": "DCSource",
                 "parameters": {
                     "amplitude": "input_amp",
                     "start": 200.0,
                     "stop": 800.0
-                }
+                },
+                "pynn_input": "DCSource"
             }
         },
         "regions": {
diff --git a/examples/Example11_Synapses.net.nml b/examples/Example11_Synapses.net.nml
index 9d8825f..b54f0a8 100644
--- a/examples/Example11_Synapses.net.nml
+++ b/examples/Example11_Synapses.net.nml
@@ -1,5 +1,5 @@
 <neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.2.xsd" id="Example11_Synapses">
-    <notes>Generated by NeuroMLlite v0.4.4
+    <notes>Generated by NeuroMLlite v0.5.1
     Generated network: Example11_Synapses
     Generation seed: 1234
     NeuroMLlite parameters: 
diff --git a/examples/Example1_TestNetwork.json b/examples/Example1_TestNetwork.json
index 3863480..c71d791 100644
--- a/examples/Example1_TestNetwork.json
+++ b/examples/Example1_TestNetwork.json
@@ -1,6 +1,6 @@
 {
     "TestNetwork": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
         "notes": "A simple network with 2 populations & projection between them. No info yet on what the cells are so network can't be simulated.",
         "populations": {
             "pop0": {
diff --git a/examples/Example2_TestNetwork.json b/examples/Example2_TestNetwork.json
index b984dac..e9ae88d 100644
--- a/examples/Example2_TestNetwork.json
+++ b/examples/Example2_TestNetwork.json
@@ -1,6 +1,6 @@
 {
     "Example2_TestNetwork": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
         "notes": "A simple network with 2 populations & projection between them. Cells are specified to be NeuroML 2 HH cell models & pre population is given a spiking input.",
         "cells": {
             "hhcell": {
diff --git a/examples/Example2_TestNetwork.net.nml b/examples/Example2_TestNetwork.net.nml
index e7c919b..04a7efd 100644
--- a/examples/Example2_TestNetwork.net.nml
+++ b/examples/Example2_TestNetwork.net.nml
@@ -1,5 +1,5 @@
 <neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.2.xsd" id="Example2_TestNetwork">
-    <notes>Generated by NeuroMLlite v0.4.4
+    <notes>Generated by NeuroMLlite v0.5.1
     Generated network: Example2_TestNetwork
     Generation seed: 1234</notes>
     <include href="test_files/inputs.nml"/>
diff --git a/examples/Example3.py b/examples/Example3.py
index b4d26bc..67cda1d 100644
--- a/examples/Example3.py
+++ b/examples/Example3.py
@@ -22,7 +22,7 @@
     network=new_file,
     duration="1000",
     dt="0.025",
-    recordTraces={"all": "*"},
+    record_traces={"all": "*"},
 )
 
 sim.to_json_file()
diff --git a/examples/Example3_Network.json b/examples/Example3_Network.json
index 8beda1f..f40c109 100644
--- a/examples/Example3_Network.json
+++ b/examples/Example3_Network.json
@@ -1,6 +1,6 @@
 {
     "Example3_Network": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
         "notes": "Example 3: simple network with 2 populations of NeuroML2 cells, a projection between them and spiking input.",
         "cells": {
             "hhcell": {
diff --git a/examples/Example3_Network.net.nml b/examples/Example3_Network.net.nml
index 6142862..bfc9329 100644
--- a/examples/Example3_Network.net.nml
+++ b/examples/Example3_Network.net.nml
@@ -1,5 +1,5 @@
 <neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.2.xsd" id="Example3_Network">
-    <notes>Generated by NeuroMLlite v0.4.4
+    <notes>Generated by NeuroMLlite v0.5.1
     Generated network: Example3_Network
     Generation seed: 1234</notes>
     <include href="test_files/inputs.nml"/>
diff --git a/examples/Example4.py b/examples/Example4.py
index d8c50f5..9ed8afb 100644
--- a/examples/Example4.py
+++ b/examples/Example4.py
@@ -119,13 +119,13 @@
     network=net_json_file,
     duration="1000",
     dt="0.01",
-    recordTraces={"all": "*"},
-    recordSpikes={"pop0": "*"},
+    record_traces={"all": "*"},
+    record_spikes={"pop0": "*"},
 )
 
 sim.to_json_file()
 sim.network = net_yaml_file
-sim.to_yaml_file()
+sim.to_yaml_file('%s.yaml'%sim.id)
 
 sim.network = net_json_file  # reverting, for call below...
 
diff --git a/examples/Example4_PyNN.json b/examples/Example4_PyNN.json
index b412af7..abb682b 100644
--- a/examples/Example4_PyNN.json
+++ b/examples/Example4_PyNN.json
@@ -1,52 +1,52 @@
 {
     "Example4_PyNN": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
+        "notes": "Example 4: a network with PyNN cells & inputs",
         "parameters": {
             "input_amp": 0.99
         },
-        "notes": "Example 4: a network with PyNN cells & inputs",
         "cells": {
             "testcell": {
-                "pynn_cell": "IF_cond_alpha",
                 "parameters": {
                     "tau_refrac": 5,
                     "i_offset": 0.1
-                }
+                },
+                "pynn_cell": "IF_cond_alpha"
             },
             "testcell2": {
-                "pynn_cell": "IF_cond_alpha",
                 "parameters": {
                     "tau_refrac": 5,
                     "i_offset": -0.1
-                }
+                },
+                "pynn_cell": "IF_cond_alpha"
             }
         },
         "synapses": {
             "ampaSyn": {
-                "pynn_synapse_type": "cond_alpha",
-                "pynn_receptor_type": "excitatory",
                 "parameters": {
                     "e_rev": -10,
                     "tau_syn": 2
-                }
+                },
+                "pynn_synapse_type": "cond_alpha",
+                "pynn_receptor_type": "excitatory"
             },
             "gabaSyn": {
-                "pynn_synapse_type": "cond_alpha",
-                "pynn_receptor_type": "inhibitory",
                 "parameters": {
                     "e_rev": -80,
                     "tau_syn": 10
-                }
+                },
+                "pynn_synapse_type": "cond_alpha",
+                "pynn_receptor_type": "inhibitory"
             }
         },
         "input_sources": {
             "i_clamp": {
-                "pynn_input": "DCSource",
                 "parameters": {
                     "amplitude": "input_amp",
                     "start": 200.0,
                     "stop": 800.0
-                }
+                },
+                "pynn_input": "DCSource"
             }
         },
         "regions": {
diff --git a/examples/Example4_PyNN.net.nml b/examples/Example4_PyNN.net.nml
index 9219e83..5bd6af1 100644
--- a/examples/Example4_PyNN.net.nml
+++ b/examples/Example4_PyNN.net.nml
@@ -1,5 +1,5 @@
 <neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.2.xsd" id="Example4_PyNN">
-    <notes>Generated by NeuroMLlite v0.4.4
+    <notes>Generated by NeuroMLlite v0.5.1
     Generated network: Example4_PyNN
     Generation seed: 1234
     NeuroMLlite parameters: 
diff --git a/examples/Example4_PyNN.yaml b/examples/Example4_PyNN.yaml
index ca9ae09..de68dca 100644
--- a/examples/Example4_PyNN.yaml
+++ b/examples/Example4_PyNN.yaml
@@ -1,39 +1,39 @@
 Example4_PyNN:
-    version: NeuroMLlite v0.4.4
+    version: NeuroMLlite v0.5.1
+    notes: 'Example 4: a network with PyNN cells & inputs'
     parameters:
         input_amp: 0.99
-    notes: 'Example 4: a network with PyNN cells & inputs'
     cells:
         testcell:
-            pynn_cell: IF_cond_alpha
             parameters:
                 tau_refrac: 5
                 i_offset: 0.1
-        testcell2:
             pynn_cell: IF_cond_alpha
+        testcell2:
             parameters:
                 tau_refrac: 5
                 i_offset: -0.1
+            pynn_cell: IF_cond_alpha
     synapses:
         ampaSyn:
-            pynn_synapse_type: cond_alpha
-            pynn_receptor_type: excitatory
             parameters:
                 e_rev: -10
                 tau_syn: 2
-        gabaSyn:
             pynn_synapse_type: cond_alpha
-            pynn_receptor_type: inhibitory
+            pynn_receptor_type: excitatory
+        gabaSyn:
             parameters:
                 e_rev: -80
                 tau_syn: 10
+            pynn_synapse_type: cond_alpha
+            pynn_receptor_type: inhibitory
     input_sources:
         i_clamp:
-            pynn_input: DCSource
             parameters:
                 amplitude: input_amp
                 start: 200.0
                 stop: 800.0
+            pynn_input: DCSource
     regions:
         region1:
             x: 0.0
diff --git a/examples/Example5.py b/examples/Example5.py
index bfc268c..abda353 100644
--- a/examples/Example5.py
+++ b/examples/Example5.py
@@ -65,8 +65,8 @@
 
 from neuromllite import Simulation
 
-recordTraces = {"all": "*"}
-recordSpikes = {"all": "*"}
+record_traces = {"all": "*"}
+record_spikes = {"all": "*"}
 
 
 sim = Simulation(
@@ -74,8 +74,8 @@
     network=new_file,
     duration=500,
     dt=0.025,
-    recordTraces=recordTraces,
-    recordSpikes=recordSpikes,
+    record_traces=record_traces,
+    record_spikes=record_spikes,
 )
 
 sim.to_json_file()
diff --git a/examples/Example6.py b/examples/Example6.py
index b33edc7..a03dde3 100644
--- a/examples/Example6.py
+++ b/examples/Example6.py
@@ -195,17 +195,17 @@ def generate(ref="Example6_PyNN", add_inputs=True):
     ################################################################################
     ###   Build Simulation object & save as JSON
 
-    recordTraces = {}
-    recordSpikes = {}
+    record_traces = {}
+    record_spikes = {}
 
     from neuromllite.utils import evaluate
 
     for p in pops:
         forecast_size = evaluate(pop_dict[p].size, net.parameters)
-        recordTraces[p] = list(range(min(2, forecast_size)))
-        recordSpikes[p] = "*"
+        record_traces[p] = list(range(min(2, forecast_size)))
+        record_spikes[p] = "*"
     for ip in input_pops:
-        recordSpikes[ip] = "*"
+        record_spikes[ip] = "*"
 
     sim = Simulation(
         id="Sim%s" % net.id,
@@ -213,8 +213,8 @@ def generate(ref="Example6_PyNN", add_inputs=True):
         duration="100",
         dt="0.025",
         seed=1234,
-        recordTraces=recordTraces,
-        recordSpikes=recordSpikes,
+        record_traces=record_traces,
+        record_spikes=record_spikes,
     )
 
     sim.to_json_file()
diff --git a/examples/Example6_PyNN.json b/examples/Example6_PyNN.json
index 086ca8d..a7da544 100644
--- a/examples/Example6_PyNN.json
+++ b/examples/Example6_PyNN.json
@@ -1,6 +1,7 @@
 {
     "Example6_PyNN": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
+        "notes": "Another network for PyNN - work in progress...",
         "parameters": {
             "N_scaling": 0.005,
             "layer_height": 400,
@@ -8,10 +9,8 @@
             "depth": 100,
             "input_weight": 0.1
         },
-        "notes": "Another network for PyNN - work in progress...",
         "cells": {
             "CorticalCell": {
-                "pynn_cell": "IF_curr_exp",
                 "parameters": {
                     "cm": 0.25,
                     "i_offset": 0.0,
@@ -20,31 +19,32 @@
                     "v_reset": -65.0,
                     "v_rest": -65.0,
                     "v_thresh": -50.0
-                }
+                },
+                "pynn_cell": "IF_curr_exp"
             },
             "InputCell": {
-                "pynn_cell": "SpikeSourcePoisson",
                 "parameters": {
                     "start": 0,
                     "duration": 10000000000,
                     "rate": 150
-                }
+                },
+                "pynn_cell": "SpikeSourcePoisson"
             }
         },
         "synapses": {
             "ampa": {
-                "pynn_synapse_type": "curr_exp",
-                "pynn_receptor_type": "excitatory",
                 "parameters": {
                     "tau_syn": 0.5
-                }
+                },
+                "pynn_synapse_type": "curr_exp",
+                "pynn_receptor_type": "excitatory"
             },
             "gaba": {
-                "pynn_synapse_type": "curr_exp",
-                "pynn_receptor_type": "inhibitory",
                 "parameters": {
                     "tau_syn": 0.5
-                }
+                },
+                "pynn_synapse_type": "curr_exp",
+                "pynn_receptor_type": "inhibitory"
             }
         },
         "regions": {
diff --git a/examples/Example6_PyNN.net.nml b/examples/Example6_PyNN.net.nml
index 52e954e..60ea841 100644
--- a/examples/Example6_PyNN.net.nml
+++ b/examples/Example6_PyNN.net.nml
@@ -1,5 +1,5 @@
 <neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.2.xsd" id="Example6_PyNN">
-    <notes>Generated by NeuroMLlite v0.4.4
+    <notes>Generated by NeuroMLlite v0.5.1
     Generated network: Example6_PyNN
     Generation seed: 1234
     NeuroMLlite parameters: 
diff --git a/examples/Example6_PyNN_noinputs.json b/examples/Example6_PyNN_noinputs.json
index 3f316ad..a6cc60f 100644
--- a/examples/Example6_PyNN_noinputs.json
+++ b/examples/Example6_PyNN_noinputs.json
@@ -1,6 +1,7 @@
 {
     "Example6_PyNN_noinputs": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
+        "notes": "Another network for PyNN - work in progress...",
         "parameters": {
             "N_scaling": 0.005,
             "layer_height": 400,
@@ -8,10 +9,8 @@
             "depth": 100,
             "input_weight": 0.1
         },
-        "notes": "Another network for PyNN - work in progress...",
         "cells": {
             "CorticalCell": {
-                "pynn_cell": "IF_curr_exp",
                 "parameters": {
                     "cm": 0.25,
                     "i_offset": 0.0,
@@ -20,23 +19,24 @@
                     "v_reset": -65.0,
                     "v_rest": -65.0,
                     "v_thresh": -50.0
-                }
+                },
+                "pynn_cell": "IF_curr_exp"
             }
         },
         "synapses": {
             "ampa": {
-                "pynn_synapse_type": "curr_exp",
-                "pynn_receptor_type": "excitatory",
                 "parameters": {
                     "tau_syn": 0.5
-                }
+                },
+                "pynn_synapse_type": "curr_exp",
+                "pynn_receptor_type": "excitatory"
             },
             "gaba": {
-                "pynn_synapse_type": "curr_exp",
-                "pynn_receptor_type": "inhibitory",
                 "parameters": {
                     "tau_syn": 0.5
-                }
+                },
+                "pynn_synapse_type": "curr_exp",
+                "pynn_receptor_type": "inhibitory"
             }
         },
         "regions": {
diff --git a/examples/Example6_PyNN_noinputs.net.nml b/examples/Example6_PyNN_noinputs.net.nml
index 263f785..237a5eb 100644
--- a/examples/Example6_PyNN_noinputs.net.nml
+++ b/examples/Example6_PyNN_noinputs.net.nml
@@ -1,5 +1,5 @@
 <neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.2.xsd" id="Example6_PyNN_noinputs">
-    <notes>Generated by NeuroMLlite v0.4.4
+    <notes>Generated by NeuroMLlite v0.5.1
     Generated network: Example6_PyNN_noinputs
     Generation seed: 1234
     NeuroMLlite parameters: 
diff --git a/examples/Example7.py b/examples/Example7.py
index b08977f..8914e69 100644
--- a/examples/Example7.py
+++ b/examples/Example7.py
@@ -213,8 +213,8 @@ def generate():
         duration=simtime,
         dt=dt,
         seed=123,
-        recordTraces={pE.id: [0, 1], pI.id: [0, 1]},
-        recordSpikes={
+        record_traces={pE.id: [0, 1], pI.id: [0, 1]},
+        record_spikes={
             pE.id: "*",
             pI.id: "*",
             pEpoisson.id: [0, 1, 2, 3, 4],
@@ -234,7 +234,7 @@ def generate():
         from neuromllite.sweep.ParameterSweep import *
 
         sim, net = generate()
-        sim.recordTraces = {}
+        sim.record_traces = {}
 
         fixed = {"dt": 0.025, "order": 5}
 
@@ -300,7 +300,7 @@ def generate():
     if "-sweep2" in sys.argv:
 
         sim, net = generate()
-        sim.recordTraces = {}
+        sim.record_traces = {}
 
         fixed = {"dt": 0.025, "order": 5}
 
diff --git a/examples/Example7_Brunel2000.json b/examples/Example7_Brunel2000.json
index 1f92a3d..9f6c647 100644
--- a/examples/Example7_Brunel2000.json
+++ b/examples/Example7_Brunel2000.json
@@ -1,6 +1,7 @@
 {
     "Example7_Brunel2000": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
+        "notes": "Example 7: based on network of Brunel 2000",
         "parameters": {
             "g": 4,
             "eta": 1,
@@ -14,10 +15,8 @@
             "U0": 0.0,
             "theta": 20.0
         },
-        "notes": "Example 7: based on network of Brunel 2000",
         "cells": {
             "ifcell": {
-                "pynn_cell": "IF_curr_alpha",
                 "parameters": {
                     "tau_m": "tauMem",
                     "tau_refrac": "tauRef",
@@ -26,31 +25,32 @@
                     "v_thresh": "theta",
                     "cm": 0.001,
                     "i_offset": 0
-                }
+                },
+                "pynn_cell": "IF_curr_alpha"
             },
             "poisson_input": {
-                "pynn_cell": "SpikeSourcePoisson",
                 "parameters": {
                     "rate": "1000 * (eta*theta/(J*4*order*epsilon*tauMem)) * (4*order*epsilon)",
                     "start": 0,
                     "duration": 1000000000.0
-                }
+                },
+                "pynn_cell": "SpikeSourcePoisson"
             }
         },
         "synapses": {
             "ampa": {
-                "pynn_synapse_type": "curr_alpha",
-                "pynn_receptor_type": "excitatory",
                 "parameters": {
                     "tau_syn": 0.1
-                }
+                },
+                "pynn_synapse_type": "curr_alpha",
+                "pynn_receptor_type": "excitatory"
             },
             "gaba": {
-                "pynn_synapse_type": "curr_alpha",
-                "pynn_receptor_type": "inhibitory",
                 "parameters": {
                     "tau_syn": 0.1
-                }
+                },
+                "pynn_synapse_type": "curr_alpha",
+                "pynn_receptor_type": "inhibitory"
             }
         },
         "regions": {
diff --git a/examples/Example7_Brunel2000.net.nml b/examples/Example7_Brunel2000.net.nml
index bde6791..02edac3 100644
--- a/examples/Example7_Brunel2000.net.nml
+++ b/examples/Example7_Brunel2000.net.nml
@@ -1,5 +1,5 @@
 <neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.2.xsd" id="Example7_Brunel2000">
-    <notes>Generated by NeuroMLlite v0.4.4
+    <notes>Generated by NeuroMLlite v0.5.1
     Generated network: Example7_Brunel2000
     Generation seed: 1234
     NeuroMLlite parameters: 
diff --git a/examples/Example8.py b/examples/Example8.py
index c58917d..2731db3 100644
--- a/examples/Example8.py
+++ b/examples/Example8.py
@@ -9,7 +9,7 @@
 net.notes = "Example 8: general testing..."
 
 net.seed = 7890
-net.temperature = 32
+net.temperature = 32.0
 
 net.parameters = {"N": 10, "fractionE": 0.8, "weightInput": 1}
 
@@ -22,8 +22,8 @@
 )
 net.input_sources.append(input_source)
 """
-input_source = InputSource(id='iclamp0', 
-                           pynn_input='DCSource', 
+input_source = InputSource(id='iclamp0',
+                           pynn_input='DCSource',
                            parameters={'amplitude':0.2, 'start':100., 'stop':900.})"""
 
 net.input_sources.append(input_source)
@@ -90,7 +90,7 @@
     duration="1000",
     seed="1111",
     dt="0.025",
-    recordTraces={"all": "*"},
+    record_traces={"all": "*"},
 )
 
 sim.to_json_file()
diff --git a/examples/Example8_Extension.json b/examples/Example8_Extension.json
index 6f86a7a..078f9b6 100644
--- a/examples/Example8_Extension.json
+++ b/examples/Example8_Extension.json
@@ -1,14 +1,12 @@
 {
     "Example8_Extension": {
-        "version": "NeuroMLlite v0.4.4",
-        "seed": 7890,
-        "temperature": 32.0,
+        "version": "NeuroMLlite v0.5.1",
+        "notes": "Example 8: general testing...",
         "parameters": {
             "N": 10,
             "fractionE": 0.8,
             "weightInput": 1
         },
-        "notes": "Example 8: general testing...",
         "cells": {
             "hhcell": {
                 "neuroml2_source_file": "test_files/hhcell.cell.nml"
@@ -62,6 +60,8 @@
                 "percentage": 50.0,
                 "weight": "weightInput"
             }
-        }
+        },
+        "seed": 7890,
+        "temperature": 32.0
     }
 }
\ No newline at end of file
diff --git a/examples/Example9.py b/examples/Example9.py
index a0dad4e..ac2f35a 100644
--- a/examples/Example9.py
+++ b/examples/Example9.py
@@ -52,7 +52,7 @@
     network=new_file,
     duration="1000000",
     dt="25",
-    recordVariables={"x": {"all": "*"}, "y": {"all": "*"}, "z": {"all": "*"}},
+    record_variables={"x": {"all": "*"}, "y": {"all": "*"}, "z": {"all": "*"}},
     plots2D={
         "X-Y": {"x_axis": "hrPop[0]/x", "y_axis": "hrPop[0]/y"},
         "Y-Z": {"x_axis": "hrPop[0]/y", "y_axis": "hrPop[0]/z"},
diff --git a/examples/Example9_HindmarshRose.json b/examples/Example9_HindmarshRose.json
index 8869304..c6886c1 100644
--- a/examples/Example9_HindmarshRose.json
+++ b/examples/Example9_HindmarshRose.json
@@ -1,6 +1,7 @@
 {
     "Example9_HindmarshRose": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
+        "notes": "Example 9: HindmarshRose",
         "parameters": {
             "N": 1,
             "a": 1,
@@ -15,10 +16,8 @@
             "y0": -1.0,
             "z0": 1.0
         },
-        "notes": "Example 9: HindmarshRose",
         "cells": {
             "hrCell": {
-                "lems_source_file": "test_files/HindmarshRose3d.xml",
                 "parameters": {
                     "a": "a",
                     "b": "b",
@@ -31,7 +30,8 @@
                     "x0": "x0",
                     "y0": "y0",
                     "z0": "z0"
-                }
+                },
+                "lems_source_file": "test_files/HindmarshRose3d.xml"
             }
         },
         "populations": {
diff --git a/examples/SimExample10.json b/examples/SimExample10.json
index ec54754..5a66f74 100644
--- a/examples/SimExample10.json
+++ b/examples/SimExample10.json
@@ -1,10 +1,10 @@
 {
     "SimExample10": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
         "network": "Example10_Lorenz.json",
         "duration": 10000.0,
         "dt": 1.0,
-        "recordVariables": {
+        "record_variables": {
             "x": {
                 "all": "*"
             },
diff --git a/examples/SimExample11.json b/examples/SimExample11.json
index 2ccd5b6..8fb600f 100644
--- a/examples/SimExample11.json
+++ b/examples/SimExample11.json
@@ -1,16 +1,16 @@
 {
     "SimExample11": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
         "network": "Example11_Synapses.json",
         "duration": 1000.0,
         "dt": 0.01,
-        "recordTraces": {
+        "record_traces": {
             "all": "*"
         },
-        "recordSpikes": {
+        "record_spikes": {
             "pop0": "*"
         },
-        "recordVariables": {
+        "record_variables": {
             "synapses:ampa:0/g": {
                 "pop1": "*"
             },
diff --git a/examples/SimExample3.json b/examples/SimExample3.json
index 37a00b5..003c64e 100644
--- a/examples/SimExample3.json
+++ b/examples/SimExample3.json
@@ -1,10 +1,10 @@
 {
     "SimExample3": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
         "network": "Example3_Network.json",
         "duration": 1000.0,
         "dt": 0.025,
-        "recordTraces": {
+        "record_traces": {
             "all": "*"
         }
     }
diff --git a/examples/SimExample4.json b/examples/SimExample4.json
index f600654..5740ef4 100644
--- a/examples/SimExample4.json
+++ b/examples/SimExample4.json
@@ -1,13 +1,13 @@
 {
     "SimExample4": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
         "network": "Example4_PyNN.json",
         "duration": 1000.0,
         "dt": 0.01,
-        "recordTraces": {
+        "record_traces": {
             "all": "*"
         },
-        "recordSpikes": {
+        "record_spikes": {
             "pop0": "*"
         }
     }
diff --git a/examples/SimExample4.yaml b/examples/SimExample4.yaml
index 8e5304d..f238608 100644
--- a/examples/SimExample4.yaml
+++ b/examples/SimExample4.yaml
@@ -1,9 +1,9 @@
 SimExample4:
-    version: NeuroMLlite v0.4.4
+    version: NeuroMLlite v0.5.1
     network: Example4_PyNN.yaml
     duration: 1000.0
     dt: 0.01
-    recordTraces:
+    record_traces:
         all: '*'
-    recordSpikes:
+    record_spikes:
         pop0: '*'
diff --git a/examples/SimExample6_PyNN.json b/examples/SimExample6_PyNN.json
index 6008a47..deda7a9 100644
--- a/examples/SimExample6_PyNN.json
+++ b/examples/SimExample6_PyNN.json
@@ -1,11 +1,11 @@
 {
     "SimExample6_PyNN": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
         "network": "Example6_PyNN.json",
         "duration": 100.0,
         "dt": 0.025,
         "seed": 1234,
-        "recordTraces": {
+        "record_traces": {
             "L23_E": [
                 0,
                 1
@@ -39,7 +39,7 @@
                 1
             ]
         },
-        "recordSpikes": {
+        "record_spikes": {
             "L23_E": "*",
             "L23_I": "*",
             "L4_E": "*",
diff --git a/examples/SimExample7.json b/examples/SimExample7.json
index 990d545..7b80485 100644
--- a/examples/SimExample7.json
+++ b/examples/SimExample7.json
@@ -1,11 +1,11 @@
 {
     "SimExample7": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
         "network": "Example7_Brunel2000.json",
         "duration": 1000.0,
         "dt": 0.025,
         "seed": 123,
-        "recordTraces": {
+        "record_traces": {
             "Epop": [
                 0,
                 1
@@ -15,7 +15,7 @@
                 1
             ]
         },
-        "recordSpikes": {
+        "record_spikes": {
             "Epop": "*",
             "Ipop": "*",
             "expoisson": [
diff --git a/examples/SimExample8.json b/examples/SimExample8.json
index c73a29d..74e83c2 100644
--- a/examples/SimExample8.json
+++ b/examples/SimExample8.json
@@ -1,11 +1,11 @@
 {
     "SimExample8": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
         "network": "Example8_Extension.json",
         "duration": 1000.0,
         "dt": 0.025,
         "seed": 1111,
-        "recordTraces": {
+        "record_traces": {
             "all": "*"
         }
     }
diff --git a/examples/SimExample9.json b/examples/SimExample9.json
index ba95385..1e8a211 100644
--- a/examples/SimExample9.json
+++ b/examples/SimExample9.json
@@ -1,10 +1,10 @@
 {
     "SimExample9": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
         "network": "Example9_HindmarshRose.json",
         "duration": 1000000.0,
         "dt": 25.0,
-        "recordVariables": {
+        "record_variables": {
             "x": {
                 "all": "*"
             },
diff --git a/examples/arbor/ArborExample.json b/examples/arbor/ArborExample.json
index cce9073..83abc0a 100644
--- a/examples/arbor/ArborExample.json
+++ b/examples/arbor/ArborExample.json
@@ -1,6 +1,7 @@
 {
     "ArborExample": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
+        "notes": "Example for testing Arbor",
         "parameters": {
             "v_init": -50,
             "scale": 3,
@@ -8,35 +9,34 @@
             "input_del": 50,
             "input_dur": 5
         },
-        "notes": "Example for testing Arbor",
         "cells": {
             "test_arbor_cell": {
-                "arbor_cell": "cable_cell",
                 "parameters": {
                     "v_init": "v_init",
                     "radius": 3,
                     "mechanism": "hh"
-                }
+                },
+                "arbor_cell": "cable_cell"
             }
         },
         "synapses": {
             "ampaSyn": {
-                "pynn_synapse_type": "cond_alpha",
-                "pynn_receptor_type": "excitatory",
                 "parameters": {
                     "e_rev": -10,
                     "tau_syn": 2
-                }
+                },
+                "pynn_synapse_type": "cond_alpha",
+                "pynn_receptor_type": "excitatory"
             }
         },
         "input_sources": {
             "i_clamp": {
-                "pynn_input": "DCSource",
                 "parameters": {
                     "amplitude": "input_amp",
                     "start": "input_del",
                     "stop": "input_del+input_dur"
-                }
+                },
+                "pynn_input": "DCSource"
             }
         },
         "regions": {
diff --git a/examples/arbor/ArborExample.py b/examples/arbor/ArborExample.py
index e06ed9c..5167798 100644
--- a/examples/arbor/ArborExample.py
+++ b/examples/arbor/ArborExample.py
@@ -135,13 +135,13 @@
     network=new_file,
     duration="100",
     dt="0.01",
-    recordTraces={"all": "*"},
-    recordSpikes={"pop0": "*"},
+    record_traces={"all": "*"},
+    record_spikes={"pop0": "*"},
 )
 
 sim.to_json_file()
 sim.network = new_file_yaml
-sim.to_yaml_file()
+sim.to_yaml_file('%s.yaml'%sim.id)
 
 
 ################################################################################
diff --git a/examples/arbor/ArborExample.yaml b/examples/arbor/ArborExample.yaml
index 013e476..6a68a59 100644
--- a/examples/arbor/ArborExample.yaml
+++ b/examples/arbor/ArborExample.yaml
@@ -1,33 +1,33 @@
 ArborExample:
-    version: NeuroMLlite v0.4.4
+    version: NeuroMLlite v0.5.1
+    notes: Example for testing Arbor
     parameters:
         v_init: -50
         scale: 3
         input_amp: 0.01
         input_del: 50
         input_dur: 5
-    notes: Example for testing Arbor
     cells:
         test_arbor_cell:
-            arbor_cell: cable_cell
             parameters:
                 v_init: v_init
                 radius: 3
                 mechanism: hh
+            arbor_cell: cable_cell
     synapses:
         ampaSyn:
-            pynn_synapse_type: cond_alpha
-            pynn_receptor_type: excitatory
             parameters:
                 e_rev: -10
                 tau_syn: 2
+            pynn_synapse_type: cond_alpha
+            pynn_receptor_type: excitatory
     input_sources:
         i_clamp:
-            pynn_input: DCSource
             parameters:
                 amplitude: input_amp
                 start: input_del
                 stop: input_del+input_dur
+            pynn_input: DCSource
     regions:
         region0:
             x: 0.0
diff --git a/examples/arbor/SimArborExample.json b/examples/arbor/SimArborExample.json
index d7c092a..e081d1e 100644
--- a/examples/arbor/SimArborExample.json
+++ b/examples/arbor/SimArborExample.json
@@ -1,13 +1,13 @@
 {
     "SimArborExample": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
         "network": "ArborExample.json",
         "duration": 100.0,
         "dt": 0.01,
-        "recordTraces": {
+        "record_traces": {
             "all": "*"
         },
-        "recordSpikes": {
+        "record_spikes": {
             "pop0": "*"
         }
     }
diff --git a/examples/arbor/SimArborExample.yaml b/examples/arbor/SimArborExample.yaml
index 531d249..fcf902e 100644
--- a/examples/arbor/SimArborExample.yaml
+++ b/examples/arbor/SimArborExample.yaml
@@ -1,9 +1,9 @@
 SimArborExample:
-    version: NeuroMLlite v0.4.4
+    version: NeuroMLlite v0.5.1
     network: ArborExample.yaml
     duration: 100.0
     dt: 0.01
-    recordTraces:
+    record_traces:
         all: '*'
-    recordSpikes:
+    record_spikes:
         pop0: '*'
diff --git a/neuromllite/BaseTypes.py b/neuromllite/BaseTypes.py
deleted file mode 100644
index fd09aec..0000000
--- a/neuromllite/BaseTypes.py
+++ /dev/null
@@ -1,154 +0,0 @@
-import collections
-import json
-import sys
-from collections import OrderedDict
-
-
-if __name__ == "__main__":
-
-    # Some tests
-
-    class Network(BaseWithId):
-
-        _definition = "A Network containing multiple _Population_s, connected by _Projection_s and receiving _Input_s"
-
-        def __init__(self, **kwargs):
-
-            self.allowed_children = collections.OrderedDict(
-                [
-                    ("cells", ("The cell definitions...", Cell)),
-                    ("synapses", ("The synapse definitions...", Synapse)),
-                ]
-            )
-
-            self.allowed_fields = collections.OrderedDict(
-                [
-                    ("version", ("Information on verson of NeuroMLlite", str)),
-                    (
-                        "seed",
-                        (
-                            "Seed for random number generator used when building network",
-                            int,
-                        ),
-                    ),
-                    (
-                        "random_connectivity",
-                        ("Use random connectivity", RandomConnectivity),
-                    ),
-                ]
-            )
-
-            super(Network, self).__init__(**kwargs)
-
-            self.version = "NeuroMLlite 0.0"
-
-    class Cell(BaseWithId):
-        def __init__(self, **kwargs):
-
-            self.allowed_fields = collections.OrderedDict(
-                [("neuroml2_source_file", ("File name of NeuroML2 file", str))]
-            )
-
-            super(Cell, self).__init__(**kwargs)
-
-    class Synapse(BaseWithId):
-        def __init__(self, **kwargs):
-
-            self.allowed_fields = collections.OrderedDict(
-                [("neuroml2_source_file", ("File name of NeuroML2 file", str))]
-            )
-
-            super(Synapse, self).__init__(**kwargs)
-
-    class EvaluableExpression(str):
-        def __init__(self, expr):
-            self.expr = expr
-
-    class RandomConnectivity(Base):
-        def __init__(self, **kwargs):
-
-            self.allowed_fields = collections.OrderedDict(
-                [
-                    (
-                        "probability",
-                        ("Random probability of connection", EvaluableExpression),
-                    )
-                ]
-            )
-
-            super(RandomConnectivity, self).__init__(**kwargs)
-
-    net = Network(id="netid")
-    cell = Cell(id="cellid1")
-    cell.neuroml2_source_file = "nnn"
-    cell2 = Cell(id="cellid2")
-    cell2.neuroml2_source_file = "nnn2"
-    # net.cells.append(cell)
-
-    print(net)
-    print(net.cells)
-    print(net)
-    """  """
-    net.cells.append(cell)
-    net.cells.append(cell2)
-
-    rc = RandomConnectivity(probability=0.01)
-    net.random_connectivity = rc
-    print(rc)
-    print(net)
-
-    # print(net['cells'])
-    try:
-        print(net.notcells)
-    except Exception as e:
-        print("  As expected, an exception: [%s]..." % e)
-
-    import pprint
-
-    pp = pprint.PrettyPrinter(depth=4)
-    # d0 = net.to_simple_dict()
-    # print(d0)
-    print("--- new format ---")
-    d = Base.to_dict_format(net)
-    print(d)
-    pp.pprint(dict(d))
-    print("  To JSON:")
-    print(net.to_json())
-    print("  To YAML:")
-    print(net.to_yaml())
-
-    filenamej = "%s.json" % net.id
-    net.to_json_file(filenamej)
-
-    filenamey = "%s.yaml" % net.id
-    net.id = net.id + "_yaml"
-    net.to_yaml_file(filenamey)
-    from neuromllite.utils import load_json, load_yaml, _parse_element
-
-    dataj = load_json(filenamej)
-    print_v("Loaded network specification from %s" % filenamej)
-    netj = Network()
-    _parse_element(dataj, netj)
-
-    datay = load_yaml(filenamey)
-    print_v("Loaded network specification from %s" % filenamey)
-
-    nety = Network()
-    _parse_element(datay, nety)
-
-    verbose = False
-    print("----- Before -----")
-    print(net)
-    print("----- After via %s -----" % filenamej)
-    print(netj)
-    print("----- After via %s -----" % filenamey)
-    print(nety)
-
-    print("----- Schema -----")
-    doc = net.generate_documentation(format=MARKDOWN_FORMAT)
-    with open("doc.md", "w") as d:
-        d.write(doc)
-
-    doc = net.generate_documentation(format=DICT_FORMAT)
-    with open("doc.json", "w") as d:
-        d.write(json.dumps(doc, indent=4))
diff --git a/neuromllite/NetworkGenerator.py b/neuromllite/NetworkGenerator.py
index bb34a7b..7f910d6 100644
--- a/neuromllite/NetworkGenerator.py
+++ b/neuromllite/NetworkGenerator.py
@@ -18,6 +18,15 @@
 DEFAULT_SIMULATION_SEED = 5678
 
 
+
+def __TEMP_CHECK_IF_SET(value):
+    """
+    Should just be a check for None! Update in modelspec...
+    """
+    if value is None: return False
+    if value == '': return False
+    return True
+
 def _get_rng_for_network(nl_model):
     """
     Get a random number generator and the seed used to generate it
@@ -81,7 +90,7 @@ def generate_network(
                 if not p == "__builtins__":
                     notes += "\n        %s = %s" % (p, nl_model.parameters[p])
         handler.handle_document_start(nl_model.id, notes)
-        temperature = "%sdegC" % nl_model.temperature if nl_model.temperature else None
+        temperature = "%sdegC" % nl_model.temperature if nl_model.temperature is not None else None
         handler.handle_network(nl_model.id, nl_model.notes, temperature=temperature)
 
     nml2_doc_temp = _extract_pynn_components_to_neuroml(nl_model)
@@ -108,7 +117,7 @@ def generate_network(
             )
             synapse_objects[s.id] = nml2_doc.get_by_id(s.id)
 
-        if s.pynn_synapse:
+        if hasattr(s, 'pynn_synapse') and s.pynn_synapse is not None:
             synapse_objects[s.id] = nml2_doc_temp.get_by_id(s.id)
 
     for p in nl_model.populations:
@@ -349,10 +358,10 @@ def generate_network(
 
             input_count = 0
 
-            if input.cell_ids is not None:
-                if input.percentage is not None:
+            if __TEMP_CHECK_IF_SET(input.cell_ids):
+                if __TEMP_CHECK_IF_SET(input.percentage):
                     raise Exception(
-                        "On input: %s, only one of percentage or cell_ids is allowed"
+                        "On the input: %s, only one of percentage or cell_ids is allowed"
                         % input
                     )
                 for i in input.cell_ids:
@@ -384,8 +393,8 @@ def generate_network(
                         )
                         input_count += 1
 
-            if input.percentage is not None:
-                if input.cell_ids is not None:
+            if __TEMP_CHECK_IF_SET(input.percentage):
+                if __TEMP_CHECK_IF_SET(input.cell_ids):
                     raise Exception(
                         "On input: %s, only one of percentage or cell_ids is allowed"
                         % input
@@ -674,7 +683,7 @@ def generate_neuroml2_from_network(
             for comp in model.components:
                 if i.id == comp.id:
                     print_v("Found a component: %s in %s" % (comp, fname))
-                    if i.parameters is not None and len(i.parameters) > 0:
+                    if hasattr(i, 'parameters') and len(i.parameters) > 0:
                         for p in i.parameters:
                             comp.set_parameter(
                                 p, evaluate(i.parameters[p], nl_model.parameters)
@@ -708,7 +717,7 @@ def generate_neuroml2_from_network(
                 if not incl in nml_doc.includes:
                     nml_doc.includes.append(incl)
 
-            if i.neuroml2_input:
+            if hasattr(i, 'neuroml2_input') and i.neuroml2_input is not None:
                 input_params = i.parameters if i.parameters else {}
 
                 # TODO make more generic...
@@ -1438,10 +1447,10 @@ def run(config_file, simulator):
             arbor_recipe = arbor_handler.neuroML_arbor_recipe
 
             trace_pop_indices_seg_ids = get_pops_vs_cell_indices_seg_ids(
-                simulation.recordTraces, network
+                simulation.record_traces, network
             )
             spike_pop_indices = get_pops_vs_cell_indices_seg_ids(
-                simulation.recordSpikes, network
+                simulation.record_spikes, network
             )
             """
             for pop_id in arbor_handler.populations:
@@ -1630,10 +1639,10 @@ def run(config_file, simulator):
             )
 
             trace_pop_indices_seg_ids = get_pops_vs_cell_indices_seg_ids(
-                simulation.recordTraces, network
+                simulation.record_traces, network
             )
             spike_pop_indices = get_pops_vs_cell_indices_seg_ids(
-                simulation.recordSpikes, network
+                simulation.record_spikes, network
             )
 
             for pop_id in pynn_handler.populations:
@@ -1790,7 +1799,7 @@ def run(config_file, simulator):
             simConfig.recordTraces = {}
 
             trace_pop_indices_seg_ids = get_pops_vs_cell_indices_seg_ids(
-                simulation.recordTraces, network
+                simulation.record_traces, network
             )
 
             for pop_id in trace_pop_indices_seg_ids:
@@ -1920,7 +1929,7 @@ def run(config_file, simulator):
 
             for pop_id in trace_pop_indices_seg_ids:
                 indices_segids = trace_pop_indices_seg_ids[pop_id]
-                print("Saving in pop %s: %s" % (pop_id, indices_segids))
+                print("Saving in population %s: %s" % (pop_id, indices_segids))
                 save_ref = "%s.%s.v.dat" % (simulation.id, pop_id)
                 pop_v_file = open(save_ref, "w")
                 all_v = []
@@ -1970,7 +1979,7 @@ def run(config_file, simulator):
 
             spike_pop_indices = sorted(
                 get_pops_vs_cell_indices_seg_ids(
-                    simulation.recordSpikes, network
+                    simulation.record_spikes, network
                 ).keys()
             )
 
@@ -2020,13 +2029,13 @@ def run(config_file, simulator):
             gen_spike_saves_for_cells = {}
 
             trace_pop_indices_seg_ids = get_pops_vs_cell_indices_seg_ids(
-                simulation.recordTraces, network
+                simulation.record_traces, network
             )
             spike_pop_indices = get_pops_vs_cell_indices_seg_ids(
-                simulation.recordSpikes, network
+                simulation.record_spikes, network
             )
             rate_pop_indices = get_pops_vs_cell_indices_seg_ids(
-                simulation.recordRates, network
+                simulation.record_rates, network
             )
 
             pops = network.populations
@@ -2091,9 +2100,9 @@ def run(config_file, simulator):
                         gen_plots_for_quantities[plot_ref].append(quantity)
                         gen_saves_for_quantities[save_ref].append(quantity)
 
-                if simulation.recordVariables:
-                    for var in simulation.recordVariables:
-                        to_rec = simulation.recordVariables[var]
+                if simulation.record_variables:
+                    for var in simulation.record_variables:
+                        to_rec = simulation.record_variables[var]
                         if "all" in to_rec or p.id in to_rec:
                             size = evaluate(p.size, network.parameters)
                             for i in range(size):
@@ -2195,9 +2204,10 @@ def run(config_file, simulator):
                 _print_result_info(traces, events)
                 return results  # traces, events =
     except Exception as e:
+        raise e
         raise Exception(
             "Exception while trying to run in simulator %s:\n%s" % (simulator, e)
-        )
+        ) from e
 
 
 def _print_info(l):
diff --git a/neuromllite/__init__.py b/neuromllite/__init__.py
index 903adf0..b44862d 100644
--- a/neuromllite/__init__.py
+++ b/neuromllite/__init__.py
@@ -1,17 +1,34 @@
 import collections
 
-__version__ = "0.4.4"
+__version__ = "0.5.1"
 
 # import pyNN
 # import nest
 
-from modelspec.BaseTypes import Base
-from modelspec.BaseTypes import BaseWithId
-from modelspec.BaseTypes import EvaluableExpression
+from typing import List, Dict, Any, Optional, Union, Tuple, Callable, TypeVar, Type
 
+import modelspec
+from modelspec import optional, instance_of, in_, has, field, fields
+from modelspec.base_types import Base, ValueExprType, value_expr_types
+
+
+def convert2float(x: Any) -> float:
+    """Convert to float if not None"""
+    if x is not None:
+        return float(x)
+    else:
+        return None
+
+
+def convert2int(x: Any) -> float:
+    """Convert to int if not None"""
+    if x is not None:
+        return int(x)
+    else:
+        return None
 
-class NetworkReaderX:
 
+class NetworkReaderX:
     pop_locations = {}
 
     def parse(self, handler):
@@ -21,422 +38,366 @@ def get_locations(self):
         return self.pop_locations
 
 
-class Network(BaseWithId):
-
-    _definition = "A Network containing multiple _Population_s, connected by _Projection_s and receiving _Input_s"
-
-    def __init__(self, **kwargs):
-
-        self.allowed_children = collections.OrderedDict(
-            [
-                ("cells", ("The _Cell_s which can be present in _Population_s", Cell)),
-                (
-                    "synapses",
-                    (
-                        "The _Synapse_ definitions which are used in _Projection_s",
-                        Synapse,
-                    ),
-                ),
-                (
-                    "input_sources",
-                    (
-                        "The _InputSource_ definitions which define the types of stimulus which can be applied in _Input_s",
-                        InputSource,
-                    ),
-                ),
-                (
-                    "regions",
-                    (
-                        "The _Regions_ in which _Population_s get placed",
-                        RectangularRegion,
-                    ),
-                ),
-                (
-                    "populations",
-                    (
-                        "The _Population_s of _Cell_s making up this network...",
-                        Population,
-                    ),
-                ),
-                (
-                    "projections",
-                    ("The _Projection_s between _Population_s", Projection),
-                ),
-                (
-                    "inputs",
-                    ("The inputs to apply to the elements of _Population_s", Input),
-                ),
-            ]
-        )
-
-        self.allowed_fields = collections.OrderedDict(
-            [
-                ("version", ("Information on verson of NeuroMLlite", str)),
-                (
-                    "seed",
-                    (
-                        "Seed for random number generator used when building network",
-                        int,
-                    ),
-                ),
-                (
-                    "temperature",
-                    ("Temperature at which to run network (float in deg C)", float),
-                ),
-                (
-                    "parameters",
-                    ("Dictionary of global parameters for the network", dict),
-                ),
-                (
-                    "network_reader",
-                    (
-                        "A class which can read in a network (e.g. from a structured format)",
-                        NetworkReader,
-                    ),
-                ),
-            ]
-        )
-
-        super(Network, self).__init__(**kwargs)
-
-        self.version = "NeuroMLlite v%s" % __version__
-
-
-class Cell(BaseWithId):
-    def __init__(self, **kwargs):
-
-        self.allowed_fields = collections.OrderedDict(
-            [
-                (
-                    "neuroml2_source_file",
-                    ("File name of NeuroML2 file defining the cell", str),
-                ),
-                ("lems_source_file", ("File name of LEMS file defining the cell", str)),
-                ("neuroml2_cell", ("Name of standard NeuroML2 cell type", str)),
-                ("pynn_cell", ("Name of standard PyNN cell type", str)),
-                ("arbor_cell", ("Name of standard Arbor cell type", str)),
-                ("bindsnet_node", ("Name of standard BindsNET node", str)),
-                ("parameters", ("Dictionary of parameters for the cell", dict)),
-            ]
-        )
-
-        super(Cell, self).__init__(**kwargs)
-
-
-class Synapse(BaseWithId):
-    def __init__(self, **kwargs):
-
-        self.allowed_fields = collections.OrderedDict(
-            [
-                (
-                    "neuroml2_source_file",
-                    ("File name of NeuroML2 file defining the synapse", str),
-                ),
-                (
-                    "lems_source_file",
-                    ("File name of LEMS file defining the synapse", str),
-                ),
-                (
-                    "pynn_synapse_type",
-                    (
-                        'Options: "curr_exp", "curr_alpha", "cond_exp", "cond_alpha".',
-                        str,
-                    ),
-                ),
-                ("pynn_receptor_type", ('Either "excitatory" or "inhibitory".', str)),
-                ("parameters", ("Dictionary of parameters for the synapse", dict)),
-            ]
-        )
-
-        super(Synapse, self).__init__(**kwargs)
-
-
-class InputSource(BaseWithId):
-    def __init__(self, **kwargs):
-
-        self.allowed_fields = collections.OrderedDict(
-            [
-                ("neuroml2_source_file", ("File name of NeuroML2 file", str)),
-                ("lems_source_file", ("File name of LEMS file", str)),
-                ("neuroml2_input", ("Name of standard NeuroML2 input", str)),
-                ("pynn_input", ("Name of standard PyNN input", str)),
-                ("parameters", ("Dictionary of parameters for the InputSource", dict)),
-            ]
-        )
-
-        super(InputSource, self).__init__(**kwargs)
-
-
-"""
-class Region(BaseWithId):
-
-    def __init__(self, **kwargs):
-
-        super(Region, self).__init__(**kwargs)"""
-
-
-class RectangularRegion(BaseWithId):
-    def __init__(self, **kwargs):
-
-        self.allowed_fields = collections.OrderedDict(
-            [
-                ("x", ("x coordinate of corner", float)),
-                ("y", ("y coordinate of corner", float)),
-                ("z", ("z coordinate of corner", float)),
-                ("width", ("Width of rectangular region", float)),
-                ("height", ("Height of rectangular region", float)),
-                ("depth", ("Depth of rectangular region", float)),
-            ]
-        )
-
-        super(RectangularRegion, self).__init__(**kwargs)
-
-
-class Population(BaseWithId):
-    def __init__(self, **kwargs):
-
-        # self.allowed_children = collections.OrderedDict([('positions',('List of explicit positions...',str))])
-
-        self.allowed_fields = collections.OrderedDict(
-            [
-                ("size", ("Size of population", EvaluableExpression)),
-                ("component", ("Type of _Cell_ to use in population", str)),
-                (
-                    "properties",
-                    ("Dictionary of properties (metadata) for the population", dict),
-                ),
-                ("random_layout", ("Layout in random _Region_", RandomLayout)),
-                ("relative_layout", ("Position relative to _Region_.", RelativeLayout)),
-                (
-                    "single_location",
-                    (
-                        "Explicit location of the one _Cell_ in the population",
-                        SingleLocation,
-                    ),
-                ),
-            ]
-        )
-
-        super(Population, self).__init__(**kwargs)
+@modelspec.define
+class NMLBase(Base):
+    """Base class for NeuroML objects."""
+    notes: str = field(kw_only=True, default=None, validator=optional(instance_of(str)))
+
+
+@modelspec.define
+class Cell(NMLBase):
+    """
+    A Cell definition.
+
+    Args:
+        id: Unique identifier for this Cell
+        parameters: Dictionary of parameters for the cell
+        neuroml2_source_file: File name of NeuroML2 file defining the cell
+        lems_source_file: File name of LEMS file defining the cell
+        neuroml2_cell: Name of standard NeuroML2 cell type
+        pynn_cell: Name of standard PyNN cell type
+        arbor_cell: Name of standard Arbor cell type
+        bindsnet_node: Name of standard BindsNET node
+    """
+    id: str = field(validator=instance_of(str))
+    parameters: Dict[str, Any] = field(default=None, validator=optional(instance_of(dict)))
+    neuroml2_source_file: str = field(default=None, validator=optional(instance_of(str)))
+    lems_source_file: str = field(default=None, validator=optional(instance_of(str)))
+    neuroml2_cell: str = field(default=None, validator=optional(instance_of(str)))
+    pynn_cell: str = field(default=None, validator=optional(instance_of(str)))
+    arbor_cell: str = field(default=None, validator=optional(instance_of(str)))
+    bindsnet_node: str = field(default=None, validator=optional(instance_of(str)))
+
+
+@modelspec.define
+class Synapse(NMLBase):
+    """
+    A Synapse definition.
+
+    Args:
+        id: Unique identifier for this Synapse
+        parameters: Dictionary of parameters for the synapse
+        neuroml2_source_file: File name of NeuroML2 file defining the synapse
+        lems_source_file: File name of LEMS file defining the synapse
+        pynn_synapse_type: The pynn synapse type. Valid values are: "curr_exp", "curr_alpha", "cond_exp", "cond_alpha".
+        pynn_receptor_type: The pynn receptor type. Valid values are: "excitatory", "inhibitory".
+    """
+    id: str = field(validator=instance_of(str))
+    parameters: Dict[str, Any] = field(default=None, validator=optional(instance_of(dict)))
+    neuroml2_source_file: str = field(default=None, validator=optional(instance_of(str)))
+    lems_source_file: str = field(default=None, validator=optional(instance_of(str)))
+    pynn_synapse_type: str = field(default=None, validator=optional(in_(["curr_exp", "curr_alpha", "cond_exp", "cond_alpha"])))
+    pynn_receptor_type: str = field(default=None, validator=optional(in_(["excitatory", "inhibitory"])))
+
+
+@modelspec.define
+class InputSource(NMLBase):
+    """
+    An InputSource definition.
+
+    Args:
+        id: Unique identifier for this InputSource
+        parameters: Dictionary of parameters for the InputSource
+        neuroml2_source_file: File name of NeuroML2 file defining the input source
+        neuroml2_input: Name of standard NeuroML2 input
+        lems_source_file: File name of LEMS file defining the input source
+        pynn_input: Name of PyNN input
+    """
+    id: str = field(validator=instance_of(str))
+    parameters: Dict[str, Any] = field(default=None, validator=optional(instance_of(dict)))
+    neuroml2_source_file: str = field(default=None, validator=optional(instance_of(str)))
+    neuroml2_input: str = field(default=None, validator=optional(instance_of(str)))
+    lems_source_file: str = field(default=None, validator=optional(instance_of(str)))
+    pynn_input: str = field(default=None, validator=optional(instance_of(str)))
+
+
+@modelspec.define
+class RectangularRegion(NMLBase):
+    """
+    A RectangularRegion definition.
+
+    Args:
+        id: Unique identifier for this rectangular region.
+        x: x coordinate of corner of region
+        y: y coordinate of corner of region
+        z: z coordinate of corner of region
+        width: width of the rectangular region
+        height: height of the rectangular region
+        depth: depth of the rectangular region
+    """
+    id: str = field(validator=instance_of(str))
+    x: float = field(validator=instance_of(float), converter=convert2float)
+    y: float = field(validator=instance_of(float), converter=convert2float)
+    z: float = field(validator=instance_of(float), converter=convert2float)
+    width: float = field(validator=instance_of(float), converter=convert2float)
+    height: float = field(validator=instance_of(float), converter=convert2float)
+    depth: float = field(validator=instance_of(float), converter=convert2float)
+
+
+@modelspec.define
+class RandomLayout(NMLBase):
+    """
+    A RandomLayout definition.
+
+    Args:
+        region: Region in which to place population
+    """
+    region: str = field(validator=instance_of(str))
+
+
+@modelspec.define
+class RelativeLayout(NMLBase):
+    """
+    A RelativeLayout definition.
+
+    Args:
+        region: The Region relative to which population should be positioned.
+        x: x position relative to x coordinate of Region
+        y: y position relative to y coordinate of Region
+        z: z position relative to z coordinate of Region
+    """
+    region: str = field(validator=instance_of(str))
+    x: float = field(validator=instance_of(float), converter=convert2float)
+    y: float = field(validator=instance_of(float), converter=convert2float)
+    z: float = field(validator=instance_of(float), converter=convert2float)
+
+
+@modelspec.define
+class Location(NMLBase):
+    """
+    A Location definition.
+
+    Args:
+        x: x coordinate of location
+        y: y coordinate of location
+        z: z coordinate of location
+    """
+    x: float = field(validator=instance_of(float), converter=convert2float)
+    y: float = field(validator=instance_of(float), converter=convert2float)
+    z: float = field(validator=instance_of(float), converter=convert2float)
+
+
+@modelspec.define
+class SingleLocation(NMLBase):
+    """
+    A SingleLocation definition.
+
+    Args:
+        location: Location of the single Cell.
+    """
+    location: Location = field(validator=instance_of(Location))
+
+
+@modelspec.define
+class Population(NMLBase):
+    """
+    A Population definition.
+
+    Args:
+        id: Unique identifier for this Population
+        size: The size of the population.
+        component: The type of Cell to use in this population.
+        properties: A dictionary of properties (metadata) for this population.
+        random_layout: Layout in the random RectangularRegion.
+        relative_layout: Position relative to RectangularRegion.
+        single_location: Explicit location of the one Cell in the population
+    """
+    id: str = field(validator=instance_of(str))
+    size: ValueExprType = field(validator=instance_of(value_expr_types))
+    component: str = field(validator=instance_of(str))
+    properties: Dict[str, Any] = field(default=None, validator=optional(instance_of(dict)))
+    random_layout: RandomLayout = field(default=None, validator=optional(instance_of(RandomLayout)))
+    relative_layout: RelativeLayout = field(default=None, validator=optional(instance_of(RelativeLayout)))
+    single_location: SingleLocation = field(default=None, validator=optional(instance_of(SingleLocation)))
 
     def has_positions(self):
-        if self.random_layout:
+        """
+        Returns True if the population has a position.
+
+        Returns:
+            True if the population has a position.
+        """
+        if self.random_layout is not None:
             return True
-        elif self.relative_layout:
+        elif self.relative_layout is not None:
             return True
-        elif self.single_location:
+        elif self.single_location is not None:
             return True
         else:
             return False
 
 
-class RandomLayout(Base):
-    def __init__(self, **kwargs):
-
-        self.allowed_fields = collections.OrderedDict(
-            [("region", ("Region in which to place population", str))]
-        )
-
-        super(RandomLayout, self).__init__(**kwargs)
-
-
-class RelativeLayout(Base):
-    def __init__(self, **kwargs):
-
-        self.allowed_fields = collections.OrderedDict(
-            [
-                (
-                    "region",
-                    (
-                        "The _Region_ relative to which population should be positioned",
-                        str,
-                    ),
-                ),
-                ("x", ("x position relative to x coordinate of _Region_", float)),
-                ("y", ("y position relative to y coordinate of _Region_", float)),
-                ("z", ("z position relative to z coordinate of _Region_", float)),
-            ]
-        )
-
-        super(RelativeLayout, self).__init__(**kwargs)
-
-
-class SingleLocation(Base):
-    def __init__(self, **kwargs):
-
-        # self.allowed_children = collections.OrderedDict([('locations',('The locations...',Location))])
-        self.allowed_fields = collections.OrderedDict(
-            [("location", ("The location of the single _Cell_", Location))]
-        )
-
-        super(SingleLocation, self).__init__(**kwargs)
-
-
-class Location(Base):
-    def __init__(self, **kwargs):
-
-        self.allowed_fields = collections.OrderedDict(
-            [
-                ("x", ("x coordinate", float)),
-                ("y", ("y coordinate", float)),
-                ("z", ("z coordinate", float)),
-            ]
-        )
-
-        super(Location, self).__init__(**kwargs)
-
-
-class Projection(BaseWithId):
-    def __init__(self, **kwargs):
-        self.allowed_fields = collections.OrderedDict(
-            [
-                ("presynaptic", ("Presynaptic _Population_", str)),
-                ("postsynaptic", ("Postsynaptic _Population_", str)),
-                ("synapse", ("Which _Synapse_ to use", str)),
-                (
-                    "pre_synapse",
-                    (
-                        "For continuous connections, what presynaptic component to use (default: silent analog synapse)",
-                        str,
-                    ),
-                ),
-                (
-                    "type",
-                    (
-                        "type of projection: projection (default; standard chemical, event triggered), electricalProjection (for gap junctions) or continuousProjection (for analogue/graded synapses)",
-                        str,
-                    ),
-                ),
-                ("delay", ("Delay to use (default: 0)", EvaluableExpression)),
-                ("weight", ("Weight to use (default: 1)", EvaluableExpression)),
-                (
-                    "random_connectivity",
-                    ("Use random connectivity", RandomConnectivity),
-                ),
-                (
-                    "convergent_connectivity",
-                    ("Use ConvergentConnectivity", ConvergentConnectivity),
-                ),
-                (
-                    "one_to_one_connector",
-                    (
-                        "Connect cell index i in pre pop to cell index i in post pop for all i",
-                        OneToOneConnector,
-                    ),
-                ),
-            ]
-        )
-
-        super(Projection, self).__init__(**kwargs)
-
-
-class Input(BaseWithId):
-    def __init__(self, **kwargs):
-
-        self.allowed_fields = collections.OrderedDict(
-            [
-                ("input_source", ("Type of input to use in population", str)),
-                ("population", ("Population to target", str)),
-                (
-                    "cell_ids",
-                    (
-                        "Specific ids of _Cell_s to apply this input to (cannot be used with percentage)",
-                        EvaluableExpression,
-                    ),
-                ),
-                (
-                    "percentage",
-                    (
-                        "Percentage of _Cell_s to apply this input to (cannot be used with cell_ids)",
-                        float,
-                    ),
-                ),
-                (
-                    "number_per_cell",
-                    (
-                        "Number of individual inputs per selected _Cell_ (default: 1)",
-                        EvaluableExpression,
-                    ),
-                ),
-                (
-                    "segment_ids",
-                    ("Which segments to target (default: [0])", EvaluableExpression),
-                ),
-                ("weight", ("Weight to use (default: 1)", EvaluableExpression)),
-            ]
-        )
-
-        super(Input, self).__init__(**kwargs)
-
-
-class RandomConnectivity(Base):
-    def __init__(self, **kwargs):
-
-        self.allowed_fields = collections.OrderedDict(
-            [("probability", ("Random probability of connection", EvaluableExpression))]
-        )
-
-        super(RandomConnectivity, self).__init__(**kwargs)
-
-
-class OneToOneConnector(Base):
-    def __init__(self, **kwargs):
-
-        super(OneToOneConnector, self).__init__(**kwargs)
+@modelspec.define
+class RandomConnectivity(NMLBase):
+    """
+    A RandomConnectivity definition.
+
+    Args:
+        probability: Random probability of connection.
+    """
+    probability: ValueExprType = field(validator=instance_of(value_expr_types))
+
+
+@modelspec.define
+class OneToOneConnector(NMLBase):
+    """
+    A OneToOneConnector definition.
+    """
+    pass
 
 
 # Temp! to redefine more generally!
-class ConvergentConnectivity(Base):
-    def __init__(self, **kwargs):
-
-        self.allowed_fields = collections.OrderedDict(
-            [("num_per_post", ("Number per post synaptic neuron", float))]
-        )
-
-        super(ConvergentConnectivity, self).__init__(**kwargs)
-
-
-class NetworkReader(Base):
-    def __init__(self, **kwargs):
-
-        self.allowed_fields = collections.OrderedDict(
-            [
-                ("type", ("The type of NetworkReader", str)),
-                (
-                    "parameters",
-                    ("Dictionary of parameters for the NetworkReader", dict),
-                ),
-            ]
-        )
-
-        super(NetworkReader, self).__init__(**kwargs)
-
-
-class Simulation(BaseWithId):
-    def __init__(self, **kwargs):
-
-        self.allowed_fields = collections.OrderedDict(
-            [
-                ("version", ("Information on verson of NeuroMLlite", str)),
-                ("network", ("File name of network to simulate", str)),
-                ("duration", ("Duration of simulation (ms)", float)),
-                ("dt", ("Timestep of simulation (ms)", float)),
-                (
-                    "seed",
-                    ("Seed for stochastic elements os the simulation (integer)", int),
-                ),
-                ("recordTraces", ("Record traces?", dict)),
-                ("recordSpikes", ("Record spikes?", dict)),
-                ("recordRates", ("Record rates?", dict)),
-                ("recordVariables", ("Record named variables?", dict)),
-                ("plots2D", ("Work in progress...", dict)),
-                ("plots3D", ("Work in progress...", dict)),
-            ]
-        )
-
-        super(Simulation, self).__init__(**kwargs)
-
-        self.version = "NeuroMLlite v%s" % __version__
+@modelspec.define
+class ConvergentConnectivity(NMLBase):
+    """
+    A ConvergentConnectivity definition.
+
+    Args:
+        num_per_post: Number per post-synaptic neuron.
+    """
+    num_per_post: float = field(validator=instance_of(float), converter=convert2float)
+
+
+@modelspec.define
+class Projection(NMLBase):
+    """
+    A Projection definition.
+
+    Args:
+        id: Unique identifier for this Projection
+        presynaptic: Presynaptic Population
+        postsynaptic: Postsynaptic Population
+        synapse: Which Synapse to use
+        pre_synapse: For continuous connections, what presynaptic component to use (default: silent analog synapse)
+        type: type of projection: projection (default; standard chemical, event triggered), electricalProjection
+            (for gap junctions) or continuousProjection (for analogue/graded synapses)
+        delay: Delay to use (default: 0)
+        weight: Weight to use (default: 1)
+        random_connectivity: Use random connectivity
+        convergent_connectivity: Use convergent connectivity
+        one_to_one_connector: Connect cell index i in pre pop to cell index i in post pop for all i
+
+    """
+    id: str = field(validator=instance_of(str))
+    presynaptic: str = field(validator=optional(instance_of(str)))
+    postsynaptic: str = field(validator=optional(instance_of(str)))
+    synapse: str = field(validator=optional(instance_of(str)))
+    pre_synapse: str = field(default=None, validator=optional(instance_of(str)))
+    type: str = field(default="projection", validator=optional(instance_of(str)))
+    delay: ValueExprType = field(default=None, validator=optional(instance_of(value_expr_types)))
+    weight: ValueExprType = field(default=None, validator=optional(instance_of(value_expr_types)))
+    random_connectivity: RandomConnectivity = field(default=None, validator=optional(instance_of(RandomConnectivity)))
+    convergent_connectivity: ConvergentConnectivity = field(default=None, validator=optional(instance_of(ConvergentConnectivity)))
+    one_to_one_connector: OneToOneConnector = field(default=None, validator=optional(instance_of(OneToOneConnector)))
+
+
+@modelspec.define
+class Input(NMLBase):
+    """
+    An Input definition.
+
+    Args:
+        id: Unique identifier for this Input
+        input_source: Type of input to use in population
+        population: Population to target
+        percentage: Percentage of Cells to apply input to
+        cell_ids: Specific ids of _Cell_s to apply this input to (cannot be used with percentage
+        number_per_cell: Number of individual inputs per selected Cell (default: 1)
+        segment_ids: Which segments to target (default: [0])
+        weight: Weight to use (default: 1)
+    """
+
+    id: str = field(validator=instance_of(str))
+    input_source: str = field(default=None, validator=optional(instance_of(str)))
+    population: str = field(default=None, validator=optional(instance_of(str)))
+    cell_ids: ValueExprType = field(default="", validator=optional(instance_of(value_expr_types)))
+    percentage: float = field(default=None, validator=optional(instance_of(float)), converter=convert2float)
+    number_per_cell: ValueExprType = field(default="", validator=optional(instance_of(value_expr_types)))
+    segment_ids: ValueExprType = field(default="", validator=optional(instance_of(value_expr_types)))
+    weight: ValueExprType = field(default=None, validator=optional(instance_of(value_expr_types)))
+
+
+@modelspec.define
+class NetworkReader(NMLBase):
+    """
+    A NetworkReader definition.
+
+    Args:
+        type: The type of NetworkReader
+        parameters: Dictionary of parameters for the NetworkReader
+    """
+    type: str = field(default=None, validator=optional(instance_of(str)))
+    parameters: Dict[str, Any] = field(default=None, validator=optional(instance_of(dict)))
+
+
+@modelspec.define
+class Simulation(NMLBase):
+    """
+    A Simulation definition.
+
+    Args:
+        id: Unique identifier for this Simulation
+        version: Information on verson of NeuroMLlite
+        network: File name of network to simulate
+        duration: Duration of simulation (ms)
+        dt: Timestep of simulation (ms)
+        seed: Seed for stochastic elements os the simulation
+        record_traces: Record traces?
+        record_spikes: Record spikes?
+        record_rates: Record rates?
+        record_variables: Record named variables?
+        plots2D: Work in progress...
+        plots3D: Work in progress...
+    """
+    id: str = field(validator=instance_of(str))
+    version: str = field(default=f"NeuroMLlite v{__version__}", validator=optional(instance_of(str)), metadata={"omit_if_default": False})
+    network: str = field(default=None, validator=optional(instance_of(str)))
+    duration: float = field(default=None, validator=optional(instance_of(float)), converter=convert2float)
+    dt: float = field(default=None, validator=optional(instance_of(float)), converter=convert2float)
+    seed: int = field(default=None, validator=optional(instance_of(int)), converter=convert2int)
+    record_traces: Dict[str, Any] = field(default=None, validator=optional(instance_of(dict)))
+    record_spikes: Dict[str, Any] = field(default=None, validator=optional(instance_of(dict)))
+    record_rates: Dict[str, Any] = field(default=None, validator=optional(instance_of(dict)))
+    record_variables: Dict[str, Any] = field(default=None, validator=optional(instance_of(dict)))
+    plots2D: Dict[str, Any] = field(default=None, validator=optional(instance_of(dict)))
+    plots3D: Dict[str, Any] = field(default=None, validator=optional(instance_of(dict)))
+
+
+@modelspec.define
+class Network(NMLBase):
+    """
+    A Network containing multiple Population's, connected by Projection's and receiving Input's
+
+    Args:
+        id: Unique identifier for the Network
+        parameters: Dictionary of global parameters for the network
+        cells: The Cells which can be present in Populations
+        synapses: The Synapse definitions which are used in Projections
+        input_sources: The InputSource definitions which define the types of stimulus which can be applied in Inputs
+        regions: The Regions in which Populations get placed.
+        populations: The Populations of Cells making up this network ...
+        projections: The Projections between Populations
+        inputs: The inputs to apply to the elements of Populations
+        version: Information on verson of NeuroMLlite
+        seed: Seed for random number generator used when building network
+        temperature: Temperature at which to run network (float in deg C)
+        network_reader: A class which can read in a network (e.g. from a structured format)
+        notes: Human readable notes about the network
+    """
+
+    id: str = field(validator=instance_of(str))
+    parameters: Dict[str, Any] = field(default=None, validator=optional(instance_of(dict)))
+    cells: List[Cell] = field(factory=list, validator=instance_of(list))
+    synapses: List[Synapse] = field(factory=list, validator=instance_of(list))
+    input_sources: List[InputSource] = field(factory=list, validator=instance_of(list))
+    regions: List[RectangularRegion] = field(factory=list, validator=instance_of(list))
+    populations: List[Population] = field(factory=list, validator=instance_of(list))
+    projections: List[Projection] = field(factory=list, validator=instance_of(list))
+    inputs: List[Input] = field(factory=list, validator=instance_of(list))
+    version: str = field(default=f"NeuroMLlite v{__version__}", validator=instance_of(str), metadata={"omit_if_default": False})
+    seed: int = field(default=None, validator=optional(instance_of(int)))
+    temperature: float = field(default=None, validator=optional(instance_of(float)), converter=convert2float)
+    network_reader: NetworkReader = field(default=None)
 
 
 if __name__ == "__main__":
diff --git a/neuromllite/gui/NMLliteUI.py b/neuromllite/gui/NMLliteUI.py
index aa2aca4..78bd466 100644
--- a/neuromllite/gui/NMLliteUI.py
+++ b/neuromllite/gui/NMLliteUI.py
@@ -570,7 +570,7 @@ def __init__(self, nml_sim_file, parent=None):
 
         for s in svars:
             rows += 1
-            sval = self.simulation.__getattr__(s)
+            sval = self.simulation.__getattribute__(s)
             if sval is not None:
                 label = QLabel("%s" % s)
                 paramLayout.addWidget(label, rows, 0)
diff --git a/neuromllite/utils.py b/neuromllite/utils.py
index afd4ed3..aa60c27 100644
--- a/neuromllite/utils.py
+++ b/neuromllite/utils.py
@@ -3,7 +3,7 @@
 import json
 
 
-from modelspec.BaseTypes import EvaluableExpression
+from modelspec.base_types import EvaluableExpression
 
 from modelspec.utils import (
     load_json,
@@ -55,8 +55,10 @@ def load_network_json(filename):
 
     print_v("Loaded network specification from %s" % filename)
 
-    net = Network()
-    net = _parse_element(data, net)
+    net = Network.from_dict(data)
+
+    # net = Network(id="net")
+    # net = _parse_element(data, net)
 
     return net
 
@@ -70,8 +72,10 @@ def load_network_yaml(filename):
 
     print_v("Loaded network specification from %s" % filename)
 
-    net = Network()
-    net = _parse_element(data, net)
+    net = Network.from_dict(data)
+
+    # net = Network()
+    # net = _parse_element(data, net)
 
     return net
 
@@ -81,14 +85,15 @@ def load_simulation_json(filename):
     Load a NeuroMLlite simulation JSON file
     """
 
-    with open(filename, "r") as f:
 
+    with open(filename, "r") as f:
         data = json.load(f, object_hook=ascii_encode_dict)
 
     print_v("Loaded simulation specification from %s" % filename)
 
-    sim = Simulation()
-    sim = _parse_element(data, sim)
+    sim = Simulation.from_dict(data)
+    # sim = Simulation(id="sim")
+    # sim = _parse_element(data, sim)
 
     return sim
 
@@ -279,7 +284,7 @@ def create_new_model(
         duration=duration,
         dt=dt,
         seed=simulation_seed,
-        recordTraces={"all": "*"},
+        record_traces={"all": "*"},
     )
 
     if simulation_filename == None:
diff --git a/setup.py b/setup.py
index 9ec1f26..721d3c3 100644
--- a/setup.py
+++ b/setup.py
@@ -24,7 +24,7 @@
         "pyyaml",
         "numpy",
         "pyparsing<3",
-        "modelspec<0.2.0",
+        "modelspec>=0.2.2",
     ],
     classifiers=[
         "Intended Audience :: Science/Research",


Test patch:
diff --git a/examples/spikeratetest/SimSpikers.json b/examples/spikeratetest/SimSpikers.json
index 52b6f82..b7f3bd9 100644
--- a/examples/spikeratetest/SimSpikers.json
+++ b/examples/spikeratetest/SimSpikers.json
@@ -1,15 +1,15 @@
 {
     "SimSpikers": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
         "network": "Spikers.json",
         "duration": 10000.0,
         "dt": 0.025,
-        "recordTraces": {
+        "record_traces": {
             "pop0": "*",
             "pop1": "*",
             "pop2": "*"
         },
-        "recordSpikes": {
+        "record_spikes": {
             "all": "*"
         }
     }
diff --git a/examples/spikeratetest/Spikers.json b/examples/spikeratetest/Spikers.json
index 8d98bc4..22fdc85 100644
--- a/examples/spikeratetest/Spikers.json
+++ b/examples/spikeratetest/Spikers.json
@@ -1,34 +1,34 @@
 {
     "Spikers": {
-        "version": "NeuroMLlite v0.4.4",
+        "version": "NeuroMLlite v0.5.1",
+        "notes": "Example with spiking entities..",
         "parameters": {
             "N": 10,
             "weightInput": 10,
             "input_rate": 40
         },
-        "notes": "Example with spiking entities..",
         "cells": {
             "iafcell": {
-                "pynn_cell": "IF_cond_alpha",
                 "parameters": {
                     "tau_refrac": 10
-                }
+                },
+                "pynn_cell": "IF_cond_alpha"
             },
             "InputCell": {
-                "pynn_cell": "SpikeSourcePoisson",
                 "parameters": {
                     "start": 0,
                     "duration": 10000000000,
                     "rate": "input_rate"
-                }
+                },
+                "pynn_cell": "SpikeSourcePoisson"
             },
             "InputCell100": {
-                "pynn_cell": "SpikeSourcePoisson",
                 "parameters": {
                     "start": 0,
                     "duration": 10000000000,
                     "rate": 100
-                }
+                },
+                "pynn_cell": "SpikeSourcePoisson"
             }
         },
         "input_sources": {
@@ -36,12 +36,12 @@
                 "neuroml2_source_file": "../test_files/inputs.nml"
             },
             "iclamp1": {
-                "pynn_input": "DCSource",
                 "parameters": {
                     "amplitude": 0.8,
                     "start": 100.0,
                     "stop": 900.0
-                }
+                },
+                "pynn_input": "DCSource"
             }
         },
         "populations": {
diff --git a/examples/spikeratetest/Spikers.py b/examples/spikeratetest/Spikers.py
index a93c67d..3a7e1db 100644
--- a/examples/spikeratetest/Spikers.py
+++ b/examples/spikeratetest/Spikers.py
@@ -68,16 +68,16 @@
 """
 net.synapses.append(Synapse(id='ampa', neuroml2_source_file='test_files/ampa.synapse.nml'))
 #net.synapses.append(Synapse(id='gaba', neuroml2_source_file='test_files/gaba.synapse.nml'))
-                            
-                            
+
+
 net.projections.append(Projection(id='projEI',
-                                  presynaptic=pE.id, 
+                                  presynaptic=pE.id,
                                   postsynaptic=pRS.id,
                                   synapse='ampa',
                                   delay=2,
                                   weight=0.2,
                                   random_connectivity=RandomConnectivity(probability=.8)))
-                            
+
                             """
 net.inputs.append(
     Input(
@@ -110,8 +110,8 @@
     network=new_file,
     duration="10000",
     dt="0.025",
-    recordTraces={"pop0": "*", "pop1": "*", "pop2": "*"},
-    recordSpikes={"all": "*"},
+    record_traces={"pop0": "*", "pop1": "*", "pop2": "*"},
+    record_spikes={"all": "*"},
 )
 
 sim.to_json_file()
diff --git a/neuromllite/test/test_base.py b/neuromllite/test/test_base.py
index ff416b6..9fa4fbd 100644
--- a/neuromllite/test/test_base.py
+++ b/neuromllite/test/test_base.py
@@ -1,6 +1,10 @@
 from neuromllite import *
 from neuromllite.utils import *
 
+import modelspec
+from modelspec import field
+from modelspec import optional, instance_of
+
 import pickle
 
 try:
@@ -46,93 +50,82 @@ def get_example_simulation():
         network="%s.json" % "net0",
         duration="1000",
         dt="0.01",
-        recordTraces={"all": "*"},
+        record_traces={"all": "*"},
     )
     return sim
 
 
 class TestCustomSaveLoad(unittest.TestCase):
     def test_save_load_json(self):
-        class NewNetwork(BaseWithId):
-
-            _definition = "..."
-
-            def __init__(self, **kwargs):
-
-                self.allowed_children = collections.OrderedDict(
-                    [
-                        ("cells", ("The cell definitions...", NewCell)),
-                        ("synapses", ("The synapse definitions...", NewSynapse)),
-                    ]
-                )
-
-                self.allowed_fields = collections.OrderedDict(
-                    [
-                        ("version", ("Information on verson of NeuroMLlite", str)),
-                        (
-                            "seed",
-                            (
-                                "Seed for random number generator used when building network",
-                                int,
-                            ),
-                        ),
-                        ("stable", ("Testing...", bool)),
-                        (
-                            "parameters",
-                            ("Dictionary of global parameters for the network", dict),
-                        ),
-                        (
-                            "random_connectivity",
-                            ("Use random connectivity", NewRandomConnectivity),
-                        ),
-                        ("ee0", ("TestEE", EvaluableExpression)),
-                        ("ee1", ("TestEE", EvaluableExpression)),
-                        ("ee2", ("TestEE", EvaluableExpression)),
-                        ("ee3", ("TestEE", EvaluableExpression)),
-                        ("ee4", ("TestEE", EvaluableExpression)),
-                        ("ee5", ("TestEE", EvaluableExpression)),
-                        ("ee6", ("TestEE", EvaluableExpression)),
-                    ]
-                )
-
-                super(NewNetwork, self).__init__(**kwargs)
-
-                self.version = "NeuroMLlite 0.0"
-
-        class NewCell(BaseWithId):
-            def __init__(self, **kwargs):
-
-                self.allowed_fields = collections.OrderedDict(
-                    [("neuroml2_source_file", ("File name of NeuroML2 file", str))]
-                )
-
-                super(NewCell, self).__init__(**kwargs)
-
-        class NewSynapse(BaseWithId):
-            def __init__(self, **kwargs):
-
-                self.allowed_fields = collections.OrderedDict(
-                    [
-                        ("neuroml2_source_file", ("File name of NeuroML2 file", str)),
-                        ("tested", ("Is it tested?", bool)),
-                    ]
-                )
-
-                super(NewSynapse, self).__init__(**kwargs)
 
+        @modelspec.define
+        class NewCell(Base):
+            """
+            A new cell definition
+
+            Args:
+                id: the cell id
+                neuroml2_source_file: The path to the source file
+            """
+            id: str = field(validator=instance_of(str))
+            neuroml2_source_file: str = field(default=None, validator=optional(instance_of(str)))
+
+        @modelspec.define
+        class NewSynapse(Base):
+            """
+            A new synapse definition
+
+            Args:
+                id: the synapse id
+                neuroml2_source_file: The path to the source file
+                tested: A boolean attribute
+            """
+            id: str = field(validator=instance_of(str))
+            neuroml2_source_file: str = field(default=None, validator=optional(instance_of(str)))
+            tested: bool = field(default=None, validator=optional(instance_of(bool)))
+
+        @modelspec.define
         class NewRandomConnectivity(Base):
-            def __init__(self, **kwargs):
-
-                self.allowed_fields = collections.OrderedDict(
-                    [
-                        (
-                            "probability",
-                            ("Random probability of connection", EvaluableExpression),
-                        )
-                    ]
-                )
+            """
+            A new random connectivity definition
+
+            Args:
+                probability: Random probability of connection
+
+            """
+            probability: ValueExprType = field(default=None, validator=optional(instance_of(value_expr_types)))
+
+        @modelspec.define
+        class NewNetwork(Base):
+            """
+            A new network definition
+
+            Args:
+                id: a unique identifier for the network
+                cells: a list of cells
+                synapses: a list of synapses
+                version: Information on verson of NeuroMLlite
+                seed: Seed for random number generator used when building network
+                stable: Testing...
+                parameters: Dictionary of global parameters for the network
+                random_connectivity: Use random connectivity
+            """
+            id: str = field(validator=instance_of(str))
+            cells: List[NewCell] = field(factory=list)
+            synapses: List[NewSynapse] = field(factory=list)
+            version: str = field(default="NeuroMLlite 0.0", validator=instance_of(str))
+            seed: int = field(default=None, validator=optional(instance_of(int)))
+            stable: bool = field(default=None, validator=optional(instance_of(bool)))
+            parameters: Dict[str, Any] = field(default=None, validator=optional(instance_of(dict)))
+            random_connectivity: NewRandomConnectivity = field(default=None, validator=optional(instance_of(NewRandomConnectivity)))
+            ee0: ValueExprType = field(default=None, validator=optional(instance_of(value_expr_types)))
+            ee1: ValueExprType = field(default=None, validator=optional(instance_of(value_expr_types)))
+            ee2: ValueExprType = field(default=None, validator=optional(instance_of(value_expr_types)))
+            ee3: ValueExprType = field(default=None, validator=optional(instance_of(value_expr_types)))
+            ee4: ValueExprType = field(default=None, validator=optional(instance_of(value_expr_types)))
+            ee5: ValueExprType = field(default=None, validator=optional(instance_of(value_expr_types)))
+            ee6: ValueExprType = field(default=None, validator=optional(instance_of(value_expr_types)))
 
-                super(NewRandomConnectivity, self).__init__(**kwargs)
 
         net = NewNetwork(id="netid", parameters={"size": 3, "name": None})
 
@@ -182,19 +175,17 @@ def __init__(self, **kwargs):
         filenamey = "%s.yaml" % net.id
         # net.id = net.id+'_yaml'
         net.to_yaml_file(filenamey)
-        from modelspec.utils import load_json, load_yaml, _parse_element
+        from modelspec.utils import load_json, load_yaml
 
         dataj = load_json(filenamej)
         print_v("Loaded network specification from %s" % filenamej)
-        netj = NewNetwork()
-        _parse_element(dataj, netj)
+        netj = NewNetwork.from_dict(dataj)
         str_netj = str(netj)
 
         datay = load_yaml(filenamey)
         print_v("Loaded network specification from %s" % filenamey)
 
-        nety = NewNetwork()
-        _parse_element(datay, nety)
+        nety = NewNetwork.from_dict(datay)
         str_nety = str(nety)
 
         verbose = False
diff --git a/neuromllite/test/test_generate.py b/neuromllite/test/test_generate.py
index 76367bd..d32a5f0 100644
--- a/neuromllite/test/test_generate.py
+++ b/neuromllite/test/test_generate.py
@@ -20,7 +20,7 @@ def get_example_simulation(self):
             network="../../examples/Example4_PyNN.json",
             duration="1000",
             dt="0.01",
-            recordTraces={"all": "*"},
+            record_traces={"all": "*"},
         )
         return sim
 
diff --git a/neuromllite/test/test_utils.py b/neuromllite/test/test_utils.py
index 6b5035d..aa2b4c7 100644
--- a/neuromllite/test/test_utils.py
+++ b/neuromllite/test/test_utils.py
@@ -21,11 +21,11 @@ def test_pops_vs_cell_indices(self):
 
         network = get_example_network()
         sim = get_example_simulation()
-        sim.recordTraces = {}
-        sim.recordSpikes = {}
-        sim.recordRates = {}
+        sim.record_traces = {}
+        sim.record_spikes = {}
+        sim.record_rates = {}
 
-        for recordSpec in [sim.recordTraces, sim.recordSpikes, sim.recordRates]:
+        for recordSpec in [sim.record_traces, sim.record_spikes, sim.record_rates]:
 
             print("Testing...")
             recordSpec["all"] = "*"