root/trunk/src/visual_logging.py

Revision 311, 4.8 kB (checked in by apdavison, 2 months ago)

Added some module-level docstrings

Line 
1 """
2 NeuroTools.visual_logging
3 =========================
4
5 Log graphs, rather than text. This is useful when dealing with large data
6 structures, such as arrays. x-y data is plotted as a PNG file, which is stored
7 inside a zip archive.
8
9 You can specify a logging level such that only graphs with an importance above
10 that level will be created. e.g., if the logging level is set to WARNING,
11 log graphs with a level of DEBUG or INFO will not be created.
12
13 The interface is a restricted version of that available in the standard
14 library's logging module.
15
16 Functions
17 ---------
18
19 basicConfig - specify the zipfile that will be used to store the graphs, and
20               the logging level (DEBUG, INFO, WARN, etc)
21 debug       - plots data with level DEBUG
22 info        - plots data with level INFO
23 warning     - plots data with level WARNING
24 error       - plots data with level ERROR
25 critical    - plots data with level CRITICAL
26 exception   - plots data with level ERROR
27 log         - plots data with a user-specified level
28
29 """
30
31 import zipfile, atexit, os
32 from NeuroTools import check_dependency
33 from datetime import datetime
34 from logging import CRITICAL, DEBUG, ERROR, FATAL, INFO, WARN, WARNING, NOTSET
35 from time import sleep
36
37 if check_dependency('pylab'):
38     import pylab
39
40 _filename = 'visual_log.zip'
41 _zipfile = None
42 _level = INFO
43 _last_timestamp = ''
44
45 def _remove_if_empty():
46     if len(_zipfile.namelist()) == 0 and os.path.exists(_filename):
47         os.remove(_filename)
48
49 def basicConfig(filename, level=INFO):
50     global _zipfile, _filename, _level
51     _filename = filename
52     _level = level
53     #_zipfile.close()
54     if os.path.exists(filename) and zipfile.is_zipfile(filename):
55         mode = 'a'
56     else:
57         mode = 'w'
58     _zipfile = zipfile.ZipFile(filename, mode=mode, compression=zipfile.ZIP_DEFLATED)
59     atexit.register(_zipfile.close)
60     atexit.register(_remove_if_empty)
61
62 def _reopen():
63     global _zipfile
64     if (_zipfile.fp is None) or _zipfile.fp.closed:
65         _zipfile = zipfile.ZipFile(_filename, mode='a', compression=zipfile.ZIP_DEFLATED)
66
67 def flush():
68     """Until the zipfile is closed (normally on exit), the zipfile cannot
69     be accessed by other tools. Calling flush() closes the zipfile, which
70     will be reopened the next time a log function is called.
71     """
72     _zipfile.close()
73
74 def _get_timestamp():
75     """At the moment, it is not possible to create visual
76     logs at a rate of more than one/second."""
77     global _last_timestamp
78     timestamp = datetime.now().strftime('%Y%m%d-%H%M%S')
79     while timestamp == _last_timestamp:
80         sleep(0.1)
81         timestamp = datetime.now().strftime('%Y%m%d-%H%M%S')
82     _last_timestamp = timestamp
83     return timestamp
84
85 def _plot_fig(ydata, xdata, xlabel, ylabel, title):
86     _reopen()
87     timestamp = _get_timestamp()
88     # create figure
89     pylab.cla()
90     if xdata is not None:
91         pylab.plot(xdata, ydata)
92     else:
93         pylab.plot(ydata)
94     pylab.xlabel(xlabel)
95     pylab.ylabel(ylabel)
96     pylab.title(title)
97     # add it to the zipfile
98     fig_name = timestamp + '.png'
99     pylab.savefig(fig_name)
100     _zipfile.write(fig_name,
101                    os.path.join(os.path.basename(os.path.splitext(_filename)[0]), fig_name))
102     os.remove(timestamp+'.png')
103
104 def debug(ydata, xdata=None, xlabel='', ylabel='', title=''):
105     if _level <= DEBUG:
106         _plot_fig(ydata, xdata, xlabel, ylabel, title)
107
108 def info(ydata, xdata=None, xlabel='', ylabel='', title=''):
109     if _level <= INFO:
110         _plot_fig(ydata, xdata, xlabel, ylabel, title)
111
112 def warning(ydata, xdata=None, xlabel='', ylabel='', title=''):
113     if _level <= WARNING:
114         _plot_fig(ydata, xdata, xlabel, ylabel, title)
115
116 def error(ydata, xdata=None, xlabel='', ylabel='', title=''):
117     if _level <= ERROR:
118         _plot_fig(ydata, xdata, xlabel, ylabel, title)
119
120 def critical(ydata, xdata=None, xlabel='', ylabel='', title=''):
121     if _level <= CRITICAL:
122         _plot_fig(ydata, xdata, xlabel, ylabel, title)
123
124 def exception(ydata, xdata=None, xlabel='', ylabel='', title=''):
125     if _level <= ERROR:
126         _plot_fig(ydata, xdata, xlabel, ylabel, title)
127
128 def log(level, ydata, xdata=None, xlabel='', ylabel='', title=''):
129     if _level <= level:
130         _plot_fig(ydata, xdata, xlabel, ylabel, title)
131
132 def test():
133     test_file = 'visual_logging_test.zip'
134     if os.path.exists(test_file):
135         os.remove(test_file)
136     basicConfig(test_file, level=DEBUG)
137     xdata = pylab.arange(0, 2*pylab.pi, 0.02*pylab.pi)
138     debug(pylab.sin(xdata), xdata, 'x', 'sin(x)', 'visual_logging test 1')
139     flush()
140     debug(0.5*pylab.sin(2*xdata-0.3), xdata, 'x', 'sin(2x-0.3)/2')
141     debug(pylab.sqrt(xdata), xdata, 'x', 'sqrt(x)')
142     flush()
143     zf = zipfile.ZipFile(test_file, 'r')
144     print zf.namelist()
145     assert len(zf.namelist()) == 3, zf.namelist()
146     zf.close()
147    
148 # ==============================================================================
149 if __name__ == '__main__':
150     test()
Note: See TracBrowser for help on using the browser.