Table of Contents
Table of Contents
Note that in order to use ParselTongue, you need a workstation running a UNIX-like operating system with a classic AIPS installation, Python 2.2 or later and Obit. AIPS and Python will be available on most astronomer's desktops (if not, please see your local system administrator), but Obit probably isn't. A version of Obit that is known to work with ParselTongue is available from the ParselTongue Wiki. Most ParselTongue users use Linux, but people have installed in succesfully on Apple laptops running Mac OS X too.
Building Obit is by far the biggest hurdle. Since Obit depends on some other Open Source software packages getting the right packages installed before trying to build Obit is crucial. Unfortunately many Linux distributions have been "dumbed down" and are missing the crucial development packages necessary for building your own software.
Essential for building Obit are GLib 2.x and GSL (GNU Scientific Library) and of course Python. Optional are CFITSIO, FFTW, PGPLOT, XMLRPC and SWIG. Of these packages you almost certainly don't want to install SWIG. It is only needed if you want to change Obit, and if you install the wrong version Obit will fail to compile. You'll need CFITSIO if you want ParselTongue to read FITS files directly. The other packages are only useful if you want to use Obit itself. Instructions on how to install the essential packages on various popular systems can be found below.
On these Linux distributions the names of the needed packages are:
gcc |
glib2 |
glib2-devel |
gsl |
gsl-devel |
python |
python-devel |
You see see whether these packages are installed with:
$ rpm -q -a
and check whether these packages are present in the list. If they are not installed, install them using the package manager that comes with your Linux version.
On these distributions the names of the needed packages are:
gcc |
libglib2.0 |
libglib2.0-dev |
libgsl0 |
libgsl0-dev |
python-2.3 or python-2.4 |
python2.3-dev or python-2.4-dev |
(python-2.5 is probably ok too)
If you want visibility access from ParselTongue, you'll also need:
python-numarray |
You can see whether these packages are installed with:
$ dpkg -l
and check whether these packages are present in the list. If they are not installed you can easily install them with apt-get, e.g.:
$ apt-get libglib2.0-dev
You'll need XCode. XCode is part of OS X, but usually not installed by default. You can find it on the OS X install DVD, and install it from there.
The easiest way to install the necessary dependencies is by using Fink or Darwinports. Make sure you install a version suitable for your version of Mac OS X.
For Fink you'll need the following packages:
glib2 |
glib2-dev |
gsl |
I'm not sure the Apple version of Python is usable for Obit/ParselTongue. So I recommend installing:
python23 or python24 |
too (python25 is probably ok too). If you want direct access to visibility data, you'll also need:
numarray-py23 or numarray-py24 |
To make sure that Obit and ParselTongue use the Fink version of Python make sure you set the PYTHON environment variable before running configure:
$ export PYTHON=/sw/bin/python
or
$ setenv PYTHON /sw/bin/python
For OpenDarwin you'll need to install:
glib2 |
glib2-devel |
gsl |
python24 |
numarray |
and set the PYTHON environment variable to /opt/local/bin/python instead.
Once your system has the necessary tools and libraries, building Obit is fairly easy. Just create the directory where you want to install Obit and move the source code there. Then type:
$ tar xfz Obit.tar.gz $ ./configure $ make
If any of these steps fail, there probably is a problem with the prerequisites mentioned above.
Installing ParselTongue is fairly straightforward. Full, but generic, installation instructions are given in the file INSTALL included in the distribution. However, there is no real need to read them if you follow the instructions below. First unpack the distribution
$ tar xfz parseltongue-1.0.tar.gz
and enter the distribution directory
$ cd parseltongue-1.0
Now configure and install ParselTongue
$ ./configure --with-obit=obit $ make $ make install
where obit is the location where you installed Obit. Note that the last step will most likely require super-user privileges since by default, ParselTongue will be installed in /usr/local. If you do not have the appropriate privileges, replace the first step above by
$ ./configure --prefix=prefix --with-obit=obit
where prefix is the location where you want to install ParselTongue. You might simply use --prefix=$HOME to install ParselTongue in your home directory.
In order to use ParselTongue, it is convenient to add prefix/bin to your search path. In general /usr/local/bin will already be there, and if you are lucky $HOME/bin will also be included in your default search path. If they are not, or if you specified a different prefix, you can add it by issuing the command
$ PATH=$PATH:prefix/bin
if you use a Bourne shell (sh, bash) or Korn Shell (ksh, pdksh). If you use a C shell (csh, tcsh), the equivalent command is
$ setenv PATH $PATH:prefix/bin
You might want to add these commands to your .profile or .login.
Table of Contents
Before running ParselTongue, make sure you have sourced yous AIPS login script. Banana addicts will probably do this automatically as part of their .profile or .login, but otherwise you should do it manually. If aips-root is the root of your AIPS installation, issue the command
$ . aips-root/LOGIN.SH
if you use a Bourne shell (sh, bash) or Korn Shell (ksh, pdksh). If you use a C shell (csh, tcsh), the equivalent command is
$ source aips-root/LOGIN.CSH
Again, you might want to add this to your .profile or .login if you find yourself using ParselTongue regularly.
While ParselTongue is primarily intended as a scripting environment, you can also use it by starting an interactive Python interpreter. The command ParselTongue will do this for you. It will ask you for your AIPS number, and come back to you with the standard Python prompt
$ ParselTongue
Python 2.3.4 (#1, Oct 5 2004, 00:17:14)
[GCC 3.3.4 (pre 3.3.5 20040809)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
Welcome to ParselTongue
Please enter your AIPS user ID number: 666
>>>
The first time you do this, ParselTongue might take some time to get back to you as it goes over your AIPS installation to determine what tasks and adverbs are available.
The ParselTongue can also be used to start scripts directly from the command line
$ ParselTongue script.py
This sets up the required environment variables for AIPS, but in order to use ParselTongue you'll have to import the ParselTongue modules that you want to use. The following should be enough to be able to use the functionality in this cookbook
from AIPS import AIPS from AIPSTask import AIPSTask, AIPSList from AIPSData import AIPSUVData, AIPSImage
Of course you are free to import any other Python modules that you want. Because you are not running ParselTongue interactively it cannot ask you for your AIPS number so you have to set it in your script
AIPS.userno = 666
Table of Contents
It's best to start of with a simple interactive example:
$ ParselTongue ... Please enter your AIPS user ID number: 666 >>> fitld = AIPSTask('fitld') >>> fitld.infile = 'FITS:N04C2.IDI' >>> fitld.outname = 'N04C2' >>> fitld.outclass = 'UVDATA' >>> fitld.outdisk = 1 >>> fitld.outseq = 1 >>> fitld.go()
If you like bananas, it should be fairly easy to grasp what this does. Indeed these commands will use FITLD to read in the FITS-file N04C2.IDI from the FITS area, storing it in a work file on AIPS disk 1.
In the examples given above, the first line constructs a ParselTongue AIPS task object for the FITLD task. That object is an instance of the AIPSTask class. The lines that follow set several attributes of that task abject. Most of these attributes (in fact all of the attributes in this example) would be called adverbs in AIPS.
Note that most of the commands in the example are given in lowercase. Python is fussy about case. These days, it is considered rude to shout, and ALL-CAPS terminals have pretty much died out, so attributes have lowercase names, as do task names.
Here is another example
>>> imean = AIPSTask('imean', version='31DEC03') >>> imean.inname = 'MANDELBROT' >>> imean.inclass = 'MANDL' >>> imean.indisk = 1 >>> imean.inseq = 1 >>> imean.go() IMEAN1: Task IMEAN (release of 31DEC03) begins IMEAN1: Image= MANDELBROT .MANDL . 1 1 xywind= 1 1 256 256 IMEAN1: Mean and rms found by fitting peak in histogram: IMEAN1: Mean= 1.0863E+00 Rms= 9.3035E-01 **** from histogram IMEAN1: Mean and rms found by including all data: IMEAN1: Mean= 4.6120E+01 Rms= 9.4276E+01 COUNTS over 65536 pixels IMEAN1: Minimum= 1.0000E+00 at 256 256 IMEAN1: Skypos: X 0.98828 Y 1.488 IMEAN1: Maximum= 2.5400E+02 at 157 216 IMEAN1: Skypos: X -0.17188 Y 1.020 IMEAN1: returns adverbs to AIPS IMEAN1: Appears to have ended successfully IMEAN1: jop31 31DEC03 NEW: Cpu= 0.0 Real= 0 >>> print imean.pixavg, imean.pixstd 1.08630597591 0.930348217487 >>>
In this example, we create the task object in a slightly different way. By default, ParselTongue will create task objects for the default version of AIPS. But if you want to use a different version, you can say so by adding version=version. Now look at the last few lines of the example. You might not be aware of it, but IMEAN does not only accept inputs, but also produces outputs. After you have run the task, these outputs are available as attributes of the task object. Of course this not just applies to IMEAN, but to any AIPS task that returns adverbs to AIPS.
As the examples show, setting scalar and string attributes is simple. Too make it even easier, ParselTongue implements range checking on attributes
>>> imean.indisk = 10 Traceback (most recent call last): ... ValueError: value '10.0' is out of range for attribute 'indisk' >>> imean.inname = 'THIS_STRING_IS_TOO_LONG' Traceback (most recent call last): ... ValueError: string 'THIS_STRING_IS_TOO_LONG' is too long for attribute 'inname'
This makes sure you learn about your mistakes as early as possible and not when some task falls over with a possibly misterious error message.
Setting array-like attributes like aparm or sources is a bit more complicated. The problem here is that in Python array indices start at 0 instead of 1. To avoid confusion, in ParselTongue the element at index 0 is ignored such that
>>> possm.aparm[3] = 0.1
indeed sets APARM(3). The element at index 0 will contain the value None and cannot be assigned to
>>> print possm.aparm [None, 0.0, 1.0, 0.0, 1.3, -180.0, 180.0, 0.0, 0.0, 0.0, 0.0] >>> possm.aparm[0] = 0.1 Traceback (most recent call last): ... ValueError: setting element '0' is prohibited
Since you cannot assign to the element at index zero, the simple minded assignment of Python lists to attributes fails too
>>> imean.trc = [512, 512]
Traceback (most recent call last):
...
ValueError: setting element '0' is prohibited
Python's support for slicing provides a way out of it
>>> imean.trc[1:] = [512, 512]
but there is also a convenience function named AIPSList that prepends the None to the list such that the assignment works
>>> imean.trc = AIPSList([512, 512])
Note that in both cases the assignment has a small twist in that the array attribute is extended with default values up to its original length
>>> print imean.trc
[None, 512.0, 512.0, 0.0, 0.0, 0.0, 0.0, 0.0]
It is good to know that some attributes get special treatment
While it possible to specify files by their complete path names since the 31DEC02 version of AIPS there still is a limit on the length of the path name. And 48 characters does not leave you with a lot of leg room. To overcome this limitation, ParselTongue allows you to enter path names of arbitrary length, as long as the trailing component (the filename itself) does not require more than 46 characters. This works with all versions of AIPS, even with versions older than 31DEC02.
If you don't specify an area or directory for the outfile and outprint attributes, AIPS will place the output file in seemingly random locations. If you want these files to end up in the directory from where you run your script, you can prepend ./ to the filename.
Having to specify all four of name, class, disk and sequence number to refer to a work file can be a bit of a pain. To make life a we bit easier, ParselTongue provides these data attributes. If you have a ParselTongue AIPS data object (see Chapter 4, Handling AIPS data) you can use it to set these attributes, which set name, class, disk and sequence number in one go.
AIPS can be quite chatty, and in long running scripts it may be desirable that only messages about serious problems are displayed. AIPS itself provides the MSGKILL pseudoverb and ParselTongue gives you the opportunity to set it, either on per-task basis or globally as an attribute of the AIPSTask. Unfortunately, setting MSGKILL has the drawback that suppressed messages are forever lost and AIPS discourages you from using it. However, in ParselTongue you can set the msgkill attribute to a negative value. This will prevent messages from being displayed on the terminal, as if you set MSGKILL to the absolute value of the attribute, but the suppressed messages will still go to the AIPS message file. This way you can always inspect them later if the need arises.
Constructing a ParselTongue AIPS data object is fairly simple, although things are complicated a bit by the fact that AIPS deals with two kinds of data that are quite different from each other: images and UV data. The latter are created as instances of the AIPSUVData class
>>> uvdata = AIPSUVData('N04C2', 'UVDATA', 1, 1)
whereas the former use the AIPSImage class
>>> uvdata = AIPSImage('MANDELBROT', 'MANDL', 1, 1)
The syntax is similar in both cases; you specify name, class, disk and sequence number of the data. Here is an example that shows how to use the AIPSImage class to pass an image from one task to the other
imgdata = AIPSImage('MANELBROT', 'MANDL', 1, 1) mandl = AIPSTask('mandl') mandl.outdata = imgdata mandl.go() imean = AIPSTask('imean') imean.indata = imgdata imean.go()
The AIPSImage and AIPSUVData classes also provide an interface to provide access to AIPS data and manipulate it.
Manipulation is pretty much limited to deleting extension tables from a data set and deleting the data itself. The latter is a matter of calling the method zap() while the former has a somewhat more complicated interface:
zap_table(type, version)
here type is the type of the extension table as a string (e.g. 'CL') and version is the version to be deleted. Using 0 as the version deletes the highest version of the given type, wheras using -1 deletes them all. So the following example
>>> uvdata = AIPSUVData('N04C2', 'UVDATA', 1, 1) >>> uvdata.zap_table('CL', 0)
deletes the last calibration tables from the UV data set N04C2.UVDATA.1 on disk 1. Note that plot files ('PL') and slice files ('SL') can also be deleted. So the following lines
>>> imgdata = AIPSImage('MANELBROT', 'MANDL', 1, 1) >>> imgdata.zap_table('PL', -1)
can be used to throw away all previously made plots.
Deleting a complete data set or image is much simpler. After
>>> uvdata.zap() >>> imgdata.zap()
the data and image are forever lost.
Sometimes an AIPS task will fall over and leaves your data in a "busy" state. To recover from this you can use
>>> uvdata.clrstat() >>> imgdata.clrstat()
but do not do this on data that is being actively used by AIPS or ParselTongue.
The interface to access data is much richer though.
Table of Contents
ParselTongue includes a seperate module for manipulating data beyond simple inspection of metadata. It allows full access to AIPS tables, and access to visibilities an image pixels.
The Wizardry functionality has certain limitations. The most important limitation is that access to remote data is not possible; only data on the locally visible AIPS disks can be accessed. The reason is that the XML-RPC protocol used by ParselTongue for remote execution and data access is not suitable for transferring big amounts of data.
Table of Contents
ParselTongue provides a simple, yet powerfull way to capture a log of your session. If you set AIPS.log to a file object all output from AIPS tasks will be sent to that object:
>>> AIPS.log = open('ParselTongue.log', 'a')
In fact, the above is not the full truth. AIPS.log does not necessarily have to be a true Python file object; any object with a write method will do.
The output sent to AIPS.log includes the messages that are not being displayed on your terminal because the msgkill attribute was set to a negative value in the task object (this does not apply to messages killed by a positive value of this attribute; those are lost forever).
To stop logging, set AIPS.log to None.