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:
and suppose this results in a prompt asking for the name of an NDF:
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:
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).
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.
An alternative form for the subscript expression involves specifying the centre and extent of the region required along each dimension, as follows:
name( p
q,
r
s,
... )
where ‘p
q
’,
‘r
s
’,
(etc.) specify the centre and extent. Thus,
name(100
11,200
5)
would refer to an 11 x 5 pixel region of an image centred on pixel (100, 200).
If the value before the delimiting ‘’ 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 ‘’ is omitted, it will default to the number of pixels in that dimension. Thus,
image(
100,
100)
could be used to refer to a 100 x 100 pixel region located centrally within an image, while
image( 10
,
20
)
would specify a section which is the same size as the original image, but displaced so that it is centred on pixel (10, 20).
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 AST_UNFORMAT 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:
If an NDF section is specified as “”, the axis values and will be interpreted as pixel index values for pixel axis if the values are integer. If the values are non-integer, they will be interpreted as values for WCS axis . The distinction between WCS axis and pixel axis is important since pixel axis does not necessarily correspond to WCS axis (for instance the WCS axes may be rotated or permuted).
If the section is specified by centre and extent (see §??), the extent will be interpreted as a number of pixels if it is an integer value with no decimal point. Otherwise it will be interpreted as an increment on the corresponding WCS axis. Thus, if the current WCS Frame of NDF “image” describes (RA,Dec) axes:
image(10:00:00
0:0:10,
-24:00:00
0:10:00)
could be used to refer to region centred at (RA,Dec) (10:00:00,-24:00:00) and covering an extent of 10 seconds on the RA axis and 10 arc-minutes on the Dec axis. Note, the RA extent is not an arc-distance, it is an increment in Right Ascension value. So the corresponding arc-distance will depend on the declination and will become smaller as either pole is approached. However, it is possible to indicate that the extent is an arc-distance by appending one of the three string “as” (arc-seconds), “am” (arc-minutes) or “ad” (arc-degrees) to the end of the extent specifier. For instance:
image(10:00:00
10am,
-24:00:00
50as)
will cause the section to cover an RA extent corresponding to 10 arc-minutes and a Dec extent corresponding to 50 arc-seconds. An error will be reported if the current WCS Frame is not suitable (i.e. is not a SkyFrame).
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.
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(
50%,
50%)
image( 25%:75%, 25%:75% )
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).
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:
Thus, all the following might be used as valid specifications for NDF sections:
ndf(3.7) |
ndf(,5:) |
ndf(-77:12h22m12s„4) |
ndf(66 9,4:17) |
ndf( 5,6 ) |
ndf( ,:) |
ndf(5500.0 150,) |
ndf(3.0 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.