File: logtool

package info (click to toggle)
pytools 10-7
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 404 kB
  • ctags: 796
  • sloc: python: 4,175; makefile: 9
file content (263 lines) | stat: -rwxr-xr-x 8,851 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
#! /usr/bin/python

def main():
    from pytools.log import LogManager
    import sys
    from optparse import OptionParser

    description = """Operate on data gathered during code runs.
FILE is a log saved from a code run. COMMANDS may be one of the
following:
"list" to list the available time-series and constants,
"plot expr_x,expr_y" to plot a graph,
"datafile outfile expr_x,expr_y" to write out a data file.
"table variable" to print the full data table for a time series variable.
"prefix string" to set the legend prefix for all following plot commands.
"next_legend string" to set the legend string for the next plot command.
"warnings" to list the warnings that were issued during the logged run.
"saveplot filename" to save the current plot to a file.
"print" to print the current plot using "lp".
"""
    parser = OptionParser(usage="%prog FILE COMMANDS FILE COMMANDS...",
            description=description)

    parser.add_option("--scale-x", metavar="XMIN,XMAX",
            help="Set the scale of the X axis")
    parser.add_option("--scale-y", metavar="YMIN,YMAX",
            help="Set the scale of the Y axis")
    parser.add_option("--skip", metavar="N", type="int",
            help="Only use every N'th data point", default=1)
    parser.add_option("--units-x", 
            help="Show only units, not descriptions on the X axis",
            action="store_true")
    parser.add_option("--units-y", 
            help="Show only units, not descriptions on the Y axis",
            action="store_true")
    parser.add_option("--grid", 
            help="Show a grid",
            action="store_true")
    parser.add_option("--legend-expr", 
            help="Generate a legend from the expression",
            action="store_true")
    parser.add_option("--legend-descr", 
            help="Generate a legend from the description",
            action="store_true")
    parser.add_option("--title", 
            help="Set the title of a plot",
            default="Log evaluation")
    parser.add_option("--small-legend", action="store_true")
    parser.add_option("--label-x", help="Set the label on the X axis")
    parser.add_option("--label-y", help="Set the label on the Y axis")
    parser.add_option("--start-step", metavar="STEP", type="int",
            help="Start the plot at this timestep number")
    parser.add_option("--end-step",  metavar="STEP", type="int",
            help="End the plot at this timestep number")
    options, args = parser.parse_args()

    if len(args) < 1:
        parser.print_help()
        sys.exit(1)

    logmgr = None

    did_plot = False
    saveplot_filename = None
    print_plot = False

    legend_prefix = ""

    from pytools import cartesian_product, Record
    class PlotStyle(Record):
        pass

    styles = [
            PlotStyle(dashes=dashes, color=color)
            for dashes, color in cartesian_product(
                [(), (12, 2), (4, 2),  (2,2), (2,8) ],
                ["blue", "green", "red", "magenta", "cyan"],
                )]

    def check_no_file():
        if logmgr is None:
            raise RuntimeError, "no file loaded"

    next_legend = None
    
    while args:
        cmd = args.pop(0)
        if cmd == "list":
            check_no_file()

            print "Time series"
            print "-----------"

            items = list(logmgr.quantity_data.iteritems())
            items.sort(lambda a,b: cmp(a[0], b[0]))

            if items:
                col0_len = max(len(k) for k, v in items) + 1
            else:
                col0_len = 0

            for key, qdat in items:
                print "%s\t%s" % (key.ljust(col0_len), qdat.description)

            print
            print "Constants"
            print "---------"
            items = list(logmgr.constants.iteritems())
            items.sort(lambda a,b: cmp(a[0], b[0]))

            if items:
                col0_len = max(len(k) for k, v in items) + 1
            else:
                col0_len = 0

            for key, value in items:
                print "%s\t%s" % (key.ljust(col0_len), str(value))
        elif cmd == "plot":
            check_no_file()

            expr_x, expr_y = args.pop(0).split(",")

            from pylab import xlabel, ylabel, plot
            (data_x, descr_x, unit_x), (data_y, descr_y, unit_y) = \
                    logmgr.get_plot_data(expr_x, expr_y,
                            options.start_step, options.end_step)

            if options.label_x:
                xlabel(options.label_x)
            else:
                if options.units_x:
                    xlabel(unit_x)
                else:
                    xlabel("%s [%s]" % (descr_x, unit_x))

            if options.label_y:
                ylabel(options.label_y)
            else:
                if options.units_y:
                    ylabel(unit_y)
                else:
                    ylabel("%s [%s]" % (descr_y, unit_y))

            kwargs = {}

            if next_legend:
                kwargs["label"] = next_legend
            else:
                if options.legend_expr:
                    kwargs["label"] = legend_prefix+expr_y
                if options.legend_descr:
                    kwargs["label"] = legend_prefix+descr_y

            style = styles.pop(0)
            plot(data_x[::options.skip], 
                    data_y[::options.skip], 
                    dashes=style.dashes, color=style.color, 
                    hold=True,  **kwargs)

            did_plot = True
            next_legend = None
        elif cmd == "warnings":
            check_no_file()
            print logmgr.get_warnings()

        elif cmd == "datafile":
            check_no_file()

            expr_x, expr_y = args.pop(0).split(",")

            logmgr.write_datafile(args.pop(0), expr_x, expr_y)
        elif cmd == "prefix":
            legend_prefix = args.pop(0)
        elif cmd == "next_legend":
            next_legend = args.pop(0)
        elif cmd == "table":
            check_no_file()

            descrs, units, data = logmgr.get_joint_dataset(args.pop(0).split(","))
            if options.start_step is not None:
                data = [(step, tup) for step, tup in data 
                        if options.start_step <= step]
            if options.end_step is not None:
                data = [(step, tup) for step, tup in data 
                        if step <= options.end_step]

            from pytools import Table
            tbl = Table()
            tbl.add_row(["step"]+["%s [%s]" % (d, u) for d,u in zip(descrs, units)])

            for row in data:
                tbl.add_row([row[0]]+row[1])

            print tbl
        elif cmd == "saveplot":
            saveplot_filename = args.pop(0)
        elif cmd == "print":
            print_plot = True
        else:
            # not a known command, interpret as file name
            from os import access, R_OK
            if access(cmd, R_OK):
                logmgr = LogManager(cmd, "r")
            else:
                raise IOError, "file '%s' not found" % cmd

    if did_plot:
        from pylab import show, title, legend, axis, grid, savefig
        if options.legend_expr or options.legend_descr:
            if options.small_legend:
                from matplotlib.font_manager import FontProperties
                legend(borderpad=0.04, prop=FontProperties(size=8), loc="best",
                        labelspacing=0)
            else:
                legend(loc="best")

        def float_or_none(str):
            if str == "*":
                return None
            else:
                return float(str)

        xmin, xmax, ymin, ymax = axis()
        if options.scale_x:
            xmin_new, xmax_new = [float_or_none(x) for x in options.scale_x.split(",")]
            if xmin_new is not None:
                xmin = xmin_new
            if xmax_new is not None:
                xmax = xmax_new
        if options.scale_y:
            ymin_new, ymax_new = [float_or_none(x) for x in options.scale_y.split(",")]
            if ymin_new is not None:
                ymin = ymin_new
            if ymax_new is not None:
                ymax = ymax_new

        axis((xmin, xmax, ymin, ymax))

        if options.grid:
            grid()

        title(options.title)

        if print_plot:
            from tempfile import gettempprefix, gettempdir
            import os.path
            tmpname = os.path.join(gettempdir(), gettempprefix()+"logtoolprint.ps")
            savefig(tmpname, orientation="landscape", papertype="letter")

            from os import system, unlink
            system("lp %s" % tmpname)

            unlink(tmpname)

        if saveplot_filename:
            savefig(saveplot_filename)

        if not print_plot and not saveplot_filename:
            show()


if __name__ == "__main__":
    main()