FIGARO: Using `image' and Figdisp

Keith Shortridge

21st April 1995

1. Introduction

The Figaro `image' command allows you to display images on a grey-scale or colour display device. This makes it one of the most fundamental commands in the Figaro repertoire. It is worth being reasonably adept with it. On UNIX systems, `image' is supported through the use of the Figdisp display server, running on an X-terminal or directly on a workstation console. Figdisp also has a number of features that it is worth getting to know. This document is intended as an introduction to the use of the Figaro `image' command, particularly in combination with the Figdisp display server.

Some of the discussion is also relevant to anyone wanting to use the line graphics display server that also forms part of Figdisp. In particular, the discussion of cursor `focus' can be important to anyone using interactive line graphics programs like `arc'.

VMS users of Figaro who are just starting to use the UNIX version will find that there are few changes between the two systems, but the way `image' works under UNIX is noticeably different, mainly because of the use of Figdisp. This document should be particularly useful to them.

Users of the original VMS system should note that most of this document is concerned with the interaction of `image' and Figdisp, and so is really aimed mainly at users of the UNIX version of Figaro. However, Figdisp does run under VMS, and it may be that the next version of VMS Figaro will support it as a display option.

2. Initial startup

Once the initial `figaro' command has been given, you will find that the `figdisp' command is defined. This starts up the Figdisp display server. As with any X-based program, Figdisp needs to know what display device it is to use. If you are logged on directly to the workstation console, it will use the console screen without you needing to do anything more. If you are logged on to an X-terminal, you need to set the `DISPLAY' environment variable to indicate the name of the terminal to use. For this, you need to know the internet address of your terminal, or -- more usually -- a name that can be translated by the system to get this address. For example, my X-terminal is known to the system as `AAOXTF', and I set `DISPLAY' as follows:

setenv DISPLAY aaoxtf:0

You can use the full address of the terminal, either the symbolic name `' or the numeric address in the form `nnn.nnn.nnn.nnn' if you know it. Remember that whatever you use has to be understood by the machine you are logged on to. The `:0' at the end sets the screen to be used, and cannot be omitted. (You almost always want to use screen 0 -- very few machines have more than that one screen.)

Having got that bit of housekeeping out of the way, you can now give the `figdisp' command.


There are a number of options that can be specified here, and some of these are discussed later. Normally, the straight unadorned `figdisp' command suffices.

Figdisp puts out a message about numbers of grey levels and numbers of line colours and a quick bit of puff about having lots of features. It also points out that the F5 key will give you more information about these options, which is worth remembering. It starts up a display window with a grey scale display in it.

3. Displaying an image

Let's take a quick look at the way Figdisp server works, by working through a typical way I might use it to display an image. Both Figdisp and `image' have a few quirks, and this will introduce you to them. Say I have a data file `n6770.dst' in my default directory and want to display it. (This file is one of the example files supplied with Figaro.)

(It's important to note that this description assumes that you are running a window manager that requires you to click on a window to make it `active'. This is the default mode for many window managers, and is the only mode for the NCD window manager that I normally run on my X-terminal. Running in a mode that only requires you to move the cursor to a window to make it active makes the behaviour of Figdisp slightly different, and this is discussed later.)

I've just started up the Figdisp server, which has now blocked out my command window, so I bring that back to the front, obscuring the Figdisp display. Now I use the Figaro `image' command to display the image.

image n6770 reset \\

This displays my image. When the `reset' keyword is specified, the Figaro `image' command displays all of the image, and attempts to work out a sensible scale for the data based on the data values in the image, so this should give a reasonable looking image. Note that depending on the size of the image (the number of pixels it has in X and Y) you may not see all of the image in the display window -- if you think some might be missing, use the F4 key to zoom out until you have the whole image. What you see in the terminal window is something like:


Display scaled between 139.4033 and 314.1191

Compromise histogram optimisation (0.5) applied.

Display resolution changed to 463 by 241

Histogram optimisation may make display data value readout inaccurate.

We'll come back to what this all means later.

Figdisp now displays this image, at the top of the display window, where I can't see it anymore. I click in the display window to bring it to the front. The window flashes to the front, and my image suddenly moves within it.

