From: timv Date: Fri, 14 Jun 2013 18:37:07 +0000 (-0400) Subject: Minor tweaks to crash handler. Post-processor can render animates of text and X-Git-Url: https://hydra-www.ietfng.org/gitweb/?a=commitdiff_plain;h=9d1ccccbaa19efbb2ea04f49c5db63e5b46276c6;p=dyna2 Minor tweaks to crash handler. Post-processor can render animates of text and lines. Instead of hard coded nodes, edge, pos. See `example/force.dyna` --- diff --git a/examples/force.dyna b/examples/force.dyna index fb9885b..4d0c1dd 100644 --- a/examples/force.dyna +++ b/examples/force.dyna @@ -14,21 +14,35 @@ dist(U,V,T) := (x(U,T) - x(V,T))**2 + (y(U,T) - y(V,T))**2 shortestpath(U,U) min= 0 for node(U). shortestpath(U,V) min= shortestpath(U,W) + edge(W,V). -% "the unit edge length" -edgelen := 4.0. - +% Compute attractive-replusive forces f(U,V,T) := (U != V), dist(U,V,T) / (shortestpath(U,V) * edgelen) - 1. - forceX(V,T) += f(U,V,T) * (x(U,T) - x(V,T)). forceY(V,T) += f(U,V,T) * (y(U,T) - y(V,T)). +% Constants a := 0.15. -niter := 100. +niter := 200. +edgelen := 4.0. % "the unit edge length" % should `a` be negative? x(U,T) += a * forceX(U,T-1). y(U,T) += a * forceY(U,T-1). +% make graph symmetric. +edge(A,B) := 1 for edge(B,A). + +% collect nodes. +node(U) := true for edge(U,_). +node(U) := true for edge(_,U). + +% pack x and y into a tuple +pos(U,T) := tuple(x(U, T), y(U, T)). + +% visualization +frame(T, Item) := node(Name), Item is &text(Name, pos(Name, T)). +frame(T, Item) := edge(U,V), Item is &line(pos(U, T), pos(V, T)). + +% declare some edges edge("a", "b") := 1. edge("a", "c") := 1. edge("a", "d") := 1. @@ -40,12 +54,6 @@ edge("e", "f") := 1. edge("e", "g") := 1. edge("a", "i") := 1. -edge(A,B) := 1 for edge(B,A). % make graph symmetric. - -% collect nodes. -node(U) := true for edge(U,_). -node(U) := true for edge(_,U). - % randomly initialize node positions. x("a",0) += uniform(0,1). y("a",0) += uniform(0,1). x("b",0) += uniform(0,1). y("b",0) += uniform(0,1). @@ -57,5 +65,3 @@ x("g",0) += uniform(0,1). y("g",0) += uniform(0,1). x("h",0) += uniform(0,1). y("h",0) += uniform(0,1). x("i",0) += uniform(0,1). y("i",0) += uniform(0,1). x("j",0) += uniform(0,1). y("j",0) += uniform(0,1). - -pos(U,T) := tuple(x(U, T), y(U, T)). diff --git a/src/Dyna/Backend/Python/defn.py b/src/Dyna/Backend/Python/defn.py index 8d39cc6..a014199 100644 --- a/src/Dyna/Backend/Python/defn.py +++ b/src/Dyna/Backend/Python/defn.py @@ -17,6 +17,8 @@ class Aggregator(object): class BAggregator(Counter, Aggregator): + def __init__(self): + super(BAggregator, self).__init__() def inc(self, val, ruleix, variables): self[val] += 1 def dec(self, val, ruleix, variables): diff --git a/src/Dyna/Backend/Python/graph.py b/src/Dyna/Backend/Python/graph.py index f69cd2d..44f3628 100644 --- a/src/Dyna/Backend/Python/graph.py +++ b/src/Dyna/Backend/Python/graph.py @@ -1,40 +1,55 @@ -import pylab as pl -from matplotlib.animation import FuncAnimation -from collections import defaultdict +""" +Postprocessor for animated visualization of basic elements such as lines and +text. -def g(nodes, edges, t, ax, interp): - ax.cla() - ax.set_title(t) - ax.set_xlim(-2,2) - ax.set_ylim(-2,2) +We look for the following patterns in the dynabase - pos = defaultdict(lambda: (0,0)) - pos.update({node: p for _, (node, _), p in interp.chart['pos/2'][:,t,:]}) + visual element + v + frame(T, &text(String, tuple(X, Y))). + ^ + time index - for u,v in edges: - if u < v: - (a,b), (c,d) = pos[u], pos[v] - ax.plot([a,c], [b,d]) +Frames should have value true. The example above places a text element reading +`String` at position `(X,Y)` in a frame at time `T`. This element can be +specified by dyna rule. +""" - for s in nodes: - x,y = pos[s] - ax.text(x,y,s) +import pylab as pl +from matplotlib.animation import FuncAnimation +from collections import defaultdict -def animate(interp): - [(_, _, niter)] = interp.chart['niter/0'][:,] +def main(interp): - nodes = [name for _, [name], _ in interp.chart['node/1'][:,:]] - edges = [(u,v) for _, [u,v] ,_ in interp.chart['edge/2'][:,:,:]] + frame = defaultdict(list) + for _, [t, item], val in interp.chart['frame/2'][:,:,:]: + if val: + frame[t].append(item) + + nframes = max(frame) + + def draw_frame(t): + ax.cla() + ax.set_title(t) + ax.set_xlim(-2,2) # TODO: this isn't right... + ax.set_ylim(-2,2) + if t not in frame: + print 'frame', t, 'missing.' + for item in frame[t]: + if item.fn == 'line/2': + [(a,b), (c,d)] = item.args + ax.plot([a,c], [b,d], color='b', alpha=0.5) + elif item.fn == 'text/2': + (s,(x,y)) = item.args + ax.text(x,y,s) + else: + print 'dont know how to render', item fig = pl.figure() ax = pl.axes() print 'creating animation..' - anim = FuncAnimation(fig, lambda t: g(nodes, edges, t % niter, ax, interp), frames=niter) + anim = FuncAnimation(fig, draw_frame, frames=nframes) print 'saving...' anim.save('examples/force.dyna.mp4', fps=30, extra_args=['-vcodec', 'libx264']) print 'wrote examples/force.dyna.mp4' - - -def main(interp): - animate(interp) diff --git a/src/Dyna/Backend/Python/repl.py b/src/Dyna/Backend/Python/repl.py index 7758c8b..b766b23 100644 --- a/src/Dyna/Backend/Python/repl.py +++ b/src/Dyna/Backend/Python/repl.py @@ -1,7 +1,7 @@ import os, cmd, readline import debug, interpreter -from utils import DynaCompilerError, DynaInitializerException, ip, crash_handler +from utils import DynaCompilerError, DynaInitializerException, ip from chart import _repr from config import dotdynadir @@ -127,9 +127,6 @@ class REPL(cmd.Cmd, object): except KeyboardInterrupt: # Catch Control-C and resume REPL. print '^C' - self.cmdloop() - except: - # report uncatch exception. - crash_handler() + self.cmdloop() finally: readline.write_history_file(self.hist) diff --git a/src/Dyna/Backend/Python/utils.py b/src/Dyna/Backend/Python/utils.py index 4a78017..e2d1250 100644 --- a/src/Dyna/Backend/Python/utils.py +++ b/src/Dyna/Backend/Python/utils.py @@ -46,23 +46,25 @@ def dynac(f, out): raise DynaCompilerError(stderr) -def crash_handler(): - exception_handler(*sys.exc_info()) - - def exception_handler(etype, evalue, tb): # once for the log file. with file(dotdynadir / 'crash.log', 'wb') as crashreport: - h = VerboseTB(color_scheme='Linux', call_pdb=False, + h = VerboseTB(color_scheme='Linux', + call_pdb=False, ostream=crashreport, - long_header=True, include_vars=True, + long_header=True, + include_vars=True, check_cache=None) h(etype, evalue, tb) # once for the user - h = VerboseTB(color_scheme='Linux', call_pdb=False, ostream=None, - tb_offset=0, long_header=False, include_vars=True, + h = VerboseTB(color_scheme='Linux', + call_pdb=False, + ostream=None, + tb_offset=0, + long_header=False, + include_vars=False, check_cache=None) h(etype, evalue, tb)