16 USING SUBSCRIPTS TO ACCESS NDF SECTIONS

As well as providing the programmer with explicit facilities for creating NDF sections, the NDF_ system also allows both the user and the writer of applications to specify sections (subsets and super-sets) when giving the names of NDF data structures to be processed. To see how this works, consider an application which requests access to an NDF data structure as follows:

CALL NDF_ASSOC( ’IN’, ’READ’, INDF, STATUS )

and suppose this results in a prompt asking for the name of an NDF:

IN - Input NDF data structure > name

If you were to respond simply with the name of an HDS object (denoted here by “name”), then NDF_ASSOC would return a base NDF identifier for the specified data structure via its INDF argument. However, if a set of subscripts is also supplied, thus:

IN - Input NDF data structure > name(3:256,-8:4)

then NDF_ASSOC will return an identifier for the specified NDF section instead.

This process may be applied when accessing a pre-existing data structure in any situation where an NDF name alone would suffice (e.g. on the command line when invoking an application, or as a default in an interface file, etc.). Writers of applications may also use this method of selecting NDF sections when passing the names of datasets to NDF_ routines which access them (see §20.1).

Note, the tuning parameter SECMAX places a limit on the largest possible NDF section that can be created (see §23.3).

16.1 Specifying Lower and Upper Bounds

The subscript expression appended to an NDF name to specify a section may be given in several ways. One possible method, corresponding with the example above, is to give the lower and upper bounds in each dimension, as follows:

name( a:b, c:d, ... )

where ‘a:b’, ‘c:d’ (etc.) specify the lower and upper bounds. The bounds specified need not necessarily lie within the actual bounds of the NDF, because bad pixels will be supplied in the usual way, if required, to pad out the NDF’s array components whenever they are accessed. However, none of the lower bounds should exceed the corresponding upper bound.

Omitting any of the bounds from the subscript expression will cause the appropriate (lower or upper) bound of the NDF to be used instead. If the separating ‘:’ is also omitted, then the lower and upper bounds of the section will both be set to the same value, so that a single pixel will be selected for that dimension. Omitting the bounds entirely for a dimension (but still retaining the comma) will cause the entire extent of that dimension to be used. Thus,

image(,64)

could be used to specify row 64 of a 2-dimensional image, while:

cube( 1, 257:, 100 )

would specify column 1, pixels 257 onwards, selected from plane number 100 of a 3-dimensional “data cube”. Note that specifying:

image(,)

is just another way of referring to an entire image, except that it actually generates a section containing all the NDF’s pixels.

16.2 Specifying Centre and Extent

An alternative form for the subscript expression involves specifying the centre and extent of the region required along each dimension, as follows:

name( p$\sim$q, r$\sim$s, ... )

where ‘p$\sim$q’, ‘r$\sim$s’, (etc.) specify the centre and extent. Thus,

name(100$\sim$11,200$\sim$5)

would refer to an 11 x 5 pixel region of an image centred on pixel (100, 200).

If the value before the delimiting ‘$\sim$’ is omitted, it will default to the index of the central pixel in that dimension (rounded downwards if there are an even number of pixels). If the value following the ‘$\sim$’ is omitted, it will default to the number of pixels in that dimension. Thus,

image( $\sim$100, $\sim$100)

could be used to refer to a 100 x 100 pixel region located centrally within an image, while

image( 10$\sim$, 20$\sim$ )

would specify a section which is the same size as the original image, but displaced so that it is centred on pixel (10, 20).

16.3 Using WCS Coordinates to Specify Sections

Most of the previous examples use pixel indices to define the required NDF section. However, sections may also be specified within the coordinate system represented by the current Frame in the NDFs WCS FrameSet. Pixel indices should always be supplied as integer values within subscript expressions (that is, they should not include a decimal point). Anything that is non-integer will be interpreted as a WCS value.

In previous versions of the NDF library, non-integer values were interpreted as axis coordinates rather than WCS coordinates (for a description of axis coordinates, see §18). In order to retain backwards compatibility, the current version of the NDF library will continue to use this convention if the NDF has an explicitly defined axis coordinate system. Otherwise, non-integer values will be interpreted as current WCS Frame values.

