Logo

Programming in Python



Recipes

Recipes and examples can be found in the document Python recipes for GIPSY: http://www.astro.rug.nl/~gipsy/python/recipes/pythonrep.php.

Introduction

This document describes the new Python module for GIPSY which now is part of the standard distribution. Prerequisites for this module are a supported architecture (now Linux or MacOS), Python 2.3 or higher, and NumPy. If these requirements are not met, the installation procedure will produce a non-functional dummy module.

The module allows the user to write both simple scripts and complicated GIPSY programs just as easily as writing a COLA script. When writing in Python, there is no real distinction between a 'script' and a 'program'. A script is just a very simple program, often little more than a sequence of task invocations. It is also possible to write complete GIPSY programs in Python as you could with Fortran, Sheltran or C with the advantage of all the available packages and modules that you can use in your own Python environment.

All essential functions from the GIPSY library have been incorporated in the module. Special Python classes and functions have been implemented which streamline their use. Contrary to the previous version, all functionality is available through one single pre-compiled module. This is in accordance with the fact that there is also one single object library in GIPSY.

The module's functionality can be thought to be divided into the following categories:

To conclude this introduction, here are two examples of simple tasks written in Python:

#!/usr/bin/env python
from gipsy import *

init()

name = usertext('NAME=', 'Your name, please')
anyout("Hello %s!" % name)

finis()
To run a Python task, the file containing it must first be made executable: 'chmod +x hello'.
#!/usr/bin/env python
from gipsy import *

init()

base = GgiBase()
plot = base.PlotField('PLOT', 400, 400)
plot.setPosition(0, None, 0, None)
base.realize()
plot.open()
plot.export()

mainloop()

What the first task does may be obvious. The second task creates a window containing a new PGPLOT device into which any other task may draw. More examples can be found in the Python recipes for GIPSY: http://www.astro.rug.nl/~gipsy/python/recipes/pythonrep.php.

Elementary Functions

Most of these functions map directly to their Fortran/C counterparts in GIPSY's object library. For detailed information the corresponding .dc2-documentation can be consulted. The documentation below shows the functions' arguments and argument defaults, if any.

Task control

init()
initialize task's communication with Hermes, GIPSY's control process.
finis()
terminate the task's execution normally.
error(level=4, message="An error has occurred")
report an execution error and possibly terminate task.
aborttask(taskname)
force a user abort for a running task, given its taskname. The taskname should be in uppercase.
pause(message="")
suspend the task; the user can then resume it.
deputy(taskname)
run another task in the same task context (keywords etc.) as the calling task. The calling task will wait until the other task is finished.
xeq(command, keyword=None)
run another task in its own independent context. If 'keyword' is not specified, the calling task will wait until the other task is finished. Otherwise the task will continue to run and can read from the keyword to find out about the other task. During execution, information about the task can be obtained via keywords derived from 'keyword'. E.g., the taskname can be obtained via N_keyword. 'command' is a string containing a task start command, including keywords. If the previous set of keywords is to be used, 'command' should be prefixed by an exclamation sign (!) as usual. See xeq.dc2 and xeqcont.dc2.
myname()
return a string containing the name of the calling task.

Task output

anyout(text, dev=0)
display one or more lines of text on the terminal screen and/or the log file.
status(message)
display a status message.
typecli(text)
'type' characters into Hermes' command line.

User input

If a default is permitted (argument default>0), the user input functions will return the value of the argument defval when no input is given.
usertext(keyword="INPUT=", message="Enter text string", default=0, defval=None, nmax=256)
Read a text string from the user. 'nmax' is the maximum number of characters to be returned.

The following 'userxxx' functions will return a list of one or more values when the argument nmax>1 or a single value when nmax=1. The default message will be constructed depending on the arguments.

userchar(keyword="INPUT=", message=None, default=0, defval=None, width=256, nmax=1)
obtain up to 'nmax' character strings from the user. Each string can be 'width' characters wide.
usercharl(keyword="INPUT=", message=None, default=0, defval=None, width=256, nmax=1)
lower-case variant of userchar()
usercharu(keyword="INPUT=", message=None, default=0, defval=None, width=256, nmax=1)
upper-case variant of userchar()
userint(keyword="INPUT=", message=None, default=0, defval=0, nmax=1)
obtain up to 'nmax' integer numbers from the user.
userlog(keyword="INPUT=", message=None, default=0, defval=0, nmax=1)
obtain up to 'nmax' booleans (logicals) from the user.
userreal(keyword="INPUT=", message=None, default=0, defval=0.0, nmax=1)
obtain up to 'nmax' real numbers from the user.
userdble(keyword="INPUT=", message=None, default=0, defval=0.0, nmax=1)
obtain up to 'nmax' double precision numbers from the user.
userangle(keyword="INPUT=", message=None, default=0, defval=0.0, nmax=1)
obtain up to 'nmax' angles from the user.
cancel(keyword="INPUT=")
'cancel' the input associated with the keyword so that the user can be prompted again.
reject(keyword="INPUT=", message="Input not acceptable")
rejects unacceptabe input and allows the user to correct it.
wkey(keystring,task="")
define or modify one or more user input parameters. If 'task' is specified, this will be done for an active task running under that name, otherwise it is done for the calling task.
subst(substring)
specify keyword substitution for deputy tasks.
decodeint(expr, nmax=4096)
evaluate the expression 'expr' which may result in up to 'nmax' values and return these values as a list, or as a scalar when nmax=1. For the evaluation the GIPSY function 'decodeint' is used. See the document decodeint.dc2.
decodefloat(expr, nmax=4096)
evaluate the expression 'expr' which may result in up to 'nmax' values and return these values as a list, or as a scalar when nmax=1. For the evaluation the GIPSY function 'decodedble' is used. See the document decodedble.dc2.

Other

cubicspline(xus, yus, sampdist)
piecewise cubic spline through two-dimensional positions stored in lists or arrays 'xus' and 'yus'. The return value is the three-tuple (x, y, splg), where 'x' and 'y' are lists of positions that are interpolated along a cubic spline on a sample distance given by 'sampdist' (usually 1) and 'splg' is the resulting spline length.
ellipsemask(xlo, ylo, xhi, yhi, ellpar)
return a NumPy array containing a mask of points contained by an ellipse. See also ellipsefill.dc2.
evalexpr(expr, nmax=1)
evaluate the expression 'expr' which may result in up to 'nmax' values and return these values as a list, or as a scalar when nmax=1. This function calls the function 'decodefloat'. A previous version used the GIPSY function 'dcddble' for evaluation.
polymask(xlo, ylo, xhi, yhi, polyX, polyY)
return a NumPy array containing a mask of points contained by a polygon of which the vertices are given in the lists or arrays polyX and polyY. See also scanline.dc2.
unitfactor(unit1, unit2)
return the factor between the units given in the strings 'unit1' and 'unit2'. For the evaluation the GIPSY function 'factor' is used. See the document factor.dc2.