The image moves because Figdisp has caught the click in its window, and has taken this as a command to move the image so the point you clicked on is at the centre of the image. This is a neat feature, but it gets in the way when you just want to bring the window to the front or are clicking it in just to make it active.

This means that it's usually a good idea to try to bring the window to the front without actually clicking in the window itself. So click on the title bar, or on the window surround instead, or use the `front' key if you're using a SUN console with such a key. Alternatively, your window manager may bring the window to the front as you move your cursor into it -- this is discussed in more detail later.

So you want to bring the image down into the centre of the display. Move the mouse to some part of the image and click the left button. That part of the image moves to the centre. That's nice. If you try to centre the image by clicking like this, however, you'll end up moving the image around in a pretty jerky and uncontrolled way. You start by clicking at, say, lower left and the image moves towards you, and you get the impression that clicking `pulls' on the image. Then you discover that sometimes it `pushes'. It takes a while to get used to. The secret is to remember that a click moves the bit of the image you click on to the centre of the display -- then it starts to make sense. (Hint: the best way to move the image to the centre of the display is to hit the F7 key.)

At this point you might want to see some colour on the display: the Figaro `colour' command will set a false colour table for you. Try

colour grjt

and you usually get a nice display. Try

colour jos

and you usually get a pretty vile display. (The `jos' colour table was designed to highlight small variations in an image, and it usually does this very well. It just looks like something the cat couldn't quite stomach.)

Go back to a decent colour table. (Or even to a grey scale display, using `colour grey' or `colour gray' -- the two are equivalent.)

Now try the right mouse button. This is fun. This interactively changes the look up table as you move it through the image. You can really get the `network activity' light solidly locked on with this. (Hint: to get back to a decent look up table either give the `colour' command again, or press the right button and release it again without moving the cursor significantly -- this is a special case that makes Figdisp revert to the original colour table.)

You can zoom in and out of the image using the F2 and F4 keys. (Hint: remember that F3 returns you to an unzoomed image. F3 and F7 in succession will return you to an unzoomed, centered image.) While you're zooming and moving around, you can see the whole image in a small window by pressing F8. If you click in that small window, the point you selected will be centered in the main display window.

You can get a readout of the data values around the cursor by making sure the Figdisp window is active and pressing F11. But note that the data values are only approximate. Figdisp operates on the grey scale levels in the display itself and then applies a linear conversion to convert back between 8 bit grey level and actual data values. This only has 8 bit accuracy at best, and is totally fooled by a display that has been histogram optimised. Figdisp can operate in a 16 bit mode which gives much more accuracy, but Figaro 4 doesn't support this at present. Don't try to do photometry off the Figdisp data output!

You can also get a readout of the cursor position and the data value under the cursor by using the F6 key. This displays the values in the title bar of the window. The same comments about the data value apply to this as well.

The warning shown earlier in the output from `image' about the display data value being inaccurate is because the reset setting used in the example includes histogram optimisation of the image. This means that the linear scaling applied by Figdisp is completely inappropriate -- not just limited by 8 bit accuracy, but way off. `Image' puts out this warning whenever histogram optimisation is used. To switch off the histogram optimisation, add `opt=0' to the `image' command.

The way the data values window appears and disappears takes some getting used to. If the Figdisp main window is active, F11 updates the patch window. If the patch window is active, F11 closes it. It's easy to click on the patch window to make it visible, then press F11 to update it only to see it vanish! (Your window manager may allow you to select a mode where the moving the cursor into the window makes it active, with no click being needed. You may prefer this. This is discussed in more detail later.)

There's lots more. I've not even touched upon getting cuts through the data plotted. Try dragging the mouse through the image with the middle button pressed. Release it and it plots the cut you selected.

Remember that if you press F5 you get a list of what the other keys do. This is usually frustrating, since most of the other keys it mentions won't be available on your keyboard. Getting around this limitation is discussed later.

4. Understanding just what is being displayed.

If all you want is a quick look at an image, the details of the display process don't matter very much. However, if you are going to start zooming in to look in detail at some small part of your data, then it's important to appreciate just what is being displayed in the Figdisp window and how `image' is using it. There are a number of subtle ways in which you can influence this.

4.1. Working with fixed size displays

A little history may help here. When `image' was originally developed, most image display devices were specialised devices like the Grinnell, the ARGS and the IKON. These essentially provided a display memory of fixed size -- 512 by 512 by 8 bits for the ARGS, somewhat larger for the IKON. `Image' worked by collapsing the specified region of the actual image data being displayed into something that would fit into this 512 by 512 (or whatever) array. This sometimes meant that pixels in the image had to be averaged or sampled (if the selected part of the image was larger than 512 pixels in one dimension) or duplicated (if the selected part was smaller than 512 pixels). Also, the data had to be scaled to fit into the 0..255 data range allowed by the 8-bits of the display memory.

The display device operated by continually displaying on its monitor the contents of this fixed size memory array. So in general, what you saw on the display was the whole of the memory array. Most devices had facilities for zooming in or out, usually by factors of two, and for panning the zoomed image. So the display seen on the monitor screen was a `window' into the fixed size memory array. It was pretty obvious how these things worked, and nobody thought much about this when they used them. Figdisp is actually pretty similar, but somehow it isn't always so obvious just what it's doing.

It's also worth looking at just how `image' handles the case when the displayed region of the image doesn't match easily to the fixed display size provided by the display device. Say the part of the image being displayed is a rectangular region 2000 by 128 pixels. Assume this is being displayed on a device with a fixed 512 by 512 display memory.

Normally, `image' would like to fill the display screen, expanding and contracting the displayed part of the image so that it fills the screen. However, doing so will distort an image like the one in our example, stretching it in one dimension while contracting it in the other. This may be fine for data that is a two-dimensional spectrum, but it will make a real image look very odd indeed.

So `image' operates in two distinct modes. In one mode -- the default mode -- it fills the screen as best it can while maintaining the aspect ratio of the displayed data. In this case, it will compress the image in X to make its 2000 pixels fit into the 512 provided by the display. It has to do this to get all of the image displayed. If it is to maintain the aspect ratio of the image, it has to compress the 128 pixels in the data in Y by the same amount. The result is a very long and thin image running along the centre of the display memory array. This may be what you want, but for long and thin data like this it probably isn't.

In the other mode -- the `noaspect' mode, selected by setting the `aspect' keyword to false, usually by including the word `noaspect' or just `noasp' in the command line -- `image' ignores the aspect ratio of the original data and just attempts to fill the whole of the display memory. So it compresses the image in X and expands it in Y, in this case.

`Image' expands and contracts by a simple, fast, `nearest pixel' algorithm. It takes each pixel in that part of the display memory that is going to be used (all of it in `noaspect' mode, usually a subset when the aspect ratio of the image is being preserved) and works out which pixel in the original data is closest to that pixel when the image is distorted so as to match the size of the display memory. The it uses that pixel. Note that it uses one and only one original data pixel for each display memory pixel -- it does not attempt to average pixels in any way.

