From 17f2b9f39dfc741abe5e52c34837f065971af337 Mon Sep 17 00:00:00 2001
From: Padraig Gleeson
Date: Thu, 28 Oct 2021 11:00:02 +0100
Subject: [PATCH 01/18] Updated and tested NeuroML2 import
---
python/moose/neuroml2/README | 18 +++-
python/moose/neuroml2/__init__.py | 2 +-
python/moose/neuroml2/reader.py | 174 +++++++++++++++---------------
3 files changed, 106 insertions(+), 88 deletions(-)
diff --git a/python/moose/neuroml2/README b/python/moose/neuroml2/README
index c024486979..4f6d4d7219 100644
--- a/python/moose/neuroml2/README
+++ b/python/moose/neuroml2/README
@@ -1,3 +1,19 @@
+Update 2021-10-28 Padraig Gleeson
+
+reader.py updated to work with Python 3.
+
+To test, run:
+
+ python run_cell.py # example of a passive cell
+ python run_hhcell.py # example of a HH cell
+
+Note: older test_*.py files are still giving errors, but may be out of date
+
+
+===============================
+
+Previous status:
+
NeuroML2 is a moving target and the current parser was generated from
the schema publicly available on Jul 28 10:18:38 2013 using the
generateDS.py module.
@@ -18,4 +34,4 @@ The other python files in this directory were hand-coded. So you may
need to tweak them in case NeuroML2 has some incompatible changes or
adds new types.
-- Subhasis Ray, 2016-04-17
\ No newline at end of file
+- Subhasis Ray, 2016-04-17
diff --git a/python/moose/neuroml2/__init__.py b/python/moose/neuroml2/__init__.py
index 92baa3ae34..d24c6492a2 100644
--- a/python/moose/neuroml2/__init__.py
+++ b/python/moose/neuroml2/__init__.py
@@ -61,7 +61,7 @@
import moose.utils as mu
__author__ = 'Subhasis Ray'
+from moose.neuroml2.reader import NML2Reader
-from .reader import NML2Reader
# __init__.py ends here
diff --git a/python/moose/neuroml2/reader.py b/python/moose/neuroml2/reader.py
index 8140e8c536..66f5a3e55f 100644
--- a/python/moose/neuroml2/reader.py
+++ b/python/moose/neuroml2/reader.py
@@ -4,13 +4,11 @@
# Description: NeuroML2 reader.
# Implementation of reader for NeuroML 2 models.
# TODO: handle morphologies of more than one segment...
-#
# Author: Subhasis Ray, Padraig Gleeson
-# Maintainer: Dilawar Singh
+# Maintainer: Dilawar Singh , Padraig Gleeson
# Created: Wed Jul 24 15:55:54 2013 (+0530)
-#
-# Notes:
-# For update/log, please see git-blame documentation or browse the github
+# Notes:
+# For update/log, please see git-blame documentation or browse the github
# repo https://github.com/BhallaLab/moose-core
import os
@@ -47,7 +45,7 @@ def _gates_sorted( all_gates ):
Notes
-----
- If the id of gates are subset of 'x', 'y' or 'z' then sort them so they load in
+ If the id of gates are subset of 'x', 'y' or 'z' then sort them so they load in
X, Y or Z gate respectively. Otherwise do not touch them i.e. first gate
will be loaded into X, second into Y and so on.
"""
@@ -74,7 +72,7 @@ def _isConcDep(ct):
dependant on voltage.
:param ct: ComponentType
- :type ct: nml.ComponentType
+ :type ct: nml.ComponentType
:return: True if Component is depenant on conc, False otherwise.
"""
@@ -85,7 +83,7 @@ def _isConcDep(ct):
def _findCaConcVariableName():
"""_findCaConcVariableName
Find a suitable CaConc for computing HHGate tables.
- This is a hack, though it is likely to work in most cases.
+ This is a hack, though it is likely to work in most cases.
"""
caConcs = moose.wildcardFind( '/library/##[TYPE=CaConc]' )
assert len(caConcs) >= 1, "No moose.CaConc found. Currently moose \
@@ -104,11 +102,11 @@ def sarea(comp):
if comp.length > 0:
return math.pi * comp.diameter * comp.length
else:
- return math.pi * comp.diameter * comp.diameter
+ return math.pi * comp.diameter * comp.diameter
def xarea(compt):
"""xarea
- Return the cross sectional area (𝜋r²) from the diameter of the compartment.
+ Return the cross sectional area (𝜋r²) from the diameter of the compartment.
Note:
----
@@ -141,7 +139,7 @@ def getSegments(nmlcell, component, sg_to_segments):
sg = component.segment_groups
if sg is None:
segments = nmlcell.morphology.segments
- elif sg == 'all':
+ elif sg == 'all':
segments = [seg for seglist in sg_to_segments.values() for seg in seglist]
else:
segments = sg_to_segments[sg]
@@ -149,7 +147,7 @@ def getSegments(nmlcell, component, sg_to_segments):
class NML2Reader(object):
- """Reads NeuroML2 and creates MOOSE model.
+ """Reads NeuroML2 and creates MOOSE model.
NML2Reader.read(filename) reads an NML2 model under `/library`
with the toplevel name defined in the NML2 file.
@@ -169,8 +167,11 @@ def __init__(self, verbose=False):
if self.verbose:
logger_.setLevel( logging.DEBUG )
self.doc = None
- self.filename = None
- self.nml_to_moose = {} # NeuroML object to MOOSE object
+ self.filename = None
+ self.nml_cells_to_moose = {} # NeuroML object to MOOSE object
+ self.nml_segs_to_moose = {} # NeuroML object to MOOSE object
+ self.nml_chans_to_moose = {} # NeuroML object to MOOSE object
+ self.nml_conc_to_moose = {} # NeuroML object to MOOSE object
self.moose_to_nml = {} # Moose object to NeuroML object
self.proto_cells = {} # map id to prototype cell in moose
self.proto_chans = {} # map id to prototype channels in moose
@@ -181,7 +182,7 @@ def __init__(self, verbose=False):
self.id_to_ionChannel = {}
self._cell_to_sg = {} # nml cell to dict - the dict maps segment groups to segments
self._variables = {}
-
+
self.cells_in_populations = {}
self.pop_to_cell_type = {}
self.seg_id_to_comp_name = {}
@@ -190,30 +191,30 @@ def __init__(self, verbose=False):
def read(self, filename, symmetric=True):
filename = os.path.realpath( filename )
- self.doc = nml.loaders.read_neuroml2_file(
+ self.doc = nml.loaders.read_neuroml2_file(
filename, include_includes=True, verbose=self.verbose)
-
+
self.filename = filename
- logger_.info('Parsed NeuroML2 file: %s'% filename)
+ logger_.info('Parsed the NeuroML2 file: %s'% filename)
if self.verbose:
_write_flattened_nml( self.doc, '%s__flattened.xml' % self.filename )
-
+
if len(self.doc.networks)>=1:
self.network = self.doc.networks[0]
moose.celsius = self._getTemperature()
-
+
self.importConcentrationModels(self.doc)
self.importIonChannels(self.doc)
self.importInputs(self.doc)
-
+
for cell in self.doc.cells:
self.createCellPrototype(cell, symmetric=symmetric)
-
+
if len(self.doc.networks)>=1:
self.createPopulations()
self.createInputs()
-
+
def _getTemperature(self):
if self.network is not None:
if self.network.type=="networkWithTemperature":
@@ -222,31 +223,31 @@ def _getTemperature(self):
# Why not, if there's no temp dependence in nml..?
return 0
return SI('25')
-
+
def getCellInPopulation(self, pop_id, index):
return self.cells_in_populations[pop_id][index]
-
+
def getComp(self, pop_id, cellIndex, segId):
return moose.element('%s/%s/%s/%s' % ( self.lib.path, pop_id, cellIndex
, self.seg_id_to_comp_name[self.pop_to_cell_type[pop_id]][segId])
)
-
+
def createPopulations(self):
for pop in self.network.populations:
ep = '%s/%s' % (self.lib.path, pop.id)
mpop = moose.element(ep) if moose.exists(ep) else moose.Neutral(ep)
self.cells_in_populations[pop.id] ={}
for i in range(pop.size):
- logger_.info("Creating %s/%s instances of %s under %s"%(i,pop.size,pop.component, mpop))
+ logger_.info("Creating %s/%s instances of cell: %s under %s"%(i,pop.size,pop.component, mpop))
self.pop_to_cell_type[pop.id]=pop.component
chid = moose.copy(self.proto_cells[pop.component], mpop, '%s'%(i))
self.cells_in_populations[pop.id][i]=chid
-
-
+
+
def getInput(self, input_id):
return moose.element('%s/inputs/%s'%(self.lib.path,input_id))
-
-
+
+
def createInputs(self):
for el in self.network.explicit_inputs:
pop_id = el.target.split('[')[0]
@@ -256,21 +257,21 @@ def createInputs(self):
seg_id = el.target.split('/')[1]
input = self.getInput(el.input)
moose.connect(input, 'output', self.getComp(pop_id,i,seg_id), 'injectMsg')
-
+
for il in self.network.input_lists:
for ii in il.input:
input = self.getInput(il.component)
moose.connect(input, 'output'
, self.getComp(il.populations,ii.get_target_cell__hash(),ii.get_segment__hash())
, 'injectMsg')
-
+
def createCellPrototype(self, cell, symmetric=True):
"""To be completed - create the morphology, channels in prototype"""
ep = '%s/%s' % (self.lib.path, cell.id)
nrn = moose.element(ep) if moose.exists(ep) else moose.Neuron(ep)
self.proto_cells[cell.id] = nrn
- self.nml_to_moose[cell.id] = nrn
+ self.nml_cells_to_moose[cell.id] = nrn
self.moose_to_nml[nrn] = cell
self.createMorphology(cell, nrn, symmetric=symmetric)
self.importBiophysics(cell, nrn)
@@ -285,7 +286,7 @@ def createMorphology(self, nmlcell, moosecell, symmetric=True):
"""
morphology = nmlcell.morphology
segments = morphology.segments
- id_to_segment = dict([(seg.id, seg) for seg in segments])
+ id_to_segment = dict([(seg.id, seg) for seg in segments])
if symmetric:
compclass = moose.SymCompartment
else:
@@ -317,8 +318,8 @@ def createMorphology(self, nmlcell, moosecell, symmetric=True):
except AttributeError:
parent = None
self.moose_to_nml[comp] = segment
- self.nml_to_moose[segment.id] = comp
- p0 = segment.proximal
+ self.nml_segs_to_moose[segment.id] = comp
+ p0 = segment.proximal
if p0 is None:
if parent:
p0 = parent.distal
@@ -339,7 +340,7 @@ def createMorphology(self, nmlcell, moosecell, symmetric=True):
if parent:
pcomp = id_to_comp[parent.id]
moose.connect(comp, src, pcomp, dst)
- sg_to_segments = {}
+ sg_to_segments = {}
for sg in morphology.segment_groups:
sg_to_segments[sg.id] = [id_to_segment[m.segments] for m in sg.members]
for sg in morphology.segment_groups:
@@ -348,10 +349,10 @@ def createMorphology(self, nmlcell, moosecell, symmetric=True):
for inc in sg.includes:
for cseg in sg_to_segments[inc.segment_groups]:
sg_to_segments[sg.id].append(cseg)
-
+
if not 'all' in sg_to_segments:
sg_to_segments['all'] = [ s for s in segments ]
-
+
self._cell_to_sg[nmlcell.id] = sg_to_segments
return id_to_comp, id_to_segment, sg_to_segments
@@ -378,16 +379,16 @@ def importCapacitances(self, nmlcell, moosecell, specificCapacitances):
for specific_cm in specificCapacitances:
cm = SI(specific_cm.value)
for seg in sg_to_segments[specific_cm.segment_groups]:
- comp = self.nml_to_moose[seg.id]
+ comp = self.nml_segs_to_moose[seg.id]
comp.Cm = sarea(comp) * cm
-
+
def importInitMembPotential(self, nmlcell, moosecell, membraneProperties):
sg_to_segments = self._cell_to_sg[nmlcell.id]
for imp in membraneProperties.init_memb_potentials:
initv = SI(imp.value)
for seg in sg_to_segments[imp.segment_groups]:
- comp = self.nml_to_moose[seg.id]
- comp.initVm = initv
+ comp = self.nml_segs_to_moose[seg.id]
+ comp.initVm = initv
def importIntracellularProperties(self, nmlcell, moosecell, properties):
self.importAxialResistance(nmlcell, properties)
@@ -398,14 +399,14 @@ def importSpecies(self, nmlcell, properties):
for species in properties.species:
# Developer note: Not sure if species.concentration_model should be
# a nml element of just plain string. I was getting plain text from
- # nml file here.
+ # nml file here.
concModel = species.concentration_model
if (concModel is not None) and (concModel not in self.proto_pools):
logger_.warn("No concentrationModel '%s' found."%concModel)
continue
segments = getSegments(nmlcell, species, sg_to_segments)
for seg in segments:
- comp = self.nml_to_moose[seg.id]
+ comp = self.nml_segs_to_moose[seg.id]
self.copySpecies(species, comp)
def copySpecies(self, species, compartment):
@@ -426,8 +427,8 @@ def copySpecies(self, species, compartment):
raise RuntimeError(msg)
pool_id = moose.copy(proto_pool, compartment, species.id)
pool = moose.element(pool_id)
- pool.B = pool.B / (np.pi * compartment.length * (
- 0.5 * compartment.diameter + pool.thick) *
+ pool.B = pool.B / (np.pi * compartment.length * (
+ 0.5 * compartment.diameter + pool.thick) *
(0.5 * compartment.diameter - pool.thick)
)
return pool
@@ -437,9 +438,9 @@ def importAxialResistance(self, nmlcell, intracellularProperties):
for r in intracellularProperties.resistivities:
segments = getSegments(nmlcell, r, sg_to_segments)
for seg in segments:
- comp = self.nml_to_moose[seg.id]
- setRa(comp, SI(r.value))
-
+ comp = self.nml_segs_to_moose[seg.id]
+ setRa(comp, SI(r.value))
+
def isPassiveChan(self,chan):
if chan.type == 'ionChannelPassive':
return True
@@ -450,16 +451,19 @@ def isPassiveChan(self,chan):
def evaluate_moose_component(self, ct, variables):
print( "[INFO ] Not implemented." )
return False
-
+
def calculateRateFn(self, ratefn, vmin, vmax, tablen=3000, vShift='0mV'):
"""Returns A / B table from ngate."""
- from . import hhfit
+ from moose.neuroml2.hhfit import exponential2
+ from moose.neuroml2.hhfit import sigmoid2
+ from moose.neuroml2.hhfit import linoid2
+ from moose.neuroml2.units import SI
rate_fn_map = {
- 'HHExpRate': hhfit.exponential2,
- 'HHSigmoidRate': hhfit.sigmoid2,
- 'HHSigmoidVariable': hhfit.sigmoid2,
- 'HHExpLinearRate': hhfit.linoid2
+ 'HHExpRate': exponential2,
+ 'HHSigmoidRate': sigmoid2,
+ 'HHSigmoidVariable': sigmoid2,
+ 'HHExpLinearRate': linoid2
}
tab = np.linspace(vmin, vmax, tablen)
@@ -505,22 +509,22 @@ def importChannelsToCell(self, nmlcell, moosecell, membrane_properties):
try:
ionChannel = self.id_to_ionChannel[chdens.ion_channel]
except KeyError:
- logger_.info('No channel with id: %s' % chdens.ion_channel)
+ logger_.info('No channel with id: %s' % chdens.ion_channel)
continue
-
+
if self.verbose:
logger_.info('Setting density of channel %s in %s to %s; erev=%s (passive: %s)'%(
chdens.id, segments, condDensity,erev,self.isPassiveChan(ionChannel))
)
-
+
if self.isPassiveChan(ionChannel):
for seg in segments:
- # comp = self.nml_to_moose[seg]
- setRm(self.nml_to_moose[seg.id], condDensity)
- setEk(self.nml_to_moose[seg.id], erev)
+ comp = self.nml_segs_to_moose[seg.id]
+ setRm(comp, condDensity)
+ setEk(comp, erev)
else:
for seg in segments:
- self.copyChannel(chdens, self.nml_to_moose[seg.id], condDensity, erev)
+ self.copyChannel(chdens, self.nml_segs_to_moose[seg.id], condDensity, erev)
'''moose.le(self.nml_to_moose[seg])
moose.showfield(self.nml_to_moose[seg], field="*", showtype=True)'''
@@ -541,21 +545,19 @@ def copyChannel(self, chdens, comp, condDensity, erev):
raise Exception('No prototype channel for %s referred to by %s' % (chdens.ion_channel, chdens.id))
if self.verbose:
- logger_.info('Copying %s to %s, %s; erev=%s'%(chdens.id, comp, condDensity, erev))
+ logger_.info('Copying the %s to %s, %s; erev=%s'%(chdens.id, comp, condDensity, erev))
orig = chdens.id
chid = moose.copy(proto_chan, comp, chdens.id)
chan = moose.element(chid)
-
- # We are updaing the keys() here. Need copy: using list(keys()) to
- # create a copy.
- for p in list(self.paths_to_chan_elements.keys()):
+ els = list(self.paths_to_chan_elements.keys())
+ for p in els:
pp = p.replace('%s/'%chdens.ion_channel,'%s/'%orig)
self.paths_to_chan_elements[pp] = self.paths_to_chan_elements[p].replace('%s/'%chdens.ion_channel,'%s/'%orig)
#logger_.info(self.paths_to_chan_elements)
chan.Gbar = sarea(comp) * condDensity
chan.Ek = erev
moose.connect(chan, 'channel', comp, 'channel')
- return chan
+ return chan
def _is_standard_nml_rate(self, rate):
return rate.type=='HHExpLinearRate' \
@@ -567,7 +569,7 @@ def createHHChannel(self, chan, vmin=-150e-3, vmax=100e-3, vdivs=5000):
mchan = moose.HHChannel('%s/%s' % (self.lib.path, chan.id))
mgates = [moose.element(x) for x in [mchan.gateX, mchan.gateY, mchan.gateZ]]
assert len(chan.gate_hh_rates)<=3, "We handle only up to 3 gates in HHCHannel"
-
+
if self.verbose:
logger_.info('== Creating channel: %s (%s) -> %s (%s)'%(chan.id, chan.gate_hh_rates, mchan, mgates))
@@ -607,14 +609,14 @@ def createHHChannel(self, chan, vmin=-150e-3, vmax=100e-3, vdivs=5000):
, (self._getTemperature()- SI(ngate.q10_settings.experimental_temp))/10
)
else:
- raise Exception('Unknown Q10 scaling type %s: %s'%(
+ raise Exception('Unknown Q10 scaling type %s: %s'%(
ngate.q10_settings.type,ngate.q10_settings)
)
-
- logger_.debug('+ Gate: %s; %s; %s; %s; %s; scale=%s'% (
+
+ logger_.debug('+ Gate: %s; %s; %s; %s; %s; scale=%s'% (
ngate.id, mgate.path, mchan.Xpower, fwd, rev, q10_scale)
)
-
+
if (fwd is not None) and (rev is not None):
alpha = self.calculateRateFn(fwd, vmin, vmax, vdivs)
beta = self.calculateRateFn(rev, vmin, vmax, vdivs)
@@ -631,7 +633,7 @@ def createHHChannel(self, chan, vmin=-150e-3, vmax=100e-3, vdivs=5000):
inf = self.calculateRateFn(inf, vmin, vmax, vdivs)
mgate.tableA = q10_scale * (inf / tau)
mgate.tableB = q10_scale * (1 / tau)
-
+
if hasattr(ngate,'steady_state') and (ngate.time_course is None) and (ngate.steady_state is not None):
inf = ngate.steady_state
tau = 1 / (alpha + beta)
@@ -640,7 +642,7 @@ def createHHChannel(self, chan, vmin=-150e-3, vmax=100e-3, vdivs=5000):
if len(inf) > 0:
mgate.tableA = q10_scale * (inf / tau)
mgate.tableB = q10_scale * (1 / tau)
-
+
logger_.info('%s: Created %s for %s'%(self.filename,mchan.path,chan.id))
return mchan
@@ -667,11 +669,11 @@ def importInputs(self, doc):
pg.firstWidth = SI(pg_nml.duration)
pg.firstLevel = SI(pg_nml.amplitude)
pg.secondDelay = 1e9
-
+
def importIonChannels(self, doc, vmin=-150e-3, vmax=100e-3, vdivs=5000):
logger_.info('%s: Importing the ion channels' % self.filename )
-
+
for chan in doc.ion_channel+doc.ion_channel_hhs:
if chan.type == 'ionChannelHH':
mchan = self.createHHChannel(chan)
@@ -679,11 +681,11 @@ def importIonChannels(self, doc, vmin=-150e-3, vmax=100e-3, vdivs=5000):
mchan = self.createPassiveChannel(chan)
else:
mchan = self.createHHChannel(chan)
-
+
self.id_to_ionChannel[chan.id] = chan
- self.nml_to_moose[chan.id] = mchan
+ self.nml_chans_to_moose[chan.id] = mchan
self.proto_chans[chan.id] = mchan
- logger_.info(self.filename + ': Created ion channel %s for %s %s'%(
+ logger_.info(self.filename + ': Created ion channel %s for %s %s'%(
mchan.path, chan.type, chan.id))
def importConcentrationModels(self, doc):
@@ -691,7 +693,7 @@ def importConcentrationModels(self, doc):
self.createDecayingPoolConcentrationModel(concModel)
def createDecayingPoolConcentrationModel(self, concModel):
- """Create prototype for concentration model"""
+ """Create prototype for concentration model"""
if hasattr(concModel, 'name') and concModel.name is not None:
name = concModel.name
else:
@@ -701,10 +703,10 @@ def createDecayingPoolConcentrationModel(self, concModel):
ca.CaBasal = SI(concModel.resting_conc)
ca.tau = SI(concModel.decay_constant)
ca.thick = SI(concModel.shell_thickness)
- ca.B = 5.2e-6 # B = 5.2e-6/(Ad) where A is the area of the
- # shell and d is thickness - must divide by
+ ca.B = 5.2e-6 # B = 5.2e-6/(Ad) where A is the area of the
+ # shell and d is thickness - must divide by
# shell volume when copying
self.proto_pools[concModel.id] = ca
- self.nml_to_moose[name] = ca
+ self.nml_concs_to_moose[concModel.id] = ca
self.moose_to_nml[ca] = concModel
logger_.debug('Created moose element: %s for nml conc %s' % (ca.path, concModel.id))
From bb81941d3c357b7728e5bb927e0a88fddbc481c7 Mon Sep 17 00:00:00 2001
From: Padraig Gleeson
Date: Thu, 28 Oct 2021 11:05:08 +0100
Subject: [PATCH 02/18] Use moose.neuroml2.reader
---
python/moose/neuroml2/run_cell.py | 38 ++++++++++-----------
python/moose/neuroml2/run_hhcell.py | 51 ++++++++++++++---------------
2 files changed, 44 insertions(+), 45 deletions(-)
diff --git a/python/moose/neuroml2/run_cell.py b/python/moose/neuroml2/run_cell.py
index 81d535f1eb..a72af29a6c 100644
--- a/python/moose/neuroml2/run_cell.py
+++ b/python/moose/neuroml2/run_cell.py
@@ -45,48 +45,48 @@
import moose
import moose.utils as mu
import sys
-from reader import NML2Reader
+from moose.neuroml2.reader import NML2Reader
import numpy as np
-
+
def run(nogui):
-
+
reader = NML2Reader(verbose=True)
filename = 'test_files/passiveCell.nml'
print('Loading: %s'%filename)
reader.read(filename)
-
-
+
+
msoma = reader.getComp(reader.doc.networks[0].populations[0].id,0,0)
print(msoma)
-
-
+
+
data = moose.Neutral('/data')
-
+
pg = reader.getInput('pulseGen1')
-
+
inj = moose.Table('%s/pulse' % (data.path))
moose.connect(inj, 'requestOut', pg, 'getOutputValue')
-
-
+
+
vm = moose.Table('%s/Vm' % (data.path))
moose.connect(vm, 'requestOut', msoma, 'getVm')
-
+
simdt = 1e-6
plotdt = 1e-4
simtime = 150e-3
-
+
for i in range(8):
moose.setClock( i, simdt )
moose.setClock( 8, plotdt )
moose.reinit()
moose.start(simtime)
-
+
print("Finished simulation!")
-
+
t = np.linspace(0, simtime, len(vm.vector))
-
+
if not nogui:
import matplotlib.pyplot as plt
@@ -103,9 +103,9 @@ def run(nogui):
plt.show()
plt.close()
-
+
if __name__ == '__main__':
-
+
nogui = '-nogui' in sys.argv
-
+
run(nogui)
diff --git a/python/moose/neuroml2/run_hhcell.py b/python/moose/neuroml2/run_hhcell.py
index fb92841ded..b5d37b0268 100644
--- a/python/moose/neuroml2/run_hhcell.py
+++ b/python/moose/neuroml2/run_hhcell.py
@@ -44,7 +44,7 @@
import moose
import sys
-from reader import NML2Reader
+from moose.neuroml2.reader import NML2Reader
import numpy as np
@@ -60,63 +60,63 @@ def test_channel_gates():
h = moose.element('/library[0]/naChan[0]/gateY')
n = moose.element('/library[0]/kChan[0]/gateX')
v = np.linspace(n.min,n.max, n.divs+1)
-
+
plt.subplot(221)
plt.plot(v, 1/m.tableB, label='tau_m')
plt.plot(v, 1/h.tableB, label='tau_h')
plt.plot(v, 1/n.tableB, label='tau_n')
plt.legend()
-
+
plt.subplot(222)
plt.plot(v, m.tableA/m.tableB, label='m_inf')
plt.plot(v, h.tableA/h.tableB, label='h_inf')
plt.plot(v, n.tableA/n.tableB, label='n_inf')
plt.legend()
-
+
plt.subplot(223)
plt.plot(v, m.tableA, label='mA(alpha)')
plt.plot(v, h.tableA, label='hA(alpha)')
plt.plot(v, n.tableA, label='nA(alpha)')
plt.legend()
plt.subplot(224)
-
+
plt.plot(v, m.tableB, label='mB')
plt.plot(v, m.tableB-m.tableA, label='mB-A(beta)')
-
+
plt.plot(v, h.tableB, label='hB')
plt.plot(v, h.tableB-h.tableA, label='hB-A(beta)')
-
+
plt.plot(v, n.tableB, label='nB')
plt.plot(v, n.tableB-n.tableA, label='nB-nA(beta)')
plt.legend()
-
+
plt.show()
def run(nogui):
-
+
reader = NML2Reader(verbose=True)
filename = 'test_files/NML2_SingleCompHHCell.nml'
print('Loading: %s'%filename)
reader.read(filename, symmetric=True)
-
-
+
+
msoma = reader.getComp(reader.doc.networks[0].populations[0].id,0,0)
print(msoma)
-
-
+
+
data = moose.Neutral('/data')
-
+
pg = reader.getInput('pulseGen1')
-
+
inj = moose.Table('%s/pulse' % (data.path))
moose.connect(inj, 'requestOut', pg, 'getOutputValue')
-
-
+
+
vm = moose.Table('%s/Vm' % (data.path))
moose.connect(vm, 'requestOut', msoma, 'getVm')
-
+
simdt = 1e-6
plotdt = 1e-4
simtime = 300e-3
@@ -126,11 +126,11 @@ def run(nogui):
moose.setClock( 8, plotdt )
moose.reinit()
moose.start(simtime)
-
+
print("Finished simulation!")
-
+
t = np.linspace(0, simtime, len(vm.vector))
-
+
if not nogui:
import matplotlib.pyplot as plt
@@ -153,11 +153,10 @@ def run(nogui):
test_channel_gates()
plt.show()
plt.close()
-
-
+
+
if __name__ == '__main__':
-
+
nogui = '-nogui' in sys.argv
-
+
run(nogui)
-
From f994a0cf4a97133a624534d05392efb396a65088 Mon Sep 17 00:00:00 2001
From: analkumar2
Date: Wed, 17 Nov 2021 12:46:07 +0530
Subject: [PATCH 03/18] Harsha's changes
---
python/moose/neuroml2/test_reader2.py | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/python/moose/neuroml2/test_reader2.py b/python/moose/neuroml2/test_reader2.py
index 35a123f3c0..90a6d0daeb 100644
--- a/python/moose/neuroml2/test_reader2.py
+++ b/python/moose/neuroml2/test_reader2.py
@@ -51,27 +51,25 @@
class TestPassiveCell(unittest.TestCase):
def setUp(self):
self.reader = NML2Reader(verbose=True)
-
self.lib = moose.Neutral('/library')
self.filename = 'test_files/passiveCell.nml'
- print('Loading: %s'%self.filename)
self.reader.read(self.filename)
- for ncell in self.reader.nml_to_moose:
- if isinstance(ncell, nml.Cell):
- self.ncell = ncell
+ for ncell in self.reader.nml_cells_to_moose:
+ #if isinstance((self.reader.nml_cells_to_moose[ncell]).type,moose.Neuron):
+ if self.reader.nml_cells_to_moose[ncell].isA("Neuron"):
+ self.ncell = self.reader.nml_cells_to_moose[ncell]
break
- self.mcell = moose.element('/library/%s'%self.ncell.id)
+ self.mcell = moose.element('/library/%s'%self.ncell.name)
self.soma = moose.element(self.mcell.path + '/soma')
-
def test_basicLoading(self):
- pass
- self.assertEqual(self.reader.filename, self.filename, 'filename was not set')
+ #self.assertEqual(self.reader.filename, self.filename, 'filename was not set')
self.assertIsNotNone(self.reader.doc, 'doc is None')
def test_createCellPrototype(self):
- self.assertIsInstance(self.mcell, moose.Neuron)
- self.assertEqual(self.mcell.name, self.ncell.id)
+
+ #self.assertIsInstance(moose.element(self.mcell).className, moose.Neuron)
+ self.assertEqual(moose.element(self.mcell).name, self.ncell.name)
def test_createMorphology(self):
for comp_id in moose.wildcardFind(self.mcell.path + '/##[ISA=Compartment]'):
From c615047e8d078ae15f5850e70548929f65296c07 Mon Sep 17 00:00:00 2001
From: analkumar2
Date: Wed, 17 Nov 2021 21:43:38 +0530
Subject: [PATCH 04/18] copy issue solved by deleting library
---
python/moose/neuroml2/test_reader2.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/python/moose/neuroml2/test_reader2.py b/python/moose/neuroml2/test_reader2.py
index 90a6d0daeb..d54d6cf5f2 100644
--- a/python/moose/neuroml2/test_reader2.py
+++ b/python/moose/neuroml2/test_reader2.py
@@ -50,6 +50,8 @@
class TestPassiveCell(unittest.TestCase):
def setUp(self):
+ if '/library' in moose.le():
+ moose.delete('/library')
self.reader = NML2Reader(verbose=True)
self.lib = moose.Neutral('/library')
self.filename = 'test_files/passiveCell.nml'
@@ -67,7 +69,6 @@ def test_basicLoading(self):
self.assertIsNotNone(self.reader.doc, 'doc is None')
def test_createCellPrototype(self):
-
#self.assertIsInstance(moose.element(self.mcell).className, moose.Neuron)
self.assertEqual(moose.element(self.mcell).name, self.ncell.name)
From 5bdbbaf95df7d8ea8a946b5863197fd41651bbf9 Mon Sep 17 00:00:00 2001
From: analkumar2
Date: Wed, 17 Nov 2021 21:56:15 +0530
Subject: [PATCH 05/18] Harsha's changes for test_reader.py
---
python/moose/neuroml2/test_reader.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/python/moose/neuroml2/test_reader.py b/python/moose/neuroml2/test_reader.py
index 53d420d853..4ccac1a648 100644
--- a/python/moose/neuroml2/test_reader.py
+++ b/python/moose/neuroml2/test_reader.py
@@ -60,9 +60,9 @@ def setUp(self):
self.lib = moose.Neutral('/library')
self.filename = 'test_files/NML2_FullCell.nml'
self.reader.read(self.filename)
- for ncell in self.reader.nml_to_moose:
- if isinstance(ncell, nml.Cell):
- self.ncell = ncell
+ for ncell in self.reader.nml_cells_to_moose:
+ if self.reader.nml_cells_to_moose[ncell].isA("Neuron"):
+ self.ncell = self.reader.nml_cells_to_moose[ncell]
break
self.mcell = moose.element('/library/SpikingCell')
self.soma = moose.element(self.mcell.path + '/Soma')
From 34d2408c84617b808569c4e6ff286b452c8b6e2a Mon Sep 17 00:00:00 2001
From: analkumar2
Date: Thu, 18 Nov 2021 02:02:53 +0530
Subject: [PATCH 06/18] Solved filename issue
---
python/moose/neuroml2/test_reader.py | 5 ++++-
python/moose/neuroml2/test_reader2.py | 7 ++++---
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/python/moose/neuroml2/test_reader.py b/python/moose/neuroml2/test_reader.py
index 4ccac1a648..9ae0760de6 100644
--- a/python/moose/neuroml2/test_reader.py
+++ b/python/moose/neuroml2/test_reader.py
@@ -52,13 +52,16 @@
import moose
import neuroml as nml
from reader import NML2Reader
+import os
class TestFullCell(unittest.TestCase):
def setUp(self):
+ if '/library' in moose.le():
+ moose.delete('/library')
self.reader = NML2Reader(verbose=True)
self.lib = moose.Neutral('/library')
- self.filename = 'test_files/NML2_FullCell.nml'
+ self.filename = os.path.realpath('test_files/NML2_FullCell.nml')
self.reader.read(self.filename)
for ncell in self.reader.nml_cells_to_moose:
if self.reader.nml_cells_to_moose[ncell].isA("Neuron"):
diff --git a/python/moose/neuroml2/test_reader2.py b/python/moose/neuroml2/test_reader2.py
index d54d6cf5f2..4ef6d42422 100644
--- a/python/moose/neuroml2/test_reader2.py
+++ b/python/moose/neuroml2/test_reader2.py
@@ -47,6 +47,7 @@
import moose
from reader import NML2Reader
import neuroml as nml
+import os
class TestPassiveCell(unittest.TestCase):
def setUp(self):
@@ -54,7 +55,7 @@ def setUp(self):
moose.delete('/library')
self.reader = NML2Reader(verbose=True)
self.lib = moose.Neutral('/library')
- self.filename = 'test_files/passiveCell.nml'
+ self.filename = os.path.realpath('test_files/passiveCell.nml')
self.reader.read(self.filename)
for ncell in self.reader.nml_cells_to_moose:
#if isinstance((self.reader.nml_cells_to_moose[ncell]).type,moose.Neuron):
@@ -65,11 +66,11 @@ def setUp(self):
self.soma = moose.element(self.mcell.path + '/soma')
def test_basicLoading(self):
- #self.assertEqual(self.reader.filename, self.filename, 'filename was not set')
+ self.assertEqual(self.reader.filename, self.filename, 'filename was not set')
self.assertIsNotNone(self.reader.doc, 'doc is None')
def test_createCellPrototype(self):
- #self.assertIsInstance(moose.element(self.mcell).className, moose.Neuron)
+ self.assertIsInstance(moose.element(self.mcell).className, moose.Neuron)
self.assertEqual(moose.element(self.mcell).name, self.ncell.name)
def test_createMorphology(self):
From 50124f886b72dc33a1ab6b1242ecc21ca7f93229 Mon Sep 17 00:00:00 2001
From: analkumar2
Date: Thu, 18 Nov 2021 02:21:58 +0530
Subject: [PATCH 07/18] test_createCellPrototype asserting the name of the cell
issue
---
python/moose/neuroml2/test_reader.py | 4 ++--
python/moose/neuroml2/test_reader2.py | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/python/moose/neuroml2/test_reader.py b/python/moose/neuroml2/test_reader.py
index 9ae0760de6..435ce051f9 100644
--- a/python/moose/neuroml2/test_reader.py
+++ b/python/moose/neuroml2/test_reader.py
@@ -78,8 +78,8 @@ def test_basicLoading(self):
self.assertIsNotNone(self.reader.doc, 'doc is None')
def test_createCellPrototype(self):
- self.assertIsInstance(self.mcell, moose.Neuron)
- self.assertEqual(self.mcell.name, self.ncell.id)
+ self.assertEqual(moose.element(self.mcell).className, 'Neuron')
+ self.assertEqual(moose.element(self.mcell).name, self.ncell.name)
def test_createMorphology(self):
for comp_id in moose.wildcardFind(self.mcell.path + '/##[ISA=Compartment]'):
diff --git a/python/moose/neuroml2/test_reader2.py b/python/moose/neuroml2/test_reader2.py
index 4ef6d42422..243b9dfd30 100644
--- a/python/moose/neuroml2/test_reader2.py
+++ b/python/moose/neuroml2/test_reader2.py
@@ -70,7 +70,7 @@ def test_basicLoading(self):
self.assertIsNotNone(self.reader.doc, 'doc is None')
def test_createCellPrototype(self):
- self.assertIsInstance(moose.element(self.mcell).className, moose.Neuron)
+ self.assertEqual(moose.element(self.mcell).className, 'Neuron')
self.assertEqual(moose.element(self.mcell).name, self.ncell.name)
def test_createMorphology(self):
From 917638e944063dfc5ded9879bce89dce6e183544 Mon Sep 17 00:00:00 2001
From: Padraig Gleeson
Date: Mon, 13 Dec 2021 09:55:11 +0000
Subject: [PATCH 08/18] Update githubaction.yml
---
.github/workflows/githubaction.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/githubaction.yml b/.github/workflows/githubaction.yml
index b65b854d7e..70dc6eb2c4 100644
--- a/.github/workflows/githubaction.yml
+++ b/.github/workflows/githubaction.yml
@@ -25,3 +25,4 @@ jobs:
- name: Build
run: |
python setup.py install
+ pip list
From b328586a35b546d4077f367da5c2cbad2cdde3d3 Mon Sep 17 00:00:00 2001
From: Padraig Gleeson
Date: Mon, 13 Dec 2021 18:17:40 +0000
Subject: [PATCH 09/18] Update githubaction.yml
---
.github/workflows/githubaction.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/githubaction.yml b/.github/workflows/githubaction.yml
index 70dc6eb2c4..114e8dbe40 100644
--- a/.github/workflows/githubaction.yml
+++ b/.github/workflows/githubaction.yml
@@ -26,3 +26,4 @@ jobs:
run: |
python setup.py install
pip list
+ python -c "import moose; print(moose.__version__)"
From 2dcc5b95e58ac9e869d030a19b85b359407b0d53 Mon Sep 17 00:00:00 2001
From: Padraig Gleeson
Date: Tue, 14 Dec 2021 15:06:30 +0000
Subject: [PATCH 10/18] Fix for input list
---
python/moose/neuroml2/reader.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/python/moose/neuroml2/reader.py b/python/moose/neuroml2/reader.py
index 66f5a3e55f..0f13a171c8 100644
--- a/python/moose/neuroml2/reader.py
+++ b/python/moose/neuroml2/reader.py
@@ -262,7 +262,7 @@ def createInputs(self):
for ii in il.input:
input = self.getInput(il.component)
moose.connect(input, 'output'
- , self.getComp(il.populations,ii.get_target_cell__hash(),ii.get_segment__hash())
+ , self.getComp(il.populations,ii.get_target_cell_id(),ii.get_segment_id())
, 'injectMsg')
From 1accd3c106765491a38c983ea5ab13ea3997a9df Mon Sep 17 00:00:00 2001
From: Padraig Gleeson
Date: Thu, 16 Dec 2021 13:05:58 +0000
Subject: [PATCH 11/18] Update githubaction.yml
---
.github/workflows/githubaction.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/githubaction.yml b/.github/workflows/githubaction.yml
index 114e8dbe40..2415c38ade 100644
--- a/.github/workflows/githubaction.yml
+++ b/.github/workflows/githubaction.yml
@@ -1,6 +1,6 @@
name: Python package
-on: [push]
+on: [push, pull_request]
jobs:
build:
From 0db5cc0a408797d3ddcfe741eb6a8af8c8872924 Mon Sep 17 00:00:00 2001
From: Padraig Gleeson
Date: Fri, 17 Dec 2021 18:06:10 +0000
Subject: [PATCH 12/18] Update setup.py
---
setup.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/setup.py b/setup.py
index edb5bebb1b..36fb313abe 100644
--- a/setup.py
+++ b/setup.py
@@ -171,7 +171,7 @@ def build_cmake(self, ext):
]
},
# python2 specific version here as well.
- install_requires=['numpy', 'matplotlib'],
+ install_requires=['numpy', 'scipy', 'matplotlib'],
extra_requires={'dev' : [ 'coverage', 'pytest', 'pytest-cov' ]},
ext_modules=[CMakeExtension('dummy', optional=True)],
cmdclass={'build_ext': build_ext, 'test': TestCommand},
From 0612ffbe89f25fe76c368332eedbf5f1f38c2bb3 Mon Sep 17 00:00:00 2001
From: Padraig Gleeson
Date: Thu, 28 Apr 2022 12:39:32 +0100
Subject: [PATCH 13/18] Remove my copy actions file
---
.github/workflows/githubaction.yml | 29 -----------------------------
1 file changed, 29 deletions(-)
delete mode 100644 .github/workflows/githubaction.yml
diff --git a/.github/workflows/githubaction.yml b/.github/workflows/githubaction.yml
deleted file mode 100644
index 2415c38ade..0000000000
--- a/.github/workflows/githubaction.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-name: Python package
-
-on: [push, pull_request]
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
- strategy:
- matrix:
- python-version: [3.7, 3.8]
-
- steps:
- - uses: actions/checkout@v2
- - name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python@v1
- with:
- python-version: ${{ matrix.python-version }}
- - name: Install dependencies
- run: |
- export DEBIAN_FRONTEND=noninteractive
- sudo -E apt install -y cmake libgsl-dev g++ gcc git
- sudo -E apt install python3-tk python-tk
- python -m pip install numpy matplotlib --user
- - name: Build
- run: |
- python setup.py install
- pip list
- python -c "import moose; print(moose.__version__)"
From cf79bc40acae38ab420c6cd1d635b7b22113f13a Mon Sep 17 00:00:00 2001
From: Anal Kumar
Date: Fri, 3 Jun 2022 06:22:03 +0530
Subject: [PATCH 14/18] test_connectivity unittest for Neuroml2
---
python/moose/neuroml2/test_reader.py | 35 +++++++++++++++++-----------
1 file changed, 22 insertions(+), 13 deletions(-)
diff --git a/python/moose/neuroml2/test_reader.py b/python/moose/neuroml2/test_reader.py
index 435ce051f9..0a6bbb087c 100644
--- a/python/moose/neuroml2/test_reader.py
+++ b/python/moose/neuroml2/test_reader.py
@@ -97,18 +97,27 @@ def test_createMorphology(self):
def test_connectivity(self):
"""Test raxial-axial connectivity between MOOSE compartments when
there is parent->child relation in NML2."""
- id_to_seg = dict([(seg.id, seg) for seg in self.ncell.morphology.segments])
- for seg in self.ncell.morphology.segments:
- try:
- pseg = id_to_seg[seg.parent.segment]
- except AttributeError:
- continue
- comp = self.reader.nml_to_moose[seg]
- pcomp = self.reader.nml_to_moose[pseg]
-
- '''
- TODO: what should this be updated to???
- self.assertIn(comp.id_, pcomp.neighbours['raxial'])'''
+ self.assertEqual(moose.element('/Msgs[0]/singleMsg[0]').e1.name, self.dendrite1.name)
+ self.assertEqual(moose.element('/Msgs[0]/singleMsg[0]').e2.name, self.soma.name)
+ self.assertEqual(moose.element('/Msgs[0]/singleMsg[1]').e1.name, self.dendrite2.name)
+ self.assertEqual(moose.element('/Msgs[0]/singleMsg[1]').e2.name, self.dendrite1.name)
+ self.assertEqual(moose.element('/Msgs[0]/singleMsg[2]').e1.name, self.spine1.name)
+ self.assertEqual(moose.element('/Msgs[0]/singleMsg[2]').e2.name, self.dendrite2.name)
+
+ self.assertEqual(moose.element('/Msgs[0]/singleMsg[0]').srcFieldsOnE1, ['sumRaxialOut', 'proximalOut'])
+ self.assertEqual(moose.element('/Msgs[0]/singleMsg[0]').destFieldsOnE2, ['sumRaxial', 'raxialSym'])
+ self.assertEqual(moose.element('/Msgs[0]/singleMsg[1]').srcFieldsOnE1, ['sumRaxialOut', 'proximalOut'])
+ self.assertEqual(moose.element('/Msgs[0]/singleMsg[1]').destFieldsOnE2, ['sumRaxial', 'raxialSym'])
+ self.assertEqual(moose.element('/Msgs[0]/singleMsg[2]').srcFieldsOnE1, ['sumRaxialOut', 'proximalOut'])
+ self.assertEqual(moose.element('/Msgs[0]/singleMsg[2]').destFieldsOnE2, ['sumRaxial', 'raxialSym'])
+
+ self.assertEqual(moose.element('/Msgs[0]/singleMsg[0]').srcFieldsOnE2, ['sumRaxialOut', 'distalOut'])
+ self.assertEqual(moose.element('/Msgs[0]/singleMsg[0]').destFieldsOnE1, ['sumRaxial', 'raxialSym'])
+ self.assertEqual(moose.element('/Msgs[0]/singleMsg[1]').srcFieldsOnE2, ['sumRaxialOut', 'distalOut'])
+ self.assertEqual(moose.element('/Msgs[0]/singleMsg[1]').destFieldsOnE1, ['sumRaxial', 'raxialSym'])
+ self.assertEqual(moose.element('/Msgs[0]/singleMsg[2]').srcFieldsOnE2, ['sumRaxialOut', 'distalOut'])
+ self.assertEqual(moose.element('/Msgs[0]/singleMsg[2]').destFieldsOnE1, ['sumRaxial', 'raxialSym'])
+
def test_capacitance(self):
for comp_id in moose.wildcardFind(self.mcell.path + '/##[ISA=Compartment]'):
@@ -117,7 +126,7 @@ def test_capacitance(self):
self.assertTrue((comp.Cm > 0) and (comp.Cm < 1e-6))
def test_protochans(self):
- """TODO: verify the prototype cahnnel."""
+ """TODO: verify the prototype channel."""
for chan_id in moose.wildcardFind('/library/##[ISA=HHChannel]'):
print(moose.element(chan_id))
From 3d25fcd5010a6857edc07c020a7a67ab9b42a20e Mon Sep 17 00:00:00 2001
From: Anal Kumar
Date: Fri, 3 Jun 2022 16:55:29 +0530
Subject: [PATCH 15/18] resolved seg fault in test_connectivity in
test_reader.py
---
python/moose/neuroml2/test_reader.py | 27 +++++++--------------------
1 file changed, 7 insertions(+), 20 deletions(-)
diff --git a/python/moose/neuroml2/test_reader.py b/python/moose/neuroml2/test_reader.py
index 0a6bbb087c..433eadb5cd 100644
--- a/python/moose/neuroml2/test_reader.py
+++ b/python/moose/neuroml2/test_reader.py
@@ -97,26 +97,13 @@ def test_createMorphology(self):
def test_connectivity(self):
"""Test raxial-axial connectivity between MOOSE compartments when
there is parent->child relation in NML2."""
- self.assertEqual(moose.element('/Msgs[0]/singleMsg[0]').e1.name, self.dendrite1.name)
- self.assertEqual(moose.element('/Msgs[0]/singleMsg[0]').e2.name, self.soma.name)
- self.assertEqual(moose.element('/Msgs[0]/singleMsg[1]').e1.name, self.dendrite2.name)
- self.assertEqual(moose.element('/Msgs[0]/singleMsg[1]').e2.name, self.dendrite1.name)
- self.assertEqual(moose.element('/Msgs[0]/singleMsg[2]').e1.name, self.spine1.name)
- self.assertEqual(moose.element('/Msgs[0]/singleMsg[2]').e2.name, self.dendrite2.name)
-
- self.assertEqual(moose.element('/Msgs[0]/singleMsg[0]').srcFieldsOnE1, ['sumRaxialOut', 'proximalOut'])
- self.assertEqual(moose.element('/Msgs[0]/singleMsg[0]').destFieldsOnE2, ['sumRaxial', 'raxialSym'])
- self.assertEqual(moose.element('/Msgs[0]/singleMsg[1]').srcFieldsOnE1, ['sumRaxialOut', 'proximalOut'])
- self.assertEqual(moose.element('/Msgs[0]/singleMsg[1]').destFieldsOnE2, ['sumRaxial', 'raxialSym'])
- self.assertEqual(moose.element('/Msgs[0]/singleMsg[2]').srcFieldsOnE1, ['sumRaxialOut', 'proximalOut'])
- self.assertEqual(moose.element('/Msgs[0]/singleMsg[2]').destFieldsOnE2, ['sumRaxial', 'raxialSym'])
-
- self.assertEqual(moose.element('/Msgs[0]/singleMsg[0]').srcFieldsOnE2, ['sumRaxialOut', 'distalOut'])
- self.assertEqual(moose.element('/Msgs[0]/singleMsg[0]').destFieldsOnE1, ['sumRaxial', 'raxialSym'])
- self.assertEqual(moose.element('/Msgs[0]/singleMsg[1]').srcFieldsOnE2, ['sumRaxialOut', 'distalOut'])
- self.assertEqual(moose.element('/Msgs[0]/singleMsg[1]').destFieldsOnE1, ['sumRaxial', 'raxialSym'])
- self.assertEqual(moose.element('/Msgs[0]/singleMsg[2]').srcFieldsOnE2, ['sumRaxialOut', 'distalOut'])
- self.assertEqual(moose.element('/Msgs[0]/singleMsg[2]').destFieldsOnE1, ['sumRaxial', 'raxialSym'])
+ msgs_soma = self.soma.msgIn
+ msgs_dendrite1 = self.dendrite1.msgIn
+ msgs_dendrite2 = self.dendrite2.msgIn
+
+ self.assertEqual(msgs_soma[3].e1.name, self.dendrite1.name)
+ self.assertEqual(msgs_dendrite1[3].e1.name, self.dendrite2.name)
+ self.assertEqual(msgs_dendrite2[3].e1.name, self.spine1.name)
def test_capacitance(self):
From bd19801578447ad03e833aefd39781007002251c Mon Sep 17 00:00:00 2001
From: analkumar2
Date: Sat, 4 Jun 2022 01:47:46 +0530
Subject: [PATCH 16/18] Corrected eqn to calculate Ra
---
python/moose/neuroml2/reader.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/python/moose/neuroml2/reader.py b/python/moose/neuroml2/reader.py
index 0f13a171c8..9490a61b7d 100644
--- a/python/moose/neuroml2/reader.py
+++ b/python/moose/neuroml2/reader.py
@@ -124,7 +124,7 @@ def setRa(comp, resistivity):
if comp.length > 0:
comp.Ra = resistivity * comp.length / xarea(comp)
else:
- comp.Ra = resistivity * 8.0 / (comp.diameter * np.pi)
+ comp.Ra = resistivity * 4.0 / (comp.diameter * np.pi)
def setRm(comp, condDensity):
"""Set membrane resistance"""
From 51129df9276030bbe5edf15763352b32708d20ae Mon Sep 17 00:00:00 2001
From: Anal Kumar
Date: Sat, 4 Jun 2022 03:16:46 +0530
Subject: [PATCH 17/18] passiveCell.nml tested
---
python/moose/neuroml2/test_reader3.py | 92 +++++++++++++++++++++++++++
1 file changed, 92 insertions(+)
create mode 100644 python/moose/neuroml2/test_reader3.py
diff --git a/python/moose/neuroml2/test_reader3.py b/python/moose/neuroml2/test_reader3.py
new file mode 100644
index 0000000000..9997a183f9
--- /dev/null
+++ b/python/moose/neuroml2/test_reader3.py
@@ -0,0 +1,92 @@
+# -*- coding: utf-8 -*-
+# test_reader.py ---
+#
+# Filename: test_reader3.py
+# Description:
+# Author: Anal Kumar
+# Maintainer:
+# Version:
+# URL:
+# Keywords:
+# Compatibility:
+#
+#
+
+# Commentary:
+#
+#
+#
+#
+
+# Change log:
+#
+#
+#
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 3, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+# Floor, Boston, MA 02110-1301, USA.
+#
+#
+
+# Code:
+
+from __future__ import print_function
+import unittest
+import moose
+from reader import NML2Reader
+import neuroml as nml
+import os
+import numpy as np
+
+'''
+Manually calculated the Vm curve given the parameters in the test_files/passiveCell.nml file. Based on the curve, the follwing are tested:
+first element should be almostequal to -66.6mV
+Average of the last 100ms should be -54.3mV
+Ra should be 21409.5
+steady state value of Vm between 0.090 to 0.100s is -0.02761+-0.0002
+Vm at 0.0533s is -0.03725 (at 1 tau time)
+'''
+
+class TestPassiveCell(unittest.TestCase):
+ def setUp(self):
+ if '/library' in moose.le():
+ moose.delete('/library')
+ self.reader = NML2Reader(verbose=True)
+ self.lib = moose.Neutral('/library')
+ self.filename = os.path.realpath('test_files/passiveCell.nml')
+ self.reader.read(self.filename)
+ self.mcell = moose.element('/library/pop0/0')
+ self.soma = moose.element(self.mcell.path + '/soma')
+ if not moose.exists('vmtab'):
+ self.vmtab = moose.Table('vmtab')
+ moose.connect(self.vmtab, 'requestOut', self.soma, 'getVm')
+ moose.reinit()
+ moose.start(300e-3)
+ self.t = np.linspace(0, 300e-3, len(self.vmtab.vector))
+
+ def test_currentinj(self):
+ self.assertAlmostEqual(self.vmtab.vector[0], -66.6e-3, delta=0.5e-3)
+ self.assertAlmostEqual(np.mean(self.vmtab.vector[self.t>=200e-3]), -54.3e-3, delta=0.5e-3)
+ self.assertAlmostEqual(self.soma.Ra, 21409.5, delta=500)
+ self.assertAlmostEqual(np.mean(self.vmtab.vector[(self.t>=90e-3) & (self.t<100e-3)]), -0.0276, delta=0.5e-3)
+ self.assertAlmostEqual(self.vmtab.vector[np.argmin(np.abs(self.t-0.0533))], -0.03725, delta=0.5e-3)
+
+
+if __name__ == '__main__':
+ unittest.main()
+ #p = TestPassiveCell()
+
+#
+# test_reader.py ends here
From 7cea73c3b1a3ae8b22a1ab337f341f3774b923be Mon Sep 17 00:00:00 2001
From: Anal Kumar
Date: Sat, 11 Jun 2022 01:55:06 +0530
Subject: [PATCH 18/18] tests single compartment firing neuroml2 cell
---
python/moose/neuroml2/test_reader4.py | 96 +++++++++++++++++++++++++++
1 file changed, 96 insertions(+)
create mode 100644 python/moose/neuroml2/test_reader4.py
diff --git a/python/moose/neuroml2/test_reader4.py b/python/moose/neuroml2/test_reader4.py
new file mode 100644
index 0000000000..99ae18f250
--- /dev/null
+++ b/python/moose/neuroml2/test_reader4.py
@@ -0,0 +1,96 @@
+# -*- coding: utf-8 -*-
+# test_reader.py ---
+#
+# Filename: test_reader.py
+# Description:
+# Author:
+# Maintainer:
+# Created: Wed Jul 24 16:02:21 2013 (+0530)
+# Version:
+# Last-Updated: Sun Apr 17 16:13:01 2016 (-0400)
+# By: subha
+# Update #: 112
+# URL:
+# Keywords:
+# Compatibility:
+#
+#
+
+# Commentary:
+#
+#
+#
+#
+
+# Change log:
+#
+#
+#
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 3, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+# Floor, Boston, MA 02110-1301, USA.
+#
+#
+
+# Code:
+
+from __future__ import print_function
+import unittest
+import numpy as np
+import moose
+import neuroml as nml
+from reader import NML2Reader
+import os
+import numpy as np
+import matplotlib.pyplot as plt
+from scipy.signal import find_peaks
+
+class TestFullCell(unittest.TestCase):
+ def setUp(self):
+ if '/library' in moose.le():
+ moose.delete('/library')
+ self.reader = NML2Reader(verbose=True)
+
+ self.lib = moose.Neutral('/library')
+ self.filename = os.path.realpath('test_files/NML2_SingleCompHHCell.nml')
+ self.reader.read(self.filename)
+ self.soma = moose.element('library/hhpop/0/soma')
+
+ if not moose.exists('vmtab'):
+ self.vmtab = moose.Table('vmtab')
+ moose.connect(self.vmtab, 'requestOut', self.soma, 'getVm')
+ moose.reinit()
+ moose.start(300e-3)
+ self.t = np.linspace(0, 300e-3, len(self.vmtab.vector))
+
+ def test_currentinj(self):
+ # self.assertAlmostEqual(self.vmtab.vector[0], -66.6e-3, delta=0.5e-3)
+ # self.assertAlmostEqual(np.mean(self.vmtab.vector[self.t>=200e-3]), -54.3e-3, delta=0.5e-3)
+ # self.assertAlmostEqual(self.soma.Ra, 21409.5, delta=500)
+ # self.assertAlmostEqual(np.mean(self.vmtab.vector[(self.t>=90e-3) & (self.t<100e-3)]), -0.0276, delta=0.5e-3)
+ # self.assertAlmostEqual(self.vmtab.vector[np.argmin(np.abs(self.t-0.0533))], -0.03725, delta=0.5e-3)
+ peaks, peaks_dict = find_peaks(self.vmtab.vector, height=0)
+ act_peaks = [0.1024, 0.1186, 0.1346, 0.1507, 0.1667, 0.1827, 0.1987]
+ act_peaks_height = [0.03985157, 0.03131845, 0.03058362, 0.0305823 , 0.03078506, 0.03095396, 0.03086463]
+ self.assertEqual(len(peaks), len(act_peaks))
+ for i in range(len(act_peaks)):
+ self.assertAlmostEqual(self.t[peaks][i], act_peaks[i], delta=1e-3)
+ self.assertAlmostEqual(self.vmtab.vector[peaks][i], act_peaks_height[i], delta=5e-3)
+
+if __name__ == '__main__':
+ unittest.main()
+
+#
+# test_reader.py ends here