Moved config handling commands from hooke_cli to hooke.plugin.config.
[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 ..util.pluggable import IsSubclass, construct_graph
11
12
13 DRIVER_MODULES = [
14 #    ('csvdriver', True),
15 #    ('hdf5', True),
16 #    ('hemingclamp', True),
17 #    ('jpk', True),
18 #    ('mcs', True),
19 #    ('mfp1dexport', True),
20 #    ('mfp3d', True),
21 #    ('picoforce', True),
22 #    ('picoforcealt', True),
23     ('tutorial', True),
24 ]
25 """List of driver modules and whether they should be included by
26 default.  TODO: autodiscovery
27 """
28
29 DRIVER_SETTING_SECTION = 'drivers'
30 """Name of the config section which controls driver selection.
31 """
32
33
34 class Driver(object):
35     """Base class for file format drivers.
36     
37     :attr:`name` identifies your driver, and should match the module
38     name.
39     """
40     def __init__(self, name):
41         self.name = name
42         self.setting_section = '%s driver' % self.name
43
44     def dependencies(self):
45         """Return a list of :class:`Driver`\s we require."""
46         return []
47
48     def default_settings(self):
49         """Return a list of :class:`hooke.config.Setting`\s for any
50         configurable driver settings.
51
52         The suggested section setting is::
53
54             Setting(section=self.setting_section, help=self.__doc__)
55         """
56         return []
57
58     def is_me(self, path):
59         """Read the file and return True if the filetype can be
60         managed by the driver.  Otherwise return False.
61         """
62         return False
63
64     def read(self, path):
65         """Read data from `path` and return a
66         (:class:`hooke.curve.Data`, `info`) tuple.
67
68         The `info` :class:`dict` must contain values for the keys:
69         'filetype' and 'experiment'.  See :class:`hooke.curve.Curve`
70         for details.
71         """
72         raise NotImplementedError
73
74 # Construct driver dependency graph and load default drivers.
75
76 DRIVER_GRAPH = construct_graph(
77     this_modname=__name__,
78     submodnames=[name for name,include in DRIVER_MODULES],
79     class_selector=IsSubclass(Driver, blacklist=[Driver]))
80 """Topologically sorted list of all possible :class:`Driver`\s.
81 """
82
83 def default_settings():
84     settings = [Setting(DRIVER_SETTING_SECTION,
85                         help='Enable/disable default drivers.')]
86     for dnode in DRIVER_GRAPH:
87         driver = dnode.data
88         default_include = [di for mod_name,di in DRIVER_MODULES
89                            if mod_name == driver.name][0]
90         help = driver.__doc__.split('\n', 1)[0]
91         settings.append(Setting(
92                 section=DRIVER_SETTING_SECTION,
93                 option=driver.name,
94                 value=str(default_include),
95                 help=help,
96                 ))
97     for dnode in DRIVER_GRAPH:
98         driver = dnode.data
99         settings.extend(driver.default_settings())
100     return settings