1 """The driver module provides :class:`Driver`\s for identifying and
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.
9 from ..config import Setting
10 from ..util.graph import Node, Graph
14 # ('csvdriver', True),
16 # ('hemingclamp', True),
19 # ('mfp1dexport', True),
21 # ('picoforce', True),
22 # ('picoforcealt', True),
25 """List of driver modules and whether they should be included by
26 default. TODO: autodiscovery
29 class NotRecognized (ValueError):
30 def __init__(self, path):
31 msg = 'Not a recognizable curve format: %s' % self.path
32 ValueError.__init__(self, msg)
36 """Base class for file format drivers.
38 :attr:`name` identifies your driver, and should match the module
41 def __init__(self, name):
43 self.setting_section = '%s driver' % self.name
45 def dependencies(self):
46 """Return a list of :class:`Driver`\s we require."""
49 def default_settings(self):
50 """Return a list of :class:`hooke.config.Setting`\s for any
51 configurable driver settings.
53 The suggested section setting is::
55 Setting(section=self.setting_section, help=self.__doc__)
59 def is_me(self, path):
60 """Read the file and return True if the filetype can be
61 managed by the driver. Otherwise return False.
66 """Read data from `path` and return a
67 (:class:`hooke.curve.Data`, `info`) tuple.
69 The `info` :class:`dict` must contain values for the keys:
70 'filetype' and 'experiment'. See :class:`hooke.curve.Curve`
73 raise NotImplementedError
75 # Construct driver dependency graph and load default drivers.
78 """(name, instance) :class:`dict` of all possible :class:`Driver`\s.
81 for driver_modname,default_include in DRIVER_MODULES:
82 assert len([mod_name for mod_name,di in DRIVER_MODULES]) == 1, \
83 'Multiple %s entries in DRIVER_MODULES' % mod_name
84 this_mod = __import__(__name__, fromlist=[driver_modname])
85 driver_mod = getattr(this_mod, driver_modname)
86 for objname in dir(driver_mod):
87 obj = getattr(driver_mod, objname)
89 subclass = issubclass(obj, Driver)
92 if subclass == True and obj != Driver:
94 if d.name != driver_modname:
95 raise Exception('Driver name %s does not match module name %s'
96 % (d.name, driver_modname))
99 DRIVER_GRAPH = Graph([Node([DRIVERS[name] for name in d.dependencies()],
101 for d in DRIVERS.values()])
102 DRIVER_GRAPH.topological_sort()
105 def default_settings():
107 'drivers', help='Enable/disable default drivers.')]
108 for dnode in DRIVER_GRAPH:
110 default_include = [di for mod_name,di in DRIVER_MODULES
111 if mod_name == driver.name][0]
112 help = driver.__doc__.split('\n', 1)[0]
113 settings.append(Setting(
116 value=str(default_include),
119 for dnode in DRIVER_GRAPH:
121 settings.extend(driver.default_settings())