It's important to note that compressing the data in this way looses information. Once the data has been compressed to make it fit into the display memory, no amount of zooming in on display memory pixels will show you pixels in the original image that had to be missed out in the sampling process.

4.2. A variable size display memory -- Figdisp.

Figdisp operates in almost exactly the same way as the fixed size, specialised displays. To a program using it as a display, it appears as an array of display memory -- this is an actual array allocated in the memory of the machine on which it is running -- of a given size. A program like `image' can write into it in just the same way as it might write into the display memory of an ARGS or an IKON.

However, the dimensions of the Figdisp display memory array can be modified to suit the purposes of the program running it.

The window in which the Figdisp display appears is just a window that shows all or part of this display memory array. Note that it does not necessarily show all of the display memory. The monitor on which the display window appears has a fixed number of pixels in each dimension, and the display window makes use of a subset of these. The display window can be resized (just how depends on the window manager being used) by the user.

The display window can be zoomed in or out by factors of two. In its unzoomed mode, one pixel on the monitor screen maps exactly to one pixel in the Figdisp display memory array. This means that if the display memory is larger than the display window, in terms of pixels, not all the display memory is visible to the user. If the display window is larger than the display memory, some of the window will not be displaying anything and will be black.

So although Figdisp is working in essentially the same way as a traditional fixed size display device, it is complicated by the fact that the display memory used by Figdisp can be resized, and by the fact that the display window can be so easily changed in size.

So, if the Figdisp display memory has been set to some very large dimensions, an unzoomed display window will not show the whole of the display memory. There are two separate mappings to think of here -- all or part of the original data array (in the Figaro data file) has been mapped in some way, by `image', onto the display memory, and some or all of the display memory is visible through the display window on the terminal screen.

