/bluepyopt/ephys/simulators.py

https://github.com/BlueBrain/BluePyOpt · Python · 164 lines · 156 code · 6 blank · 2 comment · 0 complexity · dad290bb838afcf958982e4cb6137e81 MD5 · raw file

  1. """Simulator classes"""
  2. # pylint: disable=W0511
  3. import os
  4. import logging
  5. import imp
  6. import ctypes
  7. import platform
  8. import warnings
  9. logger = logging.getLogger(__name__)
  10. class NrnSimulator(object):
  11. """Neuron simulator"""
  12. def __init__(self, dt=None, cvode_active=True, cvode_minstep=None,
  13. random123_globalindex=None):
  14. """Constructor"""
  15. if platform.system() == 'Windows':
  16. # hoc.so does not exist on NEURON Windows
  17. # although \\hoc.pyd can work here, it gives an error for
  18. # nrn_nobanner_ line
  19. self.disable_banner = False
  20. self.banner_disabled = False
  21. else:
  22. self.disable_banner = True
  23. self.banner_disabled = False
  24. self.neuron.h.load_file('stdrun.hoc')
  25. self.dt = dt if dt is not None else self.neuron.h.dt
  26. self.neuron.h.dt = self.dt
  27. self.neuron.h.cvode_active(1 if cvode_active else 0)
  28. self.cvode_minstep_value = cvode_minstep
  29. self.cvode_active = cvode_active
  30. self.random123_globalindex = random123_globalindex
  31. @property
  32. def cvode(self):
  33. """Return cvode instance"""
  34. return self.neuron.h.CVode()
  35. @property
  36. def cvode_minstep(self):
  37. """Return cvode minstep value"""
  38. return self.cvode.minstep()
  39. @cvode_minstep.setter
  40. def cvode_minstep(self, value):
  41. """Set cvode minstep value"""
  42. self.cvode.minstep(value)
  43. @staticmethod
  44. def _nrn_disable_banner():
  45. """Disable Neuron banner"""
  46. nrnpy_path = os.path.join(imp.find_module('neuron')[1])
  47. import glob
  48. hoc_so_list = \
  49. glob.glob(os.path.join(nrnpy_path, 'hoc*.so'))
  50. if len(hoc_so_list) != 1:
  51. warnings.warn('Unable to find Neuron hoc shared library in %s, '
  52. 'not disabling banner' % nrnpy_path)
  53. else:
  54. hoc_so = hoc_so_list[0]
  55. nrndll = ctypes.cdll[hoc_so]
  56. ctypes.c_int.in_dll(nrndll, 'nrn_nobanner_').value = 1
  57. # pylint: disable=R0201
  58. # TODO function below should probably a class property or something in that
  59. # sense
  60. @property
  61. def neuron(self):
  62. """Return neuron module"""
  63. if self.disable_banner and not self.banner_disabled:
  64. NrnSimulator._nrn_disable_banner()
  65. self.banner_disabled = True
  66. import neuron # NOQA
  67. return neuron
  68. def run(
  69. self,
  70. tstop=None,
  71. dt=None,
  72. cvode_active=None,
  73. random123_globalindex=None):
  74. """Run protocol"""
  75. self.neuron.h.tstop = tstop
  76. if cvode_active and dt is not None:
  77. raise ValueError(
  78. 'NrnSimulator: Impossible to combine the dt argument when '
  79. 'cvode_active is True in the NrnSimulator run method')
  80. if cvode_active is None:
  81. cvode_active = self.cvode_active
  82. if not cvode_active and dt is None: # use dt of simulator
  83. if self.neuron.h.dt != self.dt:
  84. raise Exception(
  85. 'NrnSimulator: Some process has changed the '
  86. 'time step dt of Neuron since the creation of this '
  87. 'NrnSimulator object. Not sure this is intended:\n'
  88. 'current dt: %.6g\n'
  89. 'init dt: %.6g' % (self.neuron.h.dt, self.dt))
  90. dt = self.dt
  91. self.neuron.h.cvode_active(1 if cvode_active else 0)
  92. if self.cvode_minstep_value is not None:
  93. save_minstep = self.cvode_minstep
  94. self.cvode_minstep = self.cvode_minstep_value
  95. if cvode_active:
  96. logger.debug('Running Neuron simulator %.6g ms, with cvode', tstop)
  97. else:
  98. self.neuron.h.dt = dt
  99. self.neuron.h.steps_per_ms = 1.0 / dt
  100. logger.debug(
  101. 'Running Neuron simulator %.6g ms, with dt=%r',
  102. tstop,
  103. dt)
  104. if random123_globalindex is None:
  105. random123_globalindex = self.random123_globalindex
  106. if random123_globalindex is not None:
  107. rng = self.neuron.h.Random()
  108. rng.Random123_globalindex(random123_globalindex)
  109. try:
  110. self.neuron.h.run()
  111. except Exception as e:
  112. raise NrnSimulatorException('Neuron simulator error', e)
  113. if self.cvode_minstep_value is not None:
  114. self.cvode_minstep = save_minstep
  115. logger.debug('Neuron simulation finished')
  116. class NrnSimulatorException(Exception):
  117. """All exception generated by Neuron simulator"""
  118. def __init__(self, message, original):
  119. """Constructor"""
  120. super(NrnSimulatorException, self).__init__(message)
  121. self.original = original