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
to your
search path. In general prefix
/bin/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
$
sourceaips-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=
.
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.
version
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
infile
, outfile
,
outprint
, infile2
,
ofmfile
, boxfile
,
oboxfile
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.
indata
, outdata
,
in2data
, in3data
,
in4data
, out2data
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.
msgkill
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
.