The IMG library has more capabilities than have been covered in the preceding descriptions, which have been kept as simple as possible. You should read the following if you need to do more than has been covered so far.
Any reasonably complex program sooner or later needs to be able to store image information between
processing stages. This program snippet (from an example called shadow.f
– see §2) shows you how
to create a temporary image for this purpose:
IMG_TMP
creates a temporary image of the size you specify (in this case the
same size as the input image). You will not be prompted for a file name for a temporary
image, and no entry is needed for it in the program’s interface file.
IMG_FREE
will delete the temporary image. IMG subroutines can access “image” data with between 1 and 3 dimensions. This allows you to handle spectra (1-D) and cubes (3-D) as well as traditional 2-dimensional images. The subroutine calls needed are almost identical to the normal ones (above) that assume 2 dimensions. They differ only in having more or less arguments for the dimension sizes. The following illustrates the possibilities:
IMG_IN2
is just a synonym for ??x]]IMG_IN
(2 dimensions are assumed if you do not say
otherwise).
As well as accessing input images, there are equivalent routines for performing most other IMG operations on images with between 1 and 3 dimensions. For instance, the following would create a new 3-dimensional image:
When accessing an existing image with (say) 2 dimensions, you will also be able to access an appropriate slice from (say) a 3-dimensional image if you specify this when you are prompted for the image name (see §5.1).
IMG also allows access to images using data types other than REAL
(which is the default). The most
useful of these are INTEGER
, INTEGER*2
, and DOUBLE PRECISION
. The subroutine calls needed are
almost identical to the normal ones except that you should append a character code to the routine
name to indicate the data type you require. The character codes (and their data types) are:
Character code | Fortran-77 data type | Description |
R | REAL | Single precision |
D | DOUBLE PRECISION | Double precision |
I | INTEGER | Integer |
W | INTEGER*2 | Word |
UW | INTEGER*2 | Unsigned word |
B | BYTE | Byte |
UB | BYTE | Unsigned byte |
DOUBLE PRECISION
.
INTEGER
.
REAL
. Note that this is a synonym for ??x]]IMG_IN
, since it also gets
a 2-D REAL
image. You should declare the image array in your program to have the corresponding Fortran data type,
as in the following example that accesses and modifies an image using INTEGER
format:
INTEGER
input image is accessed for modification
DOZERO
the image is declared as an adjustable dimension INTEGER
array.
All IMG subroutines that access images have variants that allow you to use different data types. There are also versions that allow these to be mixed with different numbers of data dimensions. Some possibilities are:
DOUBLE PRECISION
.
INTEGER
data type.
INTEGER*2
) data type.
IMG_IN
, since it gets a 2-D REAL
image. If your image isn’t stored with the type that you ask for, then it will be converted from the stored type (if possible). If you modify the data it will be re-converted to the storage type when the image is freed. New images are stored using the data type you ask for.
The data types unsigned word (UW), signed byte (B) and unsigned byte (UB) are less commonly used. Indeed, the unsigned data types have no equivalents in Fortran and should be manipulated using the PRIMDAT library (SUN/39).
IMG can access more than one image at a time using a single subroutine call. An example of this is:
’BIAS’
, ’FLAT’
and ’RAW’
. Prompts for the actual image
files will be made for each of these names and pointers to the image data will returned in
IP, which should now be an array of size 3.
’RAW’
is copied to a new file. This also copies any header information, so is
usually preferred to using ??x]]IMG_NEW
.
’BIAS’
, ’FLAT’
and
’RAW’
images together with the copy of ’RAW’
can be accessed.
There are two advantages to accessing multiple images in one call in this way:
REAL
in this case).This means that corresponding values in each of the images can be directly inter-compared by your program, even if the images themselves have different sizes or data types.
IMG can also create more than one image using a single subroutine call. Some possibilities are:
IMG_NEW
creates two new images with size 1024 1024.
The variable IP
should be declared as an INTEGER
array of size 2.
’TEMPLATE’
is copied to two new images ’OUT1’
and ’OUT2’
. Again, the pointers are returned in an array IP(2)
.
In practice, astronomical images will often contain values that are unreliable (or unknown) and should be ignored. For example, you might not be able to compute a result for every element of an image array (say where a divide by zero would occur), or your detector system may not generate sensible values everywhere. These missing data are usually flagged by setting them to a unique number that allows them to be recognised, and this is known as the “bad” data value.2
Unfortunately, unless you have complete control over your data, you cannot usually ignore the possibility that an image may contain some of these “bad” values. If you did, and processed the numbers as if they were valid data, you would at best get the wrong answer. More probably, your program would crash.
To prevent you being baffled by this pitfall, IMG will normally check whether your input images contain any bad values and will issue a warning if any are found. Then at least you know why your program crashed!
You can deal with bad data values in one of two ways. The simplest is to use a suitable program to detect them and replace them with a sensible alternative value (for example, the KAPPA - SUN/95 - program NOMAGIC will do this). Alternatively, you can modify your IMG program to take proper account of them.
If you decide to modify your program, you’ll probably want to inhibit the checks that IMG makes. This is done by appending an exclamation mark (!) to the parameter name of each affected image. So, for instance:
inhibits bad data value checking for all the input images.The following example is a version of the mean.f
program (see §2.1) that shows the sort of changes
needed to deal with bad data:
PRM_PAR
’ is included. This defines Fortran parameters for the values used to
flag bad data (it should be used by all programs that handle bad data). The parameter
names are type-dependent and have the form VAL__BAD[x]
, where [x]
is replaced by the
character code for the data type you’re processing. These codes are the same as those
used when accessing images of different data types – see §4.1.3. So, for instance, with
REAL
data you would use VAL__BADR
, while with INTEGER
data you would use VAL__BADI
,
etc. Before compiling a program that includes this file you should execute the command
prm_dev
, which creates a soft link to the include file.
REAL
, the bad data value we test against is
VAL__BADR
. If your program accesses more than one input image, you must be careful to check each of them. For instance if you were adding two images together you’d need to do something like the following:
Where A
and B
are the “images” to be added and C
is the image to store the result (in this case the
images are really 1-D INTEGER
spectra). Note how a bad value is assigned to the output image if we are
unable to calculate a result.
If you need to know more about how to handle bad data you should consult SUN/33.
Header items can come in more than one data type, so extended HDR subroutines (as for IMG) are provided to access them. If the item isn’t of the type you want, then a format conversion will be attempted. The way you specify the type you require is similar to that used for IMG routines – you just append the necessary character code to the routine name:
Character code | Fortran-77 data type | Description |
C | CHARACTER | Character string |
D | DOUBLE PRECISION | Double precision |
I | INTEGER | Integer |
L | LOGICAL | Logical |
R | REAL | Single precision |
HDR_IN
subroutine). Some of the possible calls are: REAL
value BSCALE
.
INTEGER
value BINNED
.
LOGICAL
value CHECKED
with the comment ’Data checked for
C/Rs’
. So far, header items have been assumed to originate only from one source (FITS). In reality, an image may have more than one set of header information, and these are distinguished by giving them different names. FITS headers are normally used for storing information that may be widely distributed, perhaps to people using different data reduction systems, whereas more private collections of header information may be created by using a name of your own choice. Private header information has the advantage that it is unlikely to be trampled on by other software (that believes it knows what the headers mean – rightly or wrongly) and is typically used for information needed only within a particular software package.3
Using header items from other sources is achieved simply by replacing ’ ’
(which is a
synonym for ’FITS’) with the appropriate name. Storing information in a named source
solely used by your programs is encouraged. This is better than trusting other programs
not to modify values that you have set. ’MYSOURCE’
is used in the following examples:
There are two HDR routines that allow you to access header items using an index number. Header item index numbers run from 1 through to the maximum number of items available. These facilities can be used to list all the header items, or to test for the existence of items with particular names.
The following program snippet shows how to list all the header items associated with an image. It
uses the HDR_NUMB
subroutine to query the number of items. The complete example is called
hdrlist.f
– see §2.
HDR_NUMB
counts the number of header items or the number of
occurrences of an item. The ’*’
argument indicates that all the header items are to be
counted. If an item name was given the number of occurrences of that item would be
returned (zero if none exist).
HDR_IN
returns the value of the header item as a character string.
A complication that we have glossed over so far is the fact that certain FITS header items can occur
more than once within an image. Strictly, this is limited to the keywords COMMENT
, HISTORY
and ’ ’
(blank) which are often used to construct multi-line descriptions of the contents or history of a FITS
file. To handle this, various of the HDR subroutines are “FITS occurrence aware”. For instance,
the fourth argument of the ??HDR_IN
subroutine specifies the occurrence of the item to
be read, and ??HDR_OUT
will append (rather than overwriting) items with these special
names.
FITS items can also have a comment associated with them (to be read by the recipient when a FITS file
is sent to another astronomical institution). The comment string is given by the fourth argument of the
HDR_OUT
subroutine, but this facility isn’t available for non-FITS header sources where this argument
will simply be ignored.
Header items can be stored in hierarchical structures.4 What this actually means is that a header item can be used as a “container” to store other items (which are known as components). Hierarchical items are distinguished by using a period sign in the name to separate their various components. So, for instance, if you had a series of values that described a useful region on an image you might write these out using something like:
You can examine the header items in an image by using the HDSTRACE program (SUN/102). If your
image file is called image
then you would use the command:
’MYSOURCE’
. To list the contents of a FITS source the most convenient
method is to use the KAPPA program FITSLIST (SUN/95).
If you have any hierarchical FITS headers (these were once used extensively by UK observatories), then they should look something like:
when examined by FITSLIST. To access this item using IMG you should call it’ING.DETHEAD’
. The
value of this item is shown being read by the example program hdrread.f
(see §2) next:
2It may also be known as the “invalid”, “flagged” or even “magic” value, but the meaning is the same.
3The Starlink application packages CCDPACK (SUN/139) and POLPACK (SUN/223) make extensive use of these facilities.
4Warning: you should not write hierarchical FITS header items as this violates the FITS standard (although data from outside sources may sometimes contain them).