3 Michael Hohn <mhhohn@users.sf.net>
7 l3gui - graphical environment for interacting with l3 programs and data.
15 [-f FILE | --file=FILE]
16 [-s STATEFILE | --statefile=STATEFILE]
23 The l3gui(1) command starts an interactive graphical interface for
24 editing, viewing and executing l3 language scripts and viewing and
25 editing the data produced by the scripts.
26 See link:l3lang.html[l3lang(1)] for a language description.
28 Standard facilities include interactive toplevels for l3 and Python,
29 and a worksheet-style interface for l3 scripts providing editing
30 facilities and the usual open/edit/save options.
32 The l3 language introduces several new features to support use from a
33 graphical interface; they are:
35 - A script is used as its own data browser.
36 Every expression is turned into an object with inspection
37 facilities. Both the expression and the value(s) computed by the
38 expression can be accessed through the script's text.
40 - Scripts can evolve, even after execution. The combination of
41 need-based evaluation, lexical scoping and persistence allows l3
42 scripts to _evolve_; they can be added to without re-running
43 existing code, and references to all previouly computed data are
46 - Scripts can nest arbitrarily. Lexical scoping allows for
47 arbitrarily nested (static) namespaces and avoids name collisions.
48 Every function call introduces a new (dynamic) scope, so
49 multiple calls to the same function do not produce naming conflicts,
50 even when file names are used. Multiple calls to a function are
51 tracked separately, so all values computed by all calls to a
52 function can be inspected.
54 - A data flow graph can be generated from a script.
55 In this view, named data are emphasized, and data interdependencies
56 shown. Loops cause no ``explosion'' of the data flow graph.
62 Print this documentation and exit.
65 show program's version number and exit
67 -f FILE, --file=FILE::
70 -s STATEFILE, --statefile=STATEFILE::
71 Load this l3 state file.
74 Go to Python console on exit. This allows moving between Python
75 and the gui. To restart the gui, use gtk.main()
78 Import all l3 modules (`from ... import*`) when using -i. Allows
79 for interactive updates.
84 The typical l3 usage cycle is very similar to scripting
87 1. Select scripts / functions from a library
88 2. Assemble custom scripts on the canvas
89 3. Adjust parameters and scripts
94 The l3 gui provides several features to simplify high-level script
95 use, full editing for control over detail, make(1)-like
96 incremental evaluation and persistence to avoid unnecessary
97 repetition, and data examination through the scripts themselves.
99 While the l3 gui could be used for script writing (via graphical
100 assembly), it is meant for *script use* and *user interaction*.
101 User-assembled scripts should be high-level and consist mostly of
102 topic-specific blocks (with parameters), loops, functions and
105 Practical use of the l3 gui requires a library callable from Python
106 and a collection of simple Python/l3 drivers (scripts with parameters)
109 For writing such drivers, use l3lang(1) directly, via a text editor.
111 For more complex programming, use Python to implement a library, or a
112 connection to a library.
114 The inteded use of l3gui(1), with libraries and driver scripts already
115 present, is illustrated via the examples at http://l3lang.sf.net.
117 The rest of this manual page describes the mechanics of the interface.
122 The interface starts with two canvases and some support structures as
123 shown in this figure.
125 image:images/l3gui-1-sm.png["gui on startup", link="images/l3gui-1.png"]
127 From top to bottom, there is the menu bar, two canvas zoom selectors,
128 the two canvases, and a status line.
129 The left canvas is the library canvas, presenting examples from
130 introductory to complete program, and l3 templates used to assemble
132 The right canvas is the user work area for assembling, editing,
133 running and examining scripts and data.
134 The canvases can be scrolled via the scrollbars, or via
135 button-1-drag on a canvas.
138 The relative sizes of the canvases can be adjusted by dragging the
139 vertical separator between them.
140 The horizontal separator between the canvases and status line can be
141 moved up to reveal a Python console and any l3 consoles present. See
142 also the `View` menu entries.
143 Fully exposed, the interface looks like the following.
145 image:images/l3gui-2-sm.png["gui on startup", link="images/l3gui-2.png"]
148 The menubar entries are as follows; more details are found later in
154 Load a script from a file. The script is added to the session.
157 Save the current session to file.
160 Load a prior session from file. This replaces the current session
163 Exit the gui unless *-i* was used; with *-i*, starts Python on the
168 Run an interactive l3 toplevel in an area below the canvas, insert
169 expressions in a single Program on the canvas.
171 l3 terminal console::
172 Run an interactive l3 toplevel on the console, insert expressions
173 in a single Program on the canvas.
175 l3 terminal console, one program/expr::
176 Run an interactive l3 toplevel on the console, insert every
177 expression as a separate program on the canvas.
181 show / hide python console::
182 toggle visibility of areas below the canvases.
185 Hide the left canvas and areas below the canvas.
190 Show version information.
193 Show references to this manual.
196 Display the license for l3.
202 The mouse buttons are referred to as `button-1` through `button-3`. On
203 a right-handed mouse, `button-1` is the left button, `button-2` is the
204 scrollwheel button, and `button-3` is the right button.
206 The keyboard's `Ctrl` and `Alt` keys are called `control` and `alt` here.
208 ITEM SELECTION AND HANDLING
209 ---------------------------
210 The currently selected items are outlined in orange. Items are
211 selected via the mouse in two ways.
214 Select the item under the pointer, clear existing selection.
216 control + button-1 on item::
217 Add the item under the pointer to the existing selection.
219 A selection can be copied to the canvas, or moved into another
223 Insert a copy of the current selection; if there is no selection,
224 try to parse the text on the clipboard and insert the resulting
227 button-2 on list item separator::
228 Move the current selection into the list at this location (the top
229 item when multiple items are selected).
231 The selection can be cleared.
233 button-1 on canvas (without dragging)::
239 LOADING AND SAVING SESSIONS
240 ---------------------------
241 The session state includes all visible scripts and data, their display
242 positions, and all data accumulated during program execution.
244 The current session can be saved when no program is executing, via
245 `file > save session to`.
247 Restoring a session from a file replaces the current session, which
248 must be saved if it is to be kept. To restore a session, use
249 `file > load session`.
256 The gui provides several ways to get scripts for further assembly and
257 use. Once imported, the script is treated as a structure, although
258 the display still resembles the original text. Most expressions
259 display in the original's text form, but source code lines are
260 separated with a narrow horizontal marker that can be used for
261 insertion. All imported scripts are put into a `Program` block to
262 allow for collapsing/expanding and execution of the script.
265 Copying from the procedure library
266 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
267 Prepackaged functionality provided for l3 is kept in the left canvas
268 as outline. Select the parts of interest via `button-1`, copy them to
269 the canvas via `button-2`, and adjust parameters as described in
270 <<s-editing, the EDITING PROGRAMS section, autoref>>.
275 Short script fragments copied from another application can be pasted
276 via `button-2` on the canvas if no other expression is currently
277 selected. To paste text, first use `button-1` on the canvas to clear
278 its selection, then `button-2` to paste the text.
280 The pasted text is parsed and checked for valid syntax, but not
281 executed. If the syntax is valid, a script is inserted as a `Program`
282 at the mouse location. Otherwise, a single string holding the pasted
286 .Successful pasting of script
287 =======================================================
296 image:images/l3gui-3-sm.png["Successfull paste", link="images/l3gui-3.png"]
298 after pasting via `button-1` (to clear any other selection) followed
300 =======================================================
304 .Unsuccessful pasting of script
305 =======================================================
312 contains a syntax error and looks like
314 image:images/l3gui-4-sm.png["Successfull paste", link="images/l3gui-4.png"]
316 after pasting via `button-1` (to clear any other selection) followed
318 =======================================================
325 For writing larger scripts from scratch, using a text editor with
326 support for Python programs is strongly recommended. See emacs(1) or
327 vim(1). Once such a script is written (and ideally, tested on trivial
328 data using Python), it can be imported via `file > import script`.
330 // [[importing-example]]
331 // .Importing scripts or fragments.
332 // =======================================================
333 // picture: ways of importing scripts and script fragments
336 // pasted expression is not.
338 // Every part of an expression can now be selected. See
339 // <<selection-example, the selection example, autoref>>.
340 // =======================================================
343 Recording input and output from console interaction
344 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
345 For more interactive use, command-line input can be used.
346 Using the `menu > edit > l3 terminal console` selection, an interactive l3
347 toplevel is run on the console the gui was started from. At the same
348 time, a new empty `Program:` is inserted on the canvas.
349 Expressions can be entered at the toplevel in the same way as in
350 Python, and are evaluated when complete. If evaluation succeeds, the
351 expression is appended to the `Program:` and the l3 structural
352 manipulations are then available; in particular, the value(s) may be
356 .Using the toplevel with the gui.
357 =======================================================
358 The toplevel is is started and expressions tried. The `Program`
359 accumulates the history of successful commands, while the values
360 accumulated by the loop are inserted via the gui menu.
362 image:images/l3gui-7.png["Viewing values as image"]
363 =======================================================
365 At any time expressions may be inserted in the history through the
366 gui, and the `Program` re-run. As for any l3 program, only the
367 inserted expression is run, providing a way to evolve running programs
368 through insertion, not only appending.
374 The editing facilities of l3gui are focused on structural editing --
375 insertion and removal of expressions, and the selection of values
376 associated with expressions. These operations can be done any time,
377 but are most useful after a script has been run (whether successfully
378 or not), and allow incremental refinement of scripts.
380 Notably absent is an advanced text-editing facility, as there
381 are better and established tools for writing scripts. For the simple
382 textual edits required (such as setting parameter values and other
383 form-filling), a simple edit window is used.
385 Most expressions display as text, but outlines, programs, lists,
386 functions, conditionals and loops can display in long form.
388 Programs, lists and tuples displayed in long form have explicit item
389 separators that allow insertion of items in the position of the
390 separator, by selecting an item elsewhere and using `button-2` on the
393 Items already in the list/tuple can be dragged out via button-1-drag.
397 .Editing long-form expressions
398 =======================================================
403 and via `button-1` select the `1`; this highlights just `1`.
404 On the canvas next to the program, press `button-2`; a copy of the
405 `1` is put at the pointer location. Repeat this for the `2` to get
406 something like the following.
408 image:images/l3gui-8.png["Simple expression copies."]
410 To insert the `1` into the program, select the copy via
411 `button-1` and click on the grey bar above the `1+2` with `button-2`.
413 Repeat this for the `2` to get a new program:
415 image:images/l3gui-9.png["Newly assembled program."]
417 =======================================================
420 Text display allows selecting of individual subexpressions, but
421 editing is always done on the entire textual expression.
422 Double-clicking `button-1` on an expression pops up a simple edit
423 window. In the window, `ESC` or `Cancel` abort the edit, while
424 `Ctrl-Enter` or `Ok` commits the change.
426 // .Editing textual expressions
427 // =======================================================
428 // Double-click the second copy of `1` with `button-1`, and an editing
429 // window opens. Change the expression to `3` and select `Ok`.
430 // =======================================================
434 In the edit window, replacing a script expression with another
435 containing the same *text* and pressing `Ok` is not the same as
436 pressing `Cancel`. Replacing an expression *always* removes the
437 original and inserts the new one, even if the text is identical.
438 And a new expression will be evaluated again when its containing
439 `Program:` is run. See <<section-incremental, incremental evaluation,
446 Prior sections discuss obtaining and manipulate expressions. Further
447 operations are specific to that expression, and are available through
448 the expression's menu, accessed via `Button-3`.
451 // Use grep -nH -e gtk.MenuItem *
452 // in l3gui to get full summary.
454 The following is a summary of the menu entries. Their usage details
459 Every expression has these menu entries.
462 Add a comment to the expression. This inserts the template
463 ``double-click to edit'' which can be edited.
465 copy to clipboard (as raw text)::
466 Form a pretty-printed string representation of this expression and
467 copy it to the clipboard.
470 Delete this expression.
473 Delete all selected expressions. This entry is for convenience
474 and may not affect its expression.
477 (developer) Print an AST dump of the expression to the console,
478 including ID and timestamp for every node.
481 (developer) Print all values of the expression the expression to
482 the console, with indentation indicating clone structure.
484 export values as string::
485 Print all values of the expression to the console.
487 insert values as l3 list::
488 Insert a vertical list holding all the values associated with the
491 insert values as l3 list list::
492 Insert a near-square list of lists holding all the values
493 associated with the selected expression. Makes better use of
497 (developer) Start a new Python toplevel at the bottom of the gui,
498 with `self` bound in its environment.
500 evaluate locally, use console::
501 (developer) Start a new Python toplevel on the console,
502 with `self` bound in its environment.
506 Exit the gui unless *-i* was used; with *-i*, starts Python on the
512 Display this expression in a compact, single-line form.
515 Deprecated. Value selection is done using the selection. See
516 <<section-context, narrowing the data selection, autoref>>.
518 Additions for outlines/programs
519 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
520 Only a `Program` (outline) expression has a `Run` menu entry, so to execute a
521 fragment of code that is not already inside a program requires putting
525 Execute this program.
528 Show this outline, its comment, and the full contents. Program
529 editing is only possible in this view.
531 view nested outlines::
532 Show this outline, its comment, and all contained outlines.
534 view this level only::
535 Collapse the outline to this level.
538 show values written::
539 Show all names assigned to in this outline.
542 Show all names referred to in this outline.
545 Additions for the selection
546 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
547 The selection is the orange outline surrounding one or more
549 in addition to highlighting items, it also provides some features of
552 print values in context::
553 When an expression is used in loops or multiple function calls,
554 values can be viewed more selectively by narrowing to one of the
555 loops/function calls. See
556 <<section-context, Narrowing the data selection, autoref>>.
559 item screenshot to /tmp/foo.png::
560 For development. Take a screenshot of just this item, save to
561 /tmp/foo.png. Requires the canvas to be at the upper left scroll
565 Additions for list item separators
566 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
568 The list item separators serve to insert items, but can also be used
569 to select a range of items between two of them.
572 Set end position for range selection.
574 select region (from here to mark)::
575 Select all items in the range.
578 Additions for strings representing local files
579 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
581 For files holding known data of certain type, special viewing /
582 insertion actions are available.
584 First are those calling external programs to view files.
586 .spi -> xmipp_show -sel <path>::
587 Display spider selection file via `xmipp_show`
589 .spi -> xmipp_show -vol <path>::
590 Display spider volume file via `xmipp_show`
592 .txt -> $EDITOR <path>::
593 Open a plain text file in an external editor.
595 The following files types are directly handled in l3.
598 Insert a view of the image on the canvas.
600 .hdf file -> insert as l3 list::
601 For HDF files using a simple list-of-images structure (eman2),
602 display a vertical list of images.
604 .hdf file -> insert as l3 list list::
605 For HDF files using a simple list-of-images structure (eman2),
606 try to display a square array of images to maximize use of canvas
610 Additions for names with string values representing local files
611 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
612 Name expression (`a`, `"a"`, and `a.b`) with string values that
613 represent local files have entries
616 .any -> insert (file path) list::
617 Insert the list of files represented by the name.
619 .png -> insert (file path, image) list::
620 Insert the list of (file name, image) tuples represented by the
627 Treat a map like a directory and list all names bound in it.
629 print working directory (pwd)::
630 (deprecated) For a `Subdir`, show its name.
633 Additions for some native Python values
634 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
635 Values representing images (certain numpy arrays) have some simple
638 set image size as default::
639 Set the current scale size as default for future image insertions.
642 Reduce this image by 40%. Does not affect future image insertions.
645 Enlarge this image by 40%. Does not affect future image insertions.
652 Code in l3 is never executed automatically. Further, execution can
653 only start from programs (which display as outlines).
657 =======================================================
662 Then right-click (`button-3`) on `Program` > `run code`. The text
663 `(1, INT)` is shown on the console, where `INT` is some integer. The
664 `2` is highlighted in an orange outline.
665 =======================================================
668 Because expressions and outlines can nest, it is possible to start
669 execution from the ``inside'' of a program. This is not necessary
670 because l3 evaluation skips already-executed expressions, but it can
671 be convenient while working on a nested script. If needed values have
672 not been calculated, an error is given and execution of the program
673 stops at the error location.
678 [[section-interaction]]
681 Data are the result of expression evaluation. L3 attaches
682 a datum to the expression that created it, allowing point-and-click
686 Simple data selection
687 ~~~~~~~~~~~~~~~~~~~~~
689 For scripts with single-level loops or function calls, a single
690 item selection is sufficient to view data.
692 [[ex-value-selection]]
693 .Selection of datum value.
694 =======================================================
695 Paste and run the program
699 Then select the `-` menu (`button-3`) and `dump values`.
700 Note that there is only one value, `1`.
701 =======================================================
705 Expressions inside loops or tail calls may have more than one value,
706 so every expression's menu has a `dump values` entry that prints all
707 values associated with the expression to the terminal.
710 .Selection of data values.
711 =======================================================
712 Paste and run the program
718 select the `-` menu (`button-3`) and `dump values`.
719 Note that there are now three values.
720 =======================================================
724 Instead of printing values, values can be wrapped as l3 expressions
725 and inserted on the canvas, using the `insert values as` menu entry.
726 In this form, values are ready to be used in or by other scripts.
728 Wrapped values are referenced, not copied.
731 .Insertion of data values.
732 =======================================================
733 Paste and run the program
738 To import these values for further editing,
739 select the `-` menu (`button-3`) and `insert values as l3 list`.
740 This inserts a list containing the values.
741 =======================================================
743 When a data to PNG converter is available, the bitmap image is
744 displayed by l3gui instead of the textual representation of the data.
745 These custom viewers are never interactive, and are intended to
746 provide a quantitative view only. The image is manipulated just like
751 .Insertion of data thumbnails.
752 =======================================================
755 inline "import numpy as N"
756 N.random.ranf( (35, 14) )
758 and run the program. The array data is printed to the console. Now
759 right-click `N` and select `insert values as l3 list`. This inserts a
760 list with one entry, the image. Right-click the image, select
761 `enlarge image 40%` several times. This will look like the following.
763 image:images/l3gui-5.png["Viewing values as image", link="images/l3gui-5.png"]
765 =======================================================
767 For more detailed data examination or manipulation, data must be saved
768 to file and external processes used. File names should be formed via
771 '_plot-%d.png' % new_id()
773 so their names are always unique. l3 makes no attempt at tracking the
774 data passed out this way; instead, the data is assumed CONSTANT. If
775 an external program is used to modify data, the new data should be
776 written to a new file.
778 // The l3 `subdir:` command can help with this,
779 // by creating a new, empty directory in which to put data.
783 Narrowing the data selection
784 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
786 When loops are nested or functions called from multiple sources, the
787 simple selection mechanism displays *all* values. This is usually not
788 desired, so the selection can be narrowed.
791 .Selection narrowed to single function call
792 ========================================================
793 The following script defines a simple iteration scheme to (very) roughly
794 approximate `sqrt(x)`, and tries this scheme using two starting values.
796 # Sqrt iteration with error bound.
798 if abs(xn**2 - x) > 0.0001:
799 xnp1 = 1.0 / 2 * (xn + x / xn)
807 # Try a different starting point.
810 To examine the values of `xnp1` generated by the first try, select
811 `xnp1` via left-click, and add `try(9.0, 5.0)` to the selection via
812 control-left-click. Then use a right-click on `xnp1` and choose
813 `insert values as l3 list` to get the following.
815 image:images/l3gui-6.png["Viewing values selectively",
816 link="images/l3gui-6.png"]
817 ========================================================
819 // [[ex-narrow-loop]]
820 // .Selection narrowed to single loop
821 // ========================================================
823 // ========================================================
827 [[section-incremental]]
828 INCREMENTAL SCRIPT DEVELOPMENT
829 ------------------------------
830 Script execution and script writing can be mixed using the l3 gui,
831 without saving intermediate values to files or incurring a time
832 penalty for rerunning all scripts.
834 A program that ran successfully may reveal the need for more
835 information. Instead of writing a new script replicating many of the
836 same iterations and data references, the new relevant expressions can
837 be added to the existing program, and the resulting program run.
838 In the rerun, only the additions are executed.
840 // [[ex-dynamic-addition]]
841 // .Evolving a script, post-execution.
842 // =======================================================
843 // Additions execute in the environment of the program, just as the
844 // original expressions. Thus, there is no need to rewrite loops, copy
845 // files, or introduce new file names.
846 // =======================================================
849 This is similar to the behavior of make(1), in which targets are only
850 updated when their dependencies require it. Unlike make(1),
852 - there is only one ``target'', the successfull execution of the
854 - there is no search for prerequisites; variables must be bound
856 - scripts can be nested, and additions can be made inside loops or
862 Errors in scripts return control to the user for correction, with the
863 faulty expression highlighted in orange. The expression can be
864 replaced with a correct one, and the program run again.
866 Execution resumes from the fixed expression; previously run code and
867 values produced by it are reused.
870 .Fixing a run-time error inside a program
871 =======================================================
872 This script has a small typo in a branch executed late in the script's
875 inline('from time import sleep')
876 for work in range(0, 4):
877 # A long-running command...
879 print "%d%% done" % (100.0 * work / (4-1))
881 # ... with a small error in later execution
884 Running this script takes about 3 seconds and results in the console output
889 Traceback (most recent call last):
892 l3lang.ast.UnboundSymbol: 'No binding found for: worj'
894 and the following display:
896 image:images/l3gui-10.png["Error location highlighted in orange"]
898 Fixing the error (double-click `button-1` on `worj` and change it to
899 `work`) and running again takes only the remaining second and produces
904 indicating that prior parts have not been re-run.
906 =======================================================
911 $HOME/.l3lang/l3rc, ./.l3rc
913 ENVIRONMENT VARIABLES
914 ---------------------
915 L3HOME:: Directory containing l3lang/ and l3gui/
917 EDITOR:: The executable name of the external editor to use.
921 Many annoyances; this is version 0.3.1 after all.
923 This manual page contains examples.
932 Michael Hohn, mhhohn@users.sf.net
936 Copyright (C) 2004-8 Lawrence Berkeley National Laboratory.
937 l3 is released under the BSD license. See license.txt for details.