Permalink
Browse files

Removed Cell, Morphology, Segment, etc. classes to NeuroMLH5.py

  • Loading branch information...
1 parent 648320a commit 0d171c9cc561a8b5a70221769de78174dd29efe8 @pgleeson committed Apr 25, 2012
Showing with 213 additions and 142 deletions.
  1. +187 −0 ideas/padraig/hdf5tests/NeuroMLH5.py
  2. +0 −16 ideas/padraig/hdf5tests/readCA1.py
  3. +26 −126 ideas/padraig/hdf5tests/readXmlHdf5.py
@@ -0,0 +1,187 @@
+# -*- coding: utf-8 -*-
+"""
+
+A set of classes for saving a neuronal morphology as a HDF5 file, while providing an API similar to the one generated
+by generateDS.py from the NeuroML2 XML Schema
+
+Longer term the Morphology/Segment/Distal etc. classes should be substituted into the generated API for more efficient storage of morphologies...
+
+Author: Padraig Gleeson
+"""
+
+from neuroml import *
+import h5py
+import numpy
+
+class NeuroMLH5(object):
+
+ def __init__(self, id):
+ self.id = id
+ f = h5py.File('%s.hdf'%id, 'w')
+ f.attrs['neurohdf_version'] = '0.1'
+ f.attrs['id'] = id
+
+ self._neuroml = f.create_group("neuroml")
+ self.cells = []
+
+ def __str__(self):
+ return "NeuroML: %s with %i cells"%(self.id, len(self.cells))
+
+ def createCell(self, cell_id):
+ cell_group = self._neuroml.create_group("cell_%s"%cell_id)
+ cell = CellH5(cell_id, cell_group)
+ self.cells.append(cell)
+ return cell
+
+
+
+class CellH5(object):
+
+ def __init__(self, id, cell):
+ self.id = id
+ self._cell = cell
+ self.morphology = MorphologyH5("morphology_%s"%id, self)
+
+
+ def __str__(self):
+ return "Cell: %s with %i segments"%(self.id, len(self.morphology.segments))
+
+ def addTestMorph(self, size):
+
+ self.morphology._point_dataset = self.morphology._morphology.create_dataset( "points", [size+1], self.morphology._point_dtype, compression='gzip', compression_opts=4)
+ self.morphology._segment_dataset = self.morphology._morphology.create_dataset("segments", [size], self.morphology._my_dtype, compression='gzip', compression_opts=4)
+
+ for i in range(0,size):
+ if i == 0:
+ self.morphology._point_dataset[0] = (0,0,0,5)
+
+ self.morphology._point_dataset[i+1] = ((i+1)*0.1,(i+1)*0.2,(i+1)*0.3,3)
+ self.morphology._segment_dataset[i] = (i, "seg_%i"%i, i-1, i+1, i)
+
+ #print self.morphology._point_dataset
+ #print self.morphology._segment_dataset
+
+
+class MorphologyH5(object):
+
+ _point_dtype = numpy.dtype([('x', 'f'), ('y', 'f'), ('z', 'f'), ('diameter', 'f')])
+
+ _str_type = h5py.new_vlen(str)
+ _my_dtype = numpy.dtype([('id', 'i'), ('name', _str_type), ('parent', 'i'), ('distal_point', 'i'), ('proximal_point', 'i')])
+
+
+ def __init__(self, id, cell):
+ self.id = id
+ self._cell = cell
+
+ self._morphology = cell._cell.create_group("morphology")
+ self._morphology.attrs['id'] = id
+
+
+ def __getattr__(self, name):
+ #print "MorphologyH5 asked for attr: %s"%name
+
+ if name is "segments":
+ #print "Asked for my %i segments"%self._segment_dataset.shape[0]
+
+ #TODO: this should be cached!
+ segments = []
+ for i in range(self._segment_dataset.shape[0]):
+ #print "Creating object for %s: "%str(self._segment_dataset[i][0])
+ seg = SegmentH5(self._segment_dataset[i][0], self)
+ segments.append(seg)
+
+ return segments
+ else:
+ return None
+
+ def __get_segment_name__(self, id):
+ return self._segment_dataset[id][1]
+
+ def __get_segment_parent__(self, id):
+ return self._segment_dataset[id][2]
+
+ def __get_segment_distal_point__(self, id):
+ return self._segment_dataset[id][3]
+
+ def __get_segment_proximal_point__(self, id):
+ return self._segment_dataset[id][4]
+
+ def __get_point_x__(self, index):
+ return self._point_dataset[index][0]
+
+ def __get_point_y__(self, index):
+ return self._point_dataset[index][1]
+
+ def __get_point_z__(self, index):
+ return self._point_dataset[index][2]
+
+ def __get_point_diameter__(self, index):
+ return self._point_dataset[index][3]
+
+
+class SegmentH5(object):
+
+ def __init__(self, id, morphology):
+ self.id = id
+ self._morphology = morphology
+ self._distal = DistalH5(morphology, id)
+ self._proximal = ProximalH5(morphology, id)
+
+ def __getattr__(self, name):
+ #print "SegmentH5 %i asked for SegmentH5: %s"% (self.id,name)
+ if name is "name":
+ return self._morphology.__get_segment_name__(self.id)
+ if name is "parent":
+ return self._morphology.__get_segment_parent__(self.id)
+ if name is "distal":
+ return self._distal
+ if name is "proximal":
+ return self._proximal
+ else:
+ return None
+
+ def __str__(self):
+ return "Segment: %i (%s), parent: %s"%(self.id, self.name, self.parent)
+
+
+
+class PointH5():
+
+ def __init__(self, morphology, segment_id):
+ self._morphology = morphology
+ self._segment_id = segment_id
+
+
+ def __getattr__(self, name):
+ #print "DistalH5 asked for SegmentH5: %s"% (name)
+ if name is "x":
+ return self._morphology.__get_point_x__(self._point)
+ if name is "y":
+ return self._morphology.__get_point_y__(self._point)
+ if name is "z":
+ return self._morphology.__get_point_z__(self._point)
+ if name is "diameter":
+ return self._morphology.__get_point_diameter__(self._point)
+ else:
+ return None
+
+
+class DistalH5(PointH5):
+
+ def __init__(self, morphology, segment_id):
+ self._morphology = morphology
+ self._segment_id = segment_id
+ self._point = morphology.__get_segment_distal_point__(segment_id)
+
+class ProximalH5(PointH5):
+
+ def __init__(self, morphology, segment_id):
+ self._morphology = morphology
+ self._segment_id = segment_id
+ self._point = morphology.__get_segment_proximal_point__(segment_id)
+
+
+
+
+
@@ -55,22 +55,6 @@
dist = seg.distal
prox = seg.proximal
- '''# There should of course be a helper function for this...
- if prox is None:
- parent = int(seg.parent.segment)
- for segP in segments:
- if int(segP.id) == parent:
- prox = segP.distal
-
- print " Segment %s (%s) from (%f, %f, %f) to (%f, %f, %f)"%(seg.id,
- (seg.name if seg.name is not None else "??"),
- prox.x,
- prox.y,
- prox.z,
- dist.x,
- dist.y,
- dist.z)'''
-
parent_id = int(seg.parent.segment) if seg.parent is not None else -1
point_dataset[i] = (dist.x, dist.y, dist.z, dist.diameter)
segment_dataset[i] = (int(seg.id), seg.name, parent_id, i)
@@ -1,127 +1,13 @@
# -*- coding: utf-8 -*-
"""
-Initial version of Python API for NeuroML2
-Author: Padraig Gleeson
-"""
-
-from neuroml import *
-import h5py
-import numpy
-
-class MorphologyH5(object):
-
- _point_dtype = numpy.dtype([('x', 'f'), ('y', 'f'), ('z', 'f'), ('diameter', 'f')])
-
- _str_type = h5py.new_vlen(str)
- _my_dtype = numpy.dtype([('id', 'i'), ('name', _str_type), ('parent', 'i'), ('distal_point', 'i')])
-
-
- def __init__(self, id):
- self.id = id
- f = h5py.File('%s.hdf'%id, 'w')
- f.attrs['neurohdf_version'] = '0.1'
- f.attrs['id'] = id
-
- self._morphology = f.create_group("morphology")
-
- def __getattr__(self, name):
- print "MorphologyH5 asked for attr: %s"%name
-
- if name is "segments":
- print "Asked for my %i segments"%self._segment_dataset.shape[0]
- segments = []
- for i in range(self._segment_dataset.shape[0]):
- print "Creating object for %s: "%str(self._segment_dataset[i][0])
- seg = SegmentH5(self._segment_dataset[i][0], self)
- segments.append(seg)
- return segments
- else:
- return None
-
- def __get_segment_name__(self, id):
- '''print "Asking for name of seg %i: %s"%(id, self.segment_dataset[id][1])'''
- return self._segment_dataset[id][1]
-
- def __get_segment_parent__(self, id):
- return self._segment_dataset[id][2]
-
- def __get_segment_distal_point__(self, id):
- return self._segment_dataset[id][3]
-
-
- def __get_point_x__(self, index):
- return self._point_dataset[index][0]
- def __get_point_y__(self, index):
- return self._point_dataset[index][1]
- def __get_point_z__(self, index):
- return self._point_dataset[index][2]
- def __get_point_diameter__(self, index):
- return self._point_dataset[index][3]
-
-
-class SegmentH5(object):
-
- def __init__(self, id, morphology):
- self.id = id
- self._morphology = morphology
- self._distal = DistalH5(morphology, id)
-
- def __getattr__(self, name):
- print "SegmentH5 %i asked for SegmentH5: %s"% (self.id,name)
- if name is "name":
- return self._morphology.__get_segment_name__(self.id)
- if name is "parent":
- return self._morphology.__get_segment_parent__(self.id)
- if name is "distal":
- return self._distal
- else:
- return None
-
- def __str__(self):
- return "Segment: %i (%s), parent: %s"%(self.id, self.name, self.parent)
-
-
-
-class DistalH5():
-
- def __init__(self, morphology, segment_id):
- self._morphology = morphology
- self._segment_id = segment_id
- self._distal_point = morphology.__get_segment_distal_point__(segment_id)
-
-
- def __getattr__(self, name):
- print "DistalH5 asked for SegmentH5: %s"% (name)
- if name is "x":
- return self._morphology.__get_point_x__(self._distal_point)
- if name is "y":
- return self._morphology.__get_point_y__(self._distal_point)
- if name is "z":
- return self._morphology.__get_point_z__(self._distal_point)
- if name is "diameter":
- return self._morphology.__get_point_diameter__(self._distal_point)
- else:
- return None
-
-
-
-
-def getTestMorph(id, size):
- morph = MorphologyH5(id)
- morph._point_dataset = morph._morphology.create_dataset( "points", [size], morph._point_dtype, compression='gzip', compression_opts=4)
- morph._segment_dataset = morph._morphology.create_dataset("segments", [size], morph._my_dtype, compression='gzip', compression_opts=4)
+Reading in NeuroML from XML file, then creating HDF5 based object tree and parsing both with approx the same API...
- for i in range(0,size):
- morph._point_dataset[i] = (i*0.1,i*0.2,i*0.3,3)
- morph._segment_dataset[i] = (i, "seg_%i"%i, i-1, i)
-
-
- print morph._point_dataset
- print morph._segment_dataset
- return morph
+Author: Padraig Gleeson
+"""
+from neuroml import *
if __name__ == "__main__":
@@ -134,17 +20,13 @@ def getTestMorph(id, size):
nml2Doc = reader.read_neuroml(filename)
- print "Read in cells in v2 file with Id: "+nml2Doc.id
-
cell = nml2Doc.cell[0]
morph = cell.morphology
segments = morph.segment # not segments, this is a limitation of the code that generateDS.py creates...
-
- print "Id of cell: %s, which has %i segments"%(cell.id,len(segments))
-
+ print "------------------ Parsing XML object tree --------------------"
for seg in segments:
dist = seg.distal
prox = seg.proximal
@@ -164,16 +46,34 @@ def getTestMorph(id, size):
dist.x,
dist.y,
dist.z)
+
+
+ print
+ from NeuroMLH5 import *
+
+ neuromlH5 = NeuroMLH5("Test1")
+ cell = neuromlH5.createCell("cell1")
- morph = getTestMorph("MyTestMorph", 5)
+
+ cell.addTestMorph(5) # A helper function to quickly add a valid morphology
+
+ print "%s; %s"%(neuromlH5, cell)
+
+ morph = cell.morphology
print "Created morphology: %s"%morph.id
+
+ print "------------------ Parsing HDF5 object tree --------------------"
for seg in morph.segments:
dist = seg.distal
- print "Distal: "+str(dist.x)
- print " Segment %s (%s) from (???) to (%f, %f, %f)"%(seg.id,
+ prox = seg.proximal
+
+ print " Segment %s (%s) from (%f, %f, %f) to (%f, %f, %f)"%(seg.id,
(seg.name if seg.name is not None else "??"),
+ prox.x,
+ prox.y,
+ prox.z,
dist.x,
dist.y,
dist.z)

0 comments on commit 0d171c9

Please sign in to comment.