This makes it important to know how large the Figdisp display memory is, and how this size is controlled by `image'.

4.3. How `image' sets the Figdisp display memory size.

`Image' does attempt to control the display memory size used by Figdisp. The way it does this is a trade off between various considerations, and the choice made by `image' may not be ideal for your purposes. In that case you need to know how to override the choice that `image' will make.

The considerations involved are:

Speed. Making the display memory size larger increases the amount of processing that is involved in writing to it. `Image' writes much faster to a small display than to a large one.

Information loss. If the display memory is smaller -- in either dimension -- than the data to be displayed, the sampling required to fit the data in to the display memory results in a loss of information. Some data pixels simply get missed out.

Display size. If the display memory is much larger than the display window size, it becomes hard to see the `whole picture'. The window cannot display all the image in the display memory, without being zoomed out.

Display readout. Figdisp has the ability (normally controlled by F6) to display a readout of the position of the cursor in terms of image pixels. Unfortunately, this only works properly if there is an integer scaling applied in the mapping of data pixels to display memory pixels. This constrains the size that can be set for the display if the readout is to be correct.

In its default mode, where it maintains the aspect ratio of the original data, `image' gives highest weight to the question of information loss. It attempts to set the display memory size to match that of the data to be displayed. For large arrays, this often means that the whole of the image is not visible in the display window in an unzoomed mode. (This is easily seen if the location window -- normally controlled by F8 -- is selected, but it is easily forgotten, and one can be left wondering where the rest of the data has gone; or worse, not realising that not all is being displayed.) For large arrays, it also means that the time to display the data can increase substantially.

In its `noaspect' mode, `image' attempts to maintain an accurate display readout, while keeping a reasonable limit on the display size for speed considerations and attempting to avoid information loss. It takes the largest dimension of the data and uses that for the same dimension of the display memory, then sets some integer multiple of the other data dimension close to 512 pixels for the other dimension of the display memory. The integer requirement is to keep the display readout accurate, the 512 is chosen as a compromise between too small to show the data well and so large as to slow the display inordinately. In many cases, this compromise will not suit the user, who may want to set some other values.

4.4. Setting the display memory size yourself.

In all cases, you can control the size of the Figdisp display memory set by `image'. The parameters `nxpix' and `nypix' can be used to override the choice of x and y display memory dimensions made by `image'. When `image' changes the size of the display memory, it outputs the new size of the display memory, and this can be used as a guide when making your own choice.

Usually, if you are not using the `noaspect' mode, the only reason for changing the display size selected by `image' is to speed up the display. The fact that the whole of a large display cannot be seen in the display window in unzoomed mode is not really a problem since it can be addressed easily enough by zooming the window out (using the F4 key). You should normally pick values that are integer multiples of the dimensions of the displayed data, or the display position readout will be inaccurate -- `image' will warn you about this.

If you are using the `noaspect' mode, your main considerations will be some combination of speed and a tradeoff between loosing information through the sampling process and getting the image stretched sufficiently in the smaller dimension to make it convenient to see. It's hard to make good suggestions here. You could just set a square display of 512 by 512 -- this will produce something that will usually be visible completely in a reasonably sized display window and will be fairly fast to display. However, you will probably loose the accuracy of the position readout, and may want to tweak the values used to correct this. Experiment!

5. Changing the cursor `focus'

The programs that you run control what is displayed within any of the windows on your display, but the `window manager' is the program that controls the placement, size, etc of the windows themselves. The window manager controls the look of the window frames. Only one window manager can control your terminal at once. It is possible to switch from one window manager to another, but you need to shut down the current one before starting up another. Window managers are important for this section, since they also control the way keystrokes are sent to programs.

In a X-windows system, the term `cursor focus' refers to the way the `active window' is selected. The `active window', usually indicated by some particular highlighting of its title bar or surround (just what varies from window manager to window manager) is the window that can be thought of as being `connected' to the terminal keyboard. A keystroke made on the keyboard is passed to the program that is controlling the currently active window. Since you often have a number of windows active at once -- and therefore a number of different programs controlling them -- this becomes very important.