Data Set Access

For accessing and manipulating data in GDS sets, two classes have been defined: 'Set' and 'Axis'.

Class Set

Opening and closing

A GDS set is opened by creating a set object and closed by deleting this object:

s = Set(setspec, create=False, write=False, gethdu=None, getalt=None)
setspec: set, subset specification string e.g., 'aurora freq 1 2 3'.
Instead of a set name also the name of a FITS file may be specified. If such a FITS file consists of more than one HDU, then the HDU number needs to be specified. This can be done by appending a hash sign (#) followed by the number to the filename, e.g., 'aurora.fits#3', or alternatively by supplying the argument 'gethdu'. Alternative WCS axes can be specified in a similar way by appending a hash sign followed by a letter. HDU- and alternative axis specifications can be combined, e.g., 'aurora.fits#3#Z'. Case and order are not important.
FITS 'pseudo sets' are always read-only.
create: True if an empty new set is to be created, False if the set exists. A FITS pseudo set is considered to exist.
write: True if set is to be written to.
gethdu: For FITS pseudo sets: a function that will be called with the file's HDUlist as its argument and must return the HDU number.
getalt: For FITS pseudo sets: a function that will be called with a list of alternative WCS version codes and the HDU header as its arguments and must return a WCS version code.
del s
the set will be closed as soon as there are no references to it anymore.

Attributes of Set objects:

s.image
the set's image as a NumPy array.
s.header
a SetHeader object which interfaces to the set's header. On write, a copy of the element is created. On read, the value of the copy is returned if it exists, or otherwise the set's header element itself. See below.
s.naxis
the set's dimensionality.
s.ncoords
the set's number of axes, including 'hidden axes'.
s.axnames
the set's list of axis names.
s.slo, s.shi
lists with the set's lower and upper grid limits.
s.blo, s.bhi
if a box has been specified, lists with the box's limits, otherwise identical to s.slo, s.shi.
s.spec
the set's specification string as given when the object was created.
s.open
True when set is open.
s.wmode
True when set is writable.
s.boxspec
the set's box specification string as given to the method 'setbox()'.
s.subsets
set's list of subset coordinate words.
s.blank
Value of the undefined pixel.
s.fits
True when set is a FITS 'pseudo set'.
s.fitsname
For FITS pseudo sets: the name of the FITS file.
s.hdunum
For FITS pseudo sets: the number of the HDU. Zero-relative.
s.altwcs
For FITS pseudo sets: alternative WCS version code used for creating the set. Default: blank.
Set.max_cword
Class attribute. The highest possible value of a coordinate word for any set. Can be used to determine whether a combination of axes will fit.

Methods of Set objects.

The descriptions below show the method's arguments and argument defaults, if any.

s.update()
update set's image file on disk.
s.close()
close the set.
s.delete()
delete the set from disk. Note that the set object will continue to exist until it is deleted.
s.wminmax(level=0)
update the (sub)set's DATAMIN, DATAMAX and NBLANK.
s.whistory(history='')
write a history record to the set.
s.wcomment(comment)
write a comment record to the set.
s.setbox(boxspec)
apply a box specification string; attributes 'blo' and 'bhi' will be adjusted.
s.extend(axname, origin, size)
add or extend an axis. See gds_extend.dc2
s.write(key, level_c, buffer)
write a raw descriptor item to the set. 'key' is the descriptor's name; 'level' is the subset level and 'buffer' is a Buffer object containing the data of the descriptor. Such an object is normally first obtained from a call to method read().
r = s.axnum(axname)
get number of an axis given the name; for this and all other methods axis counting starts with zero, not 1.
r = s.copy(outset)
make a copy of the set. Subset- and box specifications are taken into account.
r = s.subimage(level, box=True)
obtain a NumPy array slice corresponding to the subset level and any specified box. If box=False, the slice of the whole subset is returned.
r = s.axes(level=0, mode='')
Obtain a list of Axis objects.
level = 0 or False : return a list of all axes in the set's order.
level = True : a list according to the set, subset specification.
level > 0 : a list according to this subset level. If it is one of the specified subsets, the list's order will be according to the set, subset specification.
mode = '' : return a list of all axes, first the axes inside the subset, then the remaining axes.
mode = 'inside' : only the subset axes.
mode = 'outside' : only the axes outside the subset.
r = s.axname(axnum)
get name of an axis given the axis number.
r = s.axorigin(axnum)
get the origin of an axis given the axis number.
r = s.axsize(axnum)
get the length of an axis given the axis number.
r = s.axperm(mode='')
obtain a list with the axis permutations of the set, subset specified when the set was opened.
if mode='inside', only the subset axis permutation is returned;
if mode='outside', only the axis permutation outside the subset is returned.
r = s.tophys(grids=None, level=0, mode='')
coordinate transformation: grid coordinates to physical coordinates.
If grids=None, the 'lower left' position of the given subset is used.
mode = 'inside' : return only coordinates within subset
mode = 'outside' : return only coordinates of subset. If subset is one of the subsets specified when the set was opened, the order is according to this specification.
r = s.togrid(phys=None, level=0, mode='')
coordinate transformation: physical coordinates to grid coordinates.
If phys=None, the 'lower left' position of the given subset is used.
mode = 'inside' : return only coordinates within subset
mode = 'outside' : return only coordinates of subset. If subset is one of the subsets specified when the set was opened, the order is according to this specification.
r = s.range(subset)
get the range (as a 2-tuple of coordinate words) of a subset given as a coordinate word.
r = s.grid(axnum, cword)
extract the grid value from a coordinate word for the specified axis. Return None if undefined.
r = s.grids(cword)
extract all grid values from a coordinate word.
r = s.word(grids, cword=0, axnum=None)
compose a new coordinate word from an existing one and one or more grid values. If 'axnum' is not None, one scalar grid value should be specified in 'grids'; if 'axnum' is None, 'grids' should be a sequence of grid values for all axes. Undefined grids in this list should be specified as 'None'.
r = s.ndims(cword=0, subset=False)
obtain the dimensionality of a coordinate word. If subset=True, cword is ignored and the dimensionality of the pre-specified subset(s) is returned instead.
r = s.type(name, level=0)
obtain FITS descriptor item type.
r = s.tablis(nitems=100)
obtain a list of (name, level) tuples for all tables present in the set. nitems is the maximum number of tuples that can be obtained. When there are more tables in the set, an exception is raised.
r = s.tabinq(name, subset=0, nitems=100)
obtain a list of column names in a table. nitems is the maximum number of columns that can be obtained. When there are more columns in the table, an exception is raised.
r = s.colinq(tabname, colname, level=0)
obtain information about a column in a table as the tuple (column type, column comments, column units, number of rows)
r = s.keys(level=0)
obtain a list of descriptor keywords at or above the specified level. Default is top level. If level is specified as None, a list with all keys at all levels is returned. In this case the items are tuples of the form (levelkeyword). This method returns keys of all descriptor types, including tables etc.
r = s.items(level=0)
obtain a list of FITS-type items at or above the specified level or at all levels if level is specified as None. Every item is a tuple of the form (keyvalue), where key is of the form described under the keys() method above.
r = s.read(key, level_c=0)
obtain a descriptor item of any type and return a Buffer object with the descriptor's contents. Buffer objects are opaque and currently cannot reveal their contents to a Python program. They can for instance be used to transfer descriptor information between different sets.
s.crecol(tabname, colname, coltype, subset=0, colcomm=" ", colunits=" ")
create a table column.
s.delcol(tabname, colname, subset=0)
delete a table column.
s.deltab(tabname, subset=0)
delete a table.

Header and table access

Header ('descriptor') and table data is accessed using the indexing and slicing syntax. This is best explained by giving some examples.

Reading header- and table data:

m = s[level, 'DATAMAX']   # get descriptor item from specified level
l = s.level               # level on which descriptor item was found
x = s[level, t, c, 0:10]  # get first 10 elements from column c in table t
x = s[level, t, c, :]     # get all elements from column c in table t
                          # Note: negative indices and strided column access
                          # are not implemented.

For data at top level (level=0), the level index may be omitted:

e = s['EPOCH']

Writing header- and table data. Again, level can be omitted when it is zero:

s[level, 'DATAMAX'] = maxfound        # write descriptor item on specified level
s[level, t, c, 0:4] = [-1, 3, -5, 7]  # write column data
s['EPOCH'] = 2000.0                   # write descriptor item at top level

Assignment of 'None' to a descriptor item causes it to be deleted. If it does not exist, this fact will be ignored.

s['TEMPHEAD'] = None                  # delete descriptor item

Descriptor items can also be deleted explicitly. Here an exception is raised when the item does not exist:

del s[level, 'DATAMAX']   # delete descriptor item on specified level
del s['OBSERVER']         # delete descriptor item on top level

To test whether a descriptor item exists, use the in operator or the method has_key():

if 'DATAMAX' not in s: anyout('No DATAMAX found')
if s.has_key('EPOCH'): anyout('Found EPOCH in header')

Class SetHeader

This class is derived from dict of which some attributes and methods have been modified and others are unchanged. Every Set object has a SetHeader object associated with it. Elements of a SetHeader object map to the associated set's header elements (tables are excluded). These elements are accessed in the same way as can be done directly with the Set object. However if a header element is written to a SetHeader object, the associated set is not affected until the method commit() is called.

Attribute

h.set
the associated set

Methods

r = h.has_key(key)
True if 'key' can be found (in SetHeader or in Set object), False otherwise. Same as 'key in h'.
h.commit()
write all header items to the associated Set object
h.clear()
remove all items from the object (standard dict method)

Class Axis

Creation

Axis objects are associated with set objects and each axis object contains all information about a specific axis. They are created as follows:

a = Axis(set, axnum, subset=0, any=False)
If 'any' is True, an arbitrary subset can be used for some operations.

Attributes of Axis objects:

a.axnum
axis number in set
a.name
axis name
a.ctype
full axis name
a.crpix
reference pixel
a.crval
reference value
a.cdelt
pixel separation
a.cunit
natural axis units
a.dunit
secondary axis units
a.slo, a.shi
lists with the lowest and highest grid coordinate in the set.
a.blo, a.bhi
lists with the lowest and highest grid coordinates in box. Only defined for 'outside' axes when an explicit subset has been given (any=False). In the latter case they are both set to the appropriate grid coordinate. Attempting to access the attribute when it is not defined, causes an exception to be raised.
a.axtype
axis type: a 2-tuple consisting of an integer code and a descriptive text string, or None if not defined. See table below.
a.skysys
sky system: a 2-tuple consisting of an integer code and a descriptive text string, or None if not defined. See table below.
a.prosys
projection system: a 2-tuple consisting of an integer code and a descriptive text string, or None if not defined. See table below.
a.velsys
velocity system: a 2-tuple consisting of an integer code and a descriptive text string, or None if not defined. See table below.

Axis types

0:unknown type of axis
1:spatial axis longitude
2:spatial axis latitude
3:spectral axis frequency
4:spectral axis velocity
5:spectral axis wavelength
6:spectral axis inverse wavelength
7:spectral axis log(wavelength)
8:time axis
9:polarisation axis
10:parameter axis
11:sample axis of IRAS data
12:tick axis of IRAS data
13:detector axis of IRAS data
14:  snip axis of IRAS data

Sky systems

1:equatorial
2:galactic
3:ecliptic
4:  supergalactic

Projection systems

1:AITOFF equal area
2:equivalent cylindrical
3:flat
4:gnomonic
5:orthographic
6:rectangular
7:global sinusoidal
8:north celestial pole (WSRT)
9:stereographic
10:  Mercator projection

Velocity systems

0:unknown velocity system
1:optical
2:  radio

Event handling

There are two classes for event handling which are independent of (but usually used in combination with) a graphical user interface, such as PyQt4, GTK, Tkinter or GIPSY's own Ggi. Within Ggi another class has been defined for handling mouse events in plotfields. For background information, please refer to the web page http://www.astro.rug.nl/~gipsy/pguide/event-driven.html.

Instead of using GIPSY's own event loop mainloop(), it is also possible to delegate event processing to the event loop of an external toolkit, such as Qt. This can be done with the functions herconnect() and hersignal() or with qtconnect(), tkconnect() or gtkconnect(), which call the former two functions and connect to the appropriate toolkit. These functions are described below.

Class KeyCallback

Objects of this class are responsible for handling keyword events. A keyword event occurs when a user input keyword is changed (either by the user in any other way), cancelled or rejected. A KeyCallback object will not be deleted before it is inactive.

Creation

cbobj = KeyCallback(proc, key, mask=KEYCHANGE, schedule=True, **attr)
proc - function to be called upon a keyword event, matching 'mask'. This function will called with one argument: the current object.
key - user input keyword
mask - event mask
schedule - if True: schedule callback immediately.
attr - keyword arguments defining extra attributes for this object.

Attributes (read-only)

The callback function can use these attributes for determining its action. Except the attributes described below, it also can use any extra attributes which were defined when the callback object was created.

cbobj.event
code of event currently being handled: KEYCHANGE, KEYCANCEL or KEYREJECT.
cbobj.key
user input keyword.
cbobj.mask
event mask: bitwise OR of any of the codes KEYCHANGE, KEYCANCEL and KEYREJECT.
cbobj.active
True when event handling is enabled.

Methods

cbobj.schedule()
enable calling the registered function.
cbobj.deschedule()
disable calling the registered function.

Class TimeCallback

Objects of this class are responsible for handling timer events. Timer events occur periodically whenever a predefined period of time expires. A TimeCallback object will not be deleted before it is inactive. Except for the Qt4 and GTK toolkits (used by the corresponding Matplotlib backends), this class cannot be used when event handling is delegated to an external event loop.

Creation

cbobj = TimeCallback(proc, interval, schedule=True, **attr)
proc - function to be called each time when interval has expired. This function will be called with one argument: the current object.
interval - time interval in seconds
schedule - if True: schedule callback immediately
attr - keyword arguments defining extra attributes

Attribute (read-only)

Except the attribute described below, there are also extra attributes which were defined when the callback object was created.

cbobj.active
True when event handling is enabled.

Methods

cbobj.schedule()
enable calling the registered function.
cbobj.deschedule()
disable calling the registered function.

Class InputCallback

Objects of this class can be used to handle multiple inputs for a keyword, including recall files. For every input the specified handler function will be called. If necessary, multiple inputs are queued by the object. An InputCallback object will not be deleted before it is inactive. This class makes use of the classes KeyCallback and TimeCallback.

Creation

cbobj = InputCallback(proc, key, function=usertext, args={}, schedule=True, active=True, **attr)
proc - handler function to be called when keyword input is available. It will be called with one argument: the current object.
key - user input keyword. This keyword should not be handled by code outside InputCallback.
function - function which actually reads the input. Must be one of the user input functions described above. Default usertext. This function is called with arguments default=2 and defval=None.
args - dictionary with extra arguments to function. 'nmax' and possibly 'width' can be specified here.
schedule - if True (default), the object immediately becomes active, receiving keyword values.
active - if True (default), the object immediately starts calling the handler function when input is available.
attr - keyword arguments defining extra attributes for the object.

Attributes (read-only)

cbobj.value
the value as it is read by function(). When an error has been encountered, this attribute will contain a tuple with the following structure:

   (key, errormessage, inputstring)

'inputstring' is the input string causing the error condition.
cbobj.key
the user input keyword.

Methods

cbobj.schedule()
activate the object so that it starts receiving keyword values.
cbobj.deschedule()
deactivate the object and stop receiving keyword values and calling the handler function. Any queued input values are discarded.
cbobj.suspend()
deactivate the object so that the handler function will not be called. The object keeps receiving new keyword values.
cbobj.resume()
activate the object so that the handler function will be called when input is available.

Function mainloop

mainloop()
when an event occurs, this function takes care of calling all functions which were registered to handle this event. It will return as soon as there are no active callback objects. This feature can be used together with xeq() to run tasks in parallel in a controlled way. In tasks with a graphical user interface, mainloop() never returns.
When mainloop() is called, Python's Global Interpreter Lock (GIL) is released. It will be re-acquired during calls to event-handling functions. This behaviour allows threading to be used from event-driven programs.

Functions to delegate event handling

fd = herconnect()
returns the file descriptor via which events from Hermes are reported. This file descriptor can be used by an external event loop to wait for events. For every event received in this way, the function hersignal() must be called.
hersignal()
calling this function will cause any pending events to be processed by the GIPSY library.
qtconnect()
using the previous two functions, this function delegates event processing to the PyQt4 module.
tkconnect()
delegate event processing to the Tkinter module.
gtkconnect()
delegate event processing to the gtk module.

Example

The following program defines two callbacks and associated event handlers: one for the keyword RUN= and another for a timer. The keyword callback is initially scheduled, but the time callback is not. When the user now sets the keyword's value to 'YES', the keyword handler will activate the time callback (given as an attribute to the key callback) which then causes the time handler to periodically display and increment the value of 'count' (given as an attribute to the time callback). This continues until RUN= is set to 'NO' which causes the time callback to be descheduled. Wen RUN= is set to 'YES' again, counting resumes.
#!/usr/bin/env python
from gipsy import *

def time_handler(cbobj):
   status("timer count= %d" % cbobj.count)
   cbobj.count += 1

def key_handler(cbobj):
   run = userlog(cbobj.key)
   if run and not cbobj.timer.active:
      cbobj.timer.schedule()
      status("timer started")
   elif not run and cbobj.timer.active:
      cbobj.timer.deschedule()
      status("timer stopped")

init()

time_cb = TimeCallback(time_handler, 1.0, False, count=0)
key_cb  = KeyCallback(key_handler, "RUN=", timer=time_cb)

mainloop()

Ggi, GIPSY's own Graphical User Interface

GIPSY's graphical user interface (Ggi) has been implemented as a number of classes and pseudo-classes which interface with the different Ggi element classes. For more information about Ggi, see http://www.astro.rug.nl/~gipsy/pguide/event-driven.html. Most Ggi elements are implemented as objects of the class _Element, which is the root of all Ggi classes. A special class is _Container, of which the objects can contain other elements. Ggi objects are never created directly, but always by calling a 'factory method' of a container object. There is one special container class, GgiBase, of which one and only one object must be instantiated. This object is the container of everything else. The creation of it causes Ggi to be initialized.

Class _Element

Abstract class which is the root of Ggi classes. The following element types are implemented as objects of this class: Button, ColorMenu, HelpMenu, Label, Logo, Progress, TextField, TextMenu.

Attributes

e.width
element's width in pixels
e.height
element's height in pixels
e.realized
True or False
e.container
other element containing this element

Methods

Note: not all methods are meaningful for every _Element object. This depends on the kind of Ggi element implemented by the object.

e.setPosition(xfrom, xid, yfrom, yid)
position the element relative to other elements or to the left and top border of the container element. In the latter case xid and/or yid is None
e.setLabel(text, width=0)
set the element's label text. width id the optional new width in pixels.
e.alignLabel
set the label's alignment: ggiLeft, ggiCenter or ggiRight.
e.active(state)
set the element's active state. True: the element can handle mouse and/or keyboard events.
e.setKeyword(key)
change the element's user input keyword
e.helpText(message)
change the element's help pop-up text
e.delete()
delete the element
e.openMpeg(filename)
start recording an MPEG movie on this element
e.recordMpeg
record a frame for an MPEG movie
e.closeMpeg()
construct MPEG movie from recorded frames

Class _Analog(_Element)

Abstract class of analog valuators. The following element types are implemented as objects of this class: Dial, Gauge.

Methods

a.setCircular(mode)
'mode': True or False. If True, keyword values outside the element's range are mapped to an appropriate value within the range.
a.setFormat(formatstring)
set the format string which the element uses to format the keyword's value. It must follow the C conventions for floating point formatting.
a.setRange(lowval, highval)
modify the valuator's range

Class _ColorEditor(_Element)

See GgiPlotColorEditor.dc2. A color editor is a composite element consisting of a a color wedge, sliders which can manipulate the colormap's slope and shift, menus for choosing the type of color map and the scaling method, etc.

Methods

ce.apply()
apply the current settings to the currently selected PGPLOT device. This can be useful for e.g. hardcopies.
m = ce.getmap(nc)
obtain a color map based on the current settings. Returns a tuple (reds, greens, blues, bred, bgreen, bblue). The first three elements are lists of color intensities of the color map and the last three elements are a representation of the BLANK color. Intensities are numbers from 0.0 to 1.0.
ce.limits(v1, v2)
specify data limits. 'v1' end 'v2' are data values corresponding with the lowest and highest color index.
ce.units(unts)
specify the data units string.

Class _Container(_Element)

Abstract class of elements which can contain other elements. It implements a number of 'factory methods' which create the elements the container can contain. The following element types are implemented as objects of this class: Form, Viewport.

Methods

These are all factory methods which create another element within the container. Common arguments are 'keyword', which is the new element's user input keyword, and 'message', which contains the help pop-up text and may be None. Other arguments are explained in the specific methods' descriptions. For detailed information, please refer to the counterparts' dc2-documents, e.g. GgiTextField.dc2.

e = c.Button(keyword, message)
create a Button. Keyword result: 'YES' or 'NO'.
e = c.ColorEditor(ci, nc, bl=0)
create plot color editor: GgiPlotColorEditor.dc2
e = c.ColorMenu(keyword, message)
create a Color menu.
e = c.Dial(keyword, message, radius, min_angle, max_angle, intervals, arrow_width, inner_length, outer_length, min_val, max_val)
create a Dial element. For details see GgiDial.dc2.
e = c.Editor(keyword, width, height, mode, contents, size)
create an Text Editor element. See GgiEditor.dc2
e = c.Form(name, border=0)
create a Form element. A Form element are is a container. 'name': the form's name; 'border': border width.
e = c.Gauge(keyword, message, length, left, right)
create a Gauge element (slider). Gauge is a subclass of Analog, which implements a number of special methods. 'length': the slider's length in pixels; 'left' is the value to be returned at the leftmost position and 'right' the value at the rightmost position.
e = c.HelpMenu(keyword, label, message, labels, documents)
create a Help Menu. 'label': label text for menu button; 'labels': a list with text strings with the menu's items' texts; 'documents': a list with document specifications. Keyword result: not useful for application
e = c.Label(text)
create a Label element
e = c.List(keyword, labels, defcol=1)
create a List element. 'labels': a list of texts; 'defcol': default number of columns. Keyword result: an integer from 0 to the number of labels-1.
e = c.Logo()
create the GIPSY logo element
e = c.Menu(keyword, message, labels)
create a Menu. 'labels' is a list with text strings with the menu's items' texts. Keyword result: an integer from 0 to the number of labels-1.
e = c.PlotField(name, width, height)
create a PlotField element with name 'name' and dimensions 'width'×'height'
e = c.Progress(keyword, message, length)
create a Progress element. 'length' is the element's length in pixels.
e = c.TextField(keyword, message, size)
create a Textfield. Keyword result: the entered text.
e = c.Viewport(keyword, width, height)
create a Viewport element with dimensions 'width'×'height'.
e = c.VtkField(name, width, height)
only when the optional VTK binding (ggivtk) is available: create a VTK element with name 'name' and dimensions 'width'×'height'.

Class _FileBrowser(_Element)

A filebrowser is a composite pop-up element for browsing directories and selecting files.

Methods

fb.closeOnOK()
cause filebrowser to close when selection is made
fb.fileInfo(detailproc)
causes detail information to be displayed. This information is provided by the function 'detailproc' which is called with the possibly already filtered and modified name as the only argument an which returns an information string.
fb.nowait()
causes the selection to be accepted without requiring the OK button to be pressed.

Class _Inset(_Element)

An Inset object is a composite pop-up element for specifying set, subset and box information.

Methods

i.closeOnOK()
cause pop-up to close when selection is made
i.ndims(n)
set default number of dimensions.

class _List(_Element)

A list element consists of a rectangular area containing a list of strings formatted in rows and columns from which the user can select an entry.

Method

l.setLabels(labels)
change the list element's label strings. 'labels' is a list of strings.

Class _Menu(_Element)

Method

m.setLabels(labels)
change the list element's label strings. 'labels' is a list of strings.

Class _PlotField(_Element)

Class which implements a PGPLOT device.

Attributes

pf.pgid
PGPLOT device identifier
pf.nframes
number of available pixmaps (for movies, for instance)
pf.xormode
non-destructive plotting mode (True or False)
pf.callback
the currently active cursor callback object

Methods

c = pf.CursorCallback(proc, schedule=True, attr)
create a cursor callback object.
'proc': function to be called on cursor events. This function will be called with one argument: the callback object.
'schedule': if True: schedule callback immediately.
'attr' keyword arguments defining extra attributes.
pf.colors(number, master=True)
increase number of available colors. If master=True (the default) only the master color table is affected. If master=False, the complete master table is made available to the current plotfield.
pf.export()
export plotfield to other tasks.
pf.frames(number)
create 'number' pixmaps e.g. for movie loops.
pf.mapColors(spans)
build a plotfield-specific color table from spans in the master color table. Up to 10 tuples (color_index, number_of_colors) can be specified.
id = pf.open()
open plotfield and return PGPLOT plot device identifier.
pf.record(frame)
store a plot window in a pixmap. 'frame' is the pixmap's number.
pf.show(frame)
recall a plot image from a pixmap. 'frame' is the pixmap's number.
pf.xor(mode)
'mode': set non-destructive plotting mode (True or False)

Class _Popup(_Element)

Abstract class of pop-up elements. These elements appear as separate windows independent of the 'main' application window.

Method

p.show(visible)
pop the element up or down, depending on 'visible' being True or False.

Class _Shell(_Container,_Popup)

Abstract class of pop-up elements which can contain other elements. The following element types are implemented as objects of this class: Dialog, Shell.

Class _Prompter(_Element)

A prompter is a pop-up window in which a simple dialog can take place. It consists of a one-line prompt text, a type-in field, a text area for extra explanation and a cancel- and ok-button.

Methods

p.accept()
accept the user's response.
p.reject()
reject the user's response.

Class _VtkField(_Element)

Implements a VTK window. Only defined when the optional VTK binding (ggivtk) is available. For more information refer to VTK's and Python/VTK's documentation.

Methods

vf.open()
initialize the VTK element.
i = vf.Interactor()
return the associated vtkXRenderWindowInteractor object.
r = vf.RenderWindow
return the associated vtkXOpenGLRenderWindow object.

Class GgiBase(_Container)

Base container class. Creating a Base object causes Ggi to be initialized. Only one Base object should be created. After creation, this object is also available via the class attribute GgiBase.base

It defines factory methods for a number of special element types.

Creation

base = GgiBase(display=None, resources=None)
display: X11 display, e.g. `kapteyn:0.0, or the default display if None.
resources: X Toolkit fallback resources, or internal default if None.

Class attribute

GgiBase.base
after it has been instantiated: the base object

Methods

base.realize()
realize the widgets which have been created until now, this means (among other things) that the windows and subwindows are actually put onto the screen.
base.handleEvents()
force pending events to be handled.
r = base.verify(message, true_text, false_text)
ask the user a question and return True or False.
e = base.Shell(name)
create a pop-up container element.
e = base.Dialog(name)
create a Dialog pop-up container element
e = base.Prompter(keyword, message)
create a Prompter pop-up element
e = base.PlotPrompter(filekeydir, devkey, message)
create a Plot Prompter element.
e = base.FileBrowser(keyword, message, converter=None)
create a file browser pop-up element. 'converter' is a function that can filter and/or modify the file names which are found. It has one argument, the filename, and it returns either None or a possibly modified filename.
e = base.Inset(namekey, insetkey, boxkey=None, message="Input set/subset")
create an element for specifying set, subset and box information.

Class _CursorCallback

Instances of this class are always associated with a _PlotField object. Only one instance can be active at any time for a plotfield.

Attributes

cbobj.active
True when event handling is enabled.
cbobj.proc
function to be called upon a cursor event This function will be called with one argument: the current _CursorCallback object.
cbobj.plotfield
_PlotField object with which callback is connected.
cbobj.x, cbobj.y
cursor position in world coordinates.
cbobj.button
event-causing button. See table.
cbobj.state
mask (bitwise OR) of all active buttons and modifiers. See table.
cbobj.key
keyboard character.

Methods

cbobj.schedule()
enable calling the registered function.
cbobj.deschedule()
disable calling the registered function.

Table

ggiButn1 1 mouse button 1
ggiButn2 2 mouse button 2
ggiButn3 4 mouse button 3
ggiShift 8 shift key
ggiCtrl 16 ctrl key
ggiKeybd 32 other keyboard key
ggiLeftArrow 0xD1 left arrow
ggiUpArrow 0xD2 up arrow
ggiRightArrow 0xD3 right arrow
ggiDownArrow 0xD4  down arrow

PGPLOT

Introduction

The binding for PGPLOT is a GIPSY-specific re-implementation Nick Patavalis' ppgplot module, originally written in 1998, subsequently lost and then 'rediscovered' by Maarten Breddels from Kapteyn. The simplified interfaces have not been implemented.

The function arguments in the descriptions below indicate which 'type' is expected and what the argument defaults are, if any. The following types are used:

int:   an integer quantity
real:   a quantity that can be converted to real (an int, float, etc.)
bool:   a boolean value (True, False, 1, 0)
vector:   a one-dimensional NumPy array or a list of floats
matrix:   a two-dimensional NumPy array or a list of floats

Functions

pgarro(real: x1, y1, x2, y2)
draw an arrow.
pgask(bool: t)
control new page prompting.
pgband(int: mode, posn=0, real: xref=0.0, yref=0.0)
read cursor position, with anchor.
pgbbuf()
begin batch of output(buffer).
pgbeam(real: xcentre, ycentre, major, minor, pa, delta, slope, int: shape)
draw elliptical shaded beam (GIPSY extension)
pgbeg(string: device, int: xnsub=1, ynsub=1)
begin PGPLOT, open output device.
pgbin(int: nbin, vector: x, data, bool: center=True)
histogram of binned data.
pgbox(string: xopt='ABCGNTS', real: xtick=0.0, int: nxsub=0, string: yopt='ABCGNTS', real: ytick=0.0, int: nysub=0)
draw labeled frame around viewport.
pgcirc(real: x, y, radius)
draw a filled or outline circle.
pgclos()
close the selected graphics device.
pgconb(matrix: a, int: cd, rd, c1, c2, r1, r2, vector: c, int: nc, vector: tr, real: blank=0.0)
contour map of a 2D data array, with blanking.
pgconf(matrix: a, int: idim, jdim, i1, i2, j1, j2, real: c1, c2, matrix: tr)
fill between two contours.
pgconl(matrix: a, int: cd, rd, c1, c2, r1, r2, real: c, vector: tr, string: label, int: intval, minint)
label contour map of a 2D data array.
pgcons(matrix: a, int: cd, rd, c1, c2, r1, r2, vector: c, int: nc, vector: tr)
contour map of a 2D data array(fast algorithm).
pgcont(matrix: a, int: cd, rd, c1, c2, r1, r2, vector: c, int: nc, vector: tr)
contour map of a 2D data array(contour-following).
pgcotic(matrix: a, int: idim, jdim, i1, i2, j1, j2, vector: c, int: nc, matrix: tr, real: blank, tlen, int tstep)
contour map of a 2D data array, with blanking and ticks (GIPSY extension)
pgctab(vector: l, r, g, b, int: nc=None, real: contra=1.0, bright=0.5)
install the color table to be used by pgimag.
pgdraw(real: x, y)
draw a line from the current pen position to a point.
pgebuf()
end batch of output(buffer).
pgellipse(real: xcentre, ycentre, major, minor, pa, startang, endang, delta)
draw ellipse (GIPSY extension)
pgend()
terminate PGPLOT.
pgenv(real: xmin, xmax, ymin, ymax, int: just=0, axis=0)
set window and viewport and draw labeled frame.
pgeras()
erase all graphics from current page.
pgetxt()
erase text from graphics display.
pgexist(int n)
test whether a Hershey symbol, with index between 1..3000, exists (GIPSY extension) Returns: bool: exists
pggray(matrix: a, int: cd, rd, c1, c2, r1, r2, real: fg, bg, vector: tr)
gray-scale map of a 2D data array.
pghi2d(matrix: data, int: cd, rd, c1, c2, r1, r2, vector: x, int: ioff, real: bias, bool: center, vector: ylims)
cross-sections through a 2D data array.
pghist(int: n, vector: data, real: datamin, datamax, int: nbin, pgflag=0)
histogram of unbinned data.
pgiden()
write username, date, and time at bottom of plot.
pgimag(matrix: a, int: cd, rd, c1, c2, r1, r2, real: fg, bg, vector: tr)
color image from a 2D data array.
pglab(string: xlabel, ylabel, toplabel)
write labels for x-axis, y-axis, and top of plot.
pgldev()
list available device types.
pglen(string: text, int: units=4)
find length of a string in a variety of units.
pgline(vector: xpts, ypts)
draw a polyline(curve defined by line-segments).
pgmove(real: x, y)
move pen(change current pen position).
pgmtxt(string: side, real: disp, coord, fjust, string: text)
write text at position relative to viewport.
pgopen(string: device)
open a graphics device.
pgpage()
advance to new page.
pgpanl(int: x=1, y=1)
switch to a different panel on the view surface.
pgpap(real: width, aspect=1.0)
change the size of the view surface .
pgpat(vector: pat)
set line style according to input pattern (GIPSY extension)
pgpoly(vector: x, y)
draw a polygon, using fill-area attributes.
pgpt(vector: xpts, ypts, int: symbol=0)
draw one or more graph markers.
pgptxt(real: x, y, angle, fjust, string: text)
write text at arbitrary position and angle.
pgqah()
inquire arrow-head style. Returns:(int: fs, real: angle, vent)
pgqbci()
query color index for displaying BLANKs by pgimag() (GIPSY extension) Returns: int: ci
pgqcf()
inquire character font. Returns: int: cf
pgqimi()
query the interpolation used by pgimag() (GIPSY extension) Returns: int: intp
pgqtxt(real: x, y, angle, just, string: text)
find bounding box of text string Returns: 4(real: x,y) tuple, bottomleft, topleft, topright, bottomright.
pgqch()
inquire character height. Returns: real: ch
pgqci() Returns: int: ci
inquire color index.
pgqcir()
inquire color index range. Returns:(int: ci1, ci2)
pgqclp()
inquire clipping status Returns: int: state.
pgqcol()
inquire color capability. Returns:(int: ci1, ci2)
pgqcr(int: ci=0)
inquire color representation. Returns:(real: r, g, b)
pgqcs(int: units=4)
inquire character height in a variety of units. Returns:(real: xch, ych)
pgqfs()
inquire fill-area style. Returns: int: fs
pgqhs()
inquire hatching style. Returns:(real: angle, sepn, phase)
pgqid()
inquire current device identifier. Returns: int: id
pgqinf(string: item)
inquire PGPLOT general information Returns: string: value.
pgqitf()
inquire image transfer function. Returns: int: itf
pgqls()
inquire line style. Returns: int: ls
pgqlw()
inquire line width. Returns: int: lw
pgqpos()
inquire current pen position. Returns:(real: x, y)
pgqvp(int: units)
inquire viewport size and position Returns:(real: x1, x2, y1, y2).
pgqvsz(int: units)
inquire size of view surface Returns:(x1, x2, y1, y2).
pgrect(real: x1, x2, y1, y2)
draw a rectangle, using fill-area attributes.
pgsah(int: fs=1, real: angle=45.0, vent=0.3)
set arrow-head style.
pgsave()
save PGPLOT attributes.
pgsbci(int: ci)
specify color index for displaying BLANKs by pgimag() (GIPSY extension)
pgsclp(int state)
enable or disable clipping at edge of viewport.
pgunsa()
restore PGPLOT attributes.
pgscf(int: cf=1)
set character font.
pgsch(real: ch=1.0)
set character height.
pgsci(int: ci=1)
set color index.
pgscir(int: ci1=0, ci2=0)
set color index range.
pgscr(int: ci, real: r, g, b)
set color representation.
pgsfs(int: fs=1)
set fill-area style.
pgshls(int: ci, real: hue, level, saturation)
set color representation using HLS system.
pgshs(real: angle, sepn, phase)
set hatching style.
pgsimi(int: intp)
specify the interpolation to be used by pgimag() (GIPSY extension)
pgsitf(int: itf)
set image transfer function.
pgslct(int: devid=0)
select an open graphics device.
pgsls(int: ls=0)
set line style.
pgslw(int: lw=1)
set line width.
pgstbg(int: tbg=0)
set text background color index.
pgsubp(int: xnsub=1, ynsub=1)
subdivide view surface into panels.
pgsvp(real: xleft=0.0, xright=1.0, ybot=0.0, ytop=1.0)
set viewport(normalized device coordinates).
pgswin(real: x1=0.0, x2=1.0, y1=0.0, y2=1.0)
set window.
pgtext(real: x, y, string: text)
write text(horizontal, left-justified).
pgunsa()
restore PGPLOT attributes.
pgupdt()
update display.
pgvsiz(real: xleft, xright, ybot, ytop)
set viewport(inches).
pgvstd()
set standard(default) viewport.
pgwedg(string: side, real: disp, width, fg, bg, string: label)
annotate an image plot with a wedge.
pgwnad(real: x1, x2, y1, y2)
set window and adjust viewport to same aspect ratio.

Using PyQt4

To enable an application using the PyQt4 toolkit to react to events generated by Hermes, the function qtconnect() (see above) must be called. Once this has been done, keyword events can be handled via KeyCallback objects as usual. With QtLink objects it is also possible to link Qt widgets to task keywords, in a similar way as it is done in GIPSY's own graphical user interface (Ggi). This can be done on a per widget basis. When a widget is linked to a keyword, certain actions on that widget will result in the keyword's value to be changed. E.g., selecting a radio button will set the value to 'Y' and deselecting it to 'N'. This value can then be read by the task. Conversely, when a keyword's value is changed, either by the user or by the task itself by calling wkey(), this value will be reflected in all widgets that are linked to this keyword.

Class QtLink

Creation

Objects of this class realise a connection between a Qt widget and a task keyword. They are created in one of the following ways:

q = QtLink(keyword, widget)
When it is created in this way, only the following widget classes are supported: QAbstractButton, QAbstractSlider, QComboBox, QDoubleSpinBox, QLabel, QLineEdit and QSpinBox.
Example:
      self.insetwidget = QLineEdit()
      self.insetlink   = QtLink("INSET=", self.insetwidget)
For other widget classes, or if a special link protocol is required, the following creation call can be used:
q = QtLink(keyword, widget, signal=None, keyval=None, widgetval=None, setval=None, compare=True)
This is essentially the same as the previous call, except that here the optional arguments are shown. These arguments can be used to specify the complete protocol of an unsupported widget, or they can be used to override (part of) the protocol of a supported widget. For instance one might prefer the 'returnPressed()' signal for a QLineEdit widget over 'editingFinished()', which is in the default protocol. Another possibility is modifying the input from a widget so that it is more meaningful in the application's context. E.g., it is possible to realize a logarithmic scale associated with a slider widget.

signal is the signal emitted by the widget to which the QtLink object's signal handler will react, e.g. the string 'returnPressed()'
keyval is a function with one argument, the task keyword, that will read the keyword's value, and returns this value, possibly after modifying it. This returned value will be used to set the widget's value.
widgetval is a function or an unbound method of the widget's class with one argument, the widget, that obtains the widget's current value and returns a string representation of this value, possibly after modifying it. This returned value will be used to set the task's keyword.
setval is an unbound method of the widget's class that will be called to set the widget's value. It must be capable of accepting the return value of keyval.
compare indicates whether the widget's value will be compared with the previous value before it is used to set the keyword's value. If it is True (the default), an unchanged value will not set the keyword again.

Method

q.close()
close the connection between the widget and the task keyword.

Example

This example shows how a slider with a logarithmic scale can be implemented. It is a fully functional GIPSY task.

#!/usr/bin/env python

import sys
from math import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import gipsy

slmin =   0                                   # slider's minimum value
slmax = 100                                   # slider's maximum value

fac = log(10.0)/float(slmax)

def sli2key(widget):                          # slider value -> keyword value
   return str(exp(float(QSlider.value(widget))*fac))

def key2sli(key):                             # keyword value -> slider value
   return log(gipsy.userdble(key))/fac

def show_value(cb):                           # display value in task status
   gipsy.status("Slider's derived value: %0.2f" % gipsy.userdble(cb.key) )

class Form(QDialog):
    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.slider = QSlider()
        self.slider.setOrientation(Qt.Horizontal)
        self.slider.setMinimum(slmin)
        self.slider.setMaximum(slmax)
        self.sliderlink = gipsy.QtLink("VALUE=", self.slider,
                                       keyval=key2sli, widgetval=sli2key)
                                              # connect keyword to widget
        layout = QVBoxLayout()
        layout.addWidget(self.slider)
        self.setLayout(layout)
        self.setWindowTitle("Log. slider")

gipsy.init()                                  # open connection with Hermes

app = QApplication(sys.argv)
gipsy.qtconnect()                             # connect Hermes events to Qt
gipsy.KeyCallback(show_value, 'VALUE=')       # register keyword callback
form = Form()
form.show()
app.exec_()

gipsy.finis()                                 # close connection with Hermes

Class QtMessage

The purpose of this class is to provide a transient message pop-up which is placed just below a specified Qt widget. It is created as follows:
QtMessage(widget, message, delay=3.0, fgcolor='red', bgcolor='white')
'widget': the Qt widget relative to which the message will be shown;
'message': a text string with the message;
'delay': is the time after which the message will disappear, default 3.0 seconds;
'fgcolor': the foreground (text) color of the message, default red;
'bgcolor': the background color, default white.

Appendix: gpython

When developing in Python, it is sometimes handy when simple things can be tried interactively. Often the enhanced interactive Python shell IPython is used for this. For GIPSY this is not possible because all user interaction has to go through Hermes. As a simple equivalent for use in GIPSY, the following script, gpython, is provided:
#!/usr/bin/env python
import sys, traceback
from gipsy import *
def out(v):
   anyout(str(v))

init()

while True:
   try:
      exec(usertext('CMD=', 'Python statement'))
   except:
      etype, evalue, etrace = sys.exc_info()
      efmt = traceback.format_exception(etype, evalue, etrace)
      for line in efmt:
         anyout(line)
   cancel('CMD=')
A session with gpython in GIPSY could then look as follows:
<USER> gpython
                                          (start gpython)    08/06/11 12:59:46
<USER> GPYTHON CMD=`s = Set('m101')`
<USER> GPYTHON CMD=out(s.image.shape)
(530, 530)
<USER> GPYTHON CMD=out(s.image[200:204, 300:304])
[[ 8979.  9325.  9152.  9152.]
 [ 8979.  8632.  8459.  8459.]
 [ 9195.  8156.  8329.  8676.]
 [ 8849.  7809.  8329.  9369.]]
<USER> GPYTHON CMD=out(s['CRTYPE1'])
Traceback (most recent call last):
  File "/tmp/gpython", line 11, in ?
    exec(usertext('CMD=', 'Python statement'))
  File "<string>", line 1, in ?
  File "gipsy.pyx", line 1676, in gipsy.Set.__getitem__ (gipsy.c:21331)
  File "gipsy.pyx", line 2104, in gipsy.Set.__rhead (gipsy.c:27444)
KeyError: "'CRTYPE1', level 0"
<USER> GPYTHON CMD=out(s['CTYPE1'])
RA---TAN
<USER> GPYTHON CMD=out(s['CRPIX1'])
265.0
<USER> GPYTHON CMD=finis()
                                          (end   gpython)    08/06/11 13:05:05
<STATUS>  GPYTHON   +++ FINISHED +++
Note the use of back-quotes when a command containing an equals sign is entered.

March 6, 2013