Ran update_copyright.py.
[hooke.git] / hooke / curve.py
index bc8138a0ade467b782466131014fe7171888d83d..4e8fbbf915ecf0d87cc549cc0ba96d15ef8954c6 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2010 W. Trevor King <wking@drexel.edu>
+# Copyright (C) 2010-2012 W. Trevor King <wking@drexel.edu>
 #
 # This file is part of Hooke.
 #
@@ -28,7 +28,6 @@ import os.path
 import numpy
 
 from .command_stack import CommandStack
-from . import experiment
 
 
 class NotRecognized (ValueError):
@@ -93,10 +92,14 @@ class Data (numpy.ndarray):
     The data-type is also YAMLable (see :mod:`hooke.util.yaml`).
 
     >>> import yaml
-    >>> print yaml.dump(d)
+    >>> s = yaml.dump(d)
+    >>> print s
     !hooke.curve.DataInfo
     columns: [distance (m), force (N)]
     <BLANKLINE>
+    >>> z = yaml.load(s)
+    >>> z
+    Data([], shape=(0, 0), dtype=float32)
     """
     def __new__(subtype, shape, dtype=numpy.float, buffer=None, offset=0,
                 strides=None, order=None, info=None):
@@ -156,23 +159,14 @@ class Curve (object):
     would consist of the approach data and the retract data.  Metadata
     would be the temperature, cantilever spring constant, etc.
 
-    Two important :attr:`info` settings are `filetype` and
-    `experiment`.  These are two strings that can be used by Hooke
-    commands/plugins to understand what they are looking at.
-
-    * :attr:`info['filetype']` should contain the name of the exact
-      filetype defined by the driver (so that filetype-speciofic
-      commands can know if they're dealing with the correct filetype).
-    * :attr:`info['experiment']` should contain an instance of a
-      :class:`hooke.experiment.Experiment` subclass to identify the
-      experiment type.  For example, various
-      :class:`hooke.driver.Driver`\s can read in force-clamp data, but
-      Hooke commands could like to know if they're looking at force
-      clamp data, regardless of their origin.
+    Each :class:`Data` block in :attr:`data` must contain an
+    :attr:`info['name']` setting with a unique (for the parent
+    curve) name identifying the data block.  This allows plugins 
+    and commands to access individual blocks.
 
-    Another important attribute is :attr:`command_stack`, which holds
-    a :class:`~hooke.command_stack.CommandStack` listing the commands
-    that have been applied to the `Curve` since loading.
+    Each curve maintiains a :class:`~hooke.command_stack.CommandStack`
+    (:attr:`command_stack`) listing the commands that have been
+    applied to the `Curve` since loading.
 
     The data-type is pickleable, to ensure we can move it between
     processes with :class:`multiprocessing.Queue`\s.
@@ -247,6 +241,8 @@ class Curve (object):
         return self.__str__()
 
     def set_path(self, path):
+        if path != None:
+            path = os.path.expanduser(path)
         self.path = path
         if self.name == None and path != None:
             self.name = os.path.basename(path)
@@ -292,7 +288,12 @@ class Curve (object):
         >>> class Hooke (object):
         ...     pass
         >>> h = Hooke()
+        >>> d = Data(shape=(3,2), info={'columns':['distance (m)', 'force (N)']})
+        >>> for i in range(3): # initialize d
+        ...    for j in range(2):
+        ...        d[i,j] = i*10 + j
         >>> c = Curve(None)
+        >>> c.data = [d]
         >>> c.set_hooke(h)
         >>> c._hooke  # doctest: +ELLIPSIS
         <hooke.curve.Hooke object at 0x...>
@@ -303,6 +304,14 @@ class Curve (object):
         <hooke.curve.Hooke object at 0x...>
         >>> c2._hooke == h
         True
+        >>> c2.data
+        [Data([[  0.,   1.],
+               [ 10.,  11.],
+               [ 20.,  21.]])]
+        >>> d.info
+        {'columns': ['distance (m)', 'force (N)']}
+        >>> id(c2.data[0]) == id(d)
+        True
         """
         copier = _copy_dispatch.get(type(self))
         if copier:
@@ -328,7 +337,12 @@ class Curve (object):
         >>> class Hooke (object):
         ...     pass
         >>> h = Hooke()
+        >>> d = Data(shape=(3,2), info={'columns':['distance (m)', 'force (N)']})
+        >>> for i in range(3): # initialize d
+        ...    for j in range(2):
+        ...        d[i,j] = i*10 + j
         >>> c = Curve(None)
+        >>> c.data = [d]
         >>> c.set_hooke(h)
         >>> c._hooke  # doctest: +ELLIPSIS
         <hooke.curve.Hooke object at 0x...>
@@ -339,6 +353,14 @@ class Curve (object):
         <hooke.curve.Hooke object at 0x...>
         >>> c2._hooke == h
         True
+        >>> c2.data
+        [Data([[  0.,   1.],
+               [ 10.,  11.],
+               [ 20.,  21.]])]
+        >>> d.info
+        {'columns': ['distance (m)', 'force (N)']}
+        >>> id(c2.data[0]) == id(d)
+        False
         """
         reductor = dispatch_table.get(type(self))
         if reductor: