# -*- coding: utf-8 -*-
from __future__ import print_function
try:
from future_builtins import zip
except ImportError:
pass
from . import moose as _moose
_tick = 8
_base = '/_utils'
_path = _base + '/y{0}'
_counter = 0
_plots = []
_moose.Neutral( _base )
_defaultFields = {
_moose.Compartment : 'Vm',
_moose.ZombieCompartment : 'Vm',
_moose.HHChannel: 'Gk',
_moose.ZombieHHChannel: 'Gk',
_moose.HHChannel2D: 'Gk',
_moose.SynChan: 'Gk',
_moose.CaConc: 'Ca',
_moose.ZombieCaConc: 'Ca',
_moose.Pool: 'conc',
_moose.ZombiePool: 'conc',
_moose.ZPool: 'conc',
_moose.BufPool: 'conc',
_moose.ZombieBufPool: 'conc',
_moose.ZBufPool: 'conc',
_moose.FuncPool: 'conc',
_moose.ZombieFuncPool: 'conc',
_moose.ZFuncPool: 'conc',
}
def _defaultField( obj ):
return _defaultFields[ type( obj ) ]
def setDt( dt ):
'''-----------
Description
-----------
Sets time-step for recording values.
---------
Arguments
---------
dt: Time-step for recording values.
-------
Returns
-------
Nothing.'''
_moose.setClock( _tick, dt )
class SetupError( Exception ):
pass
def _time( npoints = None ):
import numpy
if npoints is None:
try:
npoints = len( _plots[ 0 ].vec )
except IndexError:
raise SetupError(
'List of time-points cannot be constructed because '
'no plots have been set up yet.'
)
begin = 0.0
end = _moose.Clock( '/clock' ).currentTime
return numpy.linspace( begin, end, npoints )
class _Plot( _moose.Table ):
def __init__( self, path, obj, field, label ):
_moose.Table.__init__( self, path )
self._table = _moose.Table( path )
self.obj = obj
self.field = field
self.label = label
@property
def values( self ):
return self._table.vec
@property
def size( self ):
return len( self.values )
@property
def time( self ):
return _time( self.size )
def __iter__( self ):
return iter( self.values )
def record( obj, field = None, label = None ):
'''
'''
global _counter
# Checking if object is an iterable like list or a tuple, but not a string.
if hasattr( obj, '__iter__' ):
return [ record( o, field, label ) for o in obj ]
if isinstance( obj, str ):
obj = _moose.element( obj )
if field is None:
field = _defaultField( obj )
path = _path.format( _counter )
_counter += 1
p = _Plot( path, obj, field, label )
_plots.append( p )
_moose.connect( p, "requestData", obj, 'get_' + field )
_moose.useClock( _tick, path, "process" )
return p
def _label( plot, labelFormat = '{path}.{field}' ):
# Over-ride label format if label has been given explicitly.
if plot.label:
labelFormat = plot.label
return labelFormat.format(
path = plot.obj.path,
name = plot.obj.name,
field = plot.field
)
def _selectedPlots( selected ):
if selected is None:
# Returning a copy of this list, instead of reference. The returned
# list will be manipulated later.
return _plots[ : ]
elif isinstance( selected, _Plot ):
return [ selected ]
else:
return selected
def saveCSV(
fileName,
selected = None,
delimiter = '\t',
header = True,
headerCommentCharacter = '#',
labelFormat = '{path}.{field}',
timeCol = True,
timeHeader = 'Time',
fileMode = 'w' ):
'''
'''
import csv
plots = _selectedPlots( selected )
if header:
header = []
if timeCol:
header.append( timeHeader )
for plot in plots:
header.append( _label( plot, labelFormat ) )
header[ 0 ] = headerCommentCharacter + header[ 0 ]
if timeCol:
plots.insert( 0, _time() )
with open( fileName, fileMode ) as fout:
writer = csv.writer( fout, delimiter = delimiter )
if header:
writer.writerow( header )
writer.writerows( list(zip( *plots )) )
def saveXPLOT(
fileName,
selected = None,
labelFormat = '{path}.{field}',
fileMode = 'w' ):
'''
'''
plots = _selectedPlots( selected )
with open( fileName, fileMode ) as fout:
write = lambda line: fout.write( line + '\n' )
for ( i, plot ) in enumerate( plots ):
label = '/plotname ' + _label( plot, labelFormat )
if i > 0:
write( '' )
write( '/newplot' )
write( label )
for value in plot:
write( str( value ) )
def show(
selected = None,
combine = True,
labelFormat = '{path}.{field}',
xLabel = 'Time (s)',
yLabel = '{field}' ):
'''
'''
try:
from matplotlib import pyplot as plt
except ImportError:
print("Warning: recording.show(): Cannot find 'matplotlib'. Not showing plots.")
return
plots = _selectedPlots( selected )
if combine:
plt.figure()
for plot in plots:
if not combine:
plt.figure()
print(_label(plot))
plt.plot( plot.time, plot.values, label = _label( plot ) )
plt.legend()
plt.show()
def HDF5():
pass