Ran update-copyright.py
[hooke.git] / hooke / driver / __init__.py
1 # Copyright (C) 2010-2012 W. Trevor King <wking@tremily.us>
2 #
3 # This file is part of Hooke.
4 #
5 # Hooke is free software: you can redistribute it and/or modify it under the
6 # terms of the GNU Lesser General Public License as published by the Free
7 # Software Foundation, either version 3 of the License, or (at your option) any
8 # later version.
9 #
10 # Hooke is distributed in the hope that it will be useful, but WITHOUT ANY
11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 # A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
13 # details.
14 #
15 # You should have received a copy of the GNU Lesser General Public License
16 # along with Hooke.  If not, see <http://www.gnu.org/licenses/>.
17
18 """The driver module provides :class:`Driver`\s for identifying and
19 reading data files.
20
21 This allows Hooke to be data-file agnostic.  Drivers for various
22 commercial force spectroscopy microscopes are provided, and it's easy
23 to write your own to handle your lab's specific format.
24 """
25
26 import logging
27 import os.path
28
29 from ..config import Setting
30 from ..util.pluggable import IsSubclass, construct_graph
31
32
33 DRIVER_MODULES = [
34 #    ('csvdriver', True),
35 #    ('hdf5', True),
36     ('hemingway', True),
37     ('jpk', True),
38 #    ('mcs', True),
39 #    ('mfp1dexport', True),
40     ('mfp3d', True),
41     ('picoforce', True),
42     ('tutorial', True),
43     ('wtk', True),
44 ]
45 """List of driver modules and whether they should be included by
46 default.  TODO: autodiscovery
47 """
48
49 DRIVER_SETTING_SECTION = 'drivers'
50 """Name of the config section which controls driver selection.
51 """
52
53
54 class Driver (object):
55     """Base class for file format drivers.
56     
57     :attr:`name` identifies your driver and should match the module
58     name.
59     """
60     def __init__(self, name):
61         self.name = name
62         self.setting_section = '%s driver' % self.name
63
64     def dependencies(self):
65         """Return a list of :class:`Driver`\s we require."""
66         return []
67
68     def default_settings(self):
69         """Return a list of :class:`hooke.config.Setting`\s for any
70         configurable driver settings.
71
72         The suggested section setting is::
73
74             Setting(section=self.setting_section, help=self.__doc__)
75         """
76         return []
77
78     def is_me(self, path):
79         """Read the file and return True if the filetype can be
80         managed by the driver.  Otherwise return False.
81         """
82         return False
83
84     def read(self, path, info=None):
85         """Read data from `path` and return a
86         ([:class:`hooke.curve.Data`, ...], `info`) tuple.
87
88         The input `info` :class:`dict` may contain attributes read
89         from the :class:`~hooke.playlist.FilePlaylist`.
90
91         See :class:`hooke.curve.Curve` for details.
92         """
93         raise NotImplementedError
94
95     def logger(self):
96         return logging.getLogger('hooke')
97
98 # Construct driver dependency graph and load default drivers.
99
100 DRIVER_GRAPH = construct_graph(
101     this_modname=__name__,
102     submodnames=[name for name,include in DRIVER_MODULES],
103     class_selector=IsSubclass(Driver, blacklist=[Driver]))
104 """Topologically sorted list of all possible :class:`Driver`\s.
105 """
106
107 def default_settings():
108     settings = [Setting(DRIVER_SETTING_SECTION,
109                         help='Enable/disable default drivers.')]
110     for dnode in DRIVER_GRAPH:
111         driver = dnode.data
112         default_include = [di for mod_name,di in DRIVER_MODULES
113                            if mod_name == driver.name][0]
114         help = driver.__doc__.split('\n', 1)[0]
115         settings.append(Setting(
116                 section=DRIVER_SETTING_SECTION,
117                 option=driver.name,
118                 value=default_include,
119                 type='bool',
120                 help=help,
121                 ))
122     for dnode in DRIVER_GRAPH:
123         driver = dnode.data
124         settings.extend(driver.default_settings())
125     return settings