b1ba57f6312918847cb5c1e4712e62ccfb0c3c59
[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     ('tutorial', True),
41     ('wtk', True),
42 ]
43 """List of driver modules and whether they should be included by
44 default.  TODO: autodiscovery
45 """
46
47 DRIVER_SETTING_SECTION = 'drivers'
48 """Name of the config section which controls driver selection.
49 """
50
51
52 class Driver(object):
53     """Base class for file format drivers.
54     
55     :attr:`name` identifies your driver, and should match the module
56     name.
57     """
58     def __init__(self, name):
59         self.name = name
60         self.setting_section = '%s driver' % self.name
61
62     def dependencies(self):
63         """Return a list of :class:`Driver`\s we require."""
64         return []
65
66     def default_settings(self):
67         """Return a list of :class:`hooke.config.Setting`\s for any
68         configurable driver settings.
69
70         The suggested section setting is::
71
72             Setting(section=self.setting_section, help=self.__doc__)
73         """
74         return []
75
76     def is_me(self, path):
77         """Read the file and return True if the filetype can be
78         managed by the driver.  Otherwise return False.
79         """
80         return False
81
82     def read(self, path):
83         """Read data from `path` and return a
84         ([:class:`hooke.curve.Data`, ...], `info`) tuple.
85
86         The `info` :class:`dict` must contain values for the keys:
87         'filetype' and 'experiment'.  See :class:`hooke.curve.Curve`
88         for details.
89         """
90         raise NotImplementedError
91
92 # Construct driver dependency graph and load default drivers.
93
94 DRIVER_GRAPH = construct_graph(
95     this_modname=__name__,
96     submodnames=[name for name,include in DRIVER_MODULES],
97     class_selector=IsSubclass(Driver, blacklist=[Driver]))
98 """Topologically sorted list of all possible :class:`Driver`\s.
99 """
100
101 def default_settings():
102     settings = [Setting(DRIVER_SETTING_SECTION,
103                         help='Enable/disable default drivers.')]
104     for dnode in DRIVER_GRAPH:
105         driver = dnode.data
106         default_include = [di for mod_name,di in DRIVER_MODULES
107                            if mod_name == driver.name][0]
108         help = driver.__doc__.split('\n', 1)[0]
109         settings.append(Setting(
110                 section=DRIVER_SETTING_SECTION,
111                 option=driver.name,
112                 value=str(default_include),
113                 help=help,
114                 ))
115     for dnode in DRIVER_GRAPH:
116         driver = dnode.data
117         settings.extend(driver.default_settings())
118     return settings