import numpy
from .command_stack import CommandStack
+from . import experiment
class NotRecognized (ValueError):
dc = state['command_stack']
if hasattr(dc, '__getstate__'):
state['command_stack'] = dc.__getstate__()
+ if self.info.get('experiment', None) != None:
+ e = self.info['experiment']
+ assert isinstance(e, experiment.Experiment)
+ # HACK? require Experiment classes to be defined in the
+ # experiment module.
+ self.info['experiment'] = e.__class__.__name__
return state
def __setstate__(self, state):
if key == 'path':
self.set_path(value)
continue
+ elif key == 'info':
+ if 'experiment' not in value:
+ value['experiment'] = None
+ else:
+ # HACK? require Experiment classes to be defined in the
+ # experiment module.
+ cls = getattr(experiment, value['experiment'])
+ value['experiment'] = cls()
elif key == 'command_stack':
v = CommandStack()
v.__setstate__(value)
ret[:,0] = numpy.arange(0, 1e-3*data.shape[0], 1e-3, dtype=ret.dtype)
file_info['filetype'] = self.name
- file_info['experiment'] = experiment.ForceClamp
+ file_info['experiment'] = experiment.ForceClamp()
return ([ret,], file_info)
# and velocity clamp segments in a single experiment), but I
# have no idea what sort of analysis such experiments would
# require ;).
- info['experiment'] = experiment.VelocityClamp
+ info['experiment'] = experiment.VelocityClamp()
force_unit = chan_info['channel']['vDeflection']['conversion-set']['conversion']['force']['scaling']['unit']['unit']
assert force_unit == 'N', force_unit
force_base = chan_info['channel']['vDeflection']['conversion-set']['conversion']['force']['base-calibration-slot']
data,bin_info,wave_info = loadibw(path)
blocks,info = self._translate_ibw(data, bin_info, wave_info)
info['filetype'] = self.name
- info['experiment'] = experiment.VelocityClamp
+ info['experiment'] = experiment.VelocityClamp()
return (blocks, info)
def _translate_ibw(self, data, bin_info, wave_info):
self._check_version(info)
data = self._read_data_path(path, info)
info['filetype'] = self.name
- info['experiment'] = experiment.VelocityClamp
+ info['experiment'] = experiment.VelocityClamp()
return (data, info)
def _read_header_path(self, path):
f.close() # remember to close the file
data = curve.Data()
- info = {'filetype':'tutorial', 'experiment':experiment.Experiment}
+ info = {'filetype':'tutorial', 'experiment':experiment.Experiment()}
return (data, info)
unlabeled_approach_data, params, 'approach')
retract = self._scale_block(
unlabeled_retract_data, params, 'retract')
- info = {'filetype':self.name, 'experiment':experiment.VelocityClamp}
+ info = {'filetype':self.name, 'experiment':experiment.VelocityClamp()}
return ([approach, retract], info)
def _paths(self, path):
experiments they can handle.
"""
-class Experiment (object):
+from .util.singleton import Singleton
+
+
+class Experiment (Singleton):
"""Base class for experiment classification.
"""
pass
--- /dev/null
+# Copyright
+
+"""Define the :class:`Singleton` class.
+
+>>> class A (Singleton):
+... def init(self):
+... print 'initializing instance of %s at (%s)' % (
+... self.__class__.__name__, id(self))
+
+>>> A_instances = [A() for i in range(3)] # doctest: +ELLIPSIS
+initializing instance of A at (...)
+>>> for i in A_instances[1:]:
+... print id(i) == id(A_instances[0])
+True
+True
+
+Singletons can also be subclassed.
+
+>>> class B (A):
+... pass
+>>> B_instances = [B() for i in range(3)] # doctest: +ELLIPSIS
+initializing instance of B at (...)
+>>> for i in B_instances[1:]:
+... print id(i) == id(B_instances[0])
+True
+True
+>>> id(A_instances[0]) == id(B_instances[0])
+False
+"""
+
+class Singleton (object):
+ """A singleton class.
+
+ To create a singleton class, you subclass from Singleton; each
+ subclass will have a single instance, no matter how many times its
+ constructor is called. To further initialize the subclass
+ instance, subclasses should override 'init' instead of __init__ -
+ the __init__ method is called each time the constructor is called.
+
+ Notes
+ -----
+ Original implementation from Guido van Rossum's
+ `Unifying types and classes in Python 2.2`_.
+
+ .. Unifying types and classes in Python 2.2:
+ http://www.python.org/download/releases/2.2.3/descrintro/#__new__
+ """
+ def __new__(cls, *args, **kwds):
+ it = cls.__dict__.get('__it__')
+ if it is not None:
+ return it
+ cls.__it__ = it = object.__new__(cls)
+ it.init(*args, **kwds)
+ return it
+
+ def init(self, *args, **kwds):
+ pass