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:
- A collection of elementary functions for controlling the task's
execution, communicating with the user, etc. Examples of these are
init(), finis(), userreal(), anyout().
- Classes for accessing GIPSY data sets and FITS files.
Methods are provided to access both
the descriptor and image components of a set. The image component is made
available as a NumPy array.
- A collection of classes and methods for creating a graphical user
interface and for communicating with it.
- A collection of functions providing bindings to the PGPLOT graphics library.
It is a GIPSY-specific re-implementation of the ppgplot
binding originally created by Nick Patavalis.
- An optional class which interfaces to VTK. Only available if
Python/VTK has been installed.
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
(level, keyword). 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 (key, value),
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