Cleaned up Builtin handling and reduced driver/plugin duplication.
[hooke.git] / hooke / driver / __init__.py
1 """The driver module provides :class:`Driver`\s for identifying and
2 reading data files.
3
4 This allows Hooke to be data-file agnostic.  Drivers for various
5 commercial force spectroscopy microscopes are provided, and it's easy
6 to write your own to handle your lab's specific format.
7 """
8
9 from ..config import Setting
10 from ..plugin import construct_graph, IsSubclass
11
12 DRIVER_MODULES = [
13 #    ('csvdriver', True),
14 #    ('hdf5', True),
15 #    ('hemingclamp', True),
16 #    ('jpk', True),
17 #    ('mcs', True),
18 #    ('mfp1dexport', True),
19 #    ('mfp3d', True),
20 #    ('picoforce', True),
21 #    ('picoforcealt', True),
22     ('tutorial', True),
23 ]
24 """List of driver modules and whether they should be included by
25 default.  TODO: autodiscovery
26 """
27
28
29 class Driver(object):
30     """Base class for file format drivers.
31     
32     :attr:`name` identifies your driver, and should match the module
33     name.
34     """
35     def __init__(self, name):
36         self.name = name
37         self.setting_section = '%s driver' % self.name
38
39     def dependencies(self):
40         """Return a list of :class:`Driver`\s we require."""
41         return []
42
43     def default_settings(self):
44         """Return a list of :class:`hooke.config.Setting`\s for any
45         configurable driver settings.
46
47         The suggested section setting is::
48
49             Setting(section=self.setting_section, help=self.__doc__)
50         """
51         return []
52
53     def is_me(self, path):
54         """Read the file and return True if the filetype can be
55         managed by the driver.  Otherwise return False.
56         """
57         return False
58
59     def read(self, path):
60         """Read data from `path` and return a
61         (:class:`hooke.curve.Data`, `info`) tuple.
62
63         The `info` :class:`dict` must contain values for the keys:
64         'filetype' and 'experiment'.  See :class:`hooke.curve.Curve`
65         for details.
66         """
67         raise NotImplementedError
68
69 # Construct driver dependency graph and load default drivers.
70
71 DRIVER_GRAPH = construct_graph(
72     this_modname=__name__,
73     submodnames=[name for name,include in DRIVER_MODULES],
74     class_selector=IsSubclass(Driver, blacklist=[Driver]))
75 """Topologically sorted list of all possible :class:`Driver`\s.
76 """
77
78 def default_settings():
79     settings = [Setting(
80             'drivers', help='Enable/disable default drivers.')]
81     for dnode in DRIVER_GRAPH:
82         driver = dnode.data
83         default_include = [di for mod_name,di in DRIVER_MODULES
84                            if mod_name == driver.name][0]
85         help = driver.__doc__.split('\n', 1)[0]
86         settings.append(Setting(
87                 section='drivers',
88                 option=driver.name,
89                 value=str(default_include),
90                 help=help,
91                 ))
92     for dnode in DRIVER_GRAPH:
93         driver = dnode.data
94         settings.extend(driver.default_settings())
95     return settings