Source code for LFPy.templatecell
#!/usr/bin/env python
'''
Copyright (C) 2012 Computational Neuroscience Group, NMBU.
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 of the License, 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.
'''
import os
import neuron
import numpy as np
import pickle
from LFPy import Cell, RecExtElectrode
from LFPy.run_simulation import _run_simulation, _run_simulation_with_electrode
import sys
[docs]class TemplateCell(Cell):
'''
This class allow using cell templates with some limitations
Arguments:
::
morphology : [str]: path to morphology file;
templatefile : [str]: Cell template definition(s)
templatename : [str]: Cell template-name used for this cell object
templateargs : [str]: Arguments provided to template-definition
v_init: [-65.]: initial potential
passive: [True]/False: passive mechs are initialized if True
Ra: [150.]: axial resistance
rm: [30000]: membrane resistivity
cm: [1.0]: membrane capacitance
e_pas: [-65.]: passive mechanism reversal potential
extracellular: [True]/False: switch for NEURON's extracellular mechanism
timeres_NEURON: [0.1]: internal dt for NEURON simulation
timeres_python: [0.1]: overall dt for python simulation
tstartms: [0.]: initialization time for simulation <= 0 ms
tstopms: [100.]: stop time for simulation > 0 ms
nsegs_method: ['lambda100']/'lambda_f'/'fixed_length': nseg rule
max_nsegs_length: [None]: max segment length for method 'fixed_length'
lambda_f: [100]: AC frequency for method 'lambda_f'
delete_sections: [True]: delete pre-existing section-references
custom_code: [None]: list of model-specific code files ([.py/.hoc])
custom_fun: [None]: list of model-specific functions with args
custom_fun_args: [None]: list of args passed to custom_fun functions
pt3d: True/[False]: use pt3d-info of the cell geometries switch
verbose: True/[False]: verbose output switch
Usage of TemplateCell class:
::
import LFPy
cellParameters = {
'morphology' : 'path/to/morphology',
'templatefile' : 'path/to/template-file (.hoc)
'templatename' : 'templatename'
'templateargs' : None
'rm' : 30000,
'cm' : 1.0,
'Ra' : 150,
'timeres_NEURON' : 0.1,
'timeres_python' : 0.1,
'tstartms' : -50,
'tstopms' : 50,
}
cell = LFPy.TemplateCell(**cellParameters)
cell.simulate()
'''
def __init__(self,
templatefile='LFPyCellTemplate.hoc',
templatename='LFPyCellTemplate',
templateargs=None,
**kwargs):
'''
Initialization of the Cell object.
Arguments:
::
templatefile : Cell template definition(s)
templatename : Cell template-name used for this cell object
templateargs : Arguments provided to template-definition
**kwargs : See docstring of LFPy.Cell
'''
self.templatefile = templatefile
self.templatename = templatename
self.templateargs = templateargs
if not hasattr(neuron.h, 'd_lambda'):
neuron.h.load_file('stdlib.hoc', 'String') #NEURON std. library
neuron.h.load_file('import3d.hoc') #import 3D morphology lib
#load the cell template specification
#check if templatename exist in neuron.h namespace:
if hasattr(neuron.h, self.templatename):
print('template %s exist already' % self.templatename)
else:
if type(self.templatefile) == str:
neuron.h.load_file(self.templatefile)
elif type(self.templatefile) == list:
for template in self.templatefile:
neuron.h.load_file(template)
#initialize the cell object
Cell.__init__(self, **kwargs)
def _load_geometry(self):
'''Load the morphology-file in NEURON'''
try:
neuron.h.sec_counted = 0
except LookupError:
neuron.h('sec_counted = 0')
#the python cell object we are loading the morphology into:
celltemplate = getattr(neuron.h, self.templatename)
self.cell = celltemplate(self.templateargs)
#self.cell = getattr(neuron.h, self.templatename)(self.templateargs)
#perform a test if the morphology is already loaded:
seccount = 0
for sec in self.cell.all:
seccount += 1
if seccount == 0:
#import the morphology, try and determine format
fileEnding = self.morphology.split('.')[-1]
if not fileEnding == 'hoc' or fileEnding == 'HOC':
#create objects for importing morphologies of different formats
if fileEnding == 'asc' or fileEnding == 'ASC':
Import = neuron.h.Import3d_Neurolucida3()
if not self.verbose:
Import.quiet = 1
elif fileEnding == 'swc' or fileEnding == 'SWC':
Import = neuron.h.Import3d_SWC_read()
elif fileEnding == 'xml' or fileEnding == 'XML':
Import = neuron.h.Import3d_MorphML()
else:
raise ValueError('%s is not a recognised morphology file format! ').with_traceback('Should be either .hoc, .asc, .swc, .xml!' \
% self.morphology)
#assuming now that morphology file is the correct format
try:
Import.input(self.morphology)
except:
if not hasattr(neuron, 'neuroml'):
raise Exception('Can not import, try and copy the ' + \
'nrn/share/lib/python/neuron/neuroml ' + \
'folder into %s' % neuron.__path__[0])
else:
raise Exception('something wrong with file, see output')
try:
imprt = neuron.h.Import3d_GUI(Import, 0)
except:
raise Exception('See output, try to correct the file')
#instantiate the cell object
if fileEnding == 'xml' or fileEnding == 'XML':
#can not currently assign xml to cell template
try:
imprt.instantiate(self.cell)
except:
raise Exception("this xml file is not supported")
else:
imprt.instantiate(self.cell)
else:
neuron.h.execute("xopen(\"%s\")" % self.morphology, self.cell)
#neuron.h.load_file(1, self.morphology)
#set shapes and create sectionlists
neuron.h.define_shape()
self._create_sectionlists()
def _create_sectionlists(self):
'''Create section lists for different kinds of sections'''
#list with all sections
#test if list self.cell.all is not empty
numsec = 0
for sec in self.cell.all:
numsec += 1
if numsec > 0:
self.allsecnames = []
for sec in self.cell.all:
self.allsecnames.append(sec.name())
#hotpatching the allseclist!!!
self.allseclist = self.cell.all
#list of soma sections, assuming it is named on the format "soma*"
self.nsomasec = 0
self.somalist = neuron.h.SectionList()
for sec in self.cell.all:
if sec.name().find('soma') >= 0:
self.somalist.append(sec=sec)
self.nsomasec += 1
else:
self.allsecnames = []
for sec in self.cell.allsec():
self.allsecnames.append(sec.name())
self.allseclist = neuron.h.SectionList()
for sec in self.cell.allsec():
self.allseclist.append(sec=sec)
#list of soma sections, assuming it is named on the format "soma*"
self.nsomasec = 0
self.somalist = neuron.h.SectionList()
for sec in self.cell.allsec():
if sec.name().find('soma') >= 0:
self.somalist.append(sec=sec)
self.nsomasec += 1
def _update_pt3d(self):
'''
update the locations in neuron.hoc.space using neuron.h.pt3dchange()
'''
for i, sec in enumerate(self.allseclist):
n3d = int(neuron.h.n3d())
for n in range(n3d):
neuron.h.pt3dchange(n,
self.x3d[i][n],
self.y3d[i][n],
self.z3d[i][n],
self.diam3d[i][n])
#let NEURON know about the changes we just did:
neuron.h.define_shape()
#must recollect the geometry, otherwise we get roundoff errors!
self._collect_geometry()