+# Copyright (C) 2010-2012 W. Trevor King <wking@drexel.edu>
+#
+# This file is part of Hooke.
+#
+# Hooke is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# Hooke is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+# Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with Hooke. If not, see
+# <http://www.gnu.org/licenses/>.
+
"""The driver module provides :class:`Driver`\s for identifying and
reading data files.
to write your own to handle your lab's specific format.
"""
+import logging
+import os.path
+
from ..config import Setting
-from ..util.graph import Node, Graph
+from ..util.pluggable import IsSubclass, construct_graph
DRIVER_MODULES = [
# ('csvdriver', True),
# ('hdf5', True),
-# ('hemingclamp', True),
-# ('jpk', True),
+ ('hemingway', True),
+ ('jpk', True),
# ('mcs', True),
# ('mfp1dexport', True),
-# ('mfp3d', True),
-# ('picoforce', True),
-# ('picoforcealt', True),
+ ('mfp3d', True),
+ ('picoforce', True),
('tutorial', True),
+ ('wtk', True),
]
"""List of driver modules and whether they should be included by
default. TODO: autodiscovery
"""
-class NotRecognized (ValueError):
- def __init__(self, path):
- msg = 'Not a recognizable curve format: %s' % self.path
- ValueError.__init__(self, msg)
- self.path = path
+DRIVER_SETTING_SECTION = 'drivers'
+"""Name of the config section which controls driver selection.
+"""
+
-class Driver(object):
+class Driver (object):
"""Base class for file format drivers.
- :attr:`name` identifies your driver, and should match the module
+ :attr:`name` identifies your driver and should match the module
name.
"""
def __init__(self, name):
"""
return False
- def read(self, path):
+ def read(self, path, info=None):
"""Read data from `path` and return a
- (:class:`hooke.curve.Data`, `info`) tuple.
+ ([:class:`hooke.curve.Data`, ...], `info`) tuple.
- The `info` :class:`dict` must contain values for the keys:
- 'filetype' and 'experiment'. See :class:`hooke.curve.Curve`
- for details.
+ The input `info` :class:`dict` may contain attributes read
+ from the :class:`~hooke.playlist.FilePlaylist`.
+
+ See :class:`hooke.curve.Curve` for details.
"""
raise NotImplementedError
+ def logger(self):
+ return logging.getLogger('hooke')
+
# Construct driver dependency graph and load default drivers.
-DRIVERS = {}
-"""(name, instance) :class:`dict` of all possible :class:`Driver`\s.
+DRIVER_GRAPH = construct_graph(
+ this_modname=__name__,
+ submodnames=[name for name,include in DRIVER_MODULES],
+ class_selector=IsSubclass(Driver, blacklist=[Driver]))
+"""Topologically sorted list of all possible :class:`Driver`\s.
"""
-for driver_modname,default_include in DRIVER_MODULES:
- assert len([mod_name for mod_name,di in DRIVER_MODULES]) == 1, \
- 'Multiple %s entries in DRIVER_MODULES' % mod_name
- this_mod = __import__(__name__, fromlist=[driver_modname])
- driver_mod = getattr(this_mod, driver_modname)
- for objname in dir(driver_mod):
- obj = getattr(driver_mod, objname)
- try:
- subclass = issubclass(obj, Driver)
- except TypeError:
- continue
- if subclass == True and obj != Driver:
- d = obj()
- if d.name != driver_modname:
- raise Exception('Driver name %s does not match module name %s'
- % (d.name, driver_modname))
- DRIVERS[d.name] = d
-
-DRIVER_GRAPH = Graph([Node([DRIVERS[name] for name in d.dependencies()],
- data=d)
- for d in DRIVERS.values()])
-DRIVER_GRAPH.topological_sort()
-
-
def default_settings():
- settings = [Setting(
- 'drivers', help='Enable/disable default drivers.')]
+ settings = [Setting(DRIVER_SETTING_SECTION,
+ help='Enable/disable default drivers.')]
for dnode in DRIVER_GRAPH:
driver = dnode.data
default_include = [di for mod_name,di in DRIVER_MODULES
if mod_name == driver.name][0]
help = driver.__doc__.split('\n', 1)[0]
settings.append(Setting(
- section='drivers',
+ section=DRIVER_SETTING_SECTION,
option=driver.name,
- value=str(default_include),
+ value=default_include,
+ type='bool',
help=help,
))
for dnode in DRIVER_GRAPH: