typo fixed.
[l3full.git] / l3gui / experimental.py
blob7e4ca949817ee498d27372ad47f3d3208eb2ff7f
2 # Author: Michael H. Hohn (mhhohn@lbl.gov)
4 # Copyright (c) 2006, The Regents of the University of California
5 #
6 # See legal.txt and license.txt
9 import l3gui.main
11 #* Experimenting:
12 from l3lang.ast import *
13 from l3lang.interp import *
14 from l3lang.repl import *
15 from l3gui.main import *
16 from l3gui.cruft.pylab import *
17 from l3gui.widgets import *
18 from l3gui.l3canvas import *
19 from l3gui.misc import *
20 from l3gui.misc import _get_props, _set_props, _safed
21 from l3lang.globals import *
23 from pickle import dumps
24 import pdb, os
25 from pdb import pm
26 from pprint import pprint
28 import sys
29 import pdb
30 def enter_debug(type, value, traceback):
31 pdb.post_mortem(traceback)
33 if 0:
34 sys.excepthook = enter_debug
36 # reset via
37 if 0:
38 sys.excepthook = sys.__excepthook__
40 def inline(st):
41 exec(st, globals())
43 # NO: gtk.threads_init()
44 gobject.threads_init()
45 gtk.main()
48 import profile, pstats
49 prof = profile.Profile()
50 prof.run('gtk.main()')
52 ps = pstats.Stats(prof)
53 ps.strip_dirs()
54 ps.sort_stats('cumulative').print_stats(40)
55 ps.sort_stats('time', 'stdname').print_stats(40)
57 # Function ... was called by
58 ps.print_callers()
60 # Function ... called
61 ps.print_callees()
63 #* Misc. tests:
64 fail_here
66 in running gnome-terminal inside the phenix setup:
68 (gnome-terminal:979): Pango-WARNING **: No builtin or dynamically
69 loaded modules were found. Pango will not work correctly. This
70 probably means there was an error in the creation of:
71 '/net/ribbon/scratch1/phenix/phenix-1.22a/build/intel-linux-2.4/python/etc/pango/pango.modules'
72 You may be able to recreate this file by running
73 pango-querymodules.
75 Trying this gives
77 # Pango Modules file
78 # Automatically generated file, do not edit
80 # ModulesPath = /net/ribbon/scratch1/phenix/phenix-1.22a/build/intel-linux-2.4/python/lib/pango/1.4.0/modules
83 which is a nonexistent file..
86 #* state handling
87 #** save
88 foo = save_state(w_, '/tmp/foo.state')
91 #** view
92 # VERY useful for debugging: tree structure, plain text!
93 pprint(utils.as_list(get_current_state(w_)))
96 #** load
97 bar = load_state(w_, '/tmp/foo.state')
98 gtk.main()
100 pprint(utils.file_unpickle('/tmp/bar.1'))
104 #* Iterators
105 #** find all instances of l3If
106 lc = w_.lib_canvas.view
107 print lc._nodes
108 print filter(lambda x: isinstance(x, l3If), lc._nodes)
110 t_if = filter(lambda x: isinstance(x, l3If), lc._nodes)[0]
111 print t_if._d_cond_marker.get_property("points")
113 t_set = filter(lambda x: isinstance(x, l3Set), lc._nodes)
114 for set in t_set:
115 print set._d_lhs_marker.get_property("points")
121 #* Persistence
122 utils.file_pickle(tree)
123 #** iterators
124 itr = iter([1,2,3])
125 for ii in itr:
126 print ii
128 itr = iter([1,2,3])
129 fn = utils.file_pickle(itr)
132 #* tree focus
133 w_.node_tree.view.widget.expand_to_path( w_.node_tree.view.start ) # yes
134 w_.node_tree.view.widget.row_activated(w_.node_tree.view.start, label_col )
135 # the cursor must be released somehow...
136 w_.node_tree.view.widget.set_cursor( w_.node_tree.view.start ) # no
137 w_.node_tree.view.widget.scroll_to_cell( w_.node_tree.view.start ) # no
141 #* canvas-embedded text, running program
142 raw = list(w_.canvas.view._nodes)[1]
144 print raw._textview.get_events()
146 # Inert widget.
147 print raw._textview.get_property("sensitive")
148 raw._textview.set_property("sensitive", False)
151 print raw._ltext.get_bounds()
152 buff = raw._textview.get_buffer()
153 print buff.get_text(*buff.get_bounds())
154 raw._loutline.hide()
159 #* canvas-embedded text widget
160 #** setup
161 view = w_.canvas.view
162 ra = w_.canvas.view.root().add
164 c_root = ra(canvas.CanvasGroup)
165 c_text = gtk.TextView()
166 c_text.get_buffer().set_text("short text")
168 if 0:
169 c_label = ra(canvas.CanvasWidget,
170 anchor = gtk.ANCHOR_NORTH_WEST,
171 # size_pixels = False,
172 # height = 2,
173 # width = 6,
175 size_pixels = True,
176 height = 20,
177 width = 200,
179 widget = c_text,
180 x = 15,
181 y = 15,
183 else:
184 c_label = c_root.add(canvas.CanvasWidget,
185 anchor = gtk.ANCHOR_NORTH_WEST,
186 # size_pixels = False,
187 # height = 2,
188 # width = 6,
190 size_pixels = True,
191 height = 20,
192 width = 200,
194 widget = c_text,
195 x = 15,
196 y = 15,
199 c_label.show()
200 c_text.show()
201 if 0:
202 c_root.hide()
203 c_label.hide()
204 c_text.hide()
205 print c_label.get_bounds()
207 #** tags
208 #*** setup
209 buff = c_text.get_buffer()
210 print [ii.get_offset() for ii in buff.get_bounds()]
212 tag_call = buff.create_tag()
213 tag_size = buff.create_tag( family = "Monospace")
215 buff.apply_tag(tag_size, *buff.get_bounds() )
216 buff.apply_tag(tag_call, *buff.get_bounds() )
218 print tag_call.get_priority()
219 print tag_size.get_priority()
222 #*** events
223 def tag_event(texttag, widget, event, iter):
224 print event.type
225 if event.type == gtk.gdk.BUTTON_PRESS:
226 if event.button == 1:
227 print "at: ", iter.get_offset()
228 texttag.set_property("weight", pango.WEIGHT_HEAVY)
230 elif event.type == gtk.gdk.BUTTON_RELEASE:
231 if event.button == 1:
232 texttag.set_property("weight", pango.WEIGHT_NORMAL)
234 return False
236 tag_call.connect("event", lambda *a: tag_event(*a))
239 #*** dynamic property adjust
240 print tag_size.get_property("size-points")
241 tag_size.set_property("size-points", 12)
244 #** buffer events
245 def re_tag_inserted_text(buffer, iter, text, length):
246 iter_to = iter.copy()
247 if not iter.backward_chars(length):
248 return False
250 if iter.has_tag(tag_size):
251 print "no tagging needed"
252 return False
254 buff.apply_tag(tag_size, iter, iter_to )
255 return False
257 buff.connect_after("insert-text", lambda *a: re_tag_inserted_text(*a))
261 #** pango font adjust -- whole widget
262 # font_desc = c_text.get_pango_context().get_font_description()
263 # print font_desc.get_size() # 10240 -- 10 pt font
264 # font_desc.set_size(fs_default / 10)
266 #* canvas work
268 #** canvas content
269 nds = w_.canvas.view._nodes
271 pprint(nds)
272 gtk.main()
276 #** canvas text
277 view = w_.canvas.view
278 ra = w_.canvas.view.root().add
279 c_label = ra(canvas.CanvasText,
280 x = 12, y = 12,
281 size_points = 12 * 1,
282 scale = 1.0,
283 scale_set = True,
284 text = "the test",
286 # c_label.set_property("scale", 0.5)
287 print c_label.get_property("size-set")
288 flush_events()
289 #*** scale test
290 # The item only moves; no font size change.
291 def affine_scale(sx, sy):
292 return (sx, 0.0, 0.0, sy, 0.0, 0.0)
294 c_label.affine_relative(affine_scale(0.2, 0.2))
295 flush_events()
298 #** canvas text
299 #*** init
300 view = w_.canvas.view
301 ra = w_.canvas.view.root().add
302 c_label = ra(canvas.CanvasText,
303 x = 12, y = 15,
304 size = 10 * pango.SCALE,
305 scale = 1.0,
306 scale_set = True,
307 size_set = True,
308 text = "the test",
311 #*** Resize test.
312 c_label.set_property("size", 15 * pango.SCALE) # Resize. Good.
313 flush_events()
315 # c_label.affine_relative( (0.5, 0.0, 0.0, 0.5, 0.0, 0.0) ) # Only moves...
316 # flush_events()
319 #*** Moving item test.
320 # Drag region is the bounding box. Easy to select.
321 class foo:
322 pass
324 self = foo()
326 def drag_event(item, event):
327 if event.type == gtk.gdk.BUTTON_PRESS:
328 if event.button == 1:
329 # sm: move group start
330 self.remember_x = event.x
331 self.remember_y = event.y
332 return True
334 elif event.type == gtk.gdk.MOTION_NOTIFY:
335 if event.state & gtk.gdk.BUTTON1_MASK:
337 # Get the new position and move by the difference.
339 # sm: move group
340 new_x = event.x
341 new_y = event.y
342 dx = new_x - self.remember_x
343 dy = new_y - self.remember_y
344 item.move(dx, dy)
345 self.remember_x = new_x
346 self.remember_y = new_y
347 return True
349 return False
350 print c_label.connect("event", drag_event)
353 #*** Font change test.
354 c_label.set_property("font", "monospace") # Font style name
355 c_label.set_property("size", 12 * pango.SCALE) #
356 flush_events()
359 #*** Color change test.
360 c_label.set_property("fill-color", "red")
361 flush_events()
365 #** CanvasText speed test
366 #*** create
367 view = w_.canvas.view
368 rg = w_.canvas.view.root().add(canvas.CanvasGroup)
369 ra = rg.add
370 def add(ii):
371 c_label = ra(canvas.CanvasText,
372 x = 2 + (ii % 10) * 7,
373 y = 5 + ii / 10,
374 size = 10 * pango.SCALE,
375 scale_set = True,
376 scale = 1.8, # ignored...
377 font = "monospace",
378 size_set = True,
379 text = "txt%d" % ii,
381 return c_label
382 text_l = [add(ii) for ii in xrange(0,1000)]
383 flush_events()
386 # Zoom does change position, but not size.
388 #*** change font and size
389 # Slow!:
390 for ii in text_l:
391 ii.set_property("font", "monospace")
392 ii.set_property("size", 12 * pango.SCALE)
393 flush_events()
395 # Fast:
396 for ii in text_l:
397 ii.set_property("font", "monospace")
398 ii.set_property("size", 8 * pango.SCALE)
399 flush_events()
401 # test
402 # "scale" is ignored (maybe try cairo backend?)
403 for ii in text_l:
404 ii.set_property("scale", 1.8)
405 ii.set_property("scale_set", True)
406 flush_events()
409 #*** remove
410 # Fast:
411 rg.destroy()
412 flush_events()
414 #** canvas text tags
415 view = w_.canvas.view
417 raw = l3Rawtext(view.w_, view)
418 ## raw.destroy()
420 buff = raw._ltext.get_buffer()
421 tag_call = buff.create_tag()
422 print tag_call.get_priority()
423 tag_call.set_priority(0)
425 def tag_event(texttag, widget, event, iter):
426 print event.type
427 # useless: iter.get_offset() is always 0 for mouse buttons
428 # never signalled: gtk.gdk.ENTER_NOTIFY, LEAVE_NOTIFY
429 if event.type == gtk.gdk.BUTTON_PRESS:
430 if event.button == 1:
431 print "at: ", iter.get_offset()
432 texttag.set_property("weight", pango.WEIGHT_HEAVY)
434 elif event.type == gtk.gdk.BUTTON_RELEASE:
435 if event.button == 1:
436 texttag.set_property("weight", pango.WEIGHT_NORMAL)
438 return False
440 print tag_call.get_property("size-set")
441 tag_call.set_property("size", view._pixpu_base * 10)
442 # tag_call.set_property("size-set", False)
444 tag_call.connect("event", lambda *a: tag_event(*a))
446 # To avoid:
447 # Text reverts to old size after apply_tag...
448 # buff.apply_tag(raw._tag_size, *buff.get_bounds() )
449 # The sequence create, edit, esc, apply_tag works...
451 raw._focus_dummy.grab_focus()
453 # raw._text_orig = buff.get_text(*buff.get_bounds())
454 buff.set_text( raw._text_orig )
456 buff.apply_tag(tag_call, *buff.get_bounds() )
457 # beg, _ = buff.get_bounds()
458 # end = beg.copy()
459 # end.forward_chars(4)
460 # beg.forward_chars(1)
461 # buff.apply_tag(tag_call, beg, end )
463 buff.apply_tag(raw._tag_size, *buff.get_bounds() )
465 # buff.get_tag_table().foreach(lambda tag, _: pprint(tag))
468 #** text handling, raw
473 #** pango font adjustments
474 # Using l3Rawtext
475 view = w_.canvas.view
476 ra = w_.canvas.view.root().add
478 font_desc = view.get_pango_context().get_font_description()
479 font_desc.set_stretch(pango.STRETCH_NORMAL)
480 fs_default = font_desc.get_size() # 10240 -- 10 pt font
481 font_desc.set_size(fs_default / 10)
483 print font_desc.get_size()
485 # Any effect?
486 c_label = ra(canvas.CanvasRichText,
487 x = 10,
488 y = 10,
489 width = 10,
490 height = 5,
491 text = "NEW SAMPLE TEXT",
493 c_label.show()
494 ## c_label.hide()
495 c_label.get_buffer()
499 #** edges and nodes
500 w_.canvas.view
501 pprint(w_.canvas.view._nodes)
502 pprint(w_.canvas.view._edges)
504 pprint(w_.canvas.view._pgraph._nodes)
505 pprint(w_.canvas.view._pgraph._edges)
507 (w_.canvas.view._edges[0]).lower_to_bottom()
510 w_.canvas.view._nodes[(2, 'root')].get_bounds()
513 #** canvas anti-aliasing
514 view = w_.canvas.view
515 view.get_property('aa')
516 view.set_property('aa', True) # only at init time.
518 # canvas color
519 view = canvas.Canvas(aa = True)
520 view.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("grey5") )
523 #** canvas item zoom, affine
524 view = w_.canvas.view
525 rt = list(view._nodes)[0]._ltext
529 #** canvas zoom
530 view = w_.canvas.view
532 # n.a.
533 # view.set_center_scroll_region(True)
534 view.set_pixels_per_unit(view._pixpu * 1.6)
535 gtk.main()
537 # pixel units:
538 print view.get_scroll_offsets() # pixels
539 print view.get_scroll_region() # world
540 view.scroll_to
541 view.set_scroll_region
543 # Get widget size
544 wc = view.get_allocation().width # pixels
545 hc = view.get_allocation().height
547 # Get the display size.
548 cxw, cyw = view.c2w(wc/2, hc/2)
550 view.world_to_window(0, 0)
551 view.window_to_world(400, 400)
553 # world units
554 view.get_size()
555 view.get_size_request()
557 view.parent.children()
558 view.parent.get_child_visible
560 # No good:
561 # >>> view.parent
562 # <gtk.HBox object (GtkHBox) at 0x40d6e8c4>
563 # >>> view.parent.get_parent_window().get_size()
564 # (774, 785)
569 # Don't:
570 # c_label.destroy()
572 # GnomeCanvas-ERROR **: file gnome-canvas-rich-text.c: line 1596
573 # (blink_cb): assertion failed: (text->_priv->layout)
575 # Huge font...
576 c_label = ra(canvas.CanvasRichText,
577 x = 2, y = 2,
578 width = 10 * cp_.font_size, height = 1 * cp_.font_size,
579 text = "sample text",
583 #** line drawing
584 ra = w_.canvas.view.root().add
585 edge = ra(
586 canvas.CanvasLine,
587 fill_color = 'black',
588 first_arrowhead = 0,
589 last_arrowhead = 0,
590 line_style = gtk.gdk.LINE_SOLID,
591 width_pixels = cp_.outline_width_normal,
592 points = [ 0,0, 20,20 ], # scaled units.
595 point_l = (edge).get_property('points') # by value..
598 #** motion via properties:
599 (edge).set_property('points', [ 0, 0, 20, 10])
601 (edge).set_property('points', [ 0, 0, 20, 5])
605 #* canvas rich text
606 canv = w_.canvas.view
609 #** focus dummy
610 focus_dummy = w_.canvas.view.root().add(canvas.CanvasItem)
611 focus_dummy.hide()
612 focus_dummy.grab_focus()
615 #** the group
616 label_root = w_.canvas.view.root().add(canvas.CanvasGroup)
619 #** the text
620 label_text = label_root.add(canvas.CanvasRichText,
621 x = 20,
622 y = 10,
623 width = 50,
624 height = 20,
625 grow_height = False,
626 ### grow_height = True,
627 editable = True,
628 cursor_visible = False,
629 cursor_blink = False,
633 #** the outline.
634 print label_text.get_bounds()
635 x1, y1, x2, y2 = label_text.get_bounds()
636 x1, y1 = canv.c2w(int(x1), int(y1))
637 x2, y2 = canv.c2w(int(x2), int(y2))
639 label_rect = label_root.add(canvas.CanvasRect,
640 x1 = x1, y1 = y1,
641 x2 = x2, y2 = y2,
642 fill_color = 'green',
643 outline_color = 'blue',
644 width_pixels = cp_.outline_width_normal,
647 label_rect.lower(1)
648 label_rect.show()
651 #** event handlers
652 def tag_event_1(texttag, widget, event, iter):
653 if event.type == gtk.gdk.BUTTON_PRESS:
654 if event.button == 1:
655 print "tag_event_1: ", texttag
656 return False
658 def tag_event(texttag, widget, event, iter):
659 # useless: iter.get_offset() is always 0 for mouse buttons
660 # never signalled: gtk.gdk.ENTER_NOTIFY, LEAVE_NOTIFY
661 if event.type == gtk.gdk.BUTTON_PRESS:
662 if event.button == 1:
663 print "at: ", iter.get_offset()
664 texttag.set_property("weight", pango.WEIGHT_HEAVY)
666 elif event.type == gtk.gdk.BUTTON_RELEASE:
667 if event.button == 1:
668 texttag.set_property("weight", pango.WEIGHT_NORMAL)
670 return False
672 def select_event(item, event, data = None):
673 if event.type == gtk.gdk.BUTTON_PRESS:
674 print 'button!'
675 ### item.grab_focus()
676 if event.button == 3:
677 item.hide()
678 return False
679 return False
682 #** tags
683 # Creation order has no effect on size override.
685 buff = label_text.get_buffer()
686 buff_text = "sample text"
687 buff.set_text(buff_text)
689 # Highlight.
690 gi = buff.get_iter_at_offset
691 ct = lambda color: buff.create_tag( background = color,
692 size = int(10 * canv._pixpu_base),
693 family = "Monospace",
695 tag_call = map(ct, ["blue", "grey90"])
697 ii = buff_text.find(" ", 0)
699 # Size
700 tag_size = buff.create_tag( size = int(10 * canv._pixpu_base),
701 family = "Monospace",
703 ### No text, serious delays:
704 ### tag_size = buff.create_tag( size = 10 * pango.SCALE,
705 ### family = "Monospace")
707 # Apply them.
708 # Application order has no effect on override.
709 ### buff.apply_tag(tag_size, *buff.get_bounds() )
710 ### buff.apply_tag(tag_call[0], gi(2), gi(ii))
712 ### # The overlapping region has NO tag's text size.
713 ### buff.apply_tag(tag_size, gi(0), gi(4) )
714 ### buff.apply_tag(tag_call[0], gi(2), buff.get_bounds()[1])
716 buff.apply_tag(tag_size, gi(0), gi(4) )
717 buff.apply_tag(tag_call[0], gi(4), gi(7))
718 buff.apply_tag(tag_call[1], gi(7), buff.get_bounds()[1])
721 # jj = buff_text.find(" ", ii + 1)
722 # if jj == -1:
723 # jj = len(buff_text)
725 # buff.apply_tag(tag_call[1],
726 # gi(ii), gi(jj))
728 print tag_size.get_priority()
729 print tag_call[0].get_priority()
731 # no effect on size...
732 # tag_size.set_priority(buff.get_tag_table().get_size() - 1)
734 if 0:
735 tag_size.set_property("size", canv._pixpu_base * 1.2)
738 #** Event connection.
739 tag_size.connect("event", lambda *a: tag_event(*a))
740 tag_call[0].connect("event", lambda *a: tag_event_1(*a))
741 tag_call[1].connect("event", lambda *a: tag_event_1(*a))
743 label_root.connect("event", select_event)
748 # No effect:
749 ### canv.set_pixels_per_unit(canv._pixpu)
750 # ugly hack:
751 canv._pixpu = (1.00001 * canv._pixpu)
752 canv.set_pixels_per_unit(canv._pixpu)
755 #** affine adjustment
756 # The affine transform changes the box bounds, but not the font size...
757 # label_text.affine_relative( (0.1, 0.0,
758 # 0.0, 0.1,
759 # 0.0, 0.0) )
761 # print label_text.get_bounds()
762 # print label_text.i2c_affine(tuple(range(0,6)))
763 # print label_text.i2w_affine(tuple(range(0,6)))
765 # label_text = label_root.add(canvas.CanvasRichText,
766 # x = 40, y = 40,
767 # width = 10 * cp_.font_size, height = 1 * cp_.font_size,
768 # text = "sample text",
771 #** tried and discarded
773 ### No effect (events not received?):
774 ### label_root.connect("event", select_event)
775 ### label_root.connect("event", focus_event)
778 ### massive delays when zooming:
779 ### tag_size = buff.create_tag(# size = 12 * w_.canvas.view._pixpu,
780 ### size_points = 12,
781 ### )
783 ### core dump after zoom:
784 ### tag_size = buff.create_tag(# size = 12 * w_.canvas.view._pixpu,
785 ### scale = 0.1,
786 ### )
788 gtk.main()
791 #* minimal window sample
792 def zoom_spin_button():
793 spinner_adj = gtk.Adjustment(2.500,
794 0.1, 5.0,
795 0.1,
796 1.0, 1.0)
798 spinner = gtk.SpinButton(spinner_adj, 0.001, 3)
800 # Minimal gtk window
801 l_window = gtk.Window()
802 l_window.connect("delete-event", lambda *args: l_window.destroy())
803 l_window.set_border_width(0)
804 l_window.add(spinner)
805 l_window.show_all()
807 zoom_spin_button()
808 gtk.main()
813 #* AST details
814 aa = String("""
815 first
816 second
817 """)
818 aa.source_string() # no_source...
820 aa = reader.parse("""
822 first
823 second
825 """).body()
826 print aa.source_string() # no_source...
827 print aa.l3_string()
831 #* program formation from gui; evaluation test.
832 def info(prog):
833 print
834 view.print_info(storage, prog, show_macros = True)
836 pgraph = w_.canvas.view._pgraph
837 chains, free_nodes = pgraph.identify_programs()
838 print "Free nodes found: ", free_nodes # modeline / popup?
840 print "Chains found: ",
841 pprint(chains)
843 print "============================================"
844 print "Chain links:"
845 [info(storage.load(foo)) for foo in chains[0] ]
848 programs = [pgraph.chain_to_program(ch,
849 w_.state_.def_env,
850 w_.state_.storage,
851 ) for ch in chains]
852 print "============================================"
853 print " Program:"
854 info(programs[0])
857 print "============================================"
858 print " Evaluation:"
859 value = programs[0].interpret(def_env, storage)
861 #* bpath testing
862 #** lines
863 cnvs = w_.canvas.view
864 from canvas import MOVETO_OPEN, MOVETO, LINETO, CURVETO, END
866 ls_path = canvas.path_def_new([(MOVETO, 10, 10),
867 (LINETO, 20, 30),
868 (LINETO, 30, 40),
869 (LINETO, 40, 45),
870 (END,)
872 ls_item = cnvs.root().add(canvas.CanvasBpath,
873 width_units = 0.3,
874 outline_color = "black",
875 fill_color = "green",
877 ls_item.set_bpath(ls_path)
878 #*** Display
879 flush_events()
880 gtk.main()
881 #*** Scale
882 def affine_scale(sx, sy):
883 return (sx, 0.0, 0.0, sy, 0.0, 0.0)
885 ls_item.affine_relative(affine_scale(0.7, 0.3))
886 flush_events()
888 ls_item.affine_relative(affine_scale(1/0.7, 1/0.3))
889 flush_events()
892 # cleanup
893 ls_item.destroy()
896 #** curves
897 cnvs = w_.canvas.view
898 from canvas import MOVETO_OPEN, MOVETO, LINETO, CURVETO, END
900 def test_path(path):
901 ls_path = canvas.path_def_new(path)
902 ls_item = cnvs.root().add(canvas.CanvasBpath,
903 width_units = 1.0/w_.cp_.font_size * 2,
904 outline_color = "black",
905 fill_color = "green",
906 cap_style = gtk.gdk.CAP_ROUND,
907 join_style = gtk.gdk.JOIN_ROUND,
909 ls_item.set_bpath(ls_path)
911 ll, tt, rr, bb = canvas_item_get_bounds_world(ls_item)
912 ls_item.move( 10 + w_.cp_.off_x - ll,
913 10 + w_.cp_.off_y - tt,
915 gtk.main()
916 ls_item.destroy()
920 #*** corner
922 # Rounded corner, leaving the bezier control points on the tangent lines.
924 # p1 X
928 # p2 O
930 # +---O---------X
931 # p3 p4
932 path = [(MOVETO, 0, 0), # p1
933 (CURVETO,
934 0, 8,
935 2, 10,
936 10,10,
938 # (END,) # close
940 test_path(path)
943 #*** rounded corner rectangle
944 # rectangle w/ rounded corners, leaving the bezier control points on
945 # the tangent lines.
946 # Note: using one definition, say on [0,1]x[0,1] and scaling will also
947 # scale the rounded edges, but these must have absolute size. [ie. the
948 # rounding size must be independent of the rectangle size.]
951 def path_rectangle_rounded(el, er,
952 et, eb, # edge positions
953 cv, ch, # corner point indentation
954 sv, sh, # spline control point indentation
956 assert (el < er)
957 assert (et < eb)
959 assert ((er - el) > 2*ch)
960 assert ((eb - et) > 2*cv)
962 path = [(MOVETO, el, et + cv),
964 (LINETO, el, eb - cv),
965 (CURVETO , # bottom left
966 el , eb - sv,
967 el + sh , eb,
968 el + ch , eb,
971 (LINETO, er - ch, eb), # bottom right
972 (CURVETO ,
973 er - sh , eb,
974 er , eb - sv,
975 er , eb - cv,
978 (LINETO, er, et + cv),
979 (CURVETO , # top right
980 er , et + sv ,
981 er - sh , et,
982 er - ch , et,
985 (LINETO, el + ch, et),
986 (CURVETO , # top left
987 el + sh , et,
988 el , et + sv,
989 el , et + cv,
992 return path
994 el = 0.0 + 20
995 er = 10 + 20
996 eb = 10 + 20
997 et = 0 + 20
999 cv = 1
1000 ch = 1
1002 sh = 0.2
1003 sv = 0.2
1005 test_path(path_rectangle_rounded(el, er, et, eb,
1006 cv, ch, sv, sh))
1008 test_path(path_rectangle_rounded(5, 10, 5, 20,
1009 1, 1, 0.3, 0.3))
1012 #** path group
1014 cnvs = w_.canvas.view
1015 from canvas import MOVETO_OPEN, MOVETO, LINETO, CURVETO, END
1017 class AttrDict:
1018 def __init__(self, dct):
1019 self.__dict__.update(dct)
1021 #*** no good
1023 # Scaling is expected to widen or heighten the object, retaining the
1024 # left upper corner. For this to happen with a simple call to
1025 # affine_relative(), the upper left of the original must be at 0,0,
1026 # and the drawing must be in the positive x and y directions.
1028 # The problem here is insufficient use of CanvasGroups.
1030 def draw_path(path, width_w, **props):
1031 # This drawing order shows nothing.
1033 # Draw the path.
1034 ls_path = canvas.path_def_new(path)
1035 ls_rg = cnvs.root().add(canvas.CanvasGroup)
1036 ls_item = ls_rg.add(canvas.CanvasBpath, **props)
1037 ls_item.set_bpath(ls_path)
1039 # Reposition.
1040 flush_events()
1041 ll, tt, rr, bb = canvas_item_get_bounds_world(ls_item)
1042 ls_item.move( -ll, -tt)
1044 # not this order.
1045 # Scale to size.
1046 flush_events()
1047 sx = sy = width_w / (rr - ll)
1048 print "scale: ", sx,sy
1049 ## ls_item.affine_relative( (sx, 0.0, 0.0, sy, 0.0, 0.0) )
1051 flush_events()
1052 ll, tt, rr, bb = canvas_item_get_bounds_world(ls_item)
1053 ls_item.move( 20 + w_.cp_.off_x - ll,
1054 10 + w_.cp_.off_y - tt,
1056 return AttrDict(locals())
1059 def draw_path(path, width_w, **props):
1060 # Draw the path.
1061 ls_path = canvas.path_def_new(path)
1062 ls_rg = cnvs.root().add(canvas.CanvasGroup)
1063 ls_item = ls_rg.add(canvas.CanvasBpath, **props)
1064 ls_item.set_bpath(ls_path)
1066 # Reposition.
1067 flush_events()
1068 ll, tt, rr, bb = canvas_item_get_bounds_world(ls_item)
1069 ls_item.move( 20 + w_.cp_.off_x - ll,
1070 10 + w_.cp_.off_y - tt,
1073 # Scale using the local coordinates (the group is unchanged).
1074 sx = sy = width_w / (rr - ll)
1075 ls_item.affine_relative( (sx, 0.0, 0.0, sy, 0.0, 0.0) )
1077 return AttrDict(locals())
1080 #*** good: proper affine nesting.
1082 # @@ name the groups.
1083 # distinct nested groups for group, center, scale and
1084 # translation.
1086 def draw_path(path, width_w, **props):
1087 # Get groups.
1088 grp_trans = cnvs.root().add(canvas.CanvasGroup)
1089 grp_scale = grp_trans.add(canvas.CanvasGroup)
1090 grp_obj = grp_scale.add(canvas.CanvasGroup)
1092 # Draw the path.
1093 ls_path = canvas.path_def_new(path)
1094 ls_item = grp_obj.add(canvas.CanvasBpath, **props)
1095 ls_item.set_bpath(ls_path)
1097 # Reposition for scaling around center.
1098 # flush_events()
1099 ll, tt, rr, bb = canvas_item_get_bounds_world(grp_obj)
1100 grp_obj.move( -(ll + rr)/2, -(tt + bb)/2 )
1102 # Scale.
1103 # flush_events()
1104 ll, tt, rr, bb = canvas_item_get_bounds_world(grp_scale)
1105 sx = sy = width_w / (rr - ll)
1106 grp_scale.affine_relative( (sx, 0.0, 0.0, sy, 0.0, 0.0) )
1108 # Translate for visibility.
1109 # flush_events()
1110 ll, tt, rr, bb = canvas_item_get_bounds_world(grp_trans)
1111 grp_trans.move( 20 + w_.cp_.off_x - ll,
1112 10 + w_.cp_.off_y - tt,
1115 return AttrDict(locals())
1119 #*** triangle right
1120 path = [
1121 (MOVETO , 0, 0 ),
1122 (LINETO , 20, 20 ),
1123 (LINETO , 0, 40 ),
1124 # (LINETO , 0, 0 ),
1125 (END,)
1128 #*** triangle down
1129 path = [
1130 (MOVETO, 0,0),
1131 (LINETO, 41,0),
1132 (LINETO, 21,20),
1133 # (LINETO, 0,0), # use end to close (avoid irregularities)
1134 (END,)
1137 #*** draw
1138 dct = draw_path(path,
1140 width_units = 1.0/w_.cp_.font_size * 2,
1141 outline_color = "black",
1142 fill_color = "black",
1143 cap_style = gtk.gdk.CAP_ROUND,
1144 join_style = gtk.gdk.JOIN_ROUND,
1147 w_.dct = dct
1148 flush_events()
1150 # Transforms.
1151 print w_.dct.ls_item.i2w_affine(tuple(range(0,6)))
1152 print w_.dct.grp_trans.i2w_affine(tuple(range(0,6)))
1154 # Group tests.
1155 w_.dct.grp_scale.affine_relative( (3, 0.0, 0.0, 3, 0.0, 0.0) ) # scale
1156 w_.dct.grp_trans.move(2,2)
1158 w_.dct.grp_trans.destroy()
1161 #* l3List test
1162 cnvs = w_.canvas.view
1163 list_ = l3List(w_, cnvs)
1165 cnvs.display_bounding_box( list_._head.get_bounds())
1166 list_.hide()
1168 # list_._root_group.connect("event", lambda *a: list_.drag_event(*a))
1169 # list_._head._root_group.connect("event", lambda *a: list_.drag_event(*a))
1170 # list_._alist._root_group.connect("event", lambda *a: list_.drag_event(*a))
1172 #* bounding box testing
1173 def bounds_world(item):
1174 x, y, u, v = item.get_bounds()
1175 return item.i2w(x,y) + item.i2w(u,v)
1177 # Outline bounds != outline corners. Why?
1178 print "bounds"
1179 print rawt._loutline.get_bounds()
1180 print [rawt._loutline.get_property(prop) for prop in ['x1', 'y1', 'x2', 'y2']]
1182 def bbox_test():
1183 self__lgroup = cnvs.root().add(canvas.CanvasGroup)
1185 self__textview = gtk.TextView()
1186 self__ltext = self__lgroup.add(canvas.CanvasWidget,
1187 size_pixels = False,
1188 height = 1.5, ### params
1189 width = 20,
1191 widget = self__textview,
1192 x = 10,
1193 y = 10,
1195 x1, y1, x2, y2 = self__ltext.get_bounds() # world units
1196 x1 -= 5 / cnvs._pixpu
1197 y1 -= 5 / cnvs._pixpu
1198 x2 += 5 / cnvs._pixpu
1199 y2 += 5 / cnvs._pixpu
1201 self__loutline = self__lgroup.add(
1202 canvas.CanvasRect,
1203 x1 = x1, y1 = y1,
1204 x2 = x2, y2 = y2,
1205 fill_color = 'white',
1206 outline_color = 'black',
1207 width_pixels = cp_.outline_width_normal,
1209 st = utils.Shared()
1210 st.__dict__.update( locals())
1211 return st
1212 st = bbox_test()
1214 print "st bounds"
1215 print st.self__loutline.get_bounds()
1216 print [st.self__loutline.get_property(prop)
1217 for prop in ['x1', 'y1', 'x2', 'y2']]
1218 # Off already.
1220 #################################
1221 def bbox_test():
1222 self__lgroup = cnvs.root().add(canvas.CanvasGroup)
1224 self__loutline = self__lgroup.add(
1225 canvas.CanvasRect,
1226 x1 = 10, y1 = 11,
1227 x2 = 20, y2 = 21,
1228 fill_color = 'white',
1229 outline_color = 'black',
1230 width_pixels = cp_.outline_width_normal,
1232 st = utils.Shared()
1233 st.__dict__.update( locals())
1234 return st
1235 st = bbox_test()
1237 print "st bounds"
1238 print st.self__loutline.get_bounds()
1239 print [st.self__loutline.get_property(prop)
1240 for prop in ['x1', 'y1', 'x2', 'y2']]
1241 # Off already.
1243 #################################
1244 def bbox_test():
1245 self__lgroup = cnvs.root().add(canvas.CanvasGroup)
1247 self__loutline = self__lgroup.add(
1248 canvas.CanvasRect,
1249 x1 = 10, y1 = 11,
1250 x2 = 20, y2 = 21,
1251 fill_color = 'white',
1252 outline_color = 'black',
1253 width_pixels = 1,
1255 return utils.Shared(**locals())
1256 st = bbox_test()
1258 print "st bounds"
1259 print st.self__loutline.get_bounds()
1260 print [st.self__loutline.get_property(prop)
1261 for prop in ['x1', 'y1', 'x2', 'y2']]
1262 # Off already.
1264 print st.self__ltext.get_bounds()
1266 #################################
1268 x, y, u, v = bounds_world(rawt._loutline)
1269 print u-x, v-y
1271 print "group bounds"
1272 print rawt._root_group.get_bounds()
1273 x, y, u, v = bounds_world(rawt._root_group)
1274 print u-x, v-y
1275 print bounds_world(rawt._root_group)
1277 print "text bounds"
1278 print rawt._ltext.get_bounds()
1279 x, y, u, v = bounds_world(rawt._ltext)
1280 print u-x, v-y
1281 print bounds_world(rawt._ltext)
1283 print "world"
1284 print rawt._loutline.i2w_affine(tuple(range(0,6)))
1285 print rawt._root_group.i2w_affine(tuple(range(0,6)))
1287 print "canvas"
1288 print rawt._loutline.i2c_affine(tuple(range(0,6)))
1289 print rawt._root_group.i2c_affine(tuple(range(0,6)))
1292 #* line testing
1293 cnvs = w_.canvas.view
1294 l_line = cnvs.root().add(canvas.CanvasLine,
1295 fill_color = "black",
1296 points = [10,1,
1297 20,2,
1298 10,3,
1299 20,5,
1301 width_units = 0.2,
1302 line_style = gtk.gdk.SOLID,
1303 cap_style = gtk.gdk.CAP_ROUND,
1304 join_style = gtk.gdk.JOIN_ROUND,
1305 smooth = False,
1306 spline_steps = 12,
1309 l_line = cnvs.root().add(canvas.CanvasLine,
1310 fill_color = "blue",
1311 points = [14,1,
1312 24,2,
1313 14,3,
1314 24,5,
1316 width_units = 0.2,
1317 line_style = gtk.gdk.SOLID,
1318 cap_style = gtk.gdk.CAP_ROUND,
1319 join_style = gtk.gdk.JOIN_ROUND,
1320 smooth = True,
1321 spline_steps = 2,
1323 print l_line.get_property('points')
1324 flush_events()
1326 #* polygon testing
1327 cnvs = w_.canvas.view
1328 l_line = cnvs.root().add(canvas.CanvasPolygon,
1329 fill_color = "black",
1330 points = [10,1,
1331 20,2,
1332 10,3,
1333 20,5,
1335 width_units = 0.2,
1336 cap_style = gtk.gdk.CAP_ROUND,
1337 join_style = gtk.gdk.JOIN_ROUND,
1340 l_line = cnvs.root().add(canvas.CanvasPolygon,
1341 fill_color = "black",
1342 points = [20, 20,
1343 40, 20,
1344 40, 40,
1345 20, 40,
1346 20, 20,
1348 width_units = 0.2,
1349 cap_style = gtk.gdk.CAP_ROUND,
1350 join_style = gtk.gdk.JOIN_ROUND,
1353 print l_line.get_bounds()
1355 print l_line.get_property('points')
1356 flush_events()
1359 #* canvas ast insertion / display
1360 tree = reader.parse("[d,e]")
1361 tree = reader.parse("function = { |x,y| x - y }")
1363 tree = reader.parse("""
1364 [ function = not_yet({ |x,y| x - y }),
1365 macro = not_yet([ |x,y| z = x - y ]),
1366 raw_expression = a - b,
1367 list = [],
1368 inline_python = '''
1369 from operator import *
1370 from l3lang.test.functions import axpy
1371 ''',
1372 program = [],
1374 """)
1375 tree.setup(empty_parent(), def_env, storage)
1376 view.print_info(storage, tree)
1377 w_.lib_canvas.view.start_add_l3tree(tree)
1378 flush_events()
1380 #* pango font work
1381 pcon = w_.lib_canvas.view.get_pango_context()
1382 pcon.list_families()
1383 pcon.list_families()[0].get_name()
1384 pcon.get_font_description()
1385 print pcon.get_font_description().get_size() / pango.SCALE
1387 # Select font.
1388 sz = 20
1389 sz_orig = 10
1390 font_desc = pcon.get_font_description().copy()
1391 font_desc.set_family("monospace")
1392 font_desc.set_size(sz_orig * pango.SCALE)
1394 # Set new canvas default.
1395 pcon.set_font_description(font_desc)
1397 # Get metrics.
1398 def dump_metrics():
1399 font = pcon.load_font(font_desc)
1400 metrics = font.get_metrics()
1401 # Font sizes are in pango_units.
1402 # 1 point == PANGO_SCALE pango_units
1403 # 1 pango_point = 1/72 inch
1404 fheight = (metrics.get_ascent() + metrics.get_descent())
1405 fwidth = metrics.get_approximate_digit_width()
1406 # print fwidth / pango.SCALE
1407 # print fheight / pango.SCALE
1408 return fwidth, fheight
1409 ## logi, ink = font.get_glyph_extents("m")
1411 def lines(st):
1412 l1 = st.count('\n')
1413 if st[-1] == '\n':
1414 # No content in last line.
1415 l1 -= 1
1416 if len(st) > 0:
1417 l1 += 1
1418 return max(0, l1)
1420 def width(st):
1421 return reduce(max, [len(line) for line in st.split('\n')], 0)
1424 #** Sizing using test string.
1425 view = w_.canvas.view
1426 ra = w_.canvas.view.root().add
1427 c_string = "01234\n" * 8
1428 c_label = ra(canvas.CanvasText,
1429 x = 12, y = 25,
1430 text = c_string,
1431 font_desc = font_desc,
1433 ## c_label.destroy()
1434 flush_events()
1437 #** Set 1 cu = 1 ex
1438 l1, t1, r1, b1 = c_label.get_bounds()
1439 print "x: cu / char", (r1 - l1) / width(c_string)
1440 print "y: cu / char", (b1 - t1) / lines(c_string)
1441 print view._pixpu_base
1442 print view._pixpu
1443 cu_p_char = (r1 - l1) / width(c_string)
1444 view._pixpu = view._pixpu * cu_p_char
1445 view.set_pixels_per_unit(view._pixpu )
1448 xoff = 30
1449 yoff = 70
1451 #*** Draw long string.
1452 lng_str = "the test string,\nusing two lines"
1453 lng_label = ra(canvas.CanvasText,
1454 x = xoff, y = yoff,
1455 anchor = gtk.ANCHOR_NORTH_WEST,
1456 text = lng_str,
1457 font_desc = font_desc,
1459 ## lng_label.destroy()
1460 # Verify canvas size ratio...
1461 l1, t1, r1, b1 = lng_label.get_bounds()
1462 print "x: cu / char", (r1 - l1) / width(lng_str)
1463 print "y: cu / char", (b1 - t1) / lines(lng_str)
1465 # Compare to font metric ratio...
1466 wid, hei = dump_metrics()
1467 print "metric h / w", 1.0*hei/wid
1470 #*** Draw substring at proper position.
1471 # sub_str = "test"
1472 # sub_start = lng_str.find(sub_str)
1473 sub_top = 1
1474 sub_lef = 6
1475 sub_str = lng_str.split('\n')[sub_top][sub_lef:]
1476 sub_label = ra(canvas.CanvasText,
1477 anchor = gtk.ANCHOR_NORTH_WEST,
1478 fill_color = "blue",
1479 x = xoff, y = yoff,
1480 text = sub_str,
1481 font_desc = font_desc,
1483 sub_label.move(sub_lef, 1.0 * sub_top / wid * hei)
1484 ## sub_label.destroy()
1485 # Verify size ratio...
1486 l1, t1, r1, b1 = sub_label.get_bounds()
1487 print "x: cu / char", (r1 - l1) / width(sub_str)
1488 print "y: cu / char", (b1 - t1) / lines(sub_str)
1490 # Compare to font metric ratio...
1491 wid, hei = dump_metrics()
1492 print "metric h / w", 1.0*hei/wid
1496 #** resizing tests
1497 #*** Set new font sizes.
1498 fsize = sz * pango.SCALE
1499 font_desc.set_size(fsize)
1500 c_label.set_property('size', fsize)
1501 lng_label.set_property('size', fsize)
1502 sub_label.set_property('size', fsize)
1503 flush_events()
1504 #*** Set 1 cu = 1 ex (horizontal)
1505 l1, t1, r1, b1 = c_label.get_bounds()
1506 print "x: cu / char", (r1 - l1) / width(c_string)
1507 print "y: cu / char", (b1 - t1) / lines(c_string)
1508 print view._pixpu
1509 cu_p_char = (r1 - l1) / width(c_string)
1510 view._pixpu = view._pixpu * cu_p_char
1511 view.set_pixels_per_unit(view._pixpu )
1512 flush_events()
1513 #*** Check vertical [cu]
1514 l1, t1, r1, b1 = c_label.get_bounds()
1515 print "x: cu / char", (r1 - l1) / width(c_string)
1516 print "y: cu / char", (b1 - t1) / lines(c_string)
1517 #*** Compare font metrics (points) at new sizes
1518 wid, hei = dump_metrics()
1519 print "metric h / w", 1.0*hei/wid
1522 #** Find matching font metric.
1523 wid, hei = dump_metrics()
1524 h_o_w = 1.0 * hei / wid
1525 print "metric h / w", h_o_w
1527 sz_bnds = range(4, 41)
1528 print "pt. height/ "
1529 print "size widtht "
1530 print "-------------------"
1531 for sz in sz_bnds:
1532 fsize = sz * pango.SCALE
1533 font_desc.set_size(fsize)
1534 wid, hei = dump_metrics()
1535 sz_hw = 1.0 * hei / wid
1536 print "%-6d %.5f" % (sz, sz_hw)
1540 #* tree & clone structure
1541 tw = TreeWork(storage)
1542 loads = storage.load
1543 printi = lambda xx: print_info(storage, xx)
1544 printai = lambda xx: print_all_info(storage, xx)
1546 # id from first Symbol('abserr') inside If
1547 mid = 30221
1548 printai(loads(mid))
1549 printai(tw.find_root(loads(mid)))
1551 gtk.main()
1552 # add header, run program, compare again
1553 printai(loads(mid))
1554 printai(tw.find_root(loads(mid)))
1556 gtk.main()
1557 # change `if abserrr...` to `if prints(abserrr...`
1558 # run again, compare
1559 # no longer connected:
1560 # printai(loads(mid))
1561 # printai(tw.find_root(loads(mid)))
1562 printai(loads(30150)) # main program
1564 # search for prints...
1565 # The subtree was replaced and is re-run, including abserr()
1568 # stats for printing all info:
1571 wrt return 1.0 / 2 * (xk + x / xk)
1572 single clone prefix dump, 20 lines
1573 infix, 1 line
1574 ratio 20
1576 full sqrt.l3:
1577 prefix dump, no clones, 135 lines
1578 prefix dump, all clones, 770 lines
1579 infix, 30 lines - 10 comment = 20 lines
1580 ratio (/ 135.0 20) 6.75
1582 def try(x, xn) body
1583 infix 4
1584 prefix 24 lines
1585 ratio 6
1588 show only clone starting points: Function, Program
1592 #** print_dot
1593 def print_dot(storage, tree):
1594 # Print every expression and its clones.
1595 # This is far too much detail; only l3 Function clones are needed.
1597 iter = tree.prefix_grpd(storage)
1598 # Outermost.
1599 nd, clone_lev, indent = iter.next()
1600 print nd.source_string()
1602 try:
1603 while 1:
1604 nd, clone_lev, indent = iter.next()
1605 if clone_lev == '(':
1606 print '(clone '
1607 nd, clone_lev, indent = iter.next()
1608 print nd._id, nd.source_string()
1609 if clone_lev == ')':
1610 print ')'
1612 except StopIteration:
1613 pass
1616 #** print_dot
1617 def print_dot(storage, tree):
1618 # Print expressions once, including clones.
1619 # For every expression, include the id and link to clone
1620 # parents/sources.
1622 # Problems:
1623 # The if expressions are missing their lead indent.
1624 # The clone sources may not appear explicitly (with id); e.g., in
1626 # 1 30920
1627 # if abserr(x, xn) > 0.0001:
1628 # return loop(x, xkp1(x, xn))
1629 # else:
1630 # return xn
1632 # 30254 -> 30920 /* clone of */
1633 # 30867 -> 30920 /* cloned by */
1635 # the Function 30254 is referenced, but only shows up inside other
1636 # text.
1639 iter = tree.prefix_grpd(storage)
1640 gaa = lambda id: storage.get_attributes(
1641 id, ["clone_of", "cloned_by", "interp_env"])
1643 try:
1644 while 1:
1645 nd, clone_lev, indent = iter.next()
1646 if isinstance(nd, Program):
1647 nid = nd._id
1648 print clone_lev, nid
1649 print nd.source_string()
1651 of, by, env = gaa(nid)
1652 if of:
1653 print "%(of)d -> %(nid)d /* clone of */" % locals()
1654 if by:
1655 print "%(by)d -> %(nid)d /* cloned by */" % locals()
1656 print
1657 except StopIteration:
1658 pass
1661 #** print_dot
1662 def print_dot(storage, tree):
1663 # Print expressions once, including clones.
1664 # For every expression, include the id and link to clone
1665 # parents/sources.
1667 # Problems:
1668 # - The if expressions are missing their lead indent.
1669 # - The clone sources may not appear explicitly (with id);
1670 # - Displaying ALL clones takes too much room;
1672 iter = tree.prefix_grpd(storage)
1673 gaa = lambda id: storage.get_attributes(
1674 id, ["clone_of", "cloned_by", "interp_env"])
1676 try:
1677 while 1:
1678 nd, clone_lev, indent = iter.next()
1679 if isinstance(nd, Program):
1680 nid = nd._id
1681 print nid, '[label="%s"]; /* clone level %d */' % \
1682 (repr(nd.source_string())[1:-1].replace(r"\n",
1683 "\l"),
1684 clone_lev)
1686 of, by, env = gaa(nid)
1687 if of:
1688 print "%(of)d -> %(nid)d [color=green]; /* clone of */" % locals()
1689 if by:
1690 print "%(by)d -> %(nid)d [color=blue]; /* cloned by */" % locals()
1691 print
1692 except StopIteration:
1693 pass
1695 #** use
1696 print """
1697 digraph foo {
1698 page = "8.5,11.0"; /* size of single physical page */
1699 size="7.5,10.0"; /* graph size */
1700 /* rotate=90; */
1701 /* ratio=fill; */
1702 /* rankdir=LR; */
1703 node [shape=plaintext];
1705 print_dot(storage, t_tree)
1706 print "}"
1708 # Program P is a clone of a Function F
1709 # cloned by a Call C
1713 sload = storage.load
1715 #* l3 paper
1716 #** program
1717 t_string = open('../l3lang/test/sqrt.l3').readlines()
1718 t_tree = reader.parse("".join(t_string))
1719 t_tree.setup(empty_parent(), def_env, storage)[0].set_outl_edges(self.w_, None)
1720 # print_info(storage, t_tree)
1721 print_all_info(storage, t_tree)
1722 w_.canvas.view.clear_state( )
1723 w_.canvas.view.start_add_l3tree(t_tree)
1724 flush_events()
1725 gtk.main()
1727 #* error tracking
1728 #** filtered
1729 # put tree on canvas.
1730 # use B-3 -> hide.
1731 # zoom.
1732 import linecache, sys
1733 def traceit(frame, event, arg):
1734 if event == "line":
1735 file = frame.f_code.co_filename
1736 # SET NAME:
1737 if "usr/tmp/python-" in file:
1738 lineno = frame.f_lineno
1739 line = linecache.getline(file, lineno)
1740 print "line %d: %s" % (lineno, line.rstrip())
1741 sys.stdout.flush()
1743 return traceit
1744 sys.settrace(None)
1745 sys.settrace(traceit)
1746 #** all
1747 import linecache, sys
1748 def traceit(frame, event, arg):
1749 if event == "line":
1750 file = frame.f_code.co_filename
1751 # SET NAME:
1752 if 1:
1753 ## if "usr/tmp/python-" in file:
1754 lineno = frame.f_lineno
1755 line = linecache.getline(file, lineno)
1756 print "%s:%d: %s" % (file, lineno, line.rstrip())
1757 sys.stdout.flush()
1759 return traceit
1760 sys.settrace(None)
1761 sys.settrace(traceit)
1764 pdb.run('w_.canvas.view.centered_zoom(0.1)')
1766 # The warning is printed through
1767 # def warn...
1768 # in
1769 # intel-linux-2.4/python/lib/python2.4/warnings.py
1770 # Maybe trap these?
1773 #* local evaluation
1774 self._canvas.display_bounding_box(canvas_item_get_bounds_world(self._blank))
1775 self._canvas.display_bounding_box(self.get_bounds_world())
1776 self._canvas.display_bounding_box(canvas_item_get_bounds_world(self._d_lhs_marker))
1777 self._canvas.display_bounding_box(canvas_item_get_bounds_world(self._root_group))
1778 self._canvas.display_bounding_box(canvas_item_get_bounds_world(self._blank))
1780 # bbox checks
1781 # self._canvas.display_bounding_box(self.get_bounds_world())
1782 self._canvas.display_bounding_box(canvas_item_get_bounds_world(self._root_group))
1784 self._canvas.display_bounding_box(self._expander.get_bounds_world())
1786 #* phenix refine display
1787 #** program
1788 t_tree = reader.parse_file(
1789 os.path.expandvars('$SPXROOT/l3lang/test/refine.l3'))
1790 t_tree.setup(empty_parent(), def_env, storage).set_outl_edges(self.w_, None)
1791 ## print_info(storage, t_tree)
1792 ## view.print_all_info(storage, t_tree)
1793 w_.canvas.view.clear_state()
1794 # SLOW! But interesting to watch.
1795 w_.canvas.view.start_add_l3tree(t_tree)
1796 flush_events()
1797 gtk.main()
1798 #** program, limited depth
1799 t_tree = reader.parse_file(
1800 os.path.expandvars('$SPXROOT/l3lang/test/refine.l3'))
1801 t_tree.setup(empty_parent(), def_env, storage).set_outl_edges(self.w_, None)
1803 # hide nodes at level N
1804 vista = w_.canvas.view._vis_tab = VisibilityTable() # Reset.
1805 N = 7
1806 vista.hide_at(t_tree, N)
1808 # Check
1809 # ld = w_.state_.storage.load
1810 # for id in vista.keys():
1811 # print ld(id)
1813 # Render
1814 w_.canvas.view.clear_state()
1815 w_.canvas.view.start_add_l3tree(t_tree)
1816 flush_events()
1817 gtk.main()
1818 #** nested Map
1819 t_tree = reader.parse("""
1820 input = {
1821 pdb = {
1822 file_name = 'None',},
1823 xray_data = {
1824 file_name = 'None',
1825 labels = 'None',},
1826 r_free_flags = {
1827 file_name = 'None',
1828 label = 'None',
1829 test_flag_value = 'None',
1830 disable_suitability_test = 'False',},
1831 experimental_phases = {
1832 file_name = 'None',
1833 labels = 'None',},
1834 monomers = {
1835 file_name = 'None',},}
1836 """)
1837 t_tree.setup(empty_parent(), def_env, storage).set_outl_edges(self.w_, None)
1838 ## print_info(storage, t_tree)
1839 ## view.print_all_info(storage, t_tree)
1840 w_.canvas.view.clear_state()
1841 w_.canvas.view.start_add_l3tree(t_tree)
1842 flush_events()
1843 gtk.main()
1844 #** various file's layout
1845 def layout_file(name, level = 7):
1847 t_tree = reader.parse_file(os.path.expandvars(name))
1848 t_tree.setup(empty_parent(), def_env, storage).set_outl_edges(self.w_, None)
1850 # hide nodes at LEVEL.
1851 vista = w_.canvas.view._vis_tab = VisibilityTable() # Reset.
1852 vista.hide_at(t_tree, level)
1854 # Render
1855 w_.canvas.view.clear_state()
1856 w_.canvas.view.start_add_l3tree(t_tree)
1857 flush_events()
1858 gtk.main()
1860 layout_file('$SPXROOT/l3lang/test/refine.l3')
1861 layout_file('$SPXROOT/l3lang/test/ctf.l3')
1862 layout_file('$SPXROOT/l3lang/test/golem_1.l3')
1864 #* legible data dumping via PyYAML (yaml)
1865 import yaml
1866 print yaml.load("""
1867 - foo
1868 - bar
1869 - baz
1870 """)
1871 print yaml.dump(['foo', 'bar', 'baz'])
1873 # full state
1874 # 1. Slow
1875 # 2. yaml.representer.RepresenterError: recursive objects are not
1876 # allowed: Env(30288, Env-30269-skel.blck, [Program at 0x40d79a8c, id
1877 # 30290])
1878 yaml.dump(get_current_state(w_), stream = sys.stdout)
1879 ## yaml.dump(py_obj, stream = None)
1881 yaml.load(ya_str)
1883 #* legible data dumping via syck (yaml)
1884 #** Trivial test.
1885 import syck
1886 print syck.load("""
1887 - foo
1888 - bar
1889 - baz
1890 """)
1891 print syck.dump(['foo', 'bar', 'baz'])
1894 #** Full state.
1896 # [Mon Apr 30 10:28:42 2007]
1897 # Fails on <weakproxy> instances
1898 # with error
1899 # AttributeError: viewList instance has no attribute '__reduce__'
1900 # and there is no customization hook.
1901 syck.dump(get_current_state(w_), sys.stdout)
1904 # [Mon Apr 30 10:35:19 2007]
1905 # Try a detour via pickle. This fails too:
1906 # (.:16125): GLib-GObject-WARNING **: cannot retrieve class for
1907 # invalid (unclassed) type `<invalid>' ** ERROR **: file pygenum.c:
1908 # line 60 (pyg_enum_repr): assertion failed:
1909 # (G_IS_ENUM_CLASS(enum_class)) aborting...
1910 # /net/hooknose/scratch1/hohn/t2/sparx-bin/bin/sparx.wrap: line 36:
1911 # 16125 Aborted python -i
1912 # Process Python exited abnormally with code 134
1914 # Works after removing some more unnecessary gtk information.
1915 import pickle, syck
1916 n_tree = pickle.loads( pickle.dumps(get_current_state(w_), protocol=2))
1917 syck.dump(n_tree, sys.stdout)
1920 # l3 graphical node (local eval)
1921 import syck
1922 print syck.dump(self)
1924 # l3 tree (local eval)
1925 print syck.dump(self._l3tree)
1928 #** misc
1929 print syck.load("""
1930 connections:
1931 horizontal layout
1932 -requires
1933 -display choice
1935 connections:
1936 [horizontal layout, requires, >
1937 display choice display choice display choice
1938 display choice display choice display choice
1941 connections:
1942 horizontal layout:
1943 requires: display choice (direction)
1944 afd: display
1947 2d layout -- requires -- comment parsing
1949 """)
1951 #** Compare state files via their yaml representations.
1952 import pickle, syck
1953 from l3lang.utils import *
1955 n_tree_1 = file_unpickle('st.1')
1956 syck.dump(n_tree_1, open('st.1.syck', 'w'))
1958 n_tree_2 = file_unpickle('st.2')
1959 syck.dump(n_tree_2, open('st.2.syck', 'w'))
1964 #* local evaluation
1965 #** code & clones
1966 ==== local console; exit with end-of-file (ctrl-d) ====
1968 import l3lang.view as view
1969 view.print_all_info(self.w_.state_.storage, self._l3tree)
1971 #** code & values
1973 #* canvasgroup
1974 lcan = w_.lib_canvas.view
1975 pprint(lcan.root().item_list)
1976 # local eval
1977 pprint(self._root_group.item_list)
1979 #* visibility tables testing.
1980 lcan = w_.lib_canvas.view
1981 (lcan._vis_tab)
1982 pprint(lcan._vis_tab)
1984 # Assuming constant tree and node offset:
1985 manually_chosen = {30098: 'vis_hide',
1986 30136: 'vis_hide',
1987 30143: 'vis_hide',
1988 30148: 'vis_hide',
1989 30158: 'vis_hide',
1990 30166: 'vis_hide'}
1992 lcan._vis_tab.replace_table( manually_chosen)
1993 # use "apply mark" on topmost element.
1995 #* state files
1996 /tmp/st.lib - compacted library only.
1997 /tmp/st.for-pre-run - loop sample
2000 #* l3 loop templates
2001 #** range iteration, function version.
2002 # for i in range(n,m):
2003 # body
2004 def _for(_n, _m, body):
2005 if (_n < _m):
2006 body(_n)
2007 return _for(_n + 1, _m, body)
2008 else:
2009 return 0
2011 _for(1, 7, {|i| print_(i) })
2012 _for(30, 31, {|i| foo })
2013 # _for(1, 5, lambda i: print_(i) )
2014 # Nesting is no problem:
2015 _for(1, 4, {|i|
2016 _for(-5, -1,
2017 {|j| print_("%d %d" % (i,j)) })})
2018 #** range, macro version
2019 # [Thu Feb 9 16:29:39 2006]
2020 # Better not to use this one...
2022 # for i in range(n,m):
2023 # body
2024 def _form(_n, _m):
2025 if (_n < _m):
2026 i = _n
2027 body
2028 return _form(_n + 1, _m)
2029 else:
2030 return 0
2032 _form(1, 5)
2034 # Paste, insert body, change "i" to new name, run.
2035 # Nesting requires unique _for names; the following has a problem::
2036 def _for(_n, _m):
2037 if (_n < _m):
2038 ii = _n
2039 print_(ii)
2040 ########
2041 def _for(_n, _m):
2042 if (_n < _m):
2043 jj = _n
2044 ########
2045 print_("%d %d" % (ii, jj))
2046 ########
2047 return _for(_n + 1, _m)
2048 else:
2049 return 0
2050 _for(1, 5)
2051 ########
2052 return _for(_n + 1, _m) # wrong _for
2053 else:
2054 return 0
2055 _for(1, 5)
2058 #* context for values
2060 # Given multiple values from a single expression and its clones, find
2061 # the dynamic context -- the changed arguments to
2062 # enclosing Functions, or (sigh) the changed values of the stacked
2063 # bindings. Complicated.
2065 import l3lang.view
2066 st = w_.state_.storage
2067 load = w_.state_.storage.load
2068 tw = ast.TreeWork(w_.state_.storage)
2072 #* value extraction
2074 # LOADING RESETS THE STORAGE TABLE AND OTHERS!
2076 # U s e t h e w _ a c c e s s p a t h !
2078 import l3lang.view
2079 st = w_.state_.storage
2080 load = w_.state_.storage.load
2081 tw = ast.TreeWork(w_.state_.storage)
2083 # Toplevel id (static).
2084 l3nd = w_.selector.get_selection()
2085 c_id = l3nd._l3tree._id
2086 print load(c_id)
2087 print load(c_id).source_string()
2089 # Dynamic id(s).
2090 clone_l = st.get_attribute(c_id, "interp_clone")
2091 print len(clone_l)
2093 # If no values: is the correct storage instance used?
2094 for id in clone_l:
2095 print id, st.get_attribute(id, 'interp_result')
2097 # For deeper nesting, follow the clone trail.
2098 st.get_attribute(id, "interp_clone")
2100 # Get the context
2101 cctxt = tw.get_call_ctxt(c_id)
2102 # Raw.
2103 pprint( cctxt)
2104 # With text.
2105 tw.print_call_ctxt(cctxt)
2107 # If clones were cloned, these may be non-empty?
2108 # for id in clone_l:
2109 # print tw.get_call_ctxt(id)
2111 # symbol('i') evaluated, has time stamp, but no value, no env? --
2112 # Use correct storage!
2113 id = clone_l[1]
2114 print id, st.get_attribute(id, 'interp_result')
2115 print id, st.get_attribute(id, 'interp_env')
2116 pprint( [id, st.get_attribute_table(id)])
2118 # enclosing program
2119 parent = tw.find_first_parent(load(id), (ast.Function, ast.Program))
2120 view.print_info(st, parent)
2121 print parent._eval_env.all_bindings() # empty
2122 print parent._eval_env.lookup('i') # value, at last...
2123 global L3_TRACE
2124 L3_TRACE = 1
2125 print parent._eval_env.ie_lookup('i')
2128 #* environment viewing
2129 # local eval for program
2130 (self._l3tree)._block_env.all_bindings()
2131 (self._l3tree)._eval_env.all_bindings()
2132 (self._l3tree)._eval_env.ls()
2133 # has print_'s time stamp, but no print.
2134 # [after loading /tmp/st.post-loop ]
2136 #* state examination
2137 # Failed to complete:
2138 print syck.dump(get_current_state(w_))
2140 import pickle, pickletools
2141 st = get_current_state(w_)
2142 pickletools.dis(pickle.dumps(st, protocol=2))
2145 # local eval
2146 import pickle
2148 print (self._l3tree)._eval_env.lookup('print_')
2149 # <function print_ at 0x40402ed4>
2151 n_tree = pickle.loads( pickle.dumps(self._l3tree, protocol=2))
2152 print (n_tree)._eval_env.lookup('print_')
2154 #* voea etc. sample problem
2155 #** python support functions
2156 from l3lang.external.golem import \
2157 create_write_gridprojections, \
2158 anglist2doc, \
2159 spidbprg, \
2160 Golem
2163 #** voea
2165 # caption = 'Delta theta (degrees)',
2166 if 1:
2167 deltheta = 10
2168 anglist = Golem.voea(deltheta)
2169 else:
2172 #** gridproj
2174 if 1:
2175 # caption = 'Filename of volume to project',
2176 volfile = "volext.spi"
2178 # caption = 'Kaiser-Bessel K parameter',
2179 K = 6
2181 # caption = 'Kaiser-Bessel alpha parameter',
2182 alpha = 1.75
2184 # caption = 'Projection file pattern',
2185 filepattern = 'proj{****}.tst'
2187 # print vol.get_xsize()
2188 create_write_gridprojections(
2189 Golem.getImage(volfile),
2190 anglist, K, alpha, filepattern)
2191 else:
2194 #** anglist2doc
2195 # caption = 'Spider doc filename',
2196 if 1:
2197 docfname = 'foo-doc.tst'
2198 anglist2doc(anglist, docfname)
2199 else:
2202 #** spidbprg
2204 if 1:
2205 # caption = 'Projection file pattern',
2206 filepattern = 'proj{****}.tst' # above!
2208 # caption = 'Projection start index',
2209 minindx = 1
2211 # caption = 'Projection stop index',
2212 maxindx = 10
2214 # caption = 'Name of angle Spider doc file',
2215 angdocfile = docfname # above!
2217 # caption = 'Name of reconstructed volume',
2218 newvolname = 'newvol.spi'
2219 spidbprg(filepattern,
2220 minindx,
2221 maxindx,
2222 angdocfile,
2223 newvolname,
2225 else:
2228 # comparison in v4 shows newvolname to be poor...
2230 #* voea/bp as single program
2231 #** program
2232 tree = reader.parse("""
2233 inline '''
2234 from l3lang.external.golem import \
2235 create_write_gridprojections, \
2236 anglist2doc, \
2237 spidbprg, \
2238 Golem
2241 def _for(_n, _m, body):
2242 if (_n < _m):
2243 body(_n)
2244 return _for(_n + 1, _m, body)
2245 else:
2246 return 0
2248 def body(deltheta):
2249 if 1:
2250 anglist = Golem.voea(deltheta)
2251 else:
2254 # gridproj
2256 if 1:
2257 # caption = 'Filename of volume to project',
2258 volfile = "volext.spi"
2260 # caption = 'Kaiser-Bessel K parameter',
2261 K = 6
2263 # caption = 'Kaiser-Bessel alpha parameter',
2264 alpha = 1.75
2266 # caption = 'Projection file pattern',
2267 filepattern = 'proj{****}.tst'
2269 # print vol.get_xsize()
2270 create_write_gridprojections(
2271 Golem.getImage(volfile),
2272 anglist, K, alpha, filepattern)
2273 else:
2276 # anglist2doc
2277 # caption = 'Spider doc filename',
2278 if 1:
2279 docfname = 'foo-doc.tst'
2280 anglist2doc(anglist, docfname)
2281 else:
2284 # spidbprg
2286 if 1:
2287 # caption = 'Projection file pattern',
2288 filepattern = 'proj{****}.tst' # above!
2290 # caption = 'Projection start index',
2291 minindx = 1
2293 # caption = 'Projection stop index',
2294 maxindx = 10
2296 # caption = 'Name of angle Spider doc file',
2297 angdocfile = docfname # above!
2299 # caption = 'Name of reconstructed volume',
2300 newvolname = 'newvol.spi'
2301 spidbprg(filepattern,
2302 minindx,
2303 maxindx,
2304 angdocfile,
2305 newvolname,
2307 else:
2310 _for(40, 42, body)
2311 """)
2313 #** Directory setup.
2314 import shutil, os
2315 ev = os.path.expandvars
2316 os.chdir(ev('$SPXROOT/l3lang/test'))
2317 print os.getcwd()
2318 shutil.rmtree('bp-test')
2319 os.mkdir('bp-test')
2320 os.chdir(ev('$SPXROOT/l3lang/test/bp-test'))
2321 print os.getcwd()
2322 shutil.copyfile(ev('$SPXROOT/l3lang/test/volext.spi'), 'volext.spi')
2325 #** setup and execute
2326 if 1: # graphical
2327 tree.setup(empty_parent(), def_env, w_.state_.storage).set_outl_edges(self.w_, None)
2328 # view.print_info(storage, tree)
2329 w_.canvas.view.start_add_l3tree(tree)
2330 flush_events()
2332 if 2: # textual
2333 from l3lang import utils, reader, ast, view, interp
2334 play_env = interp.get_child_env(def_env, storage)
2335 tree.setup(empty_parent(), def_env, storage).set_outl_edges(self.w_, None)
2336 tree.interpret(def_env, storage)
2337 pprint(os.listdir(os.getcwd()))
2341 #* voea/bp using docstrings
2342 # /net/cci/hohn/w/tmp/eman2/libpyEM/Golem
2343 #** program
2344 tree = reader.parse("""
2345 inline '''
2346 from l3lang.external.golemwrap import *
2349 def _for(_n, _m, body):
2350 if (_n < _m):
2351 body(_n)
2352 return _for(_n + 1, _m, body)
2353 else:
2354 return 0
2356 def body(deltheta):
2357 anglist = voea(deltheta)
2360 # Param setting.
2362 filepattern = 'proj{****}.tst'
2365 # gridproj
2367 gridproj(getImage("volext.spi"), # nesting...
2368 anglist,
2370 1.75,
2371 {filepattern = filepattern})
2373 # Param setting.
2374 docfname = 'foo-doc.tst'
2376 # anglist2doc
2378 anglist2doc(anglist, docfname)
2381 # spidbprg
2383 spidbprg(filepattern,
2386 docfname,
2387 'newvol.spi',
2390 _for(40, 42, body)
2391 """)
2393 #** Directory setup.
2394 import shutil, os
2395 ev = os.path.expandvars
2396 os.chdir(ev('$SPXROOT/l3lang/test'))
2397 print os.getcwd()
2398 shutil.rmtree('bp-test')
2399 os.mkdir('bp-test')
2400 os.chdir(ev('$SPXROOT/l3lang/test/bp-test'))
2401 print os.getcwd()
2402 shutil.copyfile(ev('$SPXROOT/l3lang/test/volext.spi'), 'volext.spi')
2405 #** setup and execute
2406 if 1: # graphical
2407 tree.setup(empty_parent(), def_env, w_.state_.storage).set_outl_edges(self.w_, None)
2408 # view.print_info(storage, tree)
2409 w_.canvas.view.start_add_l3tree(tree)
2410 flush_events()
2412 if 2: # textual
2413 from l3lang.external import golemwrap
2414 from l3lang import utils, reader, ast, view, interp
2415 play_env = interp.get_child_env(def_env, storage)
2416 tree.setup(empty_parent(), play_env, storage)
2417 tree.interpret(play_env, storage)
2418 pprint(os.listdir(os.getcwd()))
2420 #* voea/bp w/o spider
2421 #** program
2422 tree = reader.parse("""
2423 """)
2425 #** Directory setup.
2426 import shutil, os
2427 ev = os.path.expandvars
2428 os.chdir(ev('$SPXROOT/l3lang/test'))
2429 print os.getcwd()
2430 shutil.rmtree('bp-test')
2431 os.mkdir('bp-test')
2432 os.chdir(ev('$SPXROOT/l3lang/test/bp-test'))
2433 print os.getcwd()
2434 shutil.copyfile(ev('$SPXROOT/l3lang/test/volext.spi'), 'volext.spi')
2437 #** setup and execute
2438 if 1: # graphical
2439 tree.setup(empty_parent(), def_env, w_.state_.storage)
2440 # view.print_info(storage, tree)
2441 w_.canvas.view.start_add_l3tree(tree)
2442 flush_events()
2444 if 2: # textual
2445 from l3lang import utils, reader, ast, view, interp
2446 play_env = interp.get_child_env(def_env, storage)
2447 tree.setup(empty_parent(), def_env, storage)
2448 tree.interpret(def_env, storage)
2449 pprint(os.listdir(os.getcwd()))
2452 #* beautification.
2453 def pri(tree):
2454 view.print_info(storage, tree)
2456 pri( reader.parse("aa = ff(xx)"))
2457 pri( reader.parse("aa = ff(xx, yy)"))
2458 pri( reader.parse("! aa = ! ff( !xx)"))
2460 pri( reader.parse("aa = ff(xx)"))
2461 pri( reader.parse("(aa, bb) = ff(xx)"))
2463 reader.parse("!! aa symbol")
2466 # ---------------------------------
2467 from l3lang.ast import *
2468 l3tree = reader.parse("a = f(x)")[0][0]
2469 l3tree = reader.parse("(a,b) = f(x)")[0][0]
2470 l3tree = reader.parse("(a,b) = f(x,y)")[0][0]
2471 l3tree = reader.parse("a = f(x,y)")[0][0]
2473 # ---------------------------------
2474 # Test for the special case `a = f(x)` and its
2475 # variations.
2477 # def add_l3tree_set_tuple()
2478 ma = ast.Matcher()
2479 if ma.match(l3tree,
2480 Set(Marker('aa'),
2481 Call(Marker('ff'), Marker('xx')))):
2482 # Convert to a list of args and list of return values.
2483 _function = ma['ff'] # Symbol or expr.
2484 _in = ma['xx'] # aList of args.
2485 out = ma['aa']
2486 if ma.match(out, # a,b,... =
2487 Tuple(Marker('aa'))):
2488 _out = ma['aa'] # aList
2489 elif ma.match(out, # a =
2490 MarkerTyped(String('aa'), Symbol('symbol'))):
2491 _out = aList([ma['aa']]) # aList
2492 else:
2493 no_luck
2495 # Get documentation for _in, _out, and _function.
2496 print _out, _function, _in
2498 # Get paths for editables.
2499 # Using the unique id.
2501 # Assemble table.
2504 #* ExprMarker
2505 # The initial try at an expression marker. This version is too buggy;
2506 # the new one is in widgets.py, based on a merge of l3If and
2507 # Placeholder.
2510 class daExprMarker:
2511 pass
2513 def __init__(self, w_, cnvs, l3_parent, l3_pidx, d_expr):
2515 :Arguments:
2516 - `l3_parent` The raw l3 ast parent of d_expr._l3tree.
2517 Without propagation of events from the l3 ast to its
2518 display (the current case), l3_parent should not be
2519 drawn.
2520 - `l3_pidx` The index of d_expr._l3tree in l3_parent.
2521 - `d_expr` The displayed expression to be handled here.
2523 assert isinstance(d_expr, (wdgt.l3aList, wdgt.l3Base))
2524 assert isinstance(l3_parent, (ast.astType,))
2526 self.w_ = w_
2527 self._canvas = cnvs
2529 self._l3_parent = l3_parent
2530 self._l3_pidx = l3_pidx
2531 self._d_expr = d_expr
2533 # Display.
2534 self._root_group = cnvs.root().add(canvas.CanvasGroup)
2535 self._d_parent = None
2536 self._destroy_hook = [] # (func -> None) list
2537 self._vis_indic = None # visibility status indicator
2539 # Marker(s).
2540 self._marker_points = {}
2541 self._d_marker = self.draw_marker()
2542 self._d_marker.lower_to_bottom()
2544 # Inform obj of marker.
2545 # This directs physical detachment of d_expr from daExprMarker to
2546 # daExprMarker.detach, which forwards the tree detachment.
2547 d_expr.setup_marker(self._d_marker, self)
2550 # Align with respect to d_expr.
2552 flush_events()
2553 ## _, y, x, _ = d_if.get_bounds()
2554 ## u, v, _, _ = d_cond.get_bounds()
2555 ## d_cond.move(x - u, y - v)
2558 # Event handling.
2559 self._d_marker.connect("event", lambda *a: self.insert_event(*a))
2560 # Forwarding to parent is implicit.
2561 # # self._root_group.connect("event", lambda *a:
2562 # # self.drag_event(*a))
2563 daExprMarker.__init__ = __init__
2566 #** destroy subtree and display
2567 def destroy(self):
2568 self._d_expr
2569 self._destroy_hook
2570 self._root_group.destroy()
2571 daExprMarker.destroy = destroy
2573 l3Base.add_destroy_hook = add_destroy_hook
2574 l3Base._run_destroy_hook = _run_destroy_hook
2577 #** dragging
2578 l3Nested.drag_event = drag_event
2581 def detach(self, d_expr):
2582 if d_expr != self._d_expr:
2583 raise DisplayError("Detaching invalid child.")
2585 # Reparent graphical parts.
2586 d_expr.reparent_to_root()
2588 # Update reference.
2589 self._d_expr = None
2591 # Shift body parts.
2592 pass
2594 # Refresh decoration.
2595 pass
2597 # Move following items in parent.
2598 if self._d_parent:
2599 self._d_parent.new_size_for(self)
2601 # Update tree data.
2602 if self.w_.fluid_ref(detach_l3_tree = True):
2603 # Remove the old.
2604 self._l3_parent.detach_child(self.d_expr._l3tree._id,
2605 self.w_.state_.storage)
2606 # Insert a placeholder, to keep indices valid.
2607 dummy = ast.placeholder(self._l3_parent, self.w_.state_.storage)
2608 self._l3_parent.insert_child(self._l3_pidx, dummy)
2609 daExprMarker.detach = detach
2611 def draw_marker(self):
2612 cp = self.w_.cp_
2613 points = [0 , 0,
2614 cp.exp_marker_width , 0,
2615 cp.exp_marker_width , cp.exp_marker_height,
2616 0 , cp.exp_marker_height,
2617 0 , 0,
2619 _marker = self._root_group.add(
2620 canvas.CanvasPolygon,
2621 fill_color = "black",
2622 points = points,
2623 width_units = 0.2,
2624 cap_style = gtk.gdk.CAP_ROUND,
2625 join_style = gtk.gdk.JOIN_ROUND,
2627 self._marker_points[_marker] = points
2628 return _marker
2629 daExprMarker.draw_marker = draw_marker
2631 def insert_event(self, item, event):
2632 if event.type == gtk.gdk.BUTTON_PRESS:
2633 if event.button == 2:
2634 print "insert_event"
2635 if not self.w_.selector.have_selection():
2636 ten_second_message("No node selected.")
2637 return False
2638 else:
2639 self.insert(item, self.w_.selector.get_selection())
2640 return False
2641 daExprMarker.insert_event = insert_event
2643 def insert(self, marker, newobj):
2644 assert isinstance(newobj, l3Base)
2646 if marker != self._d_marker:
2647 raise DisplayError("Insertion from wrong marker.")
2649 # Avoid special cases:
2650 if newobj.contains_recursive(self._d_expr):
2651 ten_second_message("Cannot insert object into itself.")
2652 return
2654 if newobj._canvas != self._canvas:
2655 ten_second_message("Cannot move objects across displays. "
2656 "Use copy instead.")
2657 return
2659 # Validate slot.
2660 old_entry = self._l3_parent[self._l3_pidx]
2661 slot_available(self.w_, old_entry)
2663 # Update reference.
2664 self._d_expr = d_expr = newobj
2666 # Reparent object display.
2667 newobj.reparent(self)
2669 # Position new child.
2670 flush_events()
2671 l1, t1, _, _ = self._d_marker.get_bounds()
2672 l2, t2, _, _ = self._d_expr.get_bounds()
2673 d_expr.move(l1 - l2, t1 - t2)
2675 # Reposition rest.
2677 # Refresh decoration.
2679 # Move following items in parent.
2680 if self._d_parent:
2681 self._d_parent.new_size_for(self)
2683 # Update tree data.
2684 if self.w_.fluid_ref(insert_l3_tree = True):
2685 self._l3_parent.replace_child(old_entry._id, newobj._l3tree)
2687 # Inform obj of marker.
2688 newobj.setup_marker(self._d_marker, self)
2689 pass
2690 daExprMarker.insert = insert
2693 def get_bounds(self):
2694 """ Marker interface used in Nested.drag_event.
2696 return marker_get_bounds(self.w_, self._d_marker)
2697 daExprMarker.get_bounds = get_bounds
2701 #** exprmarker test
2702 l3_parent = reader.parse("a = f(x,y)")[0][0]
2703 play_env = interp.get_child_env(def_env, storage)
2704 l3_parent.setup(empty_parent(), play_env, storage)
2706 l3_pidx = 0
2707 d_expr = w_.canvas.view.start_add_l3tree(l3_parent[l3_pidx])
2708 d_expr.move(100, 100)
2710 the_marker = daExprMarker(w_, w_.canvas.view, l3_parent, l3_pidx, d_expr)
2712 find_child_index
2714 #* stuff
2715 other = ...
2716 [ future(operation, i, other) for i in list]
2718 # operation is a pure function, no envs. Future need not provide
2719 # environment.
2721 def print_(st):
2722 print st
2724 def compute(_n, _m):
2725 if (_n < _m):
2726 print_( (_n + 1) * _m)
2727 return compute(_n + 1, _m)
2728 else:
2729 return _n
2731 compute(10,20)
2733 tree = reader.parse("""
2734 inline '''
2735 from l3lang.l3_utils import print_, pprint
2737 def compute(_n, _m):
2738 if (_n < _m):
2739 print_( (_n + 1) * _m)
2740 return compute(_n + 1, _m)
2741 else:
2742 return _n
2743 """)
2744 tree.setup(empty_parent(), def_env, w_.state_.storage)
2745 w_.canvas.view.start_add_l3tree(tree)
2747 # use functions,
2748 # use tail calls,
2749 # do not:'
2750 j = 0
2751 for i in range(0,10):
2752 j = j + i
2753 pass
2755 #* eman2 cruft
2756 from pprint import pprint
2757 from pdb import pm
2758 import atexit, pdb, sys, os
2759 from EMAN2 import EMData
2760 import EMAN2
2762 ev = os.path.expandvars
2763 print os.getcwd()
2764 os.chdir(ev('$SPXROOT/l3lang/test'))
2765 def load( file_name ):
2766 img = EMData()
2767 img.read_image( file_name )
2768 return img
2769 #** List available functionality.
2770 pprint(EMAN2.Processors.get_list())
2771 pprint(EMAN2.Projectors.get_list())
2772 pprint(EMAN2.Reconstructors.get_list())
2773 pprint(EMAN2.Cmps.get_list())
2774 #** Dump ALL get_list containing members.
2775 for nm in dir(EMAN2):
2776 try:
2777 memb = eval("EMAN2.%s.get_list" % nm)
2778 except AttributeError:
2779 continue
2780 print ("EMAN2.%s.get_list" % nm)
2781 print memb()
2782 #** simple mirror test
2783 from EMAN2 import *
2784 e = EMData()
2785 e.set_size(3,3)
2786 e.set_value_at(0,1, 1.0)
2787 print "original at start"
2788 e.print_image()
2790 # Use the processors listed by .get_list() above.
2791 f1 = e.process("mirror",{"axis":'x'})
2792 print "new mirrored image"
2793 f1.print_image()
2795 print "original after mirror (unchanged)"
2796 e.print_image()
2798 e.process_inplace("mirror",{"axis":'x'})
2799 print "original after in-place mirror"
2800 e.print_image()
2802 # Another possibility:
2803 e = EMData()
2804 e.set_size(3,3)
2805 e.set_value_at(0,0, 1.0)
2806 print "original at start"
2807 e.print_image()
2809 e = e.process("mirror",{"axis":'x'})
2810 print "new mirrored image"
2811 e.print_image()
2814 #* sample from andres' paper
2815 from EMAN2 import *
2816 #** build 3d model
2817 inline """
2818 from EMAN2 import EMNumPy
2819 def img_sphere(size, radius, axis, center, fill):
2820 from EMAN2 import EMData
2821 e = EMData()
2822 e.set_size(size, size, size)
2823 e.process_inplace('testimage.circlesphere',
2824 {'radius':radius, 'axis':axis,
2825 'c':center, 'fill':fill})
2826 return e
2830 sphere = img_sphere(32, 20, 'z', 15, 1)
2831 # Not useful.
2832 # sphere.print_image()
2834 # No slicing on emdata, use numpy array.
2835 t1 = EMNumPy.em2numpy(sphere)
2837 # View all 2d slices
2838 for ix in range(0,32):
2839 t1[ix, 0:None, 0:None]
2841 t1[0, 0]
2842 #** Try circle.
2843 inline """
2844 from EMAN2 import EMNumPy
2845 def img_circle(size, radius, center, fill):
2846 from EMAN2 import EMData
2847 e = EMData()
2848 e.set_size(size, size)
2849 e.process_inplace('testimage.circlesphere',
2850 {'radius':radius, 'c':center, 'fill':fill})
2851 return e
2853 circle = img_circle(32, 20, 15, 1)
2854 t1 = EMNumPy.em2numpy(circle)
2857 #** dither / diffuse
2858 #** form projections
2859 #** apply CTF
2860 #** add noise
2861 #** calculate SSNR
2862 #** and much more...
2863 # See "http://www.sciencedirect.com/science?_ob=ArticleURL&_udi=B6WM5-4HVMFBS-1&_user=635986&_coverDate=03%2F31%2F2006&_fmt=full&_orig=search&_cdi=6925&view=c&_acct=C000059612&_version=1&_urlVersion=0&_userid=635986&md5=0e4b1d3ea658eb6330884fef78c4b035&ref=full#SECX2"
2864 # 2D alignment and classification. Particles were normalized, low- and
2865 #high-pass filtered, soft-masked, and then centered. The low- and
2866 #high-pass filters were centered at 1/5 pixels1
2869 #* large list display
2870 xx = range(0,20000)
2871 # Insert as list list returns but keeps using 100% cpu
2873 xx = range(0,2000)
2874 # insert as list:
2875 # RuntimeError: maximum recursion depth exceeded in cmp
2877 # The number of bounds calculations (marker_get_bounds() and others)
2878 # is ~ N, and bounds calculations are VERY slow...
2880 #* Starting volume
2881 volume = load( "model.tcp" )
2883 proj = volume.project("pawel",
2884 {"angletype" : "SPIDER",
2885 "anglelist" : [10, 20, 30], # phi, theta, psi
2886 "radius" : 35 })
2890 #* visual program representation
2891 #** calc
2892 # Very convoluted example, heavily using higher-order functions.
2893 # Ugly in graphical view.
2894 t_tree = reader.parse_file(
2895 os.path.expandvars('$SPXROOT/l3lang/test/calc.l3'))
2896 t_tree.setup(empty_parent(), def_env, w_.state_.storage)
2897 w_.canvas.view.clear_state()
2898 w_.canvas.view.start_add_l3tree(t_tree)
2899 flush_events()
2902 #** ctf
2903 #*** full program
2904 # Very clean top-to-bottom script. Graphical view is still tedious.
2905 # Good reference for prototyping 'nice' graphical view w/o loops.
2906 tm_tree = reader.parse_file(
2907 os.path.expandvars('$SPXROOT/l3lang/test/ctf.l3'))
2908 tm_tree.setup(empty_parent(), def_env, w_.state_.storage)
2909 w_.canvas.view.clear_state()
2910 tm_tree_l3pic = w_.canvas.view.start_add_l3tree(tm_tree)
2911 flush_events()
2914 #*** concise view, program level, static
2915 # manually written
2916 # no program editing (static)
2917 t0_tree = reader.parse("""
2918 "project from volume"
2919 "convolve image and ctf"
2920 "produce noisy image"
2921 "apply ctf correction"
2922 "filter"
2923 """)
2924 t0_tree.setup(empty_parent(), def_env, w_.state_.storage)
2925 t0_tree_pic = w_.canvas.view.start_add_l3tree(t0_tree)
2926 flush_events()
2927 t0_tree_pic.move(+8, +5.5) # Relative movement.
2930 #*** concise view, program + calls, static
2931 # manually written
2932 # no program editing (static)
2933 t1_tree = reader.parse("""
2934 project_from_volume(spi.pj3)
2936 convolve_image_and_ctf(spi.ft, spi.tfc, spi.mu, spi.ft)
2938 produce_noisy_image(spi.mo, spi.adf)
2940 apply_ctf_correction(spi.tfcts)
2942 filter(spi.fq)
2943 """)
2944 t1_tree.setup(empty_parent(), def_env, w_.state_.storage)
2945 t1_tree_pic = w_.canvas.view.start_add_l3tree(t1_tree)
2946 flush_events()
2947 t1_tree_pic.move(+35, +7.5) # Relative movement.
2951 #*** concise view, program + manually selected details
2952 # manually written.
2953 # For ctf.l3, selected full subtrees are the desirable level of detail, so
2954 # no reordered node display is needed.
2955 # To keep the connection to the (function name based) outline view,
2956 # the function names can appear explicitly around the expansion.
2957 # For the present sample, this is redundant. Maybe not for others?
2958 t3_tree = reader.parse("""
2959 project_from_volume(
2960 spi.pj3(
2961 testimg = spi.pj3("/home/hohn/w/phenix/l3lang/test/volext.spi",
2962 [64, 64],
2963 [45.5, 27.2, -30.0])))
2965 convolve_image_and_ctf(
2966 spi.ft,
2967 spi.tfc(
2968 ctf = spi.tfc((2), # cs[mm]
2969 (10000, 0.025), # defocus(a), lambda(a)
2970 (64, 64), # dimension of the 2d array
2971 (0.17), # maximum spatial frequency
2972 (0.005, 0), # source size[a-1], defocus spread[a]
2973 (0, 0), # astigmatism[a], azimuth[deg]
2974 (0.1, 10000), # amplitude contrast ratio, gaussian envelope halfwidth
2975 (-1), # sign (+1 or -1)
2977 spi.mu,
2978 spi.ft)
2980 produce_noisy_image(
2981 spi.mo(
2982 noise = call_kwd_func(spi.mo, [64, 64], "random",
2983 { use_gaussian = 'y', mean = 1,
2984 std_deviation = 200} )),
2985 spi.adf)
2987 apply_ctf_correction(
2988 spi.tfcts(
2989 restored_img = spi.tfcts(spi.img_to_stack(noisyimg),
2990 [1, 1],
2991 spi.img_to_stack(ctf),
2992 100))
2995 filter(spi.fq)
2996 """)
2997 t3_tree.setup(empty_parent(), def_env, w_.state_.storage)
2998 t3_tree_pic = w_.canvas.view.start_add_l3tree(t3_tree)
2999 flush_events()
3000 t3_tree_pic.move(+70, +7.5) # Relative movement.
3003 #*** concise view, program + some full details
3004 # manually written
3005 # full program editing in the details
3006 # This version is disjoint from the others; it's missing the
3007 # "outline headers"
3008 t2_tree = reader.parse("""
3009 project_from_volume(
3010 testimg = spi.pj3("/home/hohn/w/phenix/l3lang/test/volext.spi",[64, 64],
3011 [45.5, 27.2, -30.0]))
3013 convolve_image_and_ctf(spi.ft,
3014 ctf = spi.tfc(
3015 (2), # cs[mm]
3016 (10000, 0.025), # defocus(a), lambda(a)
3017 (64, 64), # dimension of the 2d array
3018 (0.17), # maximum spatial frequency
3019 (0.005, 0), # source size[a-1], defocus spread[a]
3020 (0, 0), # astigmatism[a], azimuth[deg]
3021 (0.1, 10000), # amplitude contrast ratio, gaussian envelope halfwidth
3022 (-1), # sign (+1 or -1)
3023 ), spi.mu, spi.ft)
3025 produce_noisy_image(
3026 noise = call_kwd_func(spi.mo, [64, 64], "random",
3027 { use_gaussian = 'y', mean = 1,
3028 std_deviation = 200} ),
3029 spi.adf)
3031 apply_ctf_correction(restored_img = spi.tfcts(spi.img_to_stack(noisyimg),
3032 [1, 1],
3033 spi.img_to_stack(ctf),
3034 100)
3037 filter(spi.fq)
3038 """)
3039 t2_tree.setup(empty_parent(), def_env, w_.state_.storage)
3040 t2_tree_pic = w_.canvas.view.start_add_l3tree(t2_tree)
3041 flush_events()
3042 t2_tree_pic.move(+135, +7.5) # Relative movement.
3045 #* LOOP language addition.
3046 import pdb
3047 import l3lang
3048 from l3lang import utils, reader, ast, view, interp
3050 t2_tree = reader.parse("""
3051 inline "from pprint import pprint"
3052 loop dtheta(iteration, deltheta) from (1, 40):
3053 if iteration <= 10:
3054 pprint([iteration, deltheta])
3055 return dtheta(iteration + 1, deltheta / 2.0)
3056 else:
3057 return deltheta / 2.0
3058 """)
3060 play_env = interp.get_child_env(def_env, w_.state_.storage)
3062 if 2: # textual
3063 t2_tree.setup(empty_parent(), play_env, w_.state_.storage)
3064 t2_tree.interpret(play_env, w_.state_.storage)
3066 if 1: # graphical
3067 t2_tree.setup(empty_parent(), play_env, w_.state_.storage)
3068 # view.print_info(storage, tree)
3069 # pdb.run('w_.canvas.view.start_add_l3tree(t2_tree)')
3070 # b l3Loop.__init__
3071 ## fix:
3072 ##l3gui.misc.DisplayError: internal _container / _parent inconsistency.
3073 ##w_.canvas.view.clear_state()
3074 w_.canvas.view.start_add_l3tree(t2_tree)
3075 flush_events()
3076 gtk.main()
3079 #* LIST language addition.
3080 import pdb
3081 import l3lang
3082 from l3lang import utils, reader, ast, view, interp
3084 # w/o label.
3085 t2_tree = reader.parse("""
3086 inline "from pprint import pprint"
3087 list:
3089 iteration = 5
3090 if iteration <= 10:
3091 pprint([iteration])
3092 else:
3093 pprint((iteration, "small"))
3095 """)
3097 # with label.
3098 t2_tree = reader.parse("""
3099 inline "from pprint import pprint"
3100 list "A short block":
3102 iteration = 5
3103 if (iteration <= 10):
3104 pprint([iteration])
3105 else:
3106 pprint((iteration, "small"))
3108 """)
3110 play_env = interp.get_child_env(def_env, w_.state_.storage)
3112 if 1: # graphical
3113 t2_tree.setup(empty_parent(), play_env, w_.state_.storage)
3114 w_.canvas.view.start_add_l3tree(t2_tree)
3115 flush_events()
3116 gtk.main()
3118 if 2: # textual
3119 t2_tree.setup(empty_parent(), play_env, w_.state_.storage)
3120 t2_tree.interpret(play_env, w_.state_.storage)
3126 #* jsb paper
3128 The reference files for these fragments are now
3130 l3lang/test/voea-bp.py, v1.7 and beyond
3132 voea-bp-var.l3, v1.5 and beyond
3134 #** utils (evaluate this!)
3135 def canvas_add_program(text, xx = 0, yy = 0):
3136 t0_tree = reader.parse(text)
3137 t0_play_env = interp.get_child_env(def_env, w_.state_.storage)
3138 t0_tree.setup(empty_parent(), t0_play_env, w_.state_.storage)
3139 t0_tree_l3pic = w_.canvas.view.start_add_l3tree(t0_tree)
3140 t0_tree_l3pic.move(xx, yy) # Relative movement.
3142 def canvas_add_1st_expr(text, xx = 0, yy = 0):
3143 t0_tree = reader.parse(text)[0][0]
3144 t0_tree.setup(empty_parent(), def_env, w_.state_.storage)
3145 t0_tree_l3pic = w_.canvas.view.start_add_l3tree(t0_tree)
3146 t0_tree_l3pic.move(xx, yy) # Relative movement.
3148 def canvas_add_ast(self, t0_tree, xx = 0, yy = 0):
3149 from l3lang import utils, reader, ast, view, interp
3150 st = self.w_.state_
3151 t0_play_env = interp.get_child_env(st.def_env, st.storage)
3152 t0_tree.setup(ast.empty_parent(), t0_play_env, st.storage)
3153 t0_tree_l3pic = self.start_add_l3tree(t0_tree)
3154 t0_tree_l3pic.move(xx, yy) # Relative movement.
3155 return t0_tree_l3pic
3156 l3Canvas.canvas_add_ast = canvas_add_ast
3159 # print "\n".join(map(lambda (x,y): "%g %g" % (x,y),
3160 # (zip([1,2], [3,4]))))
3163 #*** plot
3164 def plot(x_l, y_l):
3165 data = "\n".join(map(lambda (x,y): "%g %g" % (x,y),
3166 zip(x_l, y_l)))
3167 os.system("""
3168 gnuplot -persist <<EOF
3170 set term post 24
3171 set out "/tmp/foo.ps"
3173 set grid
3174 set nokey
3175 ## set title "comparison"
3177 plot '-' w lines lw 6
3181 ps2epsi /tmp/foo.ps /tmp/foo.eps
3182 gv /tmp/foo.eps &
3183 """ % data)
3184 pass
3186 ## plot([1,2], [3,4])
3189 #*** directory of program run
3190 # See Program.directory
3193 #** voea-bp
3194 # #*** concise view, program level, static
3195 # # manually written
3196 # # no program editing (static)
3197 # t0_tree = reader.parse("""
3198 # "get reference volume"
3199 # "iterate delta theta"(
3200 # "calculate angles",
3201 # "projections",
3202 # "backproject",
3203 # "compare volumes",
3204 # "repeat if necessary")
3205 # """)
3206 # t0_play_env = interp.get_child_env(def_env, w_.state_.storage)
3207 # t0_tree.setup(empty_parent(), t0_play_env, w_.state_.storage)
3208 # ## w_.canvas.view.clear_state()
3209 # t0_tree_l3pic = w_.canvas.view.start_add_l3tree(t0_tree)
3210 # t0_tree_l3pic.move(+8.5, +7.5) # Relative movement.
3211 # flush_events()
3214 # #*** concise view, program + calls, static
3215 # # manually written
3216 # # no program editing (static)
3217 # t1_tree = reader.parse("""
3218 # "get reference volume"
3219 # "iterate delta theta"(
3220 # "calculate angles"(anglist = voea(deltheta)),
3221 # "projections"(proj_list = gridproj(ref_vol,
3222 # anglist,
3223 # 6,
3224 # 1.75)),
3225 # "backproject"(back_projection = backproj(proj_list,
3226 # anglist,
3227 # 0.4),
3228 # ),
3229 # "compare volumes"(ccc = EMAN2.Cmps.get("ccc").cmp(back_projection,
3230 # ref_vol)),
3231 # "repeat if necessary"(if_branch))
3232 # """)
3233 # t1_play_env = interp.get_child_env(def_env, w_.state_.storage)
3234 # t1_tree.setup(empty_parent(), t1_play_env, w_.state_.storage)
3235 # ## w_.canvas.view.clear_state()
3236 # t1_tree_l3pic = w_.canvas.view.start_add_l3tree(t1_tree)
3237 # t1_tree_l3pic.move(+42, +7.5) # Relative movement.
3238 # flush_events()
3241 #*** full program
3242 # Very clean top-to-bottom script
3243 tm_tree = reader.parse_file(
3244 os.path.expandvars('$SPXROOT/l3lang/test/voea-bp.l3'))
3245 tm_play_env = interp.get_child_env(def_env, w_.state_.storage)
3246 tm_tree.setup(empty_parent(), tm_play_env, w_.state_.storage)
3247 # w_.canvas.view.clear_state()
3248 tm_tree_l3pic = w_.canvas.view.start_add_l3tree(tm_tree)
3249 # tm_tree_l3pic.move(+77, +7.5) # Relative movement.
3250 gtk.main()
3253 #** Add text tree to canvas
3255 # num_angles
3256 # [12L, 13L, 27L, 59L, 195L]
3257 # Figure
3258 canvas_add_1st_expr("""
3259 # ccc
3261 0.8645,
3262 0.3051,
3263 0.1503,
3264 0.2821,
3265 0.5498,
3267 """)
3268 canvas_add_1st_expr("""
3269 # deltheta
3277 """)
3279 canvas_add_program("""
3280 from l3lang.test.voea_bp_support import *
3281 plot(
3282 # deltheta
3290 # ccc
3292 0.8645,
3293 0.3051,
3294 0.1503,
3295 0.2821,
3296 0.5498,
3299 """, xx=30, yy=50)
3301 # Figure from gnuplot
3304 #** get the diretory structure
3305 #*** in full
3306 ## use program -> eval locally
3307 # Static structure
3308 (self._l3tree)._block_env.print_tree()
3310 # After execution.
3311 (self._l3tree)._eval_env.print_tree()
3313 # As lists of names.
3314 # Too much content.
3315 from pprint import pprint
3316 pprint((self._l3tree)._block_env.get_tree())
3317 pprint((self._l3tree)._eval_env.get_tree())
3320 #*** More filtered.
3321 ## use program -> eval locally
3322 from pprint import pprint
3323 listing = (self._l3tree)._eval_env.get_dynamic_subtrees()
3324 pprint(listing)
3326 dir_struct = self._l3tree.directory(listing)
3327 dir_view = self._canvas.canvas_add_ast(dir_struct)
3328 dir_view.move(10, 10)
3331 #*** More^2 filtered.
3332 ## use program -> eval locally
3333 dir_struct = self._l3tree.directory_l3()
3334 dir_view = self._canvas.canvas_add_ast(dir_struct)
3335 dir_view.move(20, 20)
3337 # Figure
3338 dir_struct = List(aList([List(aList([List(aList([Symbol('volume'), Symbol('projections'), Symbol('errs'), Symbol('anglist'), Symbol('proj_list'), Symbol('back_projection'), Symbol('cross_corr'), Symbol('volfile'), Symbol('freqs'), Symbol('num_angles'), Symbol('angle_file'), Symbol('fsc_vals')])), Symbol('iteration'), Symbol('deltheta')])), List(aList([List(aList([Symbol('volume'), Symbol('projections'), Symbol('errs'), Symbol('anglist'), Symbol('proj_list'), Symbol('back_projection'), Symbol('cross_corr'), Symbol('volfile'), Symbol('freqs'), Symbol('num_angles'), Symbol('angle_file'), Symbol('fsc_vals')])), Symbol('iteration'), Symbol('deltheta')])), List(aList([List(aList([Symbol('volume'), Symbol('projections'), Symbol('errs'), Symbol('anglist'), Symbol('proj_list'), Symbol('back_projection'), Symbol('cross_corr'), Symbol('volfile'), Symbol('freqs'), Symbol('num_angles'), Symbol('angle_file'), Symbol('fsc_vals')])), Symbol('iteration'), Symbol('deltheta')])), List(aList([List(aList([Symbol('volume'), Symbol('projections'), Symbol('errs'), Symbol('anglist'), Symbol('proj_list'), Symbol('back_projection'), Symbol('cross_corr'), Symbol('volfile'), Symbol('freqs'), Symbol('num_angles'), Symbol('angle_file'), Symbol('fsc_vals')])), Symbol('iteration'), Symbol('deltheta')])), List(aList([List(aList([Symbol('volume'), Symbol('projections'), Symbol('errs'), Symbol('anglist'), Symbol('proj_list'), Symbol('back_projection'), Symbol('cross_corr'), Symbol('volfile'), Symbol('freqs'), Symbol('num_angles'), Symbol('angle_file'), Symbol('fsc_vals')])), Symbol('iteration'), Symbol('deltheta')])), Symbol('dtheta'), Symbol('spi'), Symbol('ref_vol')]))
3340 dir_view = w_.canvas.view.canvas_add_ast(dir_struct)
3341 dir_view.move(20, 20)
3344 import gtk
3345 gtk.main() # use menu->exit
3347 #* presentation-may-2006
3348 #** info
3349 # xterm reference size 120x50
3350 # plot:
3351 # convert /tmp/foo.ps -rotate 90 -resize 400x400 /tmp/foo.png
3352 #** library setup
3353 tm_tree = reader.parse("""
3354 list "library":
3355 list "em tasks":
3356 anglist2doc
3359 getImage
3360 gridproj
3361 imglist2stack
3362 spidbprg
3363 voea
3365 list "eman2 members":
3366 volume.save
3368 list "spider members":
3369 spi.bprg
3371 list "tools":
3372 init_spider
3373 setup_directory
3374 plot
3376 list "programming":
3377 PROGRAM
3378 { |x,y| x - y }
3382 (a = 2)
3383 call_function(a, b)
3385 {a = 1, b = 2}
3386 if condition:
3388 else:
3391 inline "from l3lang.test.voea_bp_support import *"
3393 loop name(arg) from (start_val):
3394 body
3395 """)
3397 tm_play_env = interp.get_child_env(def_env, w_.state_.storage)
3398 tm_tree.setup(empty_parent(), tm_play_env, w_.state_.storage)
3400 tm_tree_l3pic = w_.canvas.view.start_add_l3tree(tm_tree)
3402 gtk.main()
3405 #** value insertion preview
3406 # Figure
3407 canvas_add_1st_expr("""
3408 # ccc
3410 0.8645,
3411 0.3051,
3412 0.1503,
3413 0.2821,
3414 0.5498,
3416 """)
3417 canvas_add_1st_expr("""
3418 # deltheta
3426 """)
3428 canvas_add_program("""
3429 inline "from l3lang.test.voea_bp_support import *"
3430 plot(
3431 # deltheta
3439 # ccc
3441 0.8645,
3442 0.3051,
3443 0.1503,
3444 0.2821,
3445 0.5498,
3448 """, xx=30, yy=50)
3451 #* sparx functions as of [Jun-13-2006]
3453 #** Changed sparx imports to fix this.
3454 #** Trying to get an overview of the sparx functions
3455 # as of [Jun-13-2006]
3456 import sparx
3457 pprint(dir(sparx))
3459 # For this, the module structure SHOULD be useful. But it isn't
3460 # available interactively.
3462 # The following doesn't do much good. There are no comments, and
3463 # e.g. do_alignment (visible via dir(sparx)) is not shown at all.
3464 help(sparx)
3466 # This fails ...
3467 from sparx import libpy
3468 # with ImportError: cannot import name libpy.
3469 # Checking,
3470 sparx
3471 # is <module 'sparx' from '/net/hooknose/scratch1/hohn/rh9/ia32/installer-0.5/sparx-bin/opt/sparx/libpy/sparx.pyc'>
3473 # All because of the
3474 # from utilities import *
3475 # from filter import *
3476 # from projection import *
3477 # from fundamentals import *
3478 # from statistics import *
3479 # from alignment import *
3480 # from morphology import *
3481 # from reconstruction import *
3482 # in libpy/sparx.py!
3483 help(sparx.do_alignment)
3485 # So, I manually get the structure.
3486 # sparx
3487 # utilities
3488 # filter
3489 # projection
3490 # fundamentals
3491 # statistics
3492 # alignment
3493 # morphology
3494 # reconstruction
3496 # For nested modules, this should give information
3497 prfx, lst = ("sparx",
3498 ["utilities",
3499 "filter",
3500 "projection",
3501 "fundamentals",
3502 "statistics",
3503 "alignment",
3504 "morphology",
3505 "reconstruction",
3508 [help("%s.%s" % (prfx, itm)) for itm in lst]
3510 # But here it fails with
3511 # no Python documentation found for 'sparx.utilities'
3512 # no Python documentation found for 'sparx.filter'
3513 # no Python documentation found for 'sparx.projection'
3514 # ...
3515 # again because of the import *
3517 #** Overview of the sparx functions as of [Tue Jun 13 13:05:25 2006]
3518 import sparx.libpy as spx
3519 pprint(dir(spx))
3521 # module/function listing
3522 for mod in dir(spx):
3523 if not is_module(mod): continue
3524 for func in dir(mod):
3525 if not is_function(func): continue
3526 print "module: %s\t\tfunction: %s" % (mod, func)
3529 help(sparx)
3530 #** sparx.gui console use:
3531 import os
3532 tm_tree = reader.parse_file(
3533 os.path.expandvars('$SPXROOT/l3gui/test/iref01.py'))
3534 tm_play_env = interp.get_child_env(def_env, w_.state_.storage)
3535 tm_tree.setup(empty_parent(), tm_play_env, w_.state_.storage)
3536 tm_tree_l3pic = w_.canvas.view.start_add_l3tree(tm_tree)
3537 gtk.main()
3539 #* sparx persistence
3540 #** eman 'native' I/O
3541 import sparx as sx
3542 volume = sx.getImage( "model.tcp" )
3544 raw = sx.project(volume, [10.0, 20.0, 30.0, 0.0, 0.0], 35)
3545 raw.set(sx = 0)
3546 sx.info(raw)
3547 print raw.get_attr_dict()
3549 # Looks like spider format doesn't keep the attributes:
3550 sx.dropImage(raw, "raw.spi", itype = 's')
3551 raw_s = sx.getImage("raw.spi")
3552 sx.info(raw_s)
3553 print raw_s.get_attr_dict()
3554 print raw_s.sx
3556 # hdf works:
3557 sx.dropImage(raw, "raw.hdf")
3558 raw_s = sx.getImage("raw.hdf")
3559 sx.info(raw_s)
3560 print raw_s.get_attr_dict()
3561 print raw_s.sx
3562 #** pickling
3563 # Make sure there is no EMData.__getattr__ to avoid '__getinitargs__':
3564 # 'Not exist' caught crap.
3565 import l3lang.utils as ut
3566 ut.file_pickle(raw)
3567 raw_p = ut.file_unpickle("/tmp/foo")
3568 sx.info(raw)
3569 sx.info(raw_p)
3570 print raw.get_attr_dict()
3571 print raw_p.get_attr_dict()
3574 #** l3 state table pickling
3575 w_.state_.storage
3576 import l3lang.utils as ut
3577 ut.file_pickle(w_.state_.storage, "st.post-run-table")
3578 # takes forever; remove
3580 #* comment attachment
3581 # Similar to reader.raw_lexer(code_s)
3583 import sys, token, tokenize
3584 code_s = open(os.path.expandvars('$SPXROOT/l3gui/test/iref01.py')).read()
3587 #** comment parsing
3588 # Comment type identifier.
3589 COMMENT, _ = filter(lambda (k,v): v == 'COMMENT', token.tok_name.items())[0]
3590 NEWLINE, _ = filter(lambda (k,v): v == 'NEWLINE', token.tok_name.items())[0]
3591 NL, _ = filter(lambda (k,v): v == 'NL', token.tok_name.items())[0]
3595 #*** Cluster connected successive comment lines.
3596 # When connecting to the parse tree, this style of clustering has a
3597 # problem. Given
3599 # # comment 1
3601 # # comment 2
3603 # code 1
3604 # code 2
3606 # `comment 1` will attach to `code 1`, leaving `comment 2` to attach to
3607 # `code 2`, which is not good.
3609 # Choices:
3610 # - drop one of the comments, attach other to `code 1`
3611 # - combine comments and attach to `code 1`
3613 gen = tokenize.generate_tokens(reader.string_readline(code_s))
3614 st_accum = 0
3615 va_cluster = [] # (string, begin, end) list
3616 va_accum = [] # va_cluster list
3617 for ii in gen:
3618 (type, string, begin, end, line) = ii
3620 # Dump every comment.
3621 if type == COMMENT:
3622 print "(%r, %s, %s)" % (string, begin, end)
3624 # Cluster comment lines.
3625 if type in [COMMENT]:
3626 st_accum = 1
3627 va_cluster.append( (string, begin, end) )
3629 else:
3630 if st_accum:
3631 va_accum.append(va_cluster)
3632 st_accum = 0
3633 va_cluster = []
3635 # Dump data.
3636 pprint(va_accum, sys.stdout, 4, 2)
3639 #*** Cluster successive (incl.separated) comment lines
3640 # Combine blank-separated comment blocks.
3641 gen = tokenize.generate_tokens(reader.string_readline(code_s))
3642 st_accum = 0
3643 va_cluster = [] # (string, begin, end) list
3644 va_accum = [] # va_cluster list
3645 for ii in gen:
3646 (type, string, begin, end, line) = ii
3648 # # Dump every comment.
3649 # if type == COMMENT:
3650 # print "(%r, %s, %s)" % (string, begin, end)
3652 # Cluster successive comment lines, even those separated by blanks.
3653 if type in [COMMENT]:
3654 st_accum = 1
3655 va_cluster.append( (string, begin, end) )
3657 elif type in [NEWLINE, NL]:
3658 if st_accum:
3659 va_cluster.append( (string, begin, end) )
3660 else:
3661 if st_accum:
3662 # Remove trailing empty newlines.
3663 tl = ['\n']
3664 while tl[0] == '\n':
3665 tl = va_cluster.pop()
3666 va_cluster.append(tl)
3667 # Keep cluster.
3668 va_accum.append(va_cluster)
3669 st_accum = 0
3670 va_cluster = []
3672 pprint(va_accum)
3674 # Print cluster.
3675 for clus in va_accum:
3676 print clus[0][1] # begin
3677 for line in clus:
3678 print line[0], # body
3679 print clus[-1][2] # end
3680 print
3683 #*** Simplify comment structure
3684 # Adjust lexeme row indexing, compact clusters, and remove unused data.
3685 va_comments = [] # ((last_row, first_col), string) list
3686 va_comments = [
3687 ( (clus[-1][2][0] - 1, clus[0][1][1]), # (last_row, first_col)
3688 "".join([line[0] for line in clus]))
3689 for clus in va_accum ]
3690 pprint(va_comments)
3693 #** Tree work
3694 tree = reader.parse(code_s)
3697 #*** extract a list of leading subnodes from the parse tree
3698 lrow, lcol = -1, -1
3699 tr_lines = [] # [(start_row, col), node] list
3700 for nd in tree.subtrees():
3701 (row, col), _ = nd.get_char_range()
3702 # Prune all but first expression on a line.
3703 if row != lrow:
3704 tr_lines.append( [(row,col), nd] )
3705 ## tr_lines.append( [(row,col), nd] )
3706 lrow = row
3707 pprint(tr_lines)
3711 #** Find expression to attach to.
3712 # Consider only the first expression in given line.
3713 # Find the first expression following a comment end.
3715 def align_and_show():
3716 com_it = iter(va_comments)
3717 node_it = iter(tr_lines)
3718 com_row = lambda com: com[0][0]
3719 while 1:
3720 try: com = com_it.next()
3721 except StopIteration: break
3722 try: nd = node_it.next()
3723 except StopIteration: break
3724 com_line = com[0][0]
3725 # Find first line after current comment.
3726 while nd[0][0] <= com_line:
3727 nd = node_it.next()
3728 if com[0][1] != nd[0][1]:
3729 print "==== column mismatch"
3730 print com[1]
3731 print nd[1].source_string()
3732 align_and_show()
3734 ## import pdb; pdb.set_trace()
3737 #* selection handling
3738 # See pygtk-2.4.1/examples/ide/edit.py as example.
3740 #* gtk assertions
3741 import warnings
3742 warnings.filterwarnings("error", "assertion") # , GtkWarning
3744 # But the C code just continues on.
3746 # ... the bigger problem is that a fair amount of C code doesn't
3747 # handle the case where the assertion fails ...
3751 # Cause a sigsev
3752 view = w_.canvas.view
3753 ra = w_.canvas.view.root().add
3754 c_label = ra(canvas.CanvasText,
3755 x = 12, y = 12,
3756 size_points = 12 * 1,
3757 scale = 1.0,
3758 scale_set = True,
3759 text = "the test",
3761 flush_events()
3762 print c_label.get_bounds()
3763 print c_label.__grefcount__
3764 c_label.destroy()
3766 #* gtk proxy test
3767 view = w_.canvas.view
3768 ra = GtkObjProxy(w_.canvas.view.root())
3769 c_label = GtkObjProxy(ra.add(canvas.CanvasText,
3770 x = 12, y = 12,
3771 size_points = 12 * 1,
3772 scale = 1.0,
3773 scale_set = True,
3774 text = "the test",
3776 flush_events()
3777 print c_label.get_bounds()
3778 c_label.destroy()
3779 print c_label._live
3780 print c_label.get_bounds()
3783 #* python compile tests
3784 # Accepted as complete input...
3785 print compile('''
3786 if 1:
3791 else:
3793 ''', '<string>', 'single')
3796 #* l3 tests
3798 # test if
3799 if a > 0:
3801 else:
3804 # generic if (cond)
3807 # if
3808 x < 0,
3810 # elif
3811 x = 0,
3813 # elif
3814 x > 0,
3816 # else
3817 True,
3821 #* gtk object pickling
3822 # local eval of l3Rawtext
3823 import l3lang.utils as ut
3824 # Runs (works? Protocol 1 fails.).
3825 ut.file_pickle( self._ltext.get_property("anchor"))
3826 val = ut.file_unpickle("/tmp/foo")
3828 # oops:
3829 # (.:19911): GLib-GObject-WARNING **: cannot retrieve class for
3830 # invalid (unclassed) type `<invalid>'
3832 # ** ERROR **: file pygenum.c: line 60 (pyg_enum_repr): assertion
3833 # failed: (G_IS_ENUM_CLASS(enum_class))
3834 # aborting...
3837 #* l3IfLoop addition
3838 #** test single loop
3839 test_s = """
3840 if "loop":
3841 def lname(largs):
3842 lbody
3843 lname(cargs)
3844 """ # "
3847 #** test expression
3848 test_s = """
3849 if "loop":
3850 def _loop(bar):
3851 # calc 3d reconstruction
3852 foo = bar + 10
3853 if "loop":
3854 def _lname(foo):
3855 if done:
3856 return bar
3857 # calc 3d reconstruction
3858 # filter
3860 # repeat from gen. proj
3861 if 1:
3862 return _lname(2 - foo)
3863 _lname(foo)
3865 # filter
3867 # repeat from gen. proj
3868 if good:
3869 return _loop(bar + 1)
3870 _loop(1)
3871 """ # "
3872 l3tree = reader.parse(test_s)
3873 l3tree
3876 #** l3ifloopbreak pattern 1
3877 code_s = """
3878 if COND:
3879 return LNAME(LARGS)
3880 """ # "
3881 template = reader.parse(code_s)
3884 #** l3ifloopbreak pattern 2
3885 code_s = """
3886 if ! COND:
3887 return ARGS
3888 """ # "
3889 template = reader.parse(code_s)
3893 #** test single loop w/ break
3894 test_s = """
3895 if "loop":
3896 def lname(largs):
3897 first
3898 if 1:
3899 return 2
3900 last
3901 lname(cargs)
3902 """ # "
3905 #** test single loop w/ continue
3906 test_s = """
3907 if "loop":
3908 def lname(largs):
3909 first
3910 if 1:
3911 return lname(new_args)
3912 lname(cargs)
3913 """ # "
3917 #** l3ifloop pattern
3918 code_s = """
3919 if "loop":
3920 def LNAME(LARGS):
3921 LBODY
3922 LNAME2(CARGS)
3923 """ # "
3924 template = reader.parse(code_s)
3925 template.body()
3928 #** matcher
3929 # From template.body().
3930 ma = ast.Matcher()
3931 body = l3tree.body()
3932 if ma.match(body,
3933 If(String('loop'),
3934 aList([Set(MarkerTyped(Symbol('LNAME'), Symbol('symbol')),
3935 Function(MarkerTyped(Symbol('LARGS'), aList([])),
3936 MarkerTyped(Symbol('LBODY'), aList([])))),
3937 Call(MarkerTyped(Symbol('LNAME2'), Symbol('symbol')),
3938 MarkerTyped(Symbol('CARGS'), aList([])))]),
3939 Marker('_'))):
3940 if ma['LNAME'] != ma['LNAME2']:
3941 warn_("loop name mismatch; no special display")
3942 elif len(ma['LARGS']) != len(ma['CARGS']):
3943 warn_("arguments mismatched between loop definition and call")
3944 else:
3945 print_(ma['LNAME'])
3946 print_(ma['LARGS'])
3947 print_(ma['CARGS'])
3948 print_(ma['LBODY'])
3951 #* l3 tests
3952 #** load l3
3953 from l3lang.l3 import *
3954 run()
3955 #** interpretation order
3956 def foo():
3957 'foo'
3958 foo()
3960 #** args
3961 def foo(a,b, args):
3962 return args
3963 foo(1,2, { a = 1})
3965 #** print
3966 print 1, "hello", 2
3967 print "hello", "world"
3969 #** Function
3970 inline "from math import *"
3971 def f(a,b, c = cos(22), d = 10):
3973 def g(a,b):
3975 # errors:
3976 f(1) # too few
3977 f(1,2,3) # too many
3978 f(1,2, e = 1) # unknown keyword
3980 # ok
3981 p = g(1,2)
3982 p = f(1,2, c = cos(22), d = 1)
3983 p = f(1,2, c = 22, d = 1)
3984 p = f(1,2, c = 'c')
3985 p = f(1,2)
3986 #** Call to python
3987 inline '''
3988 def pyf(a,b, c=1):
3989 return a,b,c
3991 pyf(10,20)
3992 pyf(10,20, c = 30)
3993 #** If
3994 last_ring = 100
3995 if(last_ring==-1):
3996 last_ring=nx-2
3998 (last_ring == -1)
4000 # Ok:
4001 last_ring == -1
4002 last_ring <= -1
4005 # old errors (pre-r460)
4006 print parse('a = b')
4007 print parse('a == b')
4008 # error (r439):
4009 print parse('(a == b)')
4010 print parse('(a <= b)')
4011 # ok:
4012 print parse('(a = b)')
4013 print parse('(av1*(int(nima/2)+(nima%2)) + av2*int(nima/2))/nima')
4016 #* l3 tests, in gui (repeated interpretation checks)
4017 program:
4018 filter(lambda x: x > 2, [1,2,3,4])
4020 if 1:
4021 inline "from l3lang.l3 import *"
4022 def f(a,b, c = cos(22), d = 10):
4024 f(1,2)
4025 f(1, 2, c = 22)
4027 if ("prog", "filter test"):
4028 filter(lambda x: x > 2, [1,2,3,4])
4030 program:
4031 # subtract
4032 a - b
4034 program:
4035 6* (3 - 2)
4037 # using > "eval locally"
4038 # >>> self._l3tree
4039 # Program(aList([Call(Symbol('*'), aList([Int(6L), Call(Symbol('-'), aList([Int(3L), Int(2L)]))]))]))
4040 # >>> self._l3tree._first_char
4041 # (0, 0)
4042 # >>> self._l3tree._last_char
4043 # (2, 0)
4047 #* statement additions
4048 #** is, is not, not in
4049 code_s = """
4050 a is not None
4051 b not in [c,d]
4052 print hello, "world"
4054 reader.raw_lexer(code_s)
4057 #* l3 internals tests (from python)
4058 #** Call
4059 tree = reader.parse('f(1,2, c = sin(22), d = 10)')
4061 play_env = interp.get_child_env(def_env, storage)
4062 tree.setup(empty_parent(), play_env, storage)
4063 view.print_info(storage, tree, show_macros = True)
4065 # Internals.
4066 print tree.body().positional_args()
4067 print tree.body().nargs()
4068 print tree.body().named_args()
4069 # Interpret.
4070 tree.interpret(def_env, storage)
4071 #** Function
4072 tree = reader.parse('''
4073 def f(a,b, c = cos(22), d = 10):
4075 ''') # '''
4077 play_env = interp.get_child_env(def_env, storage)
4078 tree.setup(empty_parent(), play_env, storage)
4079 view.print_info(storage, tree, show_macros = True)
4081 func_ = tree.body()[1]
4082 print func_.positional_block_args()
4083 print func_.named_block_args()
4084 print func_.nargs()
4086 # Interpret.
4087 tree.interpret(def_env, storage)
4089 #** macro
4090 #*** parse
4091 from l3lang.view import print_ast
4092 def prnt(str):
4093 print_ast(reader.parse(str))
4094 prnt('''
4095 def "foo"():
4097 ''')
4098 #*** eval 1
4099 tree = reader.parse('''
4100 aa = 1
4101 def "foo"():
4102 print aa
4103 foo()
4104 ''')
4106 # Setup.
4107 play_env = interp.get_child_env(def_env, storage)
4108 tree.setup(empty_parent(), play_env, storage)
4109 view.print_info(storage, tree, show_macros = True)
4111 # Interpret.
4112 tree.interpret(def_env, storage)
4113 view.print_info(storage, tree)
4114 view.print_all_info(storage, tree)
4115 # ok: repeated .interpret() reuses first clone.
4117 #*** parse 2
4118 code_s = ('''
4120 print aa ;
4122 ''')
4123 reader.py_lexer(code_s)
4124 print reader.parse(code_s)
4126 #*** eval 3 - single call
4127 code_s = ('''
4128 aa = 1
4129 def "foo"():
4130 print aa
4132 foo()
4133 ''')
4134 # reader.raw_lexer(code_s)
4135 # reader.py_lexer(code_s)
4136 tree = reader.parse(code_s)
4138 # Setup.
4139 play_env = interp.get_child_env(def_env, storage)
4140 tree.setup(empty_parent(), play_env, storage)
4141 view.print_info(storage, tree, show_macros = True)
4143 # Interpret.
4144 tree.interpret(play_env, storage)
4145 view.print_info(storage, tree)
4146 view.print_all_info(storage, tree)
4147 # repeated .interpret() reuses first clone ?
4150 #*** eval 4 - variable value change
4151 code_s = ('''
4152 aa = 1
4153 def "foo"():
4154 print aa
4155 aa = aa + 1
4156 print aa
4157 foo()
4158 ''')
4159 # reader.raw_lexer(code_s)
4160 # reader.py_lexer(code_s)
4161 tree = reader.parse(code_s)
4163 # Setup.
4164 play_env = interp.get_child_env(def_env, storage)
4165 tree.setup(empty_parent(), play_env, storage)
4166 view.print_info(storage, tree, show_macros = True)
4168 # Interpret.
4169 tree.interpret(play_env, storage)
4170 view.print_env(play_env)
4171 view.print_info(storage, tree)
4172 view.print_all_info(storage, tree)
4173 # repeated .interpret() reuses first clone ???
4176 #*** eval 5 -- loop
4177 code_s = ('''
4178 aa = 1
4179 def "foo"():
4180 print aa
4181 aa = aa + 1
4182 if aa < 5:
4183 foo()
4184 foo()
4185 ''')
4186 # reader.raw_lexer(code_s)
4187 # reader.py_lexer(code_s)
4188 tree = reader.parse(code_s)
4190 # Setup.
4191 play_env = interp.get_child_env(def_env, storage)
4192 tree.setup(empty_parent(), play_env, storage)
4193 view.print_info(storage, tree, show_macros = True)
4195 # Interpret.
4196 tree.interpret(play_env, storage)
4197 view.print_all_info(storage, tree)
4198 tree.interpret(play_env, storage)
4199 view.print_all_info(storage, tree)
4201 view.print_info(storage, tree)
4202 view.print_env(play_env)
4203 # repeated .interpret() reuses first clone ???
4207 #* while loop
4209 #** eval 6 -- `while` expansion
4210 # '''
4211 # while C:
4214 # Python
4215 a = 1
4216 while a < 3:
4217 print a
4218 a = a + 1
4220 # l3 expanded
4221 code_s = ('''
4222 a = 1
4223 if "while":
4224 def "_while_123"():
4225 # Condition
4226 if not (a < 3):
4227 return
4228 else:
4229 # Body
4230 print a
4231 a = a + 1
4232 # end Body
4233 return _while_123()
4234 _while_123()
4235 ''')
4236 tree = reader.parse(code_s)
4238 # Setup.
4239 play_env = interp.get_child_env(def_env, storage)
4240 tree.setup(empty_parent(), play_env, storage)
4242 # Interpret.
4243 tree.interpret(play_env, storage)
4244 view.print_all_info(storage, tree)
4246 tree.interpret(play_env, storage)
4247 view.print_all_info(storage, tree)
4249 view.print_env(play_env)
4252 #** eval 7 -- `while` template
4253 # '''
4254 # while C:
4257 # l3 expanded
4258 code_s = ('''
4259 if "while":
4260 def "_while_ID"():
4261 if not C:
4262 return
4263 else:
4265 return _while_ID()
4266 _while_ID()
4267 ''')
4268 tree = reader.parse(code_s)
4270 # Setup.
4271 play_env = interp.get_child_env(def_env, storage)
4272 tree.setup(empty_parent(), play_env, storage)
4273 view.print_all_info(storage, tree)
4277 #** eval 8 -- `while` tests
4278 # '''
4279 #*** execution
4280 code_s = ('''
4281 a = 1
4282 while a < 3:
4283 print a
4284 a = a + 1
4285 ''')
4286 tree = reader.parse(code_s)
4288 # Setup.
4289 play_env = interp.get_child_env(def_env, storage)
4290 tree.setup(empty_parent(), play_env, storage)
4291 view.print_info(storage, tree)
4293 # Interpret.
4294 tree.interpret(play_env, storage)
4295 view.print_all_info(storage, tree)
4297 tree.interpret(play_env, storage)
4298 view.print_all_info(storage, tree)
4300 view.print_env(play_env)
4302 #*** reference comparison
4303 # Remove id / timestamp columns, then compare per-character.
4304 ref_s = ('''
4305 a = 1
4306 if "while":
4307 def "_while_ID"():
4308 # Condition
4309 if not (a < 3):
4310 return
4311 else:
4312 # Body
4313 print a
4314 a = a + 1
4315 # end Body
4316 return _while_ID()
4317 _while_ID()
4318 ''')
4319 ref_t = reader.parse(ref_s)
4320 # Setup.
4321 ref_env = interp.get_child_env(def_env, storage)
4322 ref_t.setup(empty_parent(), ref_env, storage)
4323 view.print_info(storage, ref_t)
4326 #** eval 9 -- `while` pattern
4327 # '''
4328 # l3 expanded
4329 code_s = ('''
4330 if "while":
4331 def "_while_ID"():
4332 if not COND:
4333 return
4334 else:
4335 BODY
4336 return _while_ID()
4337 _while_ID()
4338 ''')
4339 tree = reader.parse(code_s)
4342 #** while tests
4343 program:
4344 a = 1
4345 while a < 3:
4346 print a
4347 a = a + 1
4349 # Nesting, check identifiers.
4350 program:
4351 a = 1
4352 while a < 3:
4353 print a
4354 a = a + 1
4355 bb = 1
4356 while bb < 3:
4357 print a, bb
4358 print a * bb
4359 bb = bb + 1
4364 #* for loop language addition
4365 # for loop using while
4367 #** iterator wrapper
4368 class l3_iter:
4369 def __init__(self, seq):
4370 self._iter = iter(seq)
4371 self._next = None
4372 self._next_ready = False
4374 def more(self):
4375 if self._next_ready:
4376 return True
4377 try:
4378 self._next = self._iter.next()
4379 self._next_ready = True
4380 return True
4381 except StopIteration:
4382 self._next_ready = False
4383 return False
4385 def next(self):
4386 if self.more():
4387 self._next_ready = False
4388 return self._next
4389 raise InterpreterError("Request for elements from finished iterator.")
4392 #** original for
4394 # for V in I:
4397 for (x,y) in [(1,2), (3,4)]:
4398 print x, y
4401 #** expand to while
4402 program:
4403 I = l3iter([(1,2), (3,4)])
4404 while I.more():
4405 (x,y) = I.next()
4406 print x, y
4408 # To avoid pickling [(1,2), (3,4)] or I, use
4410 # inline 'I = l3iter([(1,2), (3,4)])'
4412 program:
4413 inline 'from l3lang.interp import l3iter; I = l3iter([(1,2), (3,4)])'
4414 while I.more():
4415 (x,y) = I.next()
4416 print x, y
4420 #** embed l3 'tail call' form for while:
4421 # while C:
4424 # if "while":
4425 # def "_while_ID"():
4426 # if not C: # force boolean evaluation via not
4427 # return
4428 # else:
4430 # return _while_ID()
4431 # _while_ID()
4433 program:
4434 if "for":
4435 inline 'from l3lang.interp import l3iter; I = l3iter([(1,2), (3,4)])'
4436 # orig. for
4437 def "_for_ID"():
4438 if not I.more():
4439 return
4440 else:
4441 (x,y) = I.next()
4442 print x, y
4443 return _for_ID()
4444 _for_ID()
4447 #** iterator problems
4448 # Problems:
4449 # 1. The sequence cannot be edited (it's a string)
4450 # 2. The indirection
4451 # - (value list VL) -> external (l3iter) -> (value sequence VS)
4452 # loses the time stamps between VL and VS, so that updates to VL
4453 # re-evaluate everything.
4455 # Thus, iterators are USELESS in l3: no persistence and no
4456 # incremental evaluation.
4458 # 3. Are I.more and I.next called again on repeated interpretation?
4460 # 4. External iterator assignments will cause failure:
4462 for V in I:
4465 # is ok, but
4467 I1 = get_iter()
4468 for V in I1:
4471 # will fail.
4473 # MAJOR PROBLEM:
4474 # Repeat execution of UNORDERED iterators will always fail.
4475 # l3 execution imparts unique ids, IN ORDER of execution.
4477 # Retrieving all iterator values and storing them is not an option
4478 # because iterators need not be finite.
4480 # A prime example: a true rand() MUST NOT be used in l3. Unless it's
4481 # a pseudo-random, FIXED sequence.
4484 # [Thu Jul 12 11:57:28 2007]
4485 # A possible adjustment is to let Call.interpret return all iterators
4486 # as externals, and evaluating every time as done for Inline(). If
4487 # done that way, the for loop also simplifies.
4489 program:
4490 if "for":
4491 I = l3iter([(1,2), (3,4)])
4492 # orig. for
4493 def "_for_ID"():
4494 if not I.more():
4495 return
4496 else:
4497 (x,y) = I.next()
4498 print x, y
4499 return _for_ID()
4500 _for_ID()
4503 #** iterator problems, part 2
4504 # ---------------------------------
4505 # Re-examining iterators in l3 is slow and makes interpretation yet
4506 # more complicated. Instead,
4508 # 1. make sure that l3iter instances pickle,
4510 # 2. assume (and test that) the iterator given to l3iter produces a
4511 # constant sequence, and
4513 # 3. let l3iter re-run the iterators (after unpickling, or better at
4514 # the first call to I.more) to get to the correct position in the
4515 # stream.
4516 # If the iterator itself performs a lot of work, nothing is gained
4517 # here...
4519 # Retrieving the iterator is a problem.
4520 # It cannot be saved with the l3iter instance, but re-running
4521 # l3iter(iterator) will create a new instance (losing the
4522 # timestamp/position info).
4523 # This requires some internal magic...
4526 #** simplify to sequences
4527 # ----------------------
4528 # Backtrack to Python < 2.2, without the __iterator__ mess. There,
4529 # ...
4530 # The for statement is used to iterate over the elements of a
4531 # sequence (string, tuple or list):
4532 # ...
4533 # The
4534 # sequence types support the len() and [] operators (__len__ and
4535 # __getitem__). Restricting to known-size sequences is a minor
4536 # restriction for tracked, DISPLAYED items.
4538 # For general iterators and simple uses, use Python directly. The
4539 # sample
4541 for k in edsummary.iterkeys():
4542 print k + ": %.3f" % edsummary[k]
4544 # uses an unordered iterator, so it cannot work in l3. It also performs
4545 # a trivial task not worth tracking, so it could be in python.
4547 # For this example, using
4548 for k in edsummary.keys():
4549 print k + ": %.3f" % edsummary[k]
4550 # in l3 would be better.
4552 # For sequences providing len() and getitem(), there are two choices:
4553 # 1. another wrapper ( l3traverse() ) can be added, and the
4554 # following should work:
4555 program:
4556 if "for":
4557 I = l3traverse([(1,2), (3,4)])
4558 # orig. for
4559 def "_for_ID"():
4560 if not I.more():
4561 return
4562 else:
4563 (x,y) = I.next()
4564 print x, y
4565 return _for_ID()
4566 _for_ID()
4567 # However, this wrapper would require access to l3 internals, so an
4568 # l3 version is preferable:
4570 # 2. Use a tail call form to handle indexing
4572 # for V in S:
4575 # In the following, ITEMS, IDX, LEN and LOOP are leaf nodes, to be
4576 # replaced UNIQUELY in if.setup().
4578 # See also ref[Wed Jul 18 11:38:10 2007]
4580 program:
4581 if "for":
4582 ITEMS = [(1,2), (3,4)]
4583 IDX = 0
4584 LEN = len(ITEMS)
4585 # orig. for
4586 def "LOOP"():
4587 if IDX < LEN:
4588 IDX = IDX + 1
4589 # V in S.
4590 (x,y) = ITEMS[ IDX - 1 ]
4591 # Body B
4592 print x, y
4593 # Iterate.
4594 return LOOP()
4595 LOOP()
4598 #** for tests
4599 # List as text (no insertions)
4600 program:
4601 for i in [1,2,3]:
4602 print i
4604 # List as structure.
4605 program:
4606 for i in [1,
4607 2,3]:
4608 print i
4610 program:
4611 for (i, x) in [(1, 1), (2, 4), (3,9)]:
4612 print i, x
4614 # Nesting, check identifiers.
4615 program:
4616 for i in [1,2,3]:
4617 print i
4618 for jj in [1,2,3]:
4619 print i, jj, i*jj
4623 #* scitbx flex array
4624 from scitbx.array_family import flex
4625 data = flex.random_double(size = 4)
4627 data.reshape(2,2)
4628 # Traceback (most recent call last):
4629 # File "<console>", line 1, in ?
4630 # ArgumentError: Python argument types in
4631 # double.reshape(double, int, int)
4632 # did not match C++ signature:
4633 # reshape(scitbx::af::versa<double, scitbx::af::flex_grid<scitbx::af::small<long, 10u> > > {lvalue}, scitbx::af::flex_grid<scitbx::af::small<long, 10u> >)
4636 #* slice and getitem
4637 #** python slice
4638 import numpy as N
4639 import operator
4640 na = N.arange(28).reshape((7,4))
4642 print na[1,2]
4643 # DIFFERENT:
4644 print na.__getitem__( [1,2] )
4645 print na.__getitem__( (1,2) ) # correct
4647 print na[1:4,2]
4648 print na.__getitem__( (slice(1,4), 2) )
4650 print na[1:4]
4651 print na.__getitem__( (slice(1,4), ) )
4652 print na.__getitem__( [slice(1,4)] )
4654 print na[1:3, 3:6]
4655 print na.__getitem__( (slice(1,3), slice(3,6)) )
4656 print operator.getitem(na, [slice(1,3), slice(3,6)] )
4657 print operator.getitem(na, (slice(1,3), slice(3,6)) )
4659 # Python reference values:
4660 print na[1,2]
4661 print na[1:4,2]
4662 print na[1:4]
4663 print na[1:3, 3:6]
4666 #** l3 slice
4667 # Compare with # Python reference values:
4668 inline '''
4669 import numpy as N
4671 na = N.arange(28).reshape((7,4))
4672 print na
4673 print na[1,2]
4674 print na[1:4,2]
4675 print na[1:4]
4676 print na[1:3, 3:6]
4681 #* gtk images, numeric, eman
4682 #'''
4683 import EMAN2 as em
4684 from EMAN2 import EMNumPy
4685 import Numeric as N
4686 import MLab as M
4688 #** numeric -> eman
4689 ema_arr = EMAN2.EMData()
4690 EMNumPy.numpy2em(num_arr, ema_arr)
4692 #** eman -> numeric
4693 foo = em.EMData()
4694 num_arr = EMNumPy.em2numpy(foo)
4696 EMNumPy.em2numpy(None)
4698 #** numeric -> gtk
4699 #*** 1. get numeric array
4700 num_arr = M.rand(4,4)
4702 #*** 2.b. numeric -> gtk
4703 # Convert float array to 8-bit array.
4704 rows, cols = num_arr.shape
4705 bottom = M.min(M.min(num_arr))
4706 top = M.max(M.max(num_arr))
4707 scale = (top - bottom)
4708 norm_arr = ((num_arr - bottom) / scale * 255).astype('b')
4710 #*** Use 3 8-bit arrays as (rgb) values.
4711 t3 = N.outerproduct(norm_arr, N.array([1,1,1], 'b'))
4712 t4 = N.reshape(t3, (rows, cols, 3))
4713 pix_arr = N.array(t4, 'b')
4715 #*** Get the pixbuf.
4716 # array input indexing is row, pixel, [r,g,b {,a} ]
4717 pixbuf = gtk.gdk.pixbuf_new_from_array(pix_arr,
4718 gtk.gdk.COLORSPACE_RGB, 8)
4720 #*** 3. display pixbuf as item
4721 d_canv = w_.canvas.view
4722 d_rt = d_canv.root().add(canvas.CanvasGroup)
4723 d_rt.add(canvas.CanvasPixbuf,
4724 x = 20, # world units
4725 y = 20,
4726 height_set = True,
4727 width_set = True,
4728 width = 15, # world units
4729 height = 15,
4730 pixbuf = pixbuf,
4732 d_rt.destroy()
4734 # Image orientation is consistent with `norm_arr` printed form.
4735 # Indexing is (row, col) from upper left.
4736 # Storage is row-major?
4738 # This is the first view of a VALUE -- the others are astTypes.
4739 # Useful value information is the program source.
4742 # "anchor" GtkAnchorType : Read / Write
4743 # "height" gdouble : Read / Write
4744 # "height-in-pixels" gboolean : Read / Write
4745 # "height-set" gboolean : Read / Write
4746 # "pixbuf" GdkPixbuf : Read / Write
4747 # "width" gdouble : Read / Write
4748 # "width-in-pixels" gboolean : Read / Write
4749 # "width-set" gboolean : Read / Write
4750 # "x" gdouble : Read / Write
4751 # "x-in-pixels" gboolean : Read / Write
4752 # "y" gdouble : Read / Write
4753 # "y-in-pixels" gboolean : Read / Write
4756 # # Other pixmap sources:
4757 # image = gtk.Image()
4758 # # use the current directory for the file
4759 # try:
4760 # pixbuf = gtk.gdk.pixbuf_new_from_file(GTKLOGO_IMAGE)
4761 # image.set_from_pixbuf(pixbuf)
4762 # #
4763 # image = gtk.Image()
4764 # image.set_from_file(BUDDY_IMAGE);
4765 # # image -> pixbuf
4766 # image.get_pixbuf()
4767 # # pixbuf -> canvas
4769 # gtk.gdk.pixbuf_new_from_array
4770 # gtk.gdk.Pixbuf.get_pixels_array
4771 # gtk.gdk.Pixbuf.save
4772 # call gtk.Image.queue_draw() after you change the Numeric array.
4775 # # from EMAN2.EMNumPy import numpy2em, em2numpy
4778 #* gtk images, numpy, eman
4779 #'''
4780 import EMAN2 as em
4781 from EMAN2 import EMNumPy
4782 import numpy as N
4784 #** numpy -> eman
4785 ema_arr = em.EMData()
4786 EMNumPy.numpy2em(num_arr, ema_arr)
4789 #** eman -> numpy
4790 import EMAN2
4791 ti = EMAN2.test_image(type = 1, size = (128,64))
4792 num_arr = EMNumPy.em2numpy(ti)
4793 print num_arr.shape
4794 # [Fri Mar 16 16:25:40 2007]: transposed: (64, 128)
4795 # [Mon Mar 19 11:23:08 2007]: eman2 fix by Grant Tang.
4796 # [Thu Mar 22 10:36:14 2007]: order confusion between eman2/hdf/numpy...
4799 #** numpy -> gtk
4800 #*** 1. get numpy array
4801 num_arr = N.random.ranf( (5,4) )
4803 #*** 2.b. numpy -> gtk
4804 # Convert float array to 8-bit array.
4805 rows, cols = num_arr.shape
4806 bottom = N.min(num_arr)
4807 top = N.max(num_arr)
4808 scale = (top - bottom)
4809 norm_arr = ((num_arr - bottom) / scale * 255).astype(N.uint8).reshape(rows*cols)
4812 #*** Use 3 8-bit arrays as (rgb) values.
4813 t3 = N.outer(norm_arr, N.array([1,1,1], 'b'))
4814 t4 = N.reshape(t3, (rows, cols, 3))
4815 pix_arr = N.array(t4, dtype=N.uint8)
4817 #*** Get the pixbuf.
4818 # array input indexing is row, pixel, [r,g,b {,a} ]
4819 # TypeError: pixbuf_new_from_array() argument 1 must be array, not
4820 # numpy.ndarray
4821 # pixbuf = gtk.gdk.pixbuf_new_from_array(pix_arr,
4822 # gtk.gdk.COLORSPACE_RGB, 8)
4823 pixbuf = gtk.gdk.pixbuf_new_from_data(
4824 pix_arr.tostring(order='a'),
4825 gtk.gdk.COLORSPACE_RGB,
4826 False,
4828 cols,
4829 rows,
4830 3*cols)
4832 #*** compare to input
4833 pixbuf.get_pixels_array()
4834 print pixbuf.get_pixels_array().shape
4835 print pixbuf.get_height()
4836 print pixbuf.get_width()
4839 #*** 3. display pixbuf as item
4840 d_canv = w_.canvas.view
4841 d_rt = d_canv.root().add(canvas.CanvasGroup)
4842 d_rt.add(canvas.CanvasPixbuf,
4843 x = 20, # world units
4844 y = 20,
4845 height_set = True,
4846 width_set = True,
4847 width = 15, # world units
4848 height = 15,
4849 pixbuf = pixbuf,
4851 d_rt.destroy()
4853 #* minimal EMData display test
4854 #** gui
4855 # paste:
4856 program:
4857 inline("import EMAN2 ")
4858 ti = EMAN2.test_image(type = 1, size = (128,64))
4859 # program > menu > run code
4860 # ti > menu > insert values
4863 #** console
4864 tm_tree = reader.parse('''
4865 inline("import EMAN2 ")
4866 ti = EMAN2.test_image(type = 0, size = (64,64))
4867 ''')
4868 tm_play_env = interp.get_child_env(def_env, w_.state_.storage)
4869 tm_tree.setup(empty_parent(), tm_play_env, w_.state_.storage)
4870 tm_l3pic = w_.canvas.view.start_add_l3tree(tm_tree)
4872 # run
4873 tm_l3pic._l3tree.interpret(w_.state_.def_env, w_.state_.storage)
4874 # insert list
4875 val, val_id = ast.val2ast(tm_l3pic.get_values_list())\
4876 .setup(empty_parent(),
4877 Env('dummy_env', None, None, storage),
4878 storage)
4879 w_.canvas.view.add_l3tree(val, RenderTable())
4881 gtk.main()
4883 #* l3IfOutline addition
4884 # High-level interface via outlining.
4885 #** original tree (simple)
4886 # Body from demo/proj-align/s1a.py, truncated for simplicity.
4887 ref_t = reader.parse_file("./demo/proj-align/s1a-in.py")
4888 ref_env = interp.get_child_env(def_env, storage)
4889 ref_t.setup(empty_parent(), ref_env, storage)
4890 view.print_info(storage, ref_t)
4892 # outline-regexp
4893 # (set-variable (quote outline-regexp) "[ ]*\\#+\\*+")
4894 # (set-variable (quote outline-regexp) "\\W+\" +" nil)
4896 #** OR: original tree (full)
4897 ref_t = reader.parse_file("./demo/proj-align/s1a.py")
4898 ref_env = interp.get_child_env(def_env, storage)
4899 ref_t.setup(empty_parent(), ref_env, storage)
4900 # view.print_info(storage, ref_t)
4901 #** add outline cross-refs
4902 ref_t.set_outl_edges(w_, None)
4903 #** examine embedded outline (text)
4904 view.print_info(storage, ref_t, custom = "nd._outl_parent._id")
4905 #** display outline
4906 ref_pic = w_.canvas.view.start_add_l3tree(ref_t)
4909 #** deprecated
4911 #*** outline tree, flat
4912 ref_o = ref_t.get_outline(w_)
4913 print ref_o
4915 ref_prun = ref_o.prune(w_)
4916 print ref_prun
4917 view.print_info(storage, ref_prun, custom = "nd._real_tree._id")
4920 #*** OR: outline tree, nested
4921 ref_o = ref_t.get_outline(w_, outl_type = 'nested')
4922 print ref_o
4923 view.print_info(storage, ref_o)
4925 ref_prun = ref_o.prune(w_)
4926 print ref_prun
4927 view.print_info(storage, ref_prun)
4929 #*** OR: outline tree, subtree
4930 # (nested outline to level N, then content)
4931 # Pick a nested outline manually.
4932 # here, 'Compute proj...'
4933 storage.load(40886).set_outline('subtree')
4935 ref_o = ref_t.get_outline(w_, outl_type = 'nested')
4936 # print ref_o
4937 # view.print_info(storage, ref_o)
4939 ref_prun = ref_o.prune(w_)
4940 # print ref_prun
4941 # view.print_info(storage, ref_prun)
4944 #*** display main
4945 ref_t_pic = w_.canvas.view.start_add_l3tree(ref_t)
4948 #*** display outline
4949 ref_pic = w_.canvas.view.start_add_l3tree(ref_prun)
4952 #** pattern
4953 tm_tree = reader.parse('''
4954 if ("outline", !! TITLE "sample"):
4955 BODY
4956 ''')
4957 print tm_tree
4958 #** single expression
4959 ref_s = '''
4960 ''' # "
4961 l3tree = reader.parse(ref_s)
4962 l3tree
4965 #** single nesting level
4966 code_s = """
4967 """ # "
4968 template = reader.parse(code_s)
4971 #** double nesting
4972 code_s = """
4973 """ # "
4974 template = reader.parse(code_s)
4978 #** viewlist tests
4979 vl, _ = viewList(aList([])).setup(empty_parent(), def_env, storage)
4980 sl, _ = List(aList([])).setup(empty_parent(), def_env, storage)
4982 vls = viewList().setup_viewlist(w_, ref_t)
4983 print vls
4986 #* list display tests
4987 #** no comments
4998 #** comments
4999 # Outer comment.
5004 # Inner comment.
5012 #* viewlist display tests
5013 program:
5014 # Very important
5015 # things are to be done...
5016 if ("outline", "Load volume."):
5017 vol = getImage(ev("$SPXROOT/sparx/test/model001.tcp"))
5018 # See http://www.macro-em.org/sparxwiki/prep_vol
5019 (volft, kb) = prep_vol(vol)
5021 # Like these wonderful ones...
5022 if ("outline", "Compute projection angles"):
5023 angles = even_angles(10.0, 90.0, 90.1, 0.0, 179.9,'P')
5024 nangles = len(angles)
5025 stack = "proj.hdf"
5026 sx = 0
5027 sy = 0
5029 #* system identification
5030 import sys
5031 sys.platform
5034 #* l3-system interface
5035 #** ShellCmds
5036 sc = shell_cmds
5037 ## sc = ShellCmds()
5038 sc.system('echo', ['a'], [])
5039 sc.system_wrap('echo', 'a', n='')
5040 #** subdir
5041 from l3lang.l3 import *
5042 run()
5043 # l3 input
5044 program:
5045 sd = subdir:
5046 a = 1
5047 touch('foo')
5048 pwd()
5050 #* system interface via shell wrapper
5051 #** prepare sample data directory, python
5052 import os
5053 ev = os.path.expandvars
5054 def ignore(cmd, *args, **kwd):
5055 try:
5056 cmd(*args, **kwd)
5057 except:
5058 pass
5060 ignore(os.mkdir, 'foo-sh-wrap')
5061 os.chdir('foo-sh-wrap')
5062 ignore(os.symlink,
5063 ev('$HOME/w/sparx/xmipp/Basic_Demo/walkthrough/taguA.tot'),
5064 'taguA.tot')
5065 ignore(os.symlink,
5066 ev('$HOME/w/sparx/xmipp/Basic_Demo/walkthrough/taguA.tot.inf'),
5067 'taguA.tot.inf')
5068 ignore(os.symlink,
5069 ev('$HOME/w/sparx/xmipp/Basic_Demo/walkthrough/tagtA.tot'),
5070 'tagtA.tot')
5071 ignore(os.symlink,
5072 ev('$HOME/w/sparx/xmipp/Basic_Demo/walkthrough/tagtA.tot.inf'),
5073 'tagtA.tot.inf')
5076 #** call using assumed return value structure
5077 # This is completely impractical; see ref[Mon Apr 16 14:35:34 2007]
5079 os.system('pwd; ls')
5080 (angles, coords, images, sel_tilt, sel_untilt) = xmipp_mark("taguA.tot")
5083 #** call in directory
5084 # This is a minimalistic approach, letting the user select directory
5085 # entries after execution.
5087 #*** using xmipp_mark found on system path
5088 os.system('pwd; ls -l')
5089 xmipp_mark(w_, "taguA.tot", tilted = "tagtA.tot")
5090 # In xmipp_mark:
5091 # menu -> save coords > tag.pos
5092 # menu -> save angles > tag.ang
5093 # menu -> generate images > images.xmp
5094 # > tilted.sel
5095 # > untilted.sel
5097 os.system('pwd; ls -l')
5100 #*** using l3lang.external module
5101 from l3lang.external import xmipp_wrap
5102 xmipp_wrap.xmipp_mark("/net/cci/hohn/w/sparx/xmipp/Basic_Demo/walkthrough/taguA.tot",
5103 tilted =
5104 "/net/cci/hohn/w/sparx/xmipp/Basic_Demo/walkthrough/tagtA.tot")
5106 #** with l3lang.external module
5107 #*** using subdirectory, l3
5108 # For batch programs, the toplevel should suffice:
5109 from l3lang.l3 import *
5110 run()
5112 # graphically:
5113 # l3 input, using manually specified full paths.
5114 program:
5115 inline "from l3lang.external.xmipp_wrap import *"
5116 sd = subdir:
5117 touch("test_file")
5118 touch("foobar")
5119 (status, log) = xmipp_mark(
5120 "/net/cci/hohn/w/sparx/xmipp/Basic_Demo/walkthrough/taguA.tot",
5121 tilted = "/net/cci/hohn/w/sparx/xmipp/Basic_Demo/walkthrough/tagtA.tot")
5123 print sd.foobar
5125 # Next, try commands using the file(s).
5126 sd1 = subdir:
5127 cp(sd.foobar, "foobar_copy")
5130 # value inspection, via local eval:
5131 # self.w_.state_.storage.load(self._l3tree._id)
5134 #*** directory only tests, l3
5135 # [Fri Apr 20 16:23:21 2007]
5136 program:
5137 inline "from l3lang.external.xmipp_wrap import *"
5138 sd = subdir:
5139 touch("test_file")
5140 touch("foobar")
5142 print sd.foobar
5144 # Next, try commands using the file(s).
5145 sd1 = subdir:
5146 cp(sd.foobar, "foobar_copy")
5148 print sd1.foobar_copy
5150 # [Thu Apr 19 15:32:15 2007]
5151 # state save sequence
5152 # (paste script)
5153 # (save state st.no-exec.1)
5154 # file size: 63992
5155 # (run script)
5156 # (save state st.1)
5157 # file size: 66351
5160 #* rpy test
5161 program:
5162 inline 'from rpy import *'
5164 d = r.capabilities()
5165 if d['png']:
5166 device = r.png # Robj, won't pickle
5167 ext='png'
5168 else:
5169 device = r.postscript
5170 ext='ps'
5172 faithful_data = r.faithful # short form:
5173 ed = faithful_data["eruptions"]
5176 #* numeric tests
5177 program:
5178 inline "import Numeric as N; import MLab as M"
5180 num_arr = M.rand(4,4) # Get numeric array.
5182 num_arr = M.rand(4,4)
5183 (rows, cols) = num_arr.shape
5184 bottom = M.min(M.min(num_arr))
5185 top = M.max(M.max(num_arr))
5186 scale = (top - bottom)
5187 norm_arr = ((num_arr - bottom) / scale * 255).astype('b') # Convert float array to 8-bit array.
5189 t3 = N.outerproduct(norm_arr, N.array([1,1,1], 'b'))
5190 t4 = N.reshape(t3, (rows, cols, 3))
5191 pix_arr = N.array(t4, 'b') # Use 3 8-bit arrays as (rgb) values.
5194 #* external test collection
5195 from EMAN2 import *
5196 e = EMData()
5197 e.set_size(3,3)
5198 e.set_value_at(0,1, 1.0)
5199 print "original at start"
5200 e.print_image()
5202 f1 = e.process("mirror",{"axis":'x'})
5203 print "new mirrored image"
5204 f1.print_image()
5207 #** image display test
5208 # [Fri Apr 20 16:48:25 2007]
5209 program:
5210 inline("import EMAN2 ")
5211 ti = EMAN2.test_image(type = 1, size = (128,64))
5212 # program > menu > run code
5213 # ti > menu > insert list of values l3
5216 #** Micrograph and particle selection
5217 # Using the xmipp demo and data.
5218 program:
5219 inline '''from l3lang.external.xmipp_wrap import \
5220 xmipp_mark, xmipp_do_selfile'''
5221 orig = subdir:
5222 cp('$HOME/w/sparx/xmipp/Basic_Demo/walkthrough/taguA.tot',
5223 'taguA.tot')
5224 cp('$HOME/w/sparx/xmipp/Basic_Demo/walkthrough/taguA.tot.Common.pos',
5225 'taguA.tot.Common.pos')
5226 cp('$HOME/w/sparx/xmipp/Basic_Demo/walkthrough/taguA.tot.inf',
5227 'taguA.tot.inf')
5228 cp('$HOME/w/sparx/xmipp/Basic_Demo/walkthrough/tagtA.tot',
5229 'tagtA.tot')
5230 cp('$HOME/w/sparx/xmipp/Basic_Demo/walkthrough/tagtA.tot.Common.pos',
5231 'tagtA.tot.Common.pos')
5232 cp('$HOME/w/sparx/xmipp/Basic_Demo/walkthrough/tagtA.tot.inf',
5233 'tagtA.tot.inf')
5235 mark = subdir:
5236 # Do the following in xmipp_mark:
5238 # file -> load coords
5239 # The file paths must be retrieved from l3, via
5240 # orig subdir > menu > pwd
5242 # file -> save angles
5244 # file -> generate images
5245 # 110 110 img_t
5246 # and
5247 # 110 110 img_u
5248 # Ignore the
5249 # 1551:SelFile::read: File
5250 # ..../Subdir-30214/taguA.tot.tot.Common.sel
5251 # not found
5252 # warning.
5253 (status, log) = xmipp_mark( orig.taguA_tot,
5254 tilted = orig.tagtA_tot )
5256 # Selection file listing images in current directory.
5257 xmipp_do_selfile("img_t*.xmp", "tilted.sel")
5258 xmipp_do_selfile("img_u*.xmp", "untilted.sel")
5260 # Selection file listing images relative to main directory.
5261 # A full xmipp wrapper would hide selection files completely.
5262 print (mark.l3_dirname() + "/" + "img_t*.xmp", "tilted.sel")
5263 xmipp_do_selfile(mark.l3_dirname() + "/" + "img_t*.xmp", "tilted.sel")
5264 xmipp_do_selfile(mark.l3_dirname() + "/" + "img_u*.xmp", "untilted.sel")
5266 # Note:
5267 # Even without any matching input files,
5268 # xmipp_do_selfile("img_u*.xmp", "untilted.sel")
5269 # returns status zero ...
5271 normalize
5272 xmipp_normalize
5274 mask
5275 xmipp_mask
5277 >> Need xmipp_show to view (intermediate) images.
5280 #** generate phantom
5281 inline "import l3lang.external.xmipp_wrap as xw"
5282 vol, fourpr = xw.pdbphantom("input-data/1P30.pdb",
5283 sampling_rate = 1.6,
5284 high_sampling_rate = 0.8,
5289 #** data alignment and classification
5290 align2d
5291 xmipp_align2d
5293 produce .doc file -- view as plain text.
5297 #** reconstruction
5298 reconstruct
5299 xmipp_art
5302 #** nested loop data selection
5303 # [Wed May 16 12:01:45 2007]
5304 program:
5305 if "loop":
5306 def lname(i):
5307 subdir:
5308 touch("value-file")
5309 if i > 3:
5310 return i
5311 if True:
5312 return lname(i + 1)
5313 lname(1)
5316 #* pretty-printer
5317 from l3lang.pretty import *
5319 #** manual construct / convert
5320 doc = DocText("hello") | DocBreak(" ") | DocText("world")
5322 doc.toString(40)
5323 doc.toString(4)
5326 #** construct / convert
5327 B = lambda : DocBreak(" ")
5328 T = lambda t : DocText(t)
5329 G = lambda x : DocGroupAuto(x)
5330 doc = G(T("begin") | B() |
5331 G(T("stmt1;") | B() |
5332 T("stmt2;") | B() |
5333 T("stmt3;")) | B() |
5334 T("end;"))
5336 print doc.toString(40)
5337 print doc.toString(8)
5338 print doc.toString(4)
5341 #** manual construct / convert
5342 B = lambda : DocBreak(" ")
5343 T = lambda t : DocText(t)
5344 G = lambda x : DocGroupAuto(x)
5345 GB = lambda x : DocGroupBreak(x)
5346 GF = lambda x : DocGroupFill(x)
5347 doc = G(T("begin") | B() |
5348 G(T("stmt1;") | B() |
5349 T("stmt3;"))
5350 | B() |
5351 T("end;"))
5353 print doc.toString(40) # no breaks
5354 print doc.toString(20) # break outer group
5355 print doc.toString(4) # break all
5358 #** manual construct w/ indentation
5359 B = lambda : DocBreak(" ")
5360 C = lambda x,y: DocCons(x, y)
5361 T = lambda t : DocText(t)
5362 G = lambda x : DocGroupAuto(x)
5363 GB = lambda x : DocGroupBreak(x)
5364 GF = lambda x : DocGroupFill(x)
5365 I = lambda r, x : DocNest(r, x)
5366 doc = G(T("begin") |
5367 I(4,
5368 B() |
5369 G( C(C(T("stmt1;"), B()), T("stmt3;"))))
5370 | B() |
5371 T("end;"))
5373 print doc.toString(40) # no breaks
5374 print doc.toString(20) # break outer group
5375 print doc.toString(4) # break all
5377 #* full-tree pretty printing
5378 #** manual comparison
5379 code_s = ('''
5380 a = 1
5381 def loop(a):
5382 if a < 3:
5383 print a
5384 loop(a + 1)
5385 loop(1)
5386 ''')
5387 tree = reader.parse(code_s)
5389 # Setup.
5390 play_env = interp.get_child_env(def_env, storage)
5391 tree.setup(empty_parent(), play_env, storage)
5392 # # view.print_info(storage, tree)
5393 print tree.get_infix_string(40)
5394 print tree.get_infix_string(10)
5397 #** print-parse-compare cycle function
5398 def comp_trees(otree, otree_tbl, pptree, pptree_tbl):
5399 # Compare trees and associated comments
5401 # Compare trees.
5402 print
5403 print "Check for differences..."
5404 print "--------------------------------------------"
5405 o_it = otree.top_down()
5406 pp_it = pptree.top_down()
5407 while 1:
5408 try: o_nd = o_it.next()
5409 except StopIteration: break
5410 pp_nd = pp_it.next()
5412 # Trees equal?
5413 if o_nd.eql_1(pp_nd):
5414 if otree_tbl.has_key(o_nd._id):
5415 if otree_tbl[o_nd._id].eql_1(pptree_tbl[pp_nd._id]):
5416 continue
5417 else:
5418 print ("Comment difference from line %d, col %d\n"
5419 " to line %d, col %d\n"
5420 % (o_nd._first_char[0], o_nd._first_char[1],
5421 pp_nd._first_char[0], pp_nd._first_char[1]))
5422 print otree_tbl[o_nd._id]
5423 print pptree_tbl[pp_nd._id]
5424 else:
5425 continue
5426 else:
5427 print ("Tree difference: line %d, col %d\n original:\n%s\n"
5428 " new:\n%s\n"
5430 (pp_nd._first_char[0],
5431 pp_nd._first_char[1],
5432 str(o_nd),
5433 str(pp_nd),
5436 def ppc(code_s, width):
5437 # Original tree.
5438 tree = reader.parse(code_s).single_program()
5439 tree_env = interp.get_child_env(def_env, storage)
5440 tree.setup(empty_parent(), tree_env, storage)
5441 associate_comments(w_, tree, code_s)
5443 # Tree from printed output.
5444 pp_string = tree.get_infix_string(width, w_.deco_table_)
5446 print "Pretty-printed string, width %d: " % width
5447 print "--------------------------------------------"
5448 print pp_string
5450 pp_tree = reader.parse(pp_string).single_program()
5451 pp_env = interp.get_child_env(def_env, storage)
5452 pp_tree.setup(empty_parent(), pp_env, storage)
5453 associate_comments(w_, pp_tree, pp_string)
5455 comp_trees(tree, w_.deco_table_, pp_tree, w_.deco_table_)
5457 def ppcm(code_s, width_list):
5458 for width in width_list:
5459 ppc(code_s, width)
5461 def chars(st):
5462 for ch in st:
5463 print '-%c-' % ch,
5467 #** string special case
5468 #*** repr / str behavior
5469 chars('a\nb')
5470 chars(r'a\nb')
5471 aa = reader.parse('"""a\nb"""')
5472 chars(aa.body()._primary[0])
5474 aa = reader.parse('"""Outer radius : %i\n"""')
5475 chars(aa.body()._primary[0])
5478 str(aa.body()._primary[0])
5479 # str(aa) converts unprintables into ascii
5480 # repr(aa) converts unprintables into ascii and escapes when needed
5482 # Other cases:
5483 repr('"""a"""')
5484 # '\'"""a"""\''
5486 repr("'''a'''")
5487 # '"\'\'\'a\'\'\'"'
5489 #*** tests
5490 ppc("""
5491 '''if 1:
5492 from rpy import *
5493 d = r.capabilities()
5494 if d['png']:
5495 device = r.png # Robj, won't pickle
5496 ext='png'
5497 else:
5498 device = r.postscript
5499 ext='ps'
5501 """, 40)
5506 #** def special case
5507 ppc('''
5508 def func(arg):
5509 body
5510 ''', 40)
5512 ppc('''
5513 def func(arg):
5514 body
5515 ''', 10)
5518 #** loop (set, function, operators)
5519 ppcm('''
5520 # Now for something else...
5521 # ... like a comment
5522 # ... across lines
5523 a = 1
5524 def loop(a):
5525 if a < 3:
5526 print a
5527 loop(a + 1)
5528 loop(1)
5529 ''', [40, 30, 10])
5533 #** program (program, subdir, tuple, comment)
5534 ppcm('''
5535 program:
5536 # with comment
5537 orig = subdir:
5538 add(a,b)
5539 ''', [50])
5542 ppcm('''
5543 program:
5544 orig = subdir:
5545 cp('$HOME/w/sparx/xmipp/Basic_Demo/walkthrough/taguA.tot',
5546 'taguA.tot')
5548 mark = subdir:
5549 inline "from l3lang.external.xmipp_wrap import xmipp_mark"
5550 # file -> load coords
5551 # The file paths must be retrieved from l3, via an Env
5552 # listing from the original subdir.
5554 (status, log) = xmipp_mark( orig.taguA_tot,
5555 tilted = orig.tagtA_tot )
5556 ''', [80, 70, 20])
5560 #** comment in expression
5561 ppcm('''
5562 [a,b,
5563 # the width
5566 ''', [70])
5569 #** outline
5570 ppcm('''
5571 "hello world"
5572 ''', [40])
5574 ppcm('''
5575 if ("outline", "outer 1"):
5576 if ("outline", "tools"):
5577 init_spider
5578 setup_directory
5579 plot
5581 if ("outline", "inner 2"):
5582 'nothing here'
5583 ''', [60])
5586 #* Local node examination.
5587 # From a widget with _l3tree
5588 st = self.w_.state_.storage
5589 st.load(self._l3tree._id)
5590 res = st.get_attribute(self._l3tree._id, "interp_result")
5592 #* ctf, emdata and numpy
5593 from sparx import *
5594 from EMAN2 import EMNumPy
5595 import numpy
5596 from numpy import flipud, fliplr
5597 import numpy as N
5599 #** conversion check (indep.)
5600 e1 = EMData()
5601 e1.set_size(3,4)
5602 e1.process_inplace('testimage.noise.uniform.rand')
5603 e1.get_data_pickle() # emdata -> std::vector -> python list
5608 #** conversion check (indep.)
5609 from sparx import *
5610 from EMAN2 import EMNumPy
5611 import numpy as N
5613 n1 = N.random.ranf( (5,4) )
5614 e1 = EMData(); EMNumPy.numpy2em(n1, e1)
5615 n2 = EMNumPy.em2numpy(e1)
5616 assert N.max(N.max(n2 - n1)) == 0, \
5617 "Array conversion failed (error = %g)." % N.max(N.max(n2 - n1))
5619 #** Get spider format image.
5620 image = getImage('foo.spi')
5622 #** Flip it to get correct layout.
5623 img_num = flipud(fliplr(EMNumPy.em2numpy(image)))
5624 img_em = EMData()
5625 EMNumPy.numpy2em(img_num, img_em)
5627 #*** Verify the conversion.
5628 num_2 = EMNumPy.em2numpy(img_em)
5629 assert N.max(N.max(num_2 - img_num)) == 0, "Array conversion failed."
5631 # Check a single element
5632 # Lots of matches:
5633 N.where( (img_num - img_em.get_value_at(0,0)) < 1e-14)
5634 # No matches. This means that the (0,1) element must be wrong,
5635 # not merely misplaced.
5636 N.where( (img_num - img_em.get_value_at(0,1)) < 1e-14)
5639 #** Get the ctf.
5640 ctf_img = filt_ctf(image, 2000, 2.0, 200,
5641 1.6, 0.1, -1, 100)
5643 #** Save the image with ctf applied.
5644 dropImage(ctf_img, "ctf.spi", itype = 's')
5646 #* numpy and pickle
5647 import numpy as N, pickle, types
5648 from pdb import pm
5649 print N.version.version
5650 if 1:
5651 # fails:
5652 aa = N.array([ 1, 2, 3, 4 ]);
5653 aa1 = aa.reshape
5654 print type(aa1) == types.BuiltinFunctionType
5655 pickle.dumps(aa1)
5656 if 2:
5657 # works:
5658 pickle.dumps(N.reshape)
5661 #* Numeric and pickle
5662 import Numeric as N, pickle
5663 from pdb import pm
5664 if 1:
5665 # fails:
5666 aa = N.array([ 1, 2, 3, 4 ]);
5667 aa1 = aa.resize
5668 print type(aa1) == types.BuiltinFunctionType
5669 pickle.dumps(aa1)
5670 if 2:
5671 # works
5672 pickle.dumps(N.reshape)
5674 #* outline traversal
5675 # print the outline
5676 for (nd, level) in w_.lib_tree.body().outl_top_down():
5677 print " " * level, level, nd.l_label
5679 #* timed run
5680 def time_func(fun, *args, **kwd):
5681 from time import time
5682 start = time()
5683 fun(*args, **kwd)
5684 print time() - start
5686 #* eman2 pickle tests
5687 # - Works when run in one session.
5688 # - Works across sessions.
5689 import sparx as sx, l3lang.utils as ut
5690 volume = sx.getImage( "model.tcp" )
5691 print volume.get_xsize() * volume.get_ysize() * volume.get_zsize()
5693 image = sx.project(volume, [10.0, 20.0, 30.0, 0.0, 0.0], 35)
5694 print image.get_xsize()
5696 # Image.
5697 time_func(cPickle.dumps, image, protocol = 2)
5699 ut.file_pickle(image, 'st.1')
5700 image_ld = ut.file_unpickle('st.1')
5703 # Volume.
5704 import cPickle
5705 # st = cPickle.dumps(volume, protocol=2)
5706 time_func(cPickle.dumps, volume, protocol=2)
5708 time_func(sx.dropImage, volume, "st.spi", itype = 's')
5710 ut.file_pickle(volume, 'st.2')
5711 # Load in separate session.
5712 import sparx as sx, l3lang.utils as ut
5713 volume_ld = ut.file_unpickle('st.2')
5715 vol_st = volume_ld.__getstate__()
5717 #* Set() special form: aa[ii] = rhs
5718 #** single-index pattern derivation
5719 aa = reader.parse("aa[i] = foo").body()
5721 # Set(Call(Member(Symbol('operator'),
5722 # Symbol('getitem')),
5723 # aList([Symbol('a'),
5724 # Symbol('i')])),
5725 # Symbol('foo'))
5727 aa = reader.parse("! AA[ ! II ] = ! RHS").body()
5729 Set(Call(Member(Symbol('operator'),
5730 Symbol('getitem')),
5731 aList([Marker('AA'),
5732 Marker('II')])),
5733 Marker('RHS'))
5735 #** transform to `operator.setitem(aa, ii, rhs)`
5736 print reader.parse('operator.setitem(!AA, !II, !RHS)').body()
5738 Call(Member(Symbol('operator'),
5739 Symbol('setitem')),
5740 aList([Marker('AA'),
5741 Marker('II'),
5742 Marker('RHS')]))
5745 #** numeric: single-bracket, multi-index
5746 import Numeric as N
5747 aa = N.reshape(N.array([ 1, 2, 3, 4 ]), (2,2))
5748 print aa[0,1]
5750 # Syntax error...
5751 print reader.parse("aa[0,1]").body()
5753 # Parses:
5754 print reader.parse("aa[(0,1)]").body()
5755 # long form works:
5756 print operator.getitem(aa, (0,1))
5758 # Call(Member(Symbol('operator'),
5759 # Symbol('getitem')),
5760 # aList([Symbol('aa'),
5761 # Tuple(aList([Int(0),
5762 # Int(1)]))]))
5764 # So the single-index pattern will work.
5766 #** tests
5767 print reader.parse("aa[ii] = foo").body()
5768 program:
5769 # Circumvents l3 value tracking.
5770 aa = [0,1,2]
5771 aa[0] = 4
5775 #* Set() special form: aa[ii][jj] = rhs
5776 #** Original in
5777 aa = reader.parse("! AA[ ! II ] [ !JJ ] = ! RHS").body()
5779 Set(Call(Member(Symbol('operator'),
5780 Symbol('getitem')),
5781 aList([Call(Member(Symbol('operator'),
5782 Symbol('getitem')),
5783 aList([Marker('AA'),
5784 Marker('II')])),
5785 Marker('JJ')])),
5786 Marker('RHS'))
5789 #** Transformed out.
5790 print reader.parse('''
5791 operator.setitem(
5792 operator.getitem(!AA, !II),
5793 !JJ,
5794 !RHS)''').body()
5795 Call(Member(Symbol('operator'),
5796 Symbol('setitem')),
5797 aList([Call(Member(Symbol('operator'),
5798 Symbol('getitem')),
5799 aList([Marker('AA'),
5800 Marker('II')])),
5801 Marker('JJ'),
5802 Marker('RHS')]))
5804 #** tests
5805 print reader.parse("aa[ii][jj] = foo").body()
5806 program:
5807 # Circumvents l3 value tracking.
5808 aa = [[0,1], [2,3]]
5809 aa[0]
5810 aa[1][0] = 10
5814 #* Set special form: a.foo = 2
5815 # Still uses setitem.
5816 aa = utils.Shared()
5817 aa.foo = 1
5818 operator.setitem(aa, 'foo', 2)
5819 print aa.foo
5821 #* string parsing
5822 #** n behavior, manual eval
5823 # This lets python convert the \n to an escape:
5824 aa = reader.parse('"""Outer radius : %i\n""" % 123')
5825 chars(aa.body()._primary[1][0]._primary[0])
5827 # Setup.
5828 play_env = interp.get_child_env(def_env, storage)
5829 aa.setup(empty_parent(), play_env, storage)
5830 view.print_info(storage, aa)
5832 # Interpret.
5833 news = aa.interpret(play_env, storage)
5834 chars(news[0]) # has actual newline
5835 #** n behavior, pasting
5836 """Outer radius : %i\n""" % 123
5837 # run code => ('Outer radius : 123\\n', 5496)
5838 #** compare
5839 manual eval:
5840 45065 -22 45065 String('Outer radius : %i\n')
5842 l3.py:
5843 >>> print """Outer radius : %i\n""" % 123
5844 Outer radius : 123\n
5846 pasting:
5847 45072 5494 45072 String('Outer radius : %i\\n')
5849 #** difference, commit c2c6cff9496972d40011002de24d20abca1a6bab and before
5851 # This lets python convert the \n to an escape:
5852 aa = reader.parse('"""Outer radius : %i\n""" % 123')
5854 # This won't, and that's the behavior observed from the gui / toplevel.
5855 aa = reader.parse(r'"""Outer radius : %i\n""" % 123')
5857 # This also contains \\n instead of the control code.
5858 pprint.pprint([ii for ii in tokenize.generate_tokens(string_readline(r'"Outer radius : %i\n"'))])
5861 #** difference removed
5862 # both contain \n control code.
5863 print reader.parse('"""Outer radius : %i\n""" % 123')
5865 # This won't, and that's the behavior observed from the gui / toplevel.
5866 print reader.parse(r'"""Outer radius : %i\n""" % 123')
5869 #* pytables for reading hdf
5870 #** raw experiments
5871 import tables
5872 # File is available after ali2d.l3 run
5873 fi = tables.openFile("_K-8-133679/average.hdf")
5874 # method listNodes in module tables.file:
5875 fi.listNodes # show all
5876 [li for li in fi.listNodes('/MDF/images')]
5878 # RootGroup in module tables.group object:
5879 fi.getNode('/')
5881 fi.root == fi.getNode('/') # true
5883 for node in fi.root:
5884 print node
5886 list(fi.root) # list from iterator
5887 list(fi.root)[0] # first child
5888 list(list(fi.root)[0]) # first child's children
5892 fi.listNodes('/') # get list
5893 (fi.listNodes('/')[0])._v_name
5895 for sub in fi.listNodes('/'):
5896 print sub._v_name
5898 # caution:
5899 # >>> fi.getNode('/')
5900 # / (RootGroup) ''
5901 # children := ['MDF' (Group)]
5902 # >>> fi.getNode('/').getNode('MDF')
5903 # Segmentation fault
5905 fi.getNode('/MDF/images')
5906 fi.getNode('/MDF/images')._v_attrs # print
5907 fi.getNode('/MDF/images')._v_attrs._g_listAttr() # get list
5909 fi.getNode('/MDF/images')._f_getChild('1')
5911 fi.getNode('/MDF/images/1')
5912 # tables.attributeset.AttributeSet'>
5913 fi.getNode('/MDF/images/1')._v_attrs # print info
5914 fi.getNode('/MDF/images/1')._v_attrs._g_listAttr() # get list
5915 (fi.getNode('/MDF/images/1')._v_attrs )._f_list() # get list (better)
5916 fi.getNode('/MDF/images/1')._v_attrs._g_getAttr('EMAN.Class_average')
5917 fi.getNode('/MDF/images/1')._v_attrs._g_getAttr('EMAN.nobjects')
5918 fi.getNode('/MDF/images/1')._v_attrs._g_getAttr('EMAN.members')
5921 # Array in module tables.array
5922 arr = fi.getNode('/MDF/images')._f_getChild('1')._f_getChild('image')
5923 arr = fi.getNode('/MDF/images/1/image')
5924 arr.shape
5925 a00 = arr[0,0] # Returns a 0-D array
5926 a00 = arr[0:1,0:1] # Returns a slice copy.
5929 #** relevant for eman2 use
5931 # 1. The pytable classes:
5933 # / <class 'tables.group.RootGroup'>
5934 # MDF <class 'tables.group.Group'>
5935 # images <class 'tables.group.Group'>
5936 # 0 <class 'tables.group.Group'>
5937 # image <class 'tables.array.Array'>
5938 # 1 <class 'tables.group.Group'>
5939 # image <class 'tables.array.Array'>
5941 # 2. The attributes of a Group
5942 # ... members in a Group start with some reserved prefix, like _f_
5943 # (for public methods), _g_ (for private ones), _v_ (for instance
5944 # variables) or _c_ (for class variables).
5946 # tables.attributeset.AttributeSet'>
5947 # fi.getNode('/MDF/images/1')._v_attrs # print info
5949 # Get list of attributes.
5950 (fi.getNode('/MDF/images/1')._v_attrs)._f_list()
5952 # Get attribute with arbitrary name
5953 (fi.getNode('/MDF/images/1')._v_attrs).__getattr__('EMAN.Class_average')
5954 (fi.getNode('/MDF/images/1')._v_attrs).__getattr__('EMAN.members')
5956 # Set attribute:
5957 (fi.getNode('/MDF/images/1')._v_attrs ).new_stuff = 1
5959 # got tables.exceptions.FileModeError: the file is not writable
5962 #** tools
5963 #*** Traverse the object tree
5964 def nshow(fi, indent = 0):
5965 if hasattr(fi, '_v_name'):
5966 print " "*indent, fi._v_name, type(fi)
5967 if isinstance(fi, tables.array.Array):
5968 # For tables.array, iteration is over the rows; this shows
5969 # 75 1-d numpy arrays per image.
5970 return
5971 for sub in fi:
5972 nshow(sub, indent = indent + 1)
5973 else:
5974 print " "*indent, type(fi)
5975 nshow(fi.root)
5978 #*** simplified access interface for l3 use
5979 # Inject l3_* methods.
5980 def l3_len(self):
5981 'Return the number of images.'
5982 return self.getNode('/MDF/images')._v_nchildren
5983 tables.file.File.l3_len = l3_len
5986 def l3_getimg(self, index):
5987 'Return the image at `index`.'
5988 return self.getNode('/MDF/images')._f_getChild(str(index))._f_getChild('image')
5989 tables.file.File.l3_getimg = l3_getimg
5992 def l3_getatts(self, index):
5993 ''' Return a (name, value) list holding all the attributes of
5994 image `index`.
5996 ind = str(index)
5997 attset = self.root.MDF.images._f_getChild(ind)._v_attrs
5998 return [ (att, attset.__getattr__(att)) for att in attset._f_list()]
5999 tables.file.File.l3_getatts = l3_getatts
6002 def l3_getatt(self, index, name):
6003 ''' Return the `name` attribute of the image at `index`.'''
6004 ind = str(index)
6005 attset = self.root.MDF.images._f_getChild(ind)._v_attrs
6006 return attset.__getattr__(str(name))
6007 tables.file.File.l3_getatt = l3_getatt
6011 #*** tables access tests
6012 fi.l3_len()
6013 fi.l3_getimg(0)
6014 fi.l3_getatts(0)
6015 fi.l3_getatt(0, 'EMAN.Class_average')
6016 fi.l3_getatt(0, 'EMAN.nobjects')
6017 fi.l3_getatt(0, 'EMAN.members')
6021 #* nested main loop
6022 # Using the simple function
6023 if 1:
6024 def flush_events():
6025 # Updates bounding boxes, among others.
6026 while gtk.events_pending():
6027 gtk.main_iteration()
6029 # a loop could be
6030 if 1:
6031 while True:
6032 draw()
6033 flush_events()
6035 # as long as draw() does not block.
6037 import thread
6038 from threading import Lock
6039 import time
6040 lck = Lock()
6041 value = []
6042 def _do():
6043 try:
6044 value.append(raw_input(prompt))
6045 except EOFError:
6046 value.append(EOFError())
6047 lck.release()
6048 lck.acquire()
6049 thread.start_new_thread(_do, ())
6050 # Manual main loop until input is ready.
6051 while not lck.acquire(False):
6052 self._do_event()
6053 time.sleep(0.01)
6054 if isinstance(value[-1], Exception):
6055 raise value[-1]
6056 return value[-1]
6058 #* gui/console hybrid use
6059 #** highly irregular data, not used
6060 inline('from numpy import *; from pylab import *')
6061 for ii in range(12*3):
6062 a1 = (ii, array([-2100, -200, -100 / 2.0, -1200]))
6063 # Added to loop body.
6064 a1[0:1]
6065 a1[0]
6066 a2 = (ii, sum(a1[1]))
6067 (ii % 2 == 0) and -200 or 0
6069 # This is just too painful through the gui; there is too much
6070 # heterogeneous data.
6071 #** highly irregular data, python
6072 # Just defining and editing the textual data structure is FAR
6073 # superior. E.g.
6074 # (month, amount, what)
6075 specials = [(1, [(-200, "this")]),
6076 (22, [(300, "that")]),
6078 regular = [(mon, [(-100, "one"),
6079 (-200, "two"),
6080 ]) for mon in range(0, 12*3)]
6081 spec_d = dict(specials)
6082 # for (month, mon_dat) in regular:
6083 # print (month, mon_dat + spec_d.get(month, []))
6084 # Shorter:
6085 [ (month, mon_dat + spec_d.get(month, []))
6086 for (month, mon_dat) in regular]
6089 #** highly irregular data, l3
6090 inline('''
6091 def combine(specials, regular, r_from, r_to):
6092 reg_list = [(mon, regular) for mon in xrange(r_from, r_to)]
6093 spec_d = dict(specials)
6094 return [ (month, mon_dat + spec_d.get(month, []))
6095 for (month, mon_dat) in reg_list]
6096 ''')
6098 specials = [(1, [(-200, "this")]),
6099 (22, [(300, "that")]),
6101 regular = [(-100, "one"),
6102 (-200, "two"),
6104 combined = combine(specials, regular, 0, 3*12)
6107 #** embed in l3?
6108 # if Env's keys include any python hashables, an Env can accumulate
6109 # (int, val) bindings in addition to (name, val) bindings
6110 stuff = if ("map", "embedded"):
6111 for ii in range(0, 3*12):
6112 l3.env().set(ii, [(-100, "one"), (-200, "two")])
6114 l3set(1, [(-200, "this")])
6115 l3set(22, [(300, "that")])
6119 #* list comprehension
6120 [(mon, [(-100, "one"),
6121 (-200, "two"),
6122 ]) for mon in range(0, 12*3)]
6123 # As tail call, roughly:
6124 def _foo(arg, seq, accum):
6125 accum.append()
6126 if more(seq):
6127 _foo(arg, seq[1:None], accum)
6128 _foo(mon, range(0, 12*3), [])
6129 # this is already FAR to tedious, and a tracked (l3) expansion is not
6130 # desirable anyway.
6132 #* l3 script pieces
6133 # From matplotlib-0.90.1/examples/date_demo1.py
6135 # This example requires an active internet connection since it uses
6136 # yahoo finance to get the data for plotting
6138 # The scripts are independently runnable, and must be edited to form a
6139 # single program.
6142 #** Collect finance data using yahoo's service.
6143 if ("outline", "Collect finance data"):
6144 inline """if 1:
6145 from matplotlib.finance import quotes_historical_yahoo
6146 import datetime
6148 # <span background="#ffdddd">Retrieve data for stock symbol.</span>
6149 quotes = quotes_historical_yahoo(
6150 'INTC',
6151 datetime.date( 1995, 1, 1 ),
6152 datetime.date( 2004, 4, 12 ),
6153 asobject = True)
6154 if not quotes:
6155 error("Unable to get data")
6156 else:
6157 # <span background="#ffdddd">The data attributes of quotes.</span>
6158 quotes.date
6159 quotes.open
6160 quotes.close
6161 quotes.high
6162 quotes.low
6163 quotes.volume
6168 #** Date plot.
6169 if ("outline", "Date plot"):
6170 # <span background="#ffdddd">Plot details.</span>
6172 inline """if 1:
6173 import datetime
6175 def plot_date(fname, dates, values):
6176 from pylab import figure, show
6177 import datetime
6178 from matplotlib.dates import YearLocator, MonthLocator, DateFormatter
6180 fig = figure(figsize=(7,4), dpi=100)
6181 ax = fig.add_subplot(111)
6182 ax.plot_date(dates, values, '-')
6184 # Plot details -- ticks.
6185 years = YearLocator() # every year
6186 months = MonthLocator() # every month
6187 yearsFmt = DateFormatter('%Y')
6189 ax.xaxis.set_major_locator(years)
6190 ax.xaxis.set_major_formatter(yearsFmt)
6191 ax.xaxis.set_minor_locator(months)
6192 ax.autoscale_view()
6194 for label in ax.get_xticklabels() + ax.get_yticklabels():
6195 label.set_fontsize('8')
6197 # Plot details -- coords. message box.
6198 def price(x):
6199 return '$%1.2f' % x
6200 ax.fmt_xdata = DateFormatter('%Y-%m-%d')
6201 ax.fmt_ydata = price
6202 ax.grid(True)
6204 fig.savefig(fname)
6205 return fname
6207 # <span background="#ffdddd">Plot data.</span>
6208 filename = plot_date('_plot-%d.png' % new_id(),
6209 [datetime.date(1995,1,1).toordinal(),
6210 datetime.date(1997,1,1).toordinal()],
6211 [1, 2])
6213 #** Moving average
6214 if ("outline", "Moving average."):
6215 inline """if 1:
6216 import numpy
6217 def movavg(vec, n):
6218 # A[t] = (V[t] + V[t-1] + ... + V[ t-n+1 ]) / n
6219 # t = N .. N-n
6220 import numpy
6221 assert len(vec.shape) == 1, 'Expecting vector argument.'
6222 assert n > 1, 'Averaging over less than 2 elements.'
6223 (N, ) = vec.shape
6224 assert N > n, 'Not enough samples for averaging.'
6226 ma = copy(vec) * numpy.nan
6227 for t in xrange(n - 1, N):
6228 ma[t] = 1.0 * sum(vec[t-n+1: t + 1]) / n
6229 return ma
6231 mov_avg = movavg(numpy.array([1, 2, 3, 4.0]),
6234 #** Moving average via convolution
6235 # n = 2
6236 data = numpy.array([1.0, 2,3,4])
6237 weight = numpy.array([1.0/2, 1.0/2])
6238 mov_avg = numpy.convolve(data, weight, mode='same')
6239 mov_avg[0:weight.shape[0] - 1] = numpy.nan
6242 #** Moving average, simple plot
6243 import matplotlib
6244 matplotlib.use("gtk")
6246 from numpy import *
6247 from pylab import *
6249 # n = 2
6250 data = [1.0, 2,3,4]
6251 weight = [1.0/2, 1.0/2]
6252 mov_avg = convolve(data, weight, mode='same')
6253 mov_avg[0:len(weight) - 1] = nan
6255 t1 = plot(mov_avg) # t1 won't pickle.
6256 show(mainloop=False)
6257 show()
6260 #** Date plot as widget
6261 if ("outline", "Date plot"):
6262 # <span background="#ffdddd">Plot details.</span>
6264 inline """if 1:
6265 import datetime
6267 def plot_date(dates, values):
6268 from pylab import figure, show
6269 import datetime
6270 from matplotlib.dates import YearLocator, MonthLocator, DateFormatter
6271 from matplotlib.backends.backend_gtk import FigureCanvasGTK \
6272 as FigureCanvas
6274 fig = figure(figsize=(7,4), dpi=100)
6275 ax = fig.add_subplot(111)
6276 ax.plot_date(dates, values, '-')
6278 # Plot details -- ticks.
6279 years = YearLocator() # every year
6280 months = MonthLocator() # every month
6281 yearsFmt = DateFormatter('%Y')
6283 ax.xaxis.set_major_locator(years)
6284 ax.xaxis.set_major_formatter(yearsFmt)
6285 ax.xaxis.set_minor_locator(months)
6286 ax.autoscale_view()
6288 for label in ax.get_xticklabels() + ax.get_yticklabels():
6289 label.set_fontsize('8')
6291 # Plot details -- coords. message box.
6292 def price(x):
6293 return '$%1.2f' % x
6294 ax.fmt_xdata = DateFormatter('%Y-%m-%d')
6295 ax.fmt_ydata = price
6296 ax.grid(True)
6297 return fig
6299 # <span background="#ffdddd">Plot data.</span>
6300 plot_date([datetime.date(1995,1,1).toordinal(),
6301 datetime.date(1997,1,1).toordinal()],
6302 [1, 2])
6304 # The display widget is FigureCanvas(fig). But canvas operations will
6305 # destroy this occasionally so the raw figure handle is returned and
6306 # L3 can display Native( fig : <matplotlib.figure.Figure> )
6307 # via Widget(FigureCanvas(fig)).
6310 #* single-run mode
6311 def inline(str):
6312 exec(str, globals())
6314 inline("import matplotlib as M")
6315 inline( "import pylab as P")
6316 M.use('Agg')
6317 fig = P.figure(figsize=(5,4), dpi=75)
6320 #** doc strings as help entries
6321 from types import InstanceType, MethodType
6322 import pydoc
6323 if isinstance(fig, InstanceType):
6324 helpfor = fig.__class__
6325 # All member functions of this class.
6326 for (name, memb) in pydoc.allmethods(helpfor).iteritems():
6327 _docstr = pydoc.getdoc(memb)
6328 head, body = pydoc.splitdoc(_docstr)
6329 print "\f=================================\n", name
6330 print head
6331 print "--------------------------------------------\n", body
6332 else:
6333 helpfor = fig
6339 # # Useless:
6340 help(fig)
6342 # # Help on instance of Figure in module matplotlib.figure object:
6343 # # class instance(object)
6344 # # ...
6345 # # Good, but a LOT of content:
6346 help( fig.__class__)
6350 #* numpy arrays, python objects, l3 canvas grid
6351 # Table layout is very useful and implicit when displaying a list of tuples.
6352 # When editing a table, the underlying structure should BE a table to enforce
6353 # dimensions (no shape change when items are removed) and allow row / column
6354 # manipulation.
6355 import numpy as N
6356 arr = N.array([['desc', 'val'],
6357 ['car', 1.0],
6358 ['house', 2.2]], 'O')
6360 #** Add row
6361 print arr
6362 print arr[1, None] # 'car' row
6364 arr_1 = N.concatenate(
6365 (arr[0:2, 0:None], # Indexing stupidity to get rows 0 & 1
6366 [['bike', 0.5]],
6367 arr[2:None, 0:None]
6369 print arr_1
6372 #** Add colum
6373 print arr
6374 print arr[0:None, 1] # 'val' column
6376 arr_1 = N.concatenate(
6378 arr[0:None, 0:1], # Indexing stupidity to get rows 0 & 1
6379 N.array([['ratio'],
6380 [0.5],
6381 [0.1]], 'O'),
6382 arr[0:None, 1:None]
6383 ), axis=1)
6384 print arr_1
6387 #* matplotlib figures on l3 canvas (XY Plot script)
6390 #** Another numpy stupidity
6391 import matplotlib as M
6392 import pylab as P
6393 N = 5
6394 nn = P.arange(0, N)
6395 # Gives TypeError: only length-1 arrays can be converted to Python scalars
6396 xx = sin(2* nn* pi/N)
6397 # Works
6398 xx = P.sin(2* nn* pi/N)
6401 #** l3 polygon plots
6402 if ("outline", "XY Polygon Plot"):
6403 # <span background="#ffcccc">Plot details.</span>
6404 inline '''if 1:
6405 def plot_(fname, x, y):
6406 import matplotlib as M
6407 import pylab as P
6408 M.use('Agg')
6410 fig = P.figure(figsize=(5,4), dpi=75)
6411 ax = fig.add_subplot(111)
6412 ax.plot(x, y, '-', lw=2)
6414 ax.set_xlabel('')
6415 ax.set_ylabel('')
6416 ax.set_title('Polygon plot')
6417 ax.grid(True)
6419 fig.savefig(fname)
6420 return fname
6422 inline 'from pylab import *'
6423 for N in range(3, 12):
6424 nn = arange(0, N + 1)
6425 xx = sin(2* nn* pi/N)
6426 yy = cos(2* nn* pi/N)
6427 plot_(new_name('poly', '.png'), xx, yy)
6432 #** python
6433 import matplotlib as M
6434 import pylab as P
6436 def plot_xy(fname, x, y):
6437 M.use('Agg')
6438 plot = P.plot(x, y, '-', lw=2)
6440 # P.xlabel('time (s)')
6441 # P.ylabel('voltage (mV)')
6442 # P.title('About as simple as it gets, folks')
6443 # P.grid(True)
6445 P.savefig(fname)
6447 plot_xy('simple_plot.png',
6448 P.arange(0.0, 1.0+0.01, 0.01),
6449 P.cos(2*2*pi*t)
6452 import cPickle
6453 st = cPickle.dumps(plot, protocol=2)
6454 # UnpickleableError: Cannot pickle <type 'Affine'> objects
6457 #** l3 calling python
6458 inline '''
6459 def plot_(fname, x, y):
6460 import matplotlib as M
6461 import pylab as P
6462 M.use('Agg')
6464 plot = P.plot(x, y, '-', lw=2)
6466 # P.xlabel('time (s)')
6467 # P.ylabel('voltage (mV)')
6468 # P.title('About as simple as it gets, folks')
6469 # P.grid(True)
6471 P.savefig(fname)
6473 inline 'from math import pi; import matplotlib as M; import pylab as P'
6474 t = P.arange(0.0, 1.0+0.01, 0.01)
6475 s = P.cos(2 * pi * t)
6476 plot_('simple_plot.png', s, t)
6479 # Python image read (load) test
6480 import matplotlib.image as mi
6481 import numpy as N
6482 img_arr = mi.imread('simple_plot.png')
6485 #** l3 only
6486 def plot_(fname, x, y):
6487 inline('import matplotlib as M; import pylab as P')
6488 M.use('Agg')
6489 plot = P.plot(x, y, '-', lw=2)
6491 # P.xlabel('time (s)')
6492 # P.ylabel('voltage (mV)')
6493 # P.title('About as simple as it gets, folks')
6494 # P.grid(True)
6496 P.savefig(fname)
6497 inline 'from math import pi; import matplotlib as M; import pylab as P'
6498 t = P.arange(0.0, 1.0+0.01, 0.01)
6499 s = P.cos(2 * pi * t)
6500 plot_('simple_plot.png', s, t)
6504 #** l3 only, with axis
6505 # <span background="#ffcccc">Plot details.</span>
6506 def plot_(fname, x, y):
6507 inline('import matplotlib as M; import pylab as P')
6508 M.use('Agg')
6510 fig = P.figure(figsize=(5,4), dpi=75)
6511 ax = fig.add_subplot(111)
6512 ax.plot(x, y, '-', lw=2)
6514 ax.set_xlabel('time (s)')
6515 ax.set_ylabel('voltage (mV)')
6516 ax.set_title('About as simple as it gets, folks')
6517 ax.grid(True)
6519 fig.savefig(fname)
6520 return fname
6521 inline 'from math import pi; import pylab as P'
6522 # <span background="#ffdddd">Plot data.</span>
6523 x = P.arange(0.0, 1.0+0.01, 0.01)
6524 y = P.cos(2 * pi * x)
6525 # <span background="#ffdddd">Plot file.</span>
6526 filename = plot_('_plot-%d.png' % new_id(), x, y)
6530 #** l3 with explicit figure in subplot
6531 # Plot details can be adjusted here.
6532 inline '''
6533 def plot_(fname, x, y):
6534 import matplotlib as M
6535 import pylab as P
6536 M.use('Agg')
6538 fig = P.figure(figsize=(5,4), dpi=75)
6539 ax = fig.add_subplot(111)
6540 ax.plot(x, y, '-', lw=2)
6542 ax.set_xlabel('time (s)')
6543 ax.set_ylabel('voltage (mV)')
6544 ax.set_title('About as simple as it gets, folks')
6545 ax.grid(True)
6547 fig.savefig(fname)
6549 inline 'from math import pi; import matplotlib as M; import pylab as P'
6550 x = t = P.arange(0.0, 1.0+0.01, 0.01)
6551 y = s = P.cos(2 * pi * t)
6552 # Insert plot data here.
6553 plot_('simple_plot.png', s, t)
6557 #** Plot without intermediate data file
6558 # from .../matplotlib-0.90.1/examples/to_numeric.py
6561 #** Interactive matplotlib window combined with l3gui
6562 import matplotlib as M
6563 import pylab as P
6565 from matplotlib.axes import Subplot
6566 from matplotlib.figure import Figure
6567 from matplotlib.numerix import arange, sin, pi
6569 antialias = False
6570 if antialias:
6571 from matplotlib.backends.backend_gtkagg import \
6572 FigureCanvasGTKAgg as FigureCanvas
6573 from matplotlib.backends.backend_gtkagg import \
6574 NavigationToolbar2GTKAgg as NavigationToolbar
6575 else:
6576 from matplotlib.backends.backend_gtk import \
6577 FigureCanvasGTK as FigureCanvas
6579 from matplotlib.backends.backend_gtk import \
6580 NavigationToolbar2GTK as NavigationToolbar
6582 def plot_figure():
6583 fig = Figure(figsize=(5,4), dpi=100)
6584 ax = fig.add_subplot(111)
6585 t = arange(0.0,3.0,0.01)
6586 s = sin(2*pi*t)
6587 ax.plot(t,s)
6588 ax.set_xlabel('time (s)')
6589 ax.set_ylabel('voltage (mV)')
6590 ax.set_title('About as simple as it gets, folks')
6591 ax.grid(True)
6592 return (ax, fig)
6595 def plot_win(figure):
6596 win = gtk.Window()
6597 # win.connect("destroy", lambda x: gtk.main_quit())
6598 win.set_default_size(400,300)
6599 win.set_title("Interactive plot")
6601 vbox = gtk.VBox()
6602 win.add(vbox)
6604 canvas = FigureCanvas(figure)
6605 toolbar = NavigationToolbar(canvas, win)
6606 vbox.pack_start(canvas)
6607 vbox.pack_start(toolbar, False, False)
6609 win.show_all()
6610 # gtk.main()
6611 return win
6613 # Everything is done through the figure and axis (good), but these
6614 # don't pickle.
6615 (axis, figure) = plot_figure()
6616 figure.savefig('testimage.png') # Also available via plot window.
6617 plot_win(figure)
6619 gtk.main() # test only.
6623 xx = P.arange(0.0, 1.0+0.01, 0.01)
6624 yy = P.cos(2*2*pi*xx)
6625 fname = 'simple_plot.png'
6626 if 1:
6627 M.use('GTKAgg')
6628 plot = P.plot(xx, yy, '-', lw=2)
6629 P.xlabel('time (s)')
6630 P.ylabel('voltage (mV)')
6631 P.title('About as simple as it gets, folks')
6632 P.grid(True)
6633 P.savefig(fname)
6637 #* empy macro tests
6638 #** simplest expansion
6639 from l3lang.cruft import em
6640 glo = {}
6641 em.expand(
6642 '@[def emph(str)]<span background="#ffcccc"> @str </span>@[end def]', glo)
6643 print em.expand("@emph('the comment')", glo)
6645 #** Single em interpreter, faster.
6646 from l3lang.cruft import em
6647 em_inter = em.Interpreter()
6648 em_glo = {}
6649 em_inter.expand(
6650 '@[def emph(str)]<span background="#ffcccc"> @str </span>@[end def]'
6651 '@[def strong(str)]<b> @str </b>@[end def]'
6652 , em_glo)
6653 def emx(str):
6654 print em_inter.expand(str, em_glo)
6656 #*** Expand one time:
6657 emx("@emph('the comment')")
6658 emx("@strong('bold')")
6659 emx("""@emph('the @strong("bold") comment')""")
6662 #*** Nested expansion:
6663 emx("""@emph{the @strong("bold") comment}""")
6665 #*** Ordering in nested expansions.
6666 # In this, em_l inside def gives
6667 # NameError: global name 'em_l' is not defined
6668 emx('''
6669 @{em_l = 0}
6670 @[def emph(str)]
6671 @{global em_l;
6672 em_l += 1}
6673 @[if em_l % 2]
6674 <span background="EVEN">
6675 @str
6676 </span>
6677 @[else]
6678 <span background="ODD">
6679 @str
6680 </span>
6681 @[end if]
6682 @{em_l -= 1}
6683 @[end def]
6684 ''')
6686 emx("@em_l")
6687 emx("No emphasis @emph{some emphasis @emph{nested emphasis} some emphasis}")
6690 #*** Ordering in nested expansions, 2
6691 # The following cannot work; the em_l state has to be decreased at some
6692 # future time after the macro is expanded .
6693 class emph:
6694 em_l = 0
6695 def __call__(self, stri):
6696 self.__class__.em_l += 1
6698 if self.__class__.em_l % 2:
6700 <span background="EVEN">
6701 @stri
6702 </span>
6704 else:
6706 <span background="ODD">
6707 @stri
6708 </span>
6710 self.__class__.em_l -= 1
6712 emph = _foo()
6716 #*** Ordering in nested expansions, 3
6717 # The nested expansion order is inside-out (which is wrong).
6718 emx('''
6720 def emph(stri):
6721 emph_level = empy.getGlobals().get('emph_level', -1) + 1
6722 empy.getGlobals()['emph_level'] = emph_level
6723 if (emph_level % 2) == 0:
6724 rv = empy.expand('<span background="EVEN"> @stri </span>', locals())
6725 else:
6726 rv = empy.expand('<span background="ODD"> @stri </span>', locals())
6727 empy.getGlobals()['emph_level'] = emph_level - 1
6728 return rv
6730 ''')
6731 emx("@emph('foo')")
6732 emx("@emph('hello @emph(this) world')")
6733 emx("@emph{hello @emph{this} world}")
6736 #*** Ordering in nested expansions, 4
6738 emx('''
6740 def emph(stri):
6741 emph_level = empy.getGlobals().get('emph_level', -1) + 1
6742 empy.getGlobals()['emph_level'] = emph_level
6744 exp = lambda strng: empy.expand(strng, locals())
6745 if (emph_level % 2) == 0:
6746 rv = empy.expand(
6747 empy.expand(
6748 '<span background="EVEN"> @stri </span>',
6749 locals()),
6750 locals())
6751 else:
6752 rv = empy.expand(
6753 empy.expand(
6754 '<span background="ODD"> @stri </span>',
6755 locals()),
6756 locals())
6757 empy.getGlobals()['emph_level'] = emph_level - 1
6758 return rv
6760 ''')
6761 # Works
6762 emx("@emph('foo')")
6763 # Gives NameError: name 'emph' is not defined
6764 emx("@emph('hello @emph(this) world')")
6765 emx("@emph{hello @emph{this} world}")
6769 #* User-guiding emphasis
6770 #** highlight, raw pango markup
6771 # <span background="#ffcccc">Plot details can be adjusted here.</span>
6772 inline '''if 1:
6773 def plot_(fname, x, y):
6774 import matplotlib as M
6775 import pylab as P
6776 M.use('Agg')
6778 fig = P.figure(figsize=(5,4), dpi=75)
6779 ax = fig.add_subplot(111)
6780 ax.plot(x, y, '-', lw=2)
6782 ax.set_xlabel('time (s)')
6783 ax.set_ylabel('voltage (mV)')
6784 ax.set_title('About as simple as it gets, folks')
6785 ax.grid(True)
6787 fig.savefig(fname)
6790 inline 'from math import pi; import matplotlib as M; import pylab as P'
6791 x = t = P.arange(0.0, 1.0+0.01, 0.01)
6792 y = s = P.cos(2 * pi * t)
6793 # <span background="#ffdddd">Insert plot data here.</span>
6794 plot_(
6795 # <span background="#ffdddd">Output file name.</span>
6796 'simple_plot.png',
6797 # <span background="#ffdddd">Your X.</span>
6799 # <span background="#ffdddd">Your Y.</span>
6802 #** highlight, m4 syntax.
6803 # guide(Insert plot data here.)
6804 plot_(
6805 # guide(Output file name.)
6806 'simple_plot.png',
6807 # guide(Your X.)
6809 # guide(Your Y.)
6812 #** highlight, per-line prefix syntax.
6813 #g* Insert plot data here.
6814 plot_(
6815 #g* Output file name.
6816 'simple_plot.png',
6817 #g* Your X.
6819 #g* Your Y.
6822 #** highlight, long syntax w/ line separation
6823 # This leaves blank lines.
6824 #<span background="#ffdddd">
6825 # Insert plot data here.
6826 #</span>
6827 plot_(
6828 # <span background="#ffdddd">Output file name.</span>
6829 'simple_plot.png',
6830 # <span background="#ffdddd">Your X.</span>
6832 # <span background="#ffdddd">Your Y.</span>
6838 #** Greyscale other text.
6839 # From any root node:
6840 from l3gui.widgets import *
6841 for nd in self.iter_visibles():
6842 if isinstance(nd, l3Rawtext):
6843 nd._ltext.set_property("fill-color", "#" + "d0" * 3)
6845 #** Collect user guiding info from comments.
6846 # Starting from 'eval locally',
6847 # >>> self
6848 # <l3gui.widgets.l3Program instance at 0xb780a70c>
6849 #*** Find all comments.
6850 dt = self.w_.deco_table_
6851 for nd in self._l3tree.top_down():
6852 print nd, dt.get(nd._id, None)
6854 #*** Traverse comments.
6855 def iter_comments(self):
6856 dt = self.w_.deco_table_
6857 for nd in self._l3tree.top_down():
6858 comm = dt.get(nd._id, None)
6859 if comm != None:
6860 yield comm
6863 #*** Find comments with highlighting.
6864 for comm in iter_comments(self):
6865 if (comm.find("<span background") > 0):
6866 print comm
6869 #*** Accumulate comments.
6870 print [ comm for comm in iter_comments(self)
6871 if (comm.find("<span background") > 0)]
6872 print [ comm.py_string()
6873 for comm in iter_comments(self)
6874 if (comm.find("<span background") > 0)]
6875 print '\n'.join([ comm.py_string()
6876 for comm in iter_comments(self)
6877 if (comm.find("<span background") > 0)])
6880 #*** Add accumulation to this heading's comment.
6881 # This changes the associated comment and adds state handling details.
6882 # Viewing internal information can be a transient action (use popups)
6883 # or a special view (independent display alongside).
6885 # Use deco_change_label
6886 dt = self.w_.deco_table_
6887 comm = dt.get(self._l3tree._id, None)
6889 if comm != None:
6890 prepend = comm.py_string()
6891 self._old_label = prepend
6892 else:
6893 prepend = ""
6894 print (prepend + '\n' +
6895 '\n'.join([ comm.py_string()
6896 for comm in iter_comments(self)
6897 if (comm.find("<span background") > 0)]))
6899 self.deco_change_label(label =
6900 (prepend + '\n' +
6901 '\n'.join([ comm.py_string()
6902 for comm in iter_comments(self)
6903 if (comm.find("<span background") > 0)])))
6906 #*** Display accumulation as separate node
6907 # Loosely connected to independent
6908 TODO: add as menu entry
6909 done: view_as -> full member
6910 self.view_as('flat')
6915 #* matplotlib and tools
6916 from numerix import absolute, arange, array, asarray, ones, divide,\
6917 transpose, log, log10, Float, Float32, ravel, zeros,\
6918 Int16, Int32, Int, Float64, ceil, indices, \
6919 shape, which, where, sqrt, asum, compress, maximum, minimum, \
6920 typecode, concatenate, newaxis, reshape, resize, repeat, \
6921 cross_correlate, nonzero
6923 from matplotlib.numerix import absolute, arange, array, asarray, ones, divide,\
6924 transpose, log, log10, Float, Float32, ravel, zeros,\
6925 Int16, Int32, Int, Float64, ceil, indices, \
6926 shape, which, where, sqrt, asum, compress, maximum, minimum, \
6927 typecode, concatenate, newaxis, reshape, resize, repeat, \
6928 cross_correlate, nonzero
6930 inline 'import MLab as M; from matplotlib.numerix import transpose'
6931 A = M.rand(4,4)
6932 At = transpose(A)
6935 # run from l3, gets stuck in
6936 # #0 dlamc3_ (a=0xb7a10030, b=0xb7a0ffe0) at Src/dlamch.c:685
6937 # when run from l3 AND when run in l3's python:
6938 # l3 -> python -> run -> wait.
6939 M.eig(A)
6941 #* screenshots via gtk
6942 # For capturing images of selected items it's much better to use known
6943 # coordinates and directly produce a file than using the capture ->
6944 # edit -> convert -> save sequence via the gimp or others.
6946 view = self.w_.canvas.view
6947 selection = self.w_.selector.get_selection()
6949 (sl, st, sr, sb) = selection.get_bounds()
6951 # Get selection corners.
6952 (wl, wt) = map(int, view.world_to_window(sl, st))
6953 (wr, wb) = map(int, view.world_to_window(sr, sb))
6955 # Compute selection dimensions.
6956 width = wr - wl
6957 height = wb - wt
6959 # Prepare pixbuf.
6960 pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,
6961 False, # has_alpha
6962 8, # bits_per_sample
6963 width,
6964 height)
6966 # get_from_drawable(src, cmap, src_x, src_y, dest_x, dest_y, width, height)
6967 status = pixbuf.get_from_drawable(
6968 view.get_parent_window(), # gtk.gdk.Window(gtk.gdk.Drawable)
6969 gtk.gdk.colormap_get_system(),
6970 wl, wt,
6971 0, 0,
6972 width, height
6975 if status == None:
6976 print "capture failed"
6978 pixbuf.save("/tmp/foo.png", "png")
6980 #* system state work :l3:memory_use:
6981 # good start:
6982 for (mname, memb) in self.__dict__.iteritems():
6983 print "%-20s %40s" % (mname, memb)
6985 # Check completeness.
6986 set([1,2]) - set([1])
6987 set(self.__dict__.keys()) - set(dir(self)) # Empty, good.
6990 #** Print an ordered table of member DATA.
6991 def sort(list):
6992 list.sort()
6993 return list
6995 print self
6996 for mname in sort(self.__dict__.keys()):
6997 memb = self.__dict__[mname]
6998 print " %-20s %-40s" % (mname, memb)
7001 #** Print an ordered table of member DATA.
7002 def pot1(datum):
7003 print "%s.%s instance at %x" % (datum.__module__,
7004 datum.__class__.__name__,
7005 (id(self)))
7007 for mname in sort(datum.__dict__.keys()):
7008 memb = datum.__dict__[mname]
7009 print " %-20s %-40.39s" % (mname, memb)
7010 pot1(self._l3tree)
7012 l3lang.ast.Program instance at -488123d4
7013 _attributes {}
7014 _block_env Env-30005-anonymous
7015 _first_char (28, 8)
7016 _id 30021
7020 #** ordered table of member data 2
7021 # Lines numbered,
7022 # first type occurence listed as subtree
7023 from types import *
7024 def pot2(datum, line = 1, handled = set()):
7025 # Filter built-in and already printed types
7026 if not (type(datum) == InstanceType):
7027 return line
7029 classname = "%s.%s" % (datum.__module__, datum.__class__.__name__)
7030 if classname in handled:
7031 return line
7032 handled.add(classname)
7034 # Print info
7035 print "%s.%s instance at %x" % (datum.__module__,
7036 datum.__class__.__name__,
7037 (id(self)))
7038 for mname in sort(datum.__dict__.keys()):
7039 memb = datum.__dict__[mname]
7040 print "%4d %-20s %-40.39s" % (line, mname, memb)
7041 line = pot2(memb, line = line + 1, handled = handled)
7042 return line
7043 pot2(self._l3tree, line = 1, handled = set())
7045 l3lang.ast.Program instance at -488123d4
7046 1 _attributes {}
7047 2 _block_env Env-30005-anonymous
7048 l3lang.ast.Env instance at -488123d4
7049 3 _bindings {('active', 'df'): None, ('pixel', 'df'
7050 4 _bindings_ids {('active', 'df'): 30509, ('pixel', 'df
7051 5 _bindings_memory {}
7052 6 _children [Env(30536, Env-30005-anonymous, [Progr
7053 7 _def_env_id 30001
7058 #** print ordered table of member data 3
7059 # Lines numbered,
7060 # first type occurence listed as subtree,
7061 # indentation for levels,
7062 # all later occurrences of a type refer to line number
7063 from types import *
7064 def sort(list):
7065 list.sort()
7066 return list
7067 def pot3(datum, line = 1, handled = {}, indent = 1):
7068 # Filter built-in and already printed types
7069 if not (type(datum) == InstanceType):
7070 return line
7072 space = " " * indent
7073 classname = "%s.%s" % (datum.__module__, datum.__class__.__name__)
7074 if handled.has_key(classname):
7075 print "%4d%s%s.%s instance -- see line %d" % (line,
7076 space,
7077 datum.__module__,
7078 datum.__class__.__name__,
7079 handled[classname])
7080 return line + 1
7081 else:
7082 handled[classname] = line
7084 # Print info
7085 print "%4d%s%s.%s instance at %x" % (line,
7086 space,
7087 datum.__module__,
7088 datum.__class__.__name__,
7089 (id(self)))
7090 line += 1
7091 for mname in sort(datum.__dict__.keys()):
7092 memb = datum.__dict__[mname]
7093 print "%4d%s%-20s %-40.39s" % (line, space, mname, memb)
7094 line = pot3(memb, line = line + 1, handled = handled,
7095 indent = indent + 1)
7096 return line
7097 # 210 lines
7098 pot3(self, line = 1, handled = {}, indent = 1)
7099 # 46 lines
7100 pot3(self._l3tree, line = 1, handled = {}, indent = 1)
7104 #** print ordered table of member data 4
7105 # Lines numbered,
7106 # first type occurence listed as subtree,
7107 # indentation for levels,
7108 # repeated instances of a fixed-member type refer to first's line number,
7109 # distinct instances of container types (Shared) produce new listing.
7110 from types import *
7111 import l3lang.ast
7112 def sort(list):
7113 list.sort()
7114 return list
7116 truncate_lines = "%-120.119s"
7117 truncate_lines = "%-80.79s"
7118 def pot4(datum, line = 1, handled = {}, indent = 1):
7119 # Filter built-in types.
7120 # inheriting from ListType has subtle problems.
7121 if isinstance(datum, l3lang.ast.aList):
7122 pass
7123 else:
7124 if not (type(datum) == InstanceType):
7125 return line
7127 space = " " * indent
7128 classname = "%s.%s" % (datum.__module__, datum.__class__.__name__)
7130 # Only cross-reference already visited data.
7131 if classname not in ['l3lang.utils.Shared']:
7132 if handled.has_key(classname):
7133 print "%4d%s%s.%s instance -- see line %d" % (line,
7134 space,
7135 datum.__module__,
7136 datum.__class__.__name__,
7137 handled[classname])
7138 return line + 1
7139 else:
7140 handled[classname] = line
7142 else:
7143 if handled.has_key(id(datum)):
7144 print "%4d%s%s.%s visited instance -- see line %d" % (
7145 line,
7146 space,
7147 datum.__module__,
7148 datum.__class__.__name__,
7149 handled[id(datum)])
7150 return line + 1
7152 else:
7153 handled[id(datum)] = line
7155 # Print info for this datum.
7156 if indent < 2:
7157 # Only show headers for objects not already described.
7158 print "%4d%s%s.%s instance at 0x%x" % (line,
7159 space,
7160 datum.__module__,
7161 datum.__class__.__name__,
7162 (id(datum) & 0xFFFFFFFFL))
7163 line += 1
7165 # Visit datum's children.
7166 for mname in sort(datum.__dict__.keys()):
7167 memb = datum.__dict__[mname]
7168 print truncate_lines % ("%4d%s%-20s %-60s" % (line, space, mname, memb))
7169 line = pot4(memb, line = line + 1, handled = handled,
7170 indent = indent + 1)
7171 return line
7172 # self is noise_add.l3
7173 pot4(self, line = 1, handled = {}, indent = 1)
7174 # 327 lines
7175 # 325 remember_y 60.25
7176 # 326 w_ <l3lang.utils.Shared instance at 0xb777512c>
7177 # 327 l3lang.utils.Shared visited instance -- see line 21
7179 # 1352 lines without back-reference to already-visited Shareds, e.g.
7181 # 1146 w_ <l3lang.utils.Shared instance at 0xb777512c>
7182 # 1147 __fluids {}
7183 # 1148 _non_pickling_keys []
7187 Include traversal of lists, dicts to cover this:
7189 This is missing _l3tree contents because
7190 type(self._alist.__dict__['_l3tree'])
7191 <class 'l3lang.ast.aList'>
7193 But this is not true; type returns
7194 >>> type(self._l3tree[0])
7195 <class 'l3lang.ast.aList'>
7196 while the instance members are all present:
7197 >>> dir(self._l3tree[0])
7198 ... '_first_char', '_id', '_last_char', '_parent',...
7199 And:
7200 >>> isinstance(self._l3tree[0], l3lang.ast.aList)
7201 True
7203 Other NESTED types inheriting from python built-ins:
7204 class aList(ListType):
7205 class vaList(aList):
7212 #** print ordered table of member data 5
7213 # - Lines numbered,
7214 # - first type occurence listed as subtree,
7215 # - indentation for levels,
7216 # - repeated instances of a fixed-member type refer to first's line number,
7217 # - distinct instances of container types (Shared) produce new listing.
7218 # - make line numbers org-indexable, via [[line]] and <<line>>
7220 # Tried
7221 # - including indentation level for text reading, didn't help
7222 from types import *
7223 import l3lang.ast
7224 def sort(list):
7225 list.sort()
7226 return list
7228 truncate_lines = "%-120.119s"
7229 truncate_lines = "%-80.79s"
7230 def pot5(datum, line = 1, handled = {}, indent = 1):
7232 This produces a reasonable state dump of the l3 widget provided as
7233 `datum`. The contained l3 program is included but not traversed
7234 recursively, so associated data and clones are completely ignored.
7235 '''
7236 # Filter built-in types.
7237 # inheriting from ListType has subtle problems.
7238 if isinstance(datum, l3lang.ast.aList):
7239 pass
7240 else:
7241 if not (type(datum) == InstanceType):
7242 return line
7244 space = " " * indent
7245 classname = "%s.%s" % (datum.__module__, datum.__class__.__name__)
7247 # Only cross-reference already visited data.
7248 if classname not in ['l3lang.utils.Shared']:
7249 if handled.has_key(classname):
7250 print "<<%03d>>%s%s.%s instance -- see line [[%03d]]" % (
7251 line,
7252 space,
7253 datum.__module__,
7254 datum.__class__.__name__,
7255 handled[classname])
7256 return line + 1
7257 else:
7258 handled[classname] = line
7260 else:
7261 if handled.has_key(id(datum)):
7262 print "<<%03d>>%s%s.%s visited instance -- see line [[%03d]]" % (
7263 line,
7264 space,
7265 datum.__module__,
7266 datum.__class__.__name__,
7267 handled[id(datum)])
7268 return line + 1
7270 else:
7271 handled[id(datum)] = line
7273 # Print info for this datum.
7274 if indent < 999:
7275 # Only show headers for objects not already described.
7276 print "<<%03d>>%s%s.%s instance at 0x%x" % (
7277 line,
7278 space,
7279 datum.__module__,
7280 datum.__class__.__name__,
7281 (id(datum) & 0xFFFFFFFFL))
7282 line += 1
7284 # Visit datum's children.
7285 for mname in sort(datum.__dict__.keys()):
7286 memb = datum.__dict__[mname]
7287 print truncate_lines % ("<<%03d>>%s%-20s %-60s" % (line, space, mname, memb))
7288 line = pot5(memb, line = line + 1, handled = handled,
7289 indent = indent + 1)
7290 return line
7291 # self is noise_add.l3
7292 pot5(self, line = 1, handled = {}, indent = 1)
7295 #** print ordered table of member data, org version 1
7296 # - use hex id as address, via org
7297 # - first type occurence listed as subtree,
7298 # - indentation for levels,
7299 # - repeated instances of a fixed-member type refer to first's id
7300 # - distinct instances of container types (Shared) produce new listing.
7301 # - no line numbers
7302 # - include emacs outline decoration (org-mode)
7303 from types import *
7304 import l3lang.ast
7305 import l3lang.ast as A
7307 def sort(list):
7308 list.sort()
7309 return list
7311 def hexid(datum):
7312 return (id(datum) & 0xFFFFFFFFL)
7315 #*** special printers
7316 from EMAN2 import EMData
7317 from numpy import ndarray
7319 accum_types = (EMData, ndarray)
7321 special_printers = {}
7322 accumulate_interp_res = {} # Accumulate stuff as side-effect.
7323 limit_output_lines = 100
7326 #**** Accumulate by EXCLUDING types.
7327 def _special(datum, line = 1, handled = {}, indent = 1):
7328 '''Print additional information for RamMem._attr_tables.'''
7329 first_line = line
7330 space = " " * indent
7331 for (id_, dic1) in datum.iteritems():
7332 # 3002 {...}
7333 # mem_str = max_str_len % str(dic1)
7334 mem_str = "{...}"
7335 if (line - first_line) < limit_output_lines:
7336 print truncate_lines % (
7337 "%s%s%-20s %s" % (
7338 "*" * indent,
7339 space[0: -indent],
7340 id_,
7341 mem_str))
7342 line += 1
7343 # clone_of {...}
7344 for key in sort(dic1.keys()):
7345 # Side effect: accumulation
7346 if key == 'interp_result':
7347 se_val = dic1[key]
7348 # These checks are superficial; real code must use
7349 # pickle w/o memo dict for verification.
7350 if not isinstance(se_val, (A.astType, A.aNone, A.aList)):
7351 if (isinstance(se_val, ListType) and
7352 len(se_val) > 0 and
7353 isinstance(se_val[0], (A.astType, A.aNone, A.aList))):
7354 pass
7355 else:
7356 accumulate_interp_res[id_] = dic1[key]
7357 # Print SOME output.
7358 if (line - first_line) < limit_output_lines:
7359 mem_str = max_str_len % str(dic1[key])
7360 print truncate_lines % (
7361 "%s%s%-20s %s" % (
7362 "*" * (indent + 1),
7363 space[0: -(indent + 1)] + " ",
7364 key,
7365 mem_str))
7366 line += 1
7367 return line
7368 special_printers[('RamMem', '_attr_tables')] = _special
7371 #**** Accumulate by INCLUDING types.
7372 def _special(datum, line = 1, handled = {}, indent = 1):
7373 '''Print additional information for RamMem._attr_tables.'''
7374 first_line = line
7375 space = " " * indent
7376 for (id_, dic1) in datum.iteritems():
7377 # 3002 {...}
7378 # mem_str = max_str_len % str(dic1)
7379 mem_str = "{...}"
7380 if (line - first_line) < limit_output_lines:
7381 print truncate_lines % (
7382 "%s%s%-20s %s" % (
7383 "*" * indent,
7384 space[0: -indent],
7385 id_,
7386 mem_str))
7387 line += 1
7388 # clone_of {...}
7389 for key in sort(dic1.keys()):
7390 # Side effect: accumulation
7391 if key == 'interp_result':
7392 se_val = dic1[key]
7393 if isinstance(se_val, accum_types):
7394 accumulate_interp_res[id_] = se_val
7396 # Print SOME output.
7397 if (line - first_line) < limit_output_lines:
7398 mem_str = max_str_len % str(dic1[key])
7399 print truncate_lines % (
7400 "%s%s%-20s %s" % (
7401 "*" * (indent + 1),
7402 space[0: -(indent + 1)] + " ",
7403 key,
7404 mem_str))
7405 line += 1
7406 return line
7407 special_printers[('RamMem', '_attr_tables')] = _special
7410 #**** Accumulate by INCLUDING types and lists/tuples of types
7411 def _special(datum, line = 1, handled = {}, indent = 1):
7412 '''Print additional information for RamMem._attr_tables.'''
7413 first_line = line
7414 space = " " * indent
7415 for (id_, dic1) in datum.iteritems():
7416 # 3002 {...}
7417 # mem_str = max_str_len % str(dic1)
7418 mem_str = "{...}"
7419 if (line - first_line) < limit_output_lines:
7420 print truncate_lines % (
7421 "%s%s%-20s %s" % (
7422 "*" * indent,
7423 space[0: -indent],
7424 id_,
7425 mem_str))
7426 line += 1
7427 # clone_of {...}
7428 for key in sort(dic1.keys()):
7429 # Side effect: accumulation
7430 if key == 'interp_result':
7431 se_val = dic1[key]
7432 if isinstance(se_val, accum_types):
7433 accumulate_interp_res[id_] = se_val
7434 if isinstance(se_val, (ListType, TupleType)) and \
7435 (len(se_val) > 0) and \
7436 (len(
7437 [ ob for ob in se_val
7438 if isinstance(ob, accum_types)]) > 0):
7439 accumulate_interp_res[id_] = se_val
7442 # Print SOME output.
7443 if ((line - first_line) < limit_output_lines):
7444 mem_str = max_str_len % str(dic1[key])
7445 print truncate_lines % (
7446 "%s%s%-20s %s" % (
7447 "*" * (indent + 1),
7448 space[0: -(indent + 1)] + " ",
7449 key,
7450 mem_str))
7451 line += 1
7452 return line
7453 special_printers[('RamMem', '_attr_tables')] = _special
7456 #*** main printer
7457 truncate_lines = "%-80.79s"
7458 max_str_len = "%-60.59s"
7460 truncate_lines = "%-160.159s"
7461 max_str_len = "%-.90s"
7462 from time import time
7463 def poto1(datum, line = 1, handled = {}, indent = 1):
7464 # Filter built-in types.
7465 # inheriting from ListType has subtle problems.
7466 if isinstance(datum, l3lang.ast.aList):
7467 pass
7468 else:
7469 if not (type(datum) == InstanceType):
7470 return line
7472 space = " " * indent
7473 classname = "%s.%s" % (datum.__module__, datum.__class__.__name__)
7475 # Only cross-reference already visited data.
7476 if classname not in ['l3lang.utils.Shared']:
7477 if handled.has_key(classname):
7478 print "%s%s.%s instance -- see id [[0x%x]]" % (
7479 space,
7480 datum.__module__,
7481 datum.__class__.__name__,
7482 handled[classname])
7483 return line + 1
7484 else:
7485 handled[classname] = hexid(datum)
7487 else:
7488 if handled.has_key(id(datum)):
7489 print "%s%s.%s visited instance -- see id [[0x%x]]" % (
7490 space,
7491 datum.__module__,
7492 datum.__class__.__name__,
7493 handled[id(datum)])
7494 return line + 1
7496 else:
7497 handled[id(datum)] = hexid(datum)
7499 # Print info for this datum.
7500 if indent < 2:
7501 print "%s%s%s.%s instance at <<0x%x>>" % (
7502 "*" * indent,
7503 space[0: -indent],
7504 datum.__module__,
7505 datum.__class__.__name__,
7506 hexid(datum))
7507 line += 1
7509 # Visit datum's children.
7510 for mname in sort(datum.__dict__.keys()):
7511 memb = datum.__dict__[mname]
7512 # Include timing information with lines.
7513 start = time()
7515 # For instances, produce org-mode <<label>>
7516 # mem_str = max_str_len % str(memb)
7517 mem_str = max_str_len % str(memb)
7518 if "instance at 0x" in mem_str:
7519 mem_str = "%s at <<0x%x>>" % (mem_str[0:-15], hexid(memb))
7520 elif isinstance(memb, (InstanceType, ClassType, ListType, DictType)):
7521 mem_str = "%s at <<0x%x>>" % (mem_str, hexid(memb))
7522 print truncate_lines % (
7523 "%s%s%-20s %s [%.4fs]" % (
7524 "*" * indent,
7525 space[0: -indent],
7526 mname,
7527 mem_str,
7528 time() - start))
7529 # Default printout for child.
7530 line = poto1(memb, line = line + 1, handled = handled,
7531 indent = indent + 1)
7532 # Additional custom printout.
7533 try:
7534 line = special_printers[(datum.__class__.__name__,
7535 mname)](memb, line = line + 1,
7536 handled = handled,
7537 indent = indent + 1)
7538 except KeyError:
7539 pass
7540 return line
7542 #** Get internals dump
7543 # Run gui
7544 # insert program
7545 # run program
7546 # use 'evaluate locally` on datum
7548 # Then:
7549 self
7550 poto1(self, line = 1, handled = {}, indent = 1)
7552 poto1(w_.state_.storage, line = 1, handled = {}, indent = 1)
7555 #** Compute disk / ram ratio
7556 # Given
7557 # Sr = Ram state
7558 # Sd = disk state (from accumulate_interp_res)
7559 # St = total state (from save_state)
7560 # S0 = initial state (overhead, from save_state at time 0)
7561 # R = ratio
7563 # we want
7564 # Sr(t) = R * Sd(t)
7565 # and
7566 # St(t) = Sr(t) + Sd(t) + S0
7568 # Using known values,
7569 # Sr = St - Sd - S0
7570 # so
7571 # R = (St - Sd - S0) / Sd
7572 # should (approximately) hold.
7574 # Run gui
7575 # insert program
7576 # save state to st.t0
7577 # run program
7578 # exit to toplevel
7580 # Then:
7581 poto1(w_.state_.storage, line = 1, handled = {}, indent = 1)
7582 print "items collected: ", len(accumulate_interp_res)
7584 from l3lang import utils
7585 utils.file_cPickle(get_current_state(w_), "st.total")
7586 utils.file_cPickle(accumulate_interp_res, "st.disk")
7588 S0 = os.path.getsize("st.t0")
7589 St = os.path.getsize("st.total")
7590 Sd = os.path.getsize("st.disk")
7592 print "ram / disk ratio", 1.0 * (St - Sd - S0) / Sd
7595 #** view interp_result
7596 for (id_, val) in accumulate_interp_res.iteritems():
7597 print "%10d %-.50s" % (id_, val)
7599 # What is accumulate_interp_res[33122]?
7600 type(accumulate_interp_res[33122])
7601 print w_.state_.storage.get_attribute_names(33122)
7602 print w_.state_.storage.get_attribute(33122, 'interp_env')
7606 #** object sizes
7607 try:
7608 from cStringIO import StringIO
7609 except ImportError:
7610 from StringIO import StringIO
7612 pckl_file = StringIO()
7613 pcklr = pickle.Pickler(pckl_file, protocol = 2)
7614 pcklr.memo
7615 pcklr.dump(accumulate_interp_res)
7616 print "pickle size", pckl_file.tell()
7618 # memo[id(obj)] = memo_len, obj
7619 # too many values with no back-link information to identify source.
7620 for (id_, (index, obj)) in pcklr.memo.iteritems():
7621 print "%-11x %-6d %-.50s" % (id_, index, obj)
7625 #* Custom pickle with printout.
7626 # Collecting through storage is unreliable; modify pickle itself.
7627 #** params
7628 import pickle
7629 from EMAN2 import EMData
7630 from numpy import ndarray
7632 try:
7633 from cStringIO import StringIO
7634 except ImportError:
7635 from StringIO import StringIO
7637 accum_types = (EMData, ndarray)
7638 pckl_file = StringIO()
7639 g_display_size = 10000
7640 truncate_lines = "%-60.59s"
7643 #** pickle modifications.
7644 from types import *
7645 from copy_reg import dispatch_table
7646 from copy_reg import _extension_registry, _inverted_registry, _extension_cache
7647 import marshal
7648 import sys
7649 import struct
7651 def _real_save(self, obj):
7652 # Info dump
7653 me_start = pckl_file.tell()
7654 def dump_info():
7655 obj_size = pckl_file.tell() - me_start
7656 if isinstance(obj, accum_types) or (obj_size > g_display_size):
7657 print "| %8d | \"%s\" | " % (obj_size,
7658 truncate_lines % repr(obj))
7659 # -- Info dump
7661 # Check for persistent id (defined by a subclass)
7662 pid = self.persistent_id(obj)
7663 if pid:
7664 self.save_pers(pid)
7665 dump_info()
7666 return
7668 # Check the memo
7669 x = self.memo.get(id(obj))
7670 if x:
7671 self.write(self.get(x[0]))
7672 dump_info()
7673 return
7675 # Check the type dispatch table
7676 t = type(obj)
7677 f = self.dispatch.get(t)
7678 if f:
7679 f(self, obj) # Call unbound method with explicit self
7680 dump_info()
7681 return
7683 # Check for a class with a custom metaclass; treat as regular class
7684 try:
7685 issc = issubclass(t, TypeType)
7686 except TypeError: # t is not a class (old Boost; see SF #502085)
7687 issc = 0
7688 if issc:
7689 self.save_global(obj)
7690 dump_info()
7691 return
7693 # Check copy_reg.dispatch_table
7694 reduce = dispatch_table.get(t)
7695 if reduce:
7696 rv = reduce(obj)
7697 else:
7698 # Check for a __reduce_ex__ method, fall back to __reduce__
7699 reduce = getattr(obj, "__reduce_ex__", None)
7700 if reduce:
7701 rv = reduce(self.proto)
7702 else:
7703 reduce = getattr(obj, "__reduce__", None)
7704 if reduce:
7705 rv = reduce()
7706 else:
7707 raise PicklingError("Can't pickle %r object: %r" %
7708 (t.__name__, obj))
7710 # Check for string returned by reduce(), meaning "save as global"
7711 if type(rv) is StringType:
7712 self.save_global(obj, rv)
7713 dump_info()
7714 return
7716 # Assert that reduce() returned a tuple
7717 if type(rv) is not TupleType:
7718 raise PicklingError("%s must return string or tuple" % reduce)
7720 # Assert that it returned an appropriately sized tuple
7721 l = len(rv)
7722 if not (2 <= l <= 5):
7723 raise PicklingError("Tuple returned by %s must have "
7724 "two to five elements" % reduce)
7726 # Save the reduce() output and finally memoize the object
7727 self.save_reduce(obj=obj, *rv)
7728 dump_info()
7730 # Overwrite method.
7731 def save(self, obj):
7732 # Produces too many empty () pairs.
7733 print "(",
7734 try:
7735 _real_save(self, obj)
7736 finally:
7737 print ")"
7739 def save(self, obj):
7740 _real_save(self, obj)
7742 pickle.Pickler.save = save
7745 #** Compute.
7746 accum_types = (EMData, ndarray)
7747 pckl_file = StringIO()
7748 g_display_size = 100000
7749 truncate_lines = "%-60.59s"
7750 pcklr = pickle.Pickler(pckl_file, protocol = 2)
7751 pcklr.memo
7753 # First get state_.storage,
7754 pcklr.dump(w_.state_.storage)
7756 # ... then get the REST of state_
7757 pcklr.dump(w_.state_)
7759 #* Custom pickle, collect info, get prefix dump
7760 # Collecting through storage is unreliable; modify pickle itself.
7761 #** params
7762 import pickle
7763 from EMAN2 import EMData
7764 from numpy import ndarray
7766 try:
7767 from cStringIO import StringIO
7768 except ImportError:
7769 from StringIO import StringIO
7771 g_accum_types = (EMData, ndarray)
7772 g_pckl_file = StringIO()
7773 g_display_size = 10000
7774 g_truncate_lines = "%-60.59s"
7775 g_info_stack = []
7779 #** pickle modifications.
7780 from types import *
7781 from copy_reg import dispatch_table
7782 from copy_reg import _extension_registry, _inverted_registry, _extension_cache
7783 import marshal
7784 import sys
7785 import struct
7787 def _real_save(self, obj):
7788 # Info dump
7789 me_start = g_pckl_file.tell()
7790 def dump_info():
7791 obj_size = g_pckl_file.tell() - me_start
7792 if isinstance(obj, g_accum_types) or (obj_size > g_display_size):
7793 # Forming the full repr() takes a LOT of time; maybe
7794 # settle for the type() info...
7795 g_info_stack.append( (obj_size, g_truncate_lines % repr(obj), obj) )
7796 # -- Info dump
7798 # Check for persistent id (defined by a subclass)
7799 pid = self.persistent_id(obj)
7800 if pid:
7801 self.save_pers(pid)
7802 dump_info()
7803 return
7805 # Check the memo
7806 x = self.memo.get(id(obj))
7807 if x:
7808 self.write(self.get(x[0]))
7809 dump_info()
7810 return
7812 # Check the type dispatch table
7813 t = type(obj)
7814 f = self.dispatch.get(t)
7815 if f:
7816 f(self, obj) # Call unbound method with explicit self
7817 dump_info()
7818 return
7820 # Check for a class with a custom metaclass; treat as regular class
7821 try:
7822 issc = issubclass(t, TypeType)
7823 except TypeError: # t is not a class (old Boost; see SF #502085)
7824 issc = 0
7825 if issc:
7826 self.save_global(obj)
7827 dump_info()
7828 return
7830 # Check copy_reg.dispatch_table
7831 reduce = dispatch_table.get(t)
7832 if reduce:
7833 rv = reduce(obj)
7834 else:
7835 # Check for a __reduce_ex__ method, fall back to __reduce__
7836 reduce = getattr(obj, "__reduce_ex__", None)
7837 if reduce:
7838 rv = reduce(self.proto)
7839 else:
7840 reduce = getattr(obj, "__reduce__", None)
7841 if reduce:
7842 rv = reduce()
7843 else:
7844 raise PicklingError("Can't pickle %r object: %r" %
7845 (t.__name__, obj))
7847 # Check for string returned by reduce(), meaning "save as global"
7848 if type(rv) is StringType:
7849 self.save_global(obj, rv)
7850 dump_info()
7851 return
7853 # Assert that reduce() returned a tuple
7854 if type(rv) is not TupleType:
7855 raise PicklingError("%s must return string or tuple" % reduce)
7857 # Assert that it returned an appropriately sized tuple
7858 l = len(rv)
7859 if not (2 <= l <= 5):
7860 raise PicklingError("Tuple returned by %s must have "
7861 "two to five elements" % reduce)
7863 # Save the reduce() output and finally memoize the object
7864 self.save_reduce(obj=obj, *rv)
7865 dump_info()
7867 # Overwrite method.
7868 def save(self, obj):
7869 global g_info_stack
7870 _tmp = g_info_stack
7871 g_info_stack = []
7872 try:
7873 _real_save(self, obj)
7874 finally:
7875 if len(g_info_stack) > 0:
7876 _tmp.append(g_info_stack)
7877 g_info_stack = _tmp
7879 pickle.Pickler.save = save
7882 #** view info
7883 def dump_stack(stack, indent):
7884 # Unwrap outer lists
7885 while isinstance(stack[-1], ListType):
7886 stack = stack[-1]
7887 # Get the main object head and print info.
7888 (size, rep, obj) = stack[-1]
7889 print "%s %-8d %s" % ("*" * indent, size, rep)
7890 # Get head's content, if any
7891 [dump_stack(ii, indent + 1) for ii in stack[0:-1]]
7894 #** Use.
7895 g_accum_types = (EMData, ndarray)
7896 g_pckl_file = StringIO()
7897 g_display_size = 1
7898 g_display_size = 1000
7899 g_truncate_lines = "%-60.59s"
7900 g_info_stack = []
7901 pcklr = pickle.Pickler(g_pckl_file, protocol = 2)
7902 pcklr.memo
7904 # Collect data.
7905 pcklr.dump(w_.state_)
7906 # OR
7907 pcklr.dump(w_.cp_)
7908 # Inspect
7909 dump_stack(g_info_stack, 0)
7912 g_display_size = 1
7913 pcklr.dump(self._l3tree)
7914 dump_stack(g_info_stack, 0)
7916 #* dbm interface
7917 import anydbm as any, whichdb
7918 #** Prepare.
7919 db = any.open('l3db.st', 'c')
7920 db.close()
7921 print whichdb.whichdb('l3db.st')
7922 #** Save
7923 db = any.open('l3db.st', 'c')
7924 # db[key] = val
7925 storage.sweep(db)
7926 db.close()
7928 #* Proxy for transparent persistence
7929 class Proxy:
7930 pass
7932 def __init__(self, obj):
7933 self._obj = obj
7934 Proxy.__init__ = __init__
7936 def to_cache(self, id):
7937 # TODO
7938 self._obj = None
7939 self._id = id
7940 Proxy.to_cache = to_cache
7942 def __getattr__(self, m_name):
7943 m_unbnd = getattr(self._obj.__class__, m_name)
7945 def _unwrap(*args):
7946 nargs = []
7947 for arg in args:
7948 if isinstance(arg, Proxy):
7949 nargs.append(arg._obj)
7950 else:
7951 nargs.append(arg)
7952 return (m_unbnd(self._obj, *nargs))
7954 return _unwrap
7955 Proxy.__getattr__ = __getattr__
7958 #** proxy numeric tests
7959 import numpy as N
7960 from cPickle import dumps
7961 n1 = N.random.ranf( (5,4) )
7962 n1_prox = Proxy(n1)
7963 print n1_prox + n1_prox
7964 # Size comparison.
7965 # TODO: getstate / setstate
7966 print len(dumps(n1))
7967 print len(dumps(n1_prox))
7968 n1_prox.to_cache(1234)
7969 print len(dumps(n1_prox))
7971 # Useless in-memory size guesses (spread too much)
7972 plist = [Proxy(n1) for ii in xrange(10)]
7973 id(plist[-1]) - id(plist[-2])
7974 ppos = [id(foo) for foo in plist]
7975 ppos.sort()
7976 print map(lambda (x,y): x-y, zip(ppos[1:None], ppos[0:-2]))
7979 #** proxy emdata tests
7980 from EMAN2 import EMData
7981 e1 = EMData()
7982 arr_size = (3,4)
7983 arr_size = (64, 64)
7984 print "array size", arr_size
7985 e1.set_size(*arr_size)
7986 e1.process_inplace('testimage.noise.uniform.rand')
7987 print sys.getrefcount(e1)
7988 e1_prox = Proxy(e1)
7989 print sys.getrefcount(e1)
7990 # Operators.
7991 print e1_prox + e1_prox
7993 # Sizes.
7994 print len(dumps(e1))
7995 print len(dumps(e1_prox))
7996 e1_prox.to_cache(1234)
7997 print len(dumps(e1_prox))
8002 #** create test cases
8003 import numpy as N
8004 import weakref
8005 from cPickle import dumps
8007 n1 = N.random.ranf( (5,4) )
8008 n1_prox = Proxy(n1)
8009 n1_weak = weakref.proxy(n1)
8011 # Initial refcount.
8012 print sys.getrefcount(n1)
8015 # Refcount with member ref.
8016 n1t = n1.tofile
8017 print sys.getrefcount(n1)
8020 # weakref's proxy adds no new fields:
8021 set(dir(n1_weak)) - set(dir(n1_prox._obj))
8023 from EMAN2 import EMData
8024 e1 = EMData()
8025 e1.set_size(3,4)
8026 e1.process_inplace('testimage.noise.uniform.rand')
8027 print sys.getrefcount(e1)
8028 e1prox = Proxy(e1)
8029 e1weak = weakref.proxy(e1)
8032 #** Try operators
8033 #*** numeric array works
8034 print n1_prox + n1_prox
8036 n1.__add__(n1)
8040 #*** emdata fails
8041 # TypeError: unsupported operand type(s) for +: 'instance' and 'instance'
8042 print e1prox + e1prox
8043 import operator
8044 print operator.add(e1prox, e1prox)
8046 # This runs,
8047 print e1weak + e1weak
8048 print operator.add(e1weak, e1weak)
8049 # but produces the equal? result:
8050 # <libpyEMData2.EMData object at 0x156239cc>
8051 # <libpyEMData2.EMData object at 0x156239cc>
8053 # Something is missing causing the discrepancy:
8054 print e1weak.__add__(e1weak)
8055 print e1.__add__(e1)
8056 # NotImplemented
8057 # <libpyEMData2.EMData object at 0x15623cdc>
8059 print n1.__add__
8060 print e1.__add__
8061 # <method-wrapper object at 0x1955d3cc>
8062 # <bound method EMData.__add__ of <libpyEMData2.EMData object at 0x1613da54>>
8064 print EMData.__add__(e1,e1)
8065 print EMData.__add__(e1prox,e1prox)
8066 print EMData.__add__(e1weak,e1weak)
8067 # <libpyEMData2.EMData object at 0x15623ca4>
8068 # NotImplemented
8070 e1prox._make_member_proxy('__add__')
8072 # Now this runs (work -- who knows):
8073 print e1prox + e1prox
8074 print e1prox.__add__
8075 print e1weak.__add__
8076 # <bound method EMData.__add__ of <libpyEMData2.EMData object at 0x1613da54>>
8077 # <bound method EMData.__add__ of <libpyEMData2.EMData object at 0x1613da54>>
8079 # TypeError: unsupported operand type(s) for +: 'EMData' and 'instance'
8080 print 1.0 * e1prox + e1prox
8082 # works
8083 print e1weak + e1weak
8086 #* Replace original class with proxy wrapper
8087 # Looks like there is no need for metaclasses, as this will do
8088 # everything needed. However, this will not intercept C code creating
8089 # instances, so it is too limited in practice.
8091 # Retain original
8092 import EMAN2
8093 eman2_emdata = EMAN2.EMData
8095 # Make replacement.
8096 class EMData(Proxy):
8097 def __init__(self, *args):
8098 self._obj = eman2_emdata(*args)
8100 # Bind replacement.
8101 # This binding remains valid for all FUTURE references, so it must be
8102 # done before other scripts import the module.
8103 EMAN2.EMData = EMData
8106 # Test
8107 e1 = EMAN2.EMData()
8108 e1.set_size(3,4)
8109 e1.process_inplace('testimage.noise.uniform.rand')
8110 e1.print_image()
8112 # The (C) member functions directly create the new object, so the
8113 # indirection above fails.
8114 tst_add = (e1 + e1)
8115 tst_add.print_image()
8117 #* Pickling uniquely
8118 # To get accurate memory stats, avoid repeated pickling given nested
8119 # references, e.g.
8120 # A, B, [A,B]
8122 import pickle
8123 try:
8124 from cStringIO import StringIO
8125 except ImportError:
8126 from StringIO import StringIO
8128 pckl_file = StringIO()
8129 pcklr = pickle.Pickler(pckl_file, protocol = 2)
8130 print pcklr.memo
8131 def pickle_size():
8132 return pckl_file.tell()
8135 #* string deepcopy test
8136 from copy import deepcopy, copy
8137 orig = 'the original string'
8138 cp = deepcopy(orig)
8139 print id(orig) - id(cp)
8140 # so strings 'copy' as reference.