The figure below shows a simple tree. A request percolates down from the `Request Domain' to the leaves of the tree (the MeqFreq, MeqTime and MeqParm nodes). Results are then returned back up the tree. This page describes a simple MeqTrees script that creates and processes the above tree. It describes the various sections of the script, what order they are processed by the MeqTrees browser, and how a tree is executed.
This MG_AGW_tree.mpeg video discusses the contents of the above tree in a bit more detail.
Here is the TDL script which describes the above tree.
1 from Timba.TDL import *
2 from Timba.Meq import meq
3 from Timba.Meq import meqds
4 from numarray import *
5
6 # setup a bookmark for display of results.
7 Settings.forest_state = record(bookmarks=[
8 record(name='Results',page=[
9 record(udi="/node/freq",viewer="Result Plotter",pos=(0,0)),
10 record(udi="/node/time",viewer="Result Plotter",pos=(0,1)),
11 record(udi="/node/coeff",viewer="Result Plotter",pos=(1,0)),
12 record(udi="/node/add",viewer="Result Plotter",pos=(1,1)),
13 record(udi="/node/condeq",viewer="Result Plotter",pos=(2,0)),
14 record(udi="/node/solver",viewer="Result Plotter",pos=(2,1))])]);
15
16 # Timba.TDL.Settings.forest_state is a standard TDL name.
17 # This is a record passed to Set.Forest.State.
18 Settings.forest_state.cache_policy = 100;
19
20 # Make sure our solver root node is not cleaned up
21 Settings.orphans_are_roots = True;
22
23 def _define_forest (ns):
24 """define_forest() is a standard TDL name. When a forest script is
25 loaded by, e.g., the browser, this method is automatically called to
26 define the forest. The 'ns' argument is a NodeScope object in which
27 the forest is to be defined, usually this is simply the global scope.
28 """;
29
30 # first create 2x2 polc
31 # The 'polc' array will be used to store the coefficients a,b,c,d
32 # for the polynomial fit in x and y (a +bx +cy +dxy) that we will do below
33 polc_array = zeros((2,2), Float64)
34 # initially we guess the coefficients a=1, and b,c,d = 0
35 polc_array[0,0] = 1.0
36
37 # create the polc
38 polc = meq.polc(polc_array)
39
40 # we now create a leaf called 'coeff' which is of type MeqParm and contains
41 # the polc_array we created previously.
42 ns.coeff << Meq.Parm(polc,node_groups='Parm')
43
44 # create a leaf MeqFreq node called 'freq' which has no children
45 ns.freq << Meq.Freq()
46
47 # create a leaf MeqTime node called 'time' which has no children
48 ns.time << Meq.Time()
49
50 # create a MeqAdd node called 'add' which has the children 'freq' and
51 # 'time'. As its name indicates it will add the contents of 'freq' and
52 # 'time' together. Interestingly, the result of such an addition is a
53 # 2-dimensional array!
54 ns.add << Meq.Add(ns.freq, ns.time)
55
56 # create a MeqCondeq node called 'condeq'. A MeqCondeq compares the
57 # contents of the 'add' and 'coeff' nodes
58 ns.condeq <<Meq.Condeq(ns.add, ns.coeff)
59
60 # finally create a solver
61 ns.solver << Meq.Solver(
62 num_iter=6,debug_level=10,solvable="coeff", children = ns.condeq)
63
64
65 def _test_forest (mqs,parent,wait=False):
66 """test_forest() is a standard TDL name. When a forest script is
67 loaded by, e.g., the browser, and the "test" option is set to true,
68 this method is automatically called after define_forest() to run a
69 test on the forest. The 'mqs' argument is a meqserver proxy object.
70 """;
71 # We create a time-frequency 'domain' with range 0 to 2 in
72 # frequency and 0 to 1 in time.
73 # We split the domain into a 8 x 4 "cells' array in time and
74 # frequency. The frequency range will be split into 8 increments,
75 # while the time range will be split into 4 time increments
76 cells = meq.cells(meq.domain(0,2,0,1),num_freq=8,num_time=4);
77
78 # now create and execute request on solver
79 request = meq.request(cells, rqtype='e1')
80 # mqs.meq('Node.Set.Breakpoint',record(name='solver'));
81 # mqs.meq('Debug.Set.Level',record(debug_level=100));
82 a = mqs.meq('Node.Execute',record(name='solver',request=request),wait=wait);
83
84
85 # The following is the testing branch, executed when the script is run directly
86 # via 'python script.py'
87
88 if __name__ == '__main__':
89 # run in batch mode?
90 if '-run' in sys.argv:
91 from Timba.Apps import meqserver
92 from Timba.TDL import Compile
93
94 # this starts a kernel.
95 mqs = meqserver.default_mqs(wait_init=10);
96
97 # This compiles a script as a TDL module. Any errors will be thrown as
98 # an exception, so this always returns successfully. We pass in
99 # __file__ so as to compile ourselves.
100 (mod,ns,msg) = Compile.compile_file(mqs,__file__);
101
102 # this runs the _test_forest job.
103 mod._test_forest(mqs,None,wait=True);
104 else:
105 Timba.TDL._dbg.set_verbose(5);
106 ns=NodeScope()
107 _define_forest(ns)
108 ns.Resolve()
109 print "Added %d nodes" % len(ns.AllNodes())
This MG_AGW_tree_script.mpeg video tutorial discusses the contents of the above script in some more detail.
If you go to the page MeqBrowserIntroduction, there you will find a number of video tutorials which show how to load and run the above script. That page also contains tutorials showing how to visualize the contents of nodes of a MeqTrees script.
