Add wtk driver for W. Trevor King's velocity clamp data format.
[hooke.git] / hooke / driver / __init__.py
1 # Copyright (C) 2010 W. Trevor King <wking@drexel.edu>
2 #
3 # This file is part of Hooke.
4 #
5 # Hooke is free software: you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation, either
8 # version 3 of the License, or (at your option) any later version.
9 #
10 # Hooke is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU Lesser General Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with Hooke.  If not, see
17 # <http://www.gnu.org/licenses/>.
18
19 """The driver module provides :class:`Driver`\s for identifying and
20 reading data files.
21
22 This allows Hooke to be data-file agnostic.  Drivers for various
23 commercial force spectroscopy microscopes are provided, and it's easy
24 to write your own to handle your lab's specific format.
25 """
26
27 from ..config import Setting
28 from ..util.pluggable import IsSubclass, construct_graph
29
30
31 DRIVER_MODULES = [
32 #    ('csvdriver', True),
33 #    ('hdf5', True),
34 #    ('hemingclamp', True),
35 #    ('jpk', True),
36 #    ('mcs', True),
37 #    ('mfp1dexport', True),
38 #    ('mfp3d', True),
39     ('picoforce', True),
40 #    ('picoforcealt', True),
41     ('tutorial', True),
42     ('wtk', True),
43 ]
44 """List of driver modules and whether they should be included by
45 default.  TODO: autodiscovery
46 """
47
48 DRIVER_SETTING_SECTION = 'drivers'
49 """Name of the config section which controls driver selection.
50 """
51
52
53 class Driver(object):
54     """Base class for file format drivers.
55     
56     :attr:`name` identifies your driver, and should match the module
57     name.
58     """
59     def __init__(self, name):
60         self.name = name
61         self.setting_section = '%s driver' % self.name
62
63     def dependencies(self):
64         """Return a list of :class:`Driver`\s we require."""
65         return []
66
67     def default_settings(self):
68         """Return a list of :class:`hooke.config.Setting`\s for any
69         configurable driver settings.
70
71         The suggested section setting is::
72
73             Setting(section=self.setting_section, help=self.__doc__)
74         """
75         return []
76
77     def is_me(self, path):
78         """Read the file and return True if the filetype can be
79         managed by the driver.  Otherwise return False.
80         """
81         return False
82
83     def read(self, path):
84         """Read data from `path` and return a
85         ([:class:`hooke.curve.Data`, ...], `info`) tuple.
86
87         The `info` :class:`dict` must contain values for the keys:
88         'filetype' and 'experiment'.  See :class:`hooke.curve.Curve`
89         for details.
90         """
91         raise NotImplementedError
92
93 # Construct driver dependency graph and load default drivers.
94
95 DRIVER_GRAPH = construct_graph(
96     this_modname=__name__,
97     submodnames=[name for name,include in DRIVER_MODULES],
98     class_selector=IsSubclass(Driver, blacklist=[Driver]))
99 """Topologically sorted list of all possible :class:`Driver`\s.
100 """
101
102 def default_settings():
103     settings = [Setting(DRIVER_SETTING_SECTION,
104                         help='Enable/disable default drivers.')]
105     for dnode in DRIVER_GRAPH:
106         driver = dnode.data
107         default_include = [di for mod_name,di in DRIVER_MODULES
108                            if mod_name == driver.name][0]
109         help = driver.__doc__.split('\n', 1)[0]
110         settings.append(Setting(
111                 section=DRIVER_SETTING_SECTION,
112                 option=driver.name,
113                 value=str(default_include),
114                 help=help,
115                 ))
116     for dnode in DRIVER_GRAPH:
117         driver = dnode.data
118         settings.extend(driver.default_settings())
119     return settings