Skip to content
Gijs Molenaar edited this page Feb 13, 2014 · 5 revisions

How To Run MeqTrees In Non-interactive Mode

(Please have an up-to-date system. This info is current as of r7379.)

To run MeqTrees in batch mode, you need to have three things: Main script : a TDL script that you actually want to run non-interactively. Normally this is exactly the same script that you would load into the browser (e.g. Timba/PyApps/test/pipeline_test.py, Siamese/example-sim.py, Calico/calico-wsrt.py, etc.) No changes are required.

Config file : a config file containing script options. This can be derived from .tdl.conf, but can have a more descriptive name (see e.g. Timba/PyApps/test/pipeline.tdl.conf, Siamese/batch-sim-example.tdl.conf.)

Control script : A control script that will actually implement batch-mode operations (see e.g. Timba/PyApps/test/run_pipeline_test.py, Siamese/batch-sim-example.py.)

NB: in older examples, we used to merge the main script and the control script into one, by placing control code into an if __name__ == "__main__" clause at the end of the main script. This can cause trouble with importing of sub-modules in frameworks, so I'm discouraging it from now on. Use a separate control script, it's neater anyway!

I have placed an educational example into PyApps/test. See the files pipeline_test.py, pipeline.tdl.conf, and run_pipeline_test.py, which I'll go through here.

The main script

The main script is the same script you would run in the browser, which is nice and convenient. The pipeline_test.py example defines a very simple tree for evaluating a*t+b, you can try it in the browser. Values of 'a' and 'b' are compile-time options, while the desired time interval is a runtime option.

The config file

pipeline.tdl.conf looks as follows:

  • {{{[pipeline_test] a = 2 b = 1 t0 = 1 t1 = 2

[test_b] a = 1 b = 1 t0 = 0 t1 = 10.0 pipeline_test_constants.c0 = 2 pipeline_test_constants.c1 = 3

[test_a] a = 2 b = 0 t0 = 0 t1 = 2.0 pipeline_test_constants.c0 = 5 pipeline_test_constants.c1 = 6 }}}

This is a typical config file. You can have multiple section for different scripts, or for different operations with the same script -- the naming of sections is up to you anyway. Each section must contain a complete script configuration, listing all the options.

To get a complete starting configuration for your main script, run it in the browser and look at .tdl.conf. This will contain a complete configuration section under "[your script name]", which you can simply cut-and-paste into your batch config file. Alternatively, you can cut-and-paste from the meqtree.log file. Every time you run a script in the browser, an entry is added to meqtree.log (in that script's directory) containing the complete active configuration. (NB: due to a bug in pre-r7379 MeqTrees, the contents of meqtree.log were not entirely compatible with config files. This has now been fixed. If you must use the config from an older log file, replace "= False" with "= 0", and "= True" with "= 1".)

The control script

Let's go through our example control script (Timba/PyApps/test/run_pipeline_test.py) line-by-line. First there's a standard opening:

#!/usr/bin/pythonif name == 'main': from Timba.Apps import meqserver from Timba.TDL import Compile from Timba.TDL import TDLOptions``` Then we start a meqserver. The extra arguments are passed to the meqserver as is. You may want to read them from you control script's command line:

  • mqs = meqserver.default_mqs(wait_init=10,extra=["-mt","2"]);  try:```

Once we're connected to a server, some cleanup is required before we can exit the script. Since we want to perform this cleanup regardless of whether the script ran to completion or was interrupted by an exception midway through, we use a try...finally block, with the cleanup code placed after a finally statement at the end of the script.

Then we attach to a config file and compile the main script:

  •   TDLOptions.config.read("pipeline.tdl.conf");    script = "pipeline_test.py";    mod,ns,msg = Compile.compile_file(mqs,script);```

compile_file() returns a tuple of three values, of which we only really need the first -- a reference to the compiled module object. Why do we need the module object? Because we now want to run a TDL job, which is usually a function defined within the compiled module. The wait=True argument causes the function to not return to us until the job (inside meqserver) has been completed:

  •   mod._test_forest(mqs,None,wait=True);```

If you're using a Calico or Siamese script, you may not know what the job function is. For this we have a provision for finding jobs by name or ID.

But first, some variations with the config file. The default behaviour is to use the config section "[script name]" (sans directory and suffix), which in this case is "[pipeline_test]". It is easy to tell compile_file() to use a different config section:

  •   mod,ns,msg = Compile.compile_file(mqs,script,config="test_a");    TDLOptions.get_job_func('job1')(mqs,None,wait=True);```

Note how we use get_job_func() here to find the appropriate "job function" by its ID (if you look inside pipeline_test.py, you'll see how it defines job functions with IDs.) This is what you do when you don't know the function to call directly, as would be the case with somebody else's script (e.g. a Calico script.) How do you know the job ID? Run the job in the browser, and look inside meqtree.log, it'll tell you the name and ID of the job you just ran. You can also find jobs by their long name, as demonstrated here:

  •   mod,ns,msg = Compile.compile_file(mqs,script,config="test_b");    TDLOptions.get_job_func('Run job 2')(mqs,None,wait=True);```

Finally, you can change config settings on-the-fly. This requires a little care, as compile_file() normally rereads the config file from disk. To get around this, we can manage configuration manually. First, we load initial values from a config section (save=False tells it to NOT save subsequent changes to .tdl.conf):

  •   TDLOptions.init_options("test_b",save=False);```

then we make some config adjustments:

  •   TDLOptions.set_option("a",5);    TDLOptions.set_option("t0",-1);    TDLOptions.set_option("t1",1);```

and now we recompile the script. config=None tells it to NOT reload the config file, but to use whatever config we have set up above:

  •   mod,ns,msg = Compile.compile_file(mqs,script,config=None);    mod._test_forest(mqs,None,wait=True);```

Runtime options can naturally be changed on-the-fly, no recompilation is necessary:

  •   TDLOptions.set_option("t0",-5);    TDLOptions.set_option("t1",5);    mod._test_forest(mqs,None,wait=True);```

Finally, we need to stop and exit the meqserver. This is done as follows. Note that the finally keyword is part of our try...finally block explained above:

  • finally:    # this halts the meqserver    meqserver.stop_default_mqs();    print "Bye!";```

Further examples

A more specific working example can be found under Siamese/batch-sim-example.py.

Clone this wiki locally