In particular, in Figaro, if you are using the Figdisp line graphics window with an interactive program like `arc', this becomes very important. `Arc' -- and other programs in Figaro like it, together with some interactive programs that use the image display window, such as `cpos' -- all operate by using a keystroke in the display window (the line graphics window for `arc', the image display window for `cpos') to trigger some action. This action often requires additional information to be entered into the normal terminal window.

The problem is that the position of the cursor when this keystroke is entered on the display window usually matters. In `arc' it is used to select an arc line, for example. So if you have the terminal window active when you begin, you have the problem of making the display window active and then putting the cursor in position and making the required keystroke.

If you have a window manager that needs a click in a window to make it active, this gets very messy. The click you make in the window will be interpreted as making a cursor selection but without any associated keystroke -- the result is that the program receives a position with the wrong keystroke associated with it. Even if you get the right keystroke into the program, you then have to remember to reselect the terminal window to continue the dialogue with the program.

There are two solutions to this. One is to always select the display window by clicking in somewhere outside the actual display area - the title bar, or the frame of the window. This is a fairly easy habit to get into. You also need to remember to click on the terminal window before trying to type into it. It's a discipline that can be mastered, but it can need some dedication!

A better solution for most people is to arrange things so that the active window at any time is simply the one that the cursor is positioned over. Some window managers (such as `twm') have this as their default, others (such as Sun's `olwm') can be set so that they operate in this way. Some (such as the NCD window manager) cannot be set to work in this way at all.

The potential variety of systems involved makes it hard to give detailed advice here. Here's one example. I have an NCD X-terminal, which I always run using the NCD window manager (I happen to like the built-in terminal emulator). This always requires a click on a window to make it active.

Personally, I have become used to the contortions needed to run Figaro with this window manager, but if I want to switch to a manager that doesn't require the click to activate a window, I can shut down the NCD window manager (by selecting this option from the set I get offered when I click on the screen background). If I am then logged on to a UNIX machine that supports the twm window manager (and have set the DISPLAY environment variable to indicate my terminal), I can then just give the command `twm &' and `twm' takes over my terminal and suddenly I don't need to click to make a window active any more. Alternatively, I could have started up SUN's `olwm' window manager using `olwm &'. `Olwm' allows you to set the focus policy in the workspace properties menu so you can have this set to `click' or `follow pointer'.

6. Making do without the various keys.

Pressing F5 gives you a long list of function keys that look as if they do just what you would like to do, except that your terminal almost never actually seems to have the key in question. Very few terminals have the F33 and F35 keys required to zoom in and out in Y only (as opposed to the zoom in both X and Y you get with F2 and F4). Fortunately, there are ways to redefine the keys. In fact, you can control an amazing number of Figdisp properties if you only know how.

The details are all to be found in the Figdisp manual, which is included in the Figaro release in the directory pgplot/pgdisp as figdisp.txt. This reveals that all these keys can be redefined on the command line for Figdisp. So if you really want the Y direction zoom keys to be readily available, you can startup Figdisp using

Figdisp -zoomyin F11 -zoomyout F12

and you can use F11 and F12 instead of the mysterious F33 and F35 keys. (Of course, you now can't switch in the pixel values display or do a row plot in the line graphics window, which is what those keys used to do, but you can't have everything.)

The Figdisp manual gives the full list of things you can reconfigure on the command line. The following are the names to use to reconfigure the function keys as in the above example; the names should be self-explanatory:

-zoomin, -zoomnorm, -zoomout, -zoomxin, -zoomxout, -zoomyin, -zoomyout, -helpkey, -cursor, -recenter, -showloc, -quit, -showcmap, -showpatch, -row, -imageprint, -windowprint, -invert, -showsee, -column, -decreaseSlit, -increaseSlit, -inhibit

You can always alias the Figdisp command to your personal preferred flavour, by putting in your .chsrc file something along the lines of

alias Figdisp Figdisp -zoomyin F11 -zoomyout F12

The Figdisp manual also contains some discussion of handling cursor `focus' under different window managers.