The FrameSet method is used to read each string representing an axis value. Thus the strings should be supplied in a format which AST_UNFORMAT can understand. Some classes of coordinate system (e.g. celestial longitude and latitude, or time) can use a colon‘:’ as a separator between sexagisimal field. Since a colon is also used to separate the upper and lower bounds in an NDF subscript expression, steps must be taken to differentiate the two uses of the colon character. This can be done in two ways:

(1)
One method is to use alternative sexagisimal field separators. For instance time (and Right Ascension) values can use use “hms” separators in place of colon separators. Thus an RA value of “12:02:1.1” can also be supplied as “12h02m1.1s”. Similarly, a Declination value of “-23:45:12.2” can also be supplied as “-23d45m12.2s”.
(2)
Another method is to use semi-colon “;” instead of colon “:” as the NDF subscript expression separator. This works with all classes of coordinate system, but leaves some degree of ambiguity. For instance, a subscript expression of “12:34” could mean “use pixel indices 12 to 34”, or could mean “use the single RA or Dec value 12:34”. In cases, where such ambiguity is significant, sexagisimal fields should be identified explicitly using the appropriate “dhms” separator, as described in the previous point.

If an NDF section is specified as “$\left({L}_{1}:{U}_{1},{L}_{2}:{U}_{2},...{L}_{i},{U}_{i}\right)$”, the axis values ${L}_{i}$ and ${U}_{i}$ will be interpreted as pixel index values for pixel axis $i$ if the values are integer. If the values are non-integer, they will be interpreted as values for WCS axis $i$. The distinction between WCS axis $I$ and pixel axis $I$ is important since pixel axis $I$ does not necessarily correspond to WCS axis $I$ (for instance the WCS axes may be rotated or permuted).

If the WCS axes are rotated, the NDF section actually used will be a box just large enough to hold the requested range of WCS axis values.

16.4 Using Normalised Pixel Coordinates to Specify Sections

If a numerical value representing a bound, central value, or extent is followed by a percent sign (%) then the numerical value is interpreted as a percentage of the full width of the NDF on the corresponding pixel axis. Thus, to specify the central 50% of an image on both pixel axes, either of the following sections could be used:

image( $\sim$50%, $\sim$ 50%)
image( 25%:75%, 25%:75% )

16.5 Changing Dimensionality

The number of dimensions given when specifying an NDF section need not necessarily correspond with the actual number of NDF dimensions, although usually it will do so.

If fewer dimensions are specified than there are NDF dimensions, then any unspecified bounds will be set to (1:1) for the purposes of identifying the pixels to which the section should refer. Conversely, if extra dimensions are given, then the shape of the NDF will be padded with extra bounds set to (1:1) in order to match the number of dimensions. In all cases, the resulting section will have the number of dimensions actually specified, the padding serving only to identify the pixels to which the section should refer.

This process corresponds exactly to that which takes place via the programming interface when NDF_SECT is called (see §15.6).

16.6 Mixing Bounds Expressions

WCS (or axis coordinates can be mixed with pixel indices in the same subscript expression. In fact, any of the features described earlier may be combined when specifying an NDF section, the only restrictions being:

(1)
When the shape of the resulting section is expressed in pixel indices, the lower bound must not exceed the upper bound in any dimension.
(2)
If the bounds for an axis are specified by centre and width values (rather than as lower and upper bounds), then a WCS value should not be used with a pixel index. That is, the centre and width values must both refer to the same coordinate system.

Thus, all the following might be used as valid specifications for NDF sections:

 ndf(3.7) ndf(,5:) ndf(-77:12h22m12s„4) ndf(66$\sim$9,4:17) ndf($\sim$5,6$\sim$) ndf($\sim$,:) ndf(5500.0$\sim$150,) ndf(3.0$\sim$1.5,-78.06D-3:13.0545„„)

Many other combinations are obviously possible. In cases where some bounds are given in pixel indices and some in WCS coordinates, two boxes will be formed; one representing the pixel index bounds and one representing the WCS bounds. The actual NDF section used will be the overlap of the two boxes. The pixel box will inherit any pixel index limits supplied in the bounds expression, and will use default values for any missing limits. These default pixel index bounds are just the bounds of the base NDF. Likewise, the WCS box will inherit any WCS limits supplied in the bounds expression, and will use default values for any missing limits. The default WCS limits are the bounds of a box that just includes the whole pixel box.