# Basics of the Coordinate Map¶

When you load an image it will have an associated Coordinate Map

**Coordinate Map**

The Coordinate Map contains information defining the input (domain) and output (range) Coordinate Systems of the image, and the mapping between the two Coordinate systems.

The *input* or *domain* in an image are voxel coordinates in the image array.
The *output* or *range* are the millimetre coordinates in some space, that
correspond to the input (voxel) coordinates.

```
>>> import nipy
```

Get a filename for an example file:

```
>>> from nipy.testing import anatfile
```

Get the coordinate map for the image:

```
>>> anat_img = nipy.load_image(anatfile)
>>> coordmap = anat_img.coordmap
```

For more on Coordinate Systems and their properties
`nipy.core.reference.coordinate_system`

You can inspect a coordinate map:

```
>>> coordmap.function_domain.coord_names
>>> ('i', 'j', 'k')
```

```
>>> coordmap.function_range.coord_names
('aligned-x=L->R', 'aligned-y=P->A', 'aligned-z=I->S')
```

```
>>> coordmap.function_domain.name
'voxels'
>>> coordmap.function_range.name
'aligned'
```

A Coordinate Map has a mapping from the *input* Coordinate System to the
*output* Coordinate System

Here we can see we have a voxel to millimeter mapping from the voxel space (i,j,k) to the millimeter space (x,y,z)

We can also get the name of the respective Coordinate Systems that our Coordinate Map maps between.

A Coordinate Map is two Coordinate Systems with a mapping between
them. Formally the mapping is a function that takes points from the
input Coordinate System and returns points from the output Coordinate
System. This is the same as saying that the mapping takes points in the mapping
function *domain* and transforms them to points in the mapping function *range*.

Often this is simple as applying an Affine transform. In that case the Coordinate System may well have an affine property which returns the affine matrix corresponding to the transform.

```
>>> coordmap.affine
array([[ -2., 0., 0., 32.],
[ 0., 2., 0., -40.],
[ 0., 0., 2., -16.],
[ 0., 0., 0., 1.]])
```

If you call the Coordinate Map you will apply the mapping function between the two Coordinate Systems. In this case from (i,j,k) to (x,y,z):

```
>>> coordmap([1,2,3])
array([ 30., -36., -10.])
```

It can also be used to get the inverse mapping, or in this example from (x,y,z) back to (i,j,k):

```
>>> coordmap.inverse()([30.,-36.,-10.])
array([1., 2., 3.])
```

We can see how this works if we just apply the affine ourselves using dot product.

Note

Notice the affine is using homogeneous coordinates so we need to add a 1 to our input. (And note how a direct call to the coordinate map does this work for you)

```
>>> coordmap.affine
array([[ -2., 0., 0., 32.],
[ 0., 2., 0., -40.],
[ 0., 0., 2., -16.],
[ 0., 0., 0., 1.]])
```

```
>>> import numpy as np
>>> np.dot(coordmap.affine, np.transpose([1,2,3,1]))
array([ 30., -36., -10., 1.])
```

Note

The answer is the same as above (except for the added 1)

## Use of the Coordinate Map for spatial normalization¶

The Coordinate Map can be used to describe the transformations needed to perform
spatial normalization. Suppose we have an anatomical Image from one subject
*subject_img* and we want to create an Image in a standard space like Tailarach
space. An affine registration algorithm will produce a 4-by-4 matrix
representing the affine transformation, *T*, that takes a point in the subject’s
coordinates *subject_world* to a point in Tailarach space *tailarach_world*. The
subject’s Image has its own Coordinate Map, *subject_cmap* and there is a
Coordinate Map for Tailarach space which we will call *tailarach_cmap*.

Having found the transformation matrix *T*, the next step in spatial
normalization is usually to resample the array of *subject_img* so that it has
the same shape as some atlas *atlas_img*. Note that because it is an atlas
Image, *tailarach_camp=atlas_img.coordmap*.

A resampling algorithm uses an interpolator which needs to know
which voxel of *subject_img* corresponds to which voxel of *atlas_img*.
This is therefore a function from *atlas_voxel* to *subject_voxel*.

This function, paired with the information that it is a map from atlas-voxel to subject-voxel is another example of a Coordinate Map. The code to do this might look something like the following:

```
>>> from nipy.testing import anatfile, funcfile
>>> from nipy.algorithms.registration import HistogramRegistration
>>> from nipy.algorithms.kernel_smooth import LinearFilter
```

We’ll make a smoothed version of the anatomical example image, and pretend it’s the template

```
>>> smoother = LinearFilter(anat_img.coordmap, anat_img.shape)
>>> atlas_im = smoother.smooth(anat_img)
>>> subject_im = anat_img
```

We do an affine registration between the two.

```
>>> reggie = HistogramRegistration(subject_im, atlas_im)
>>> aff = reggie.optimize('affine').as_affine()
Initial guess...
...
```

Now we make a coordmap with this transformation

```
>>> from nipy.core.api import AffineTransform
>>> subject_cmap = subject_im.coordmap
>>> talairach_cmap = atlas_im.coordmap
>>> subject_world_to_talairach_world = AffineTransform(
... subject_cmap.function_range,
... talairach_cmap.function_range,
... aff)
...
```

We resample the ‘subject’ image to the ‘atlas image

```
>>> from nipy.algorithms.resample import resample
>>> normalized_subject_im = resample(subject_im, talairach_cmap,
... subject_world_to_talairach_world,
... atlas_im.shape)
>>> normalized_subject_im.shape == atlas_im.shape
True
>>> normalized_subject_im.coordmap == atlas_im.coordmap
True
>>> np.all(normalized_subject_im.affine == atlas_im.affine)
True
```

## Mathematical definition¶

For a more formal mathematical description of the coordinate map, see Mathematical formulation of the Coordinate Map.