/bluepyopt/ephys/simulators.py
https://github.com/BlueBrain/BluePyOpt · Python · 164 lines · 156 code · 6 blank · 2 comment · 0 complexity · dad290bb838afcf958982e4cb6137e81 MD5 · raw file
- """Simulator classes"""
- # pylint: disable=W0511
- import os
- import logging
- import imp
- import ctypes
- import platform
- import warnings
- logger = logging.getLogger(__name__)
- class NrnSimulator(object):
- """Neuron simulator"""
- def __init__(self, dt=None, cvode_active=True, cvode_minstep=None,
- random123_globalindex=None):
- """Constructor"""
- if platform.system() == 'Windows':
- # hoc.so does not exist on NEURON Windows
- # although \\hoc.pyd can work here, it gives an error for
- # nrn_nobanner_ line
- self.disable_banner = False
- self.banner_disabled = False
- else:
- self.disable_banner = True
- self.banner_disabled = False
- self.neuron.h.load_file('stdrun.hoc')
- self.dt = dt if dt is not None else self.neuron.h.dt
- self.neuron.h.dt = self.dt
- self.neuron.h.cvode_active(1 if cvode_active else 0)
- self.cvode_minstep_value = cvode_minstep
- self.cvode_active = cvode_active
- self.random123_globalindex = random123_globalindex
- @property
- def cvode(self):
- """Return cvode instance"""
- return self.neuron.h.CVode()
- @property
- def cvode_minstep(self):
- """Return cvode minstep value"""
- return self.cvode.minstep()
- @cvode_minstep.setter
- def cvode_minstep(self, value):
- """Set cvode minstep value"""
- self.cvode.minstep(value)
- @staticmethod
- def _nrn_disable_banner():
- """Disable Neuron banner"""
- nrnpy_path = os.path.join(imp.find_module('neuron')[1])
- import glob
- hoc_so_list = \
- glob.glob(os.path.join(nrnpy_path, 'hoc*.so'))
- if len(hoc_so_list) != 1:
- warnings.warn('Unable to find Neuron hoc shared library in %s, '
- 'not disabling banner' % nrnpy_path)
- else:
- hoc_so = hoc_so_list[0]
- nrndll = ctypes.cdll[hoc_so]
- ctypes.c_int.in_dll(nrndll, 'nrn_nobanner_').value = 1
- # pylint: disable=R0201
- # TODO function below should probably a class property or something in that
- # sense
- @property
- def neuron(self):
- """Return neuron module"""
- if self.disable_banner and not self.banner_disabled:
- NrnSimulator._nrn_disable_banner()
- self.banner_disabled = True
- import neuron # NOQA
- return neuron
- def run(
- self,
- tstop=None,
- dt=None,
- cvode_active=None,
- random123_globalindex=None):
- """Run protocol"""
- self.neuron.h.tstop = tstop
- if cvode_active and dt is not None:
- raise ValueError(
- 'NrnSimulator: Impossible to combine the dt argument when '
- 'cvode_active is True in the NrnSimulator run method')
- if cvode_active is None:
- cvode_active = self.cvode_active
- if not cvode_active and dt is None: # use dt of simulator
- if self.neuron.h.dt != self.dt:
- raise Exception(
- 'NrnSimulator: Some process has changed the '
- 'time step dt of Neuron since the creation of this '
- 'NrnSimulator object. Not sure this is intended:\n'
- 'current dt: %.6g\n'
- 'init dt: %.6g' % (self.neuron.h.dt, self.dt))
- dt = self.dt
- self.neuron.h.cvode_active(1 if cvode_active else 0)
- if self.cvode_minstep_value is not None:
- save_minstep = self.cvode_minstep
- self.cvode_minstep = self.cvode_minstep_value
- if cvode_active:
- logger.debug('Running Neuron simulator %.6g ms, with cvode', tstop)
- else:
- self.neuron.h.dt = dt
- self.neuron.h.steps_per_ms = 1.0 / dt
- logger.debug(
- 'Running Neuron simulator %.6g ms, with dt=%r',
- tstop,
- dt)
- if random123_globalindex is None:
- random123_globalindex = self.random123_globalindex
- if random123_globalindex is not None:
- rng = self.neuron.h.Random()
- rng.Random123_globalindex(random123_globalindex)
- try:
- self.neuron.h.run()
- except Exception as e:
- raise NrnSimulatorException('Neuron simulator error', e)
- if self.cvode_minstep_value is not None:
- self.cvode_minstep = save_minstep
- logger.debug('Neuron simulation finished')
- class NrnSimulatorException(Exception):
- """All exception generated by Neuron simulator"""
- def __init__(self, message, original):
- """Constructor"""
- super(NrnSimulatorException, self).__init__(message)
- self.original = original