[Pkg-exppsy-pynifti] [Nipy-devel] Image, design, usecases

Michael Hanke michael.hanke at gmail.com
Tue May 12 08:16:39 UTC 2009


Hi,

On Mon, May 11, 2009 at 02:59:08PM -0700, Matthew Brett wrote:
> > but it is really just attaching a transformation to an image. So:
> >
> >  get_affine() -> get_transformation() ??
> 
> Hoho - that was exactly the discussion that we were having during the
> Neurospin sprint.
> 
> We are able to encapsulate arbitrary transformations, with the
> 'CoordinateMap', and the current NIPY model for an Image is the
> association of the image data array with a CoordinateMap object of
> arbitrary transformation complexity.  We found then that we often
> wanted to ask for an affine from the coordinate map, and then we asked
> whether there was really any use-case for an Image with a non-affine
> transformation, as opposed to images with always-affine
> transformations, and separate Transformation objects that can be used
> in resampling images.  I must say, I now lean towards this last
> option.

IMHO the underlying question of most aspects we are talking about is:
Where is the thin red line between pynifti/vimages (or even shorter 'vi' ;-)
and the nipy image representation. I hope I am not the last person on
the list that still is not 100% sure about the destiny of pynifti/....

Quite often someone demands basic image operations provided by 'the'
class. With respect to a clear definition about the development goal I'd
prefer to have that agreed upon and written up very early in the process
(i.e. now).

I will try to outline the two extremes in this continuum and we could
try to converge on something in-between or exactly on one of them:


Scenario one -- the is no difference to the NiPy image class
------------------------------------------------------------

To prevent confusion about where to put a certain functionality and to
not have to care about dependency issue PyNIfTI is merged into NiPy and
is therefore able to rely on its functionality. Basically the result of
loading an image will be a fully functional, fully featured image
representation within NiPy.

Advantages:

 - Generally reduced maintainance effort (there is only one package to
   release).
 - Everything goes into NiPy is is especially tailored towards its
   needs.

Disadvantages:

 - Some of us have to marry a new wife -- switch the VCS.
 - Merging it into this big thing inherits the chance that it will
   dissolve in it and makes it difficult to export it into SciPy


Scenario two -- low-level image IO
----------------------------------

All vimages does is to provide bidirectional image IO, i.e. it reads
images of various formats and turns the contained information (all of
it) into Python datatype (incl. arrays of course) and vice versa. _No_,
not even basic image operations are provided (e.g. concatenating 3ds
into a 4d).

Advantages:

 - Simple scope hopefully leads to simple implementations with
   lightweight classes.
 - Few dependencies -- just what ever is needed to access a format.
   Maybe even with a simple runtime availability check, so that people
   who do not need minc do not have to worry about hdf.
 - Potentially easy to integrate into SciPy.
 - Separate release management allows for independent stabilization.

Disadvantages:

 - For actual neuroimaging applications one would probably really need
   NiPy to be productive, but isn't this what we would aim for anyway?



My current preferences are somewhat close to the second scenario. This
would have a number of consequences. If we go with 2nd, IMHO:

Do we have to track the correspondence between file and what is in
memory? -- No, since we only deal with reading and writing in a specific
format.  When we need to write, we do, whatever caused us to think it
would be necessary.

Do we have to handle non-file origins in a special way? No, since the
input will be basic datatypes, such as arrays -- no need to care where
they are coming from. Especially if the NiPy image is not build on top
of vimages (but rather uses it) the writer will always operate on
non-file origins.


The question remains whether the NiPy image will be build on top of
vimage's image classes, or will it just use them to populate its
members. I somewhat lean towards the latter to further decouple them.


Maybe this should really go into SciPy...

... so let me propose a potentially over-simplistic interface of
scipy.io.vimages:


def load(filename, ...):
    """Load a volume image of any supported format.

    Returns:
      tuple(data, meta)

      where data is a ndarray (that could be possibly mem-mapped if
      requested by some additional argument and technically possible),
      and meta is a dictionary with any kind of meta data available from
      that file (transformations, extensions, ...) -- all converted into
      basic Python datatypes. There would be some set of conventions for
      dict-keys (e.g. 'affine' if there is an affine), but in general
      the format is not-strictly specified.
    """
    ...


def save(filename, data, format=None, meta=None, ...):
    """Save some 'data' to file.

    Parameters:
      filename: str [, tuple]
        The target filename. Could be used to perform some kind of magic
        to determine the fileformat (e.g. .nii causes NIfTI to be
        written). Could also be a filename-pair, or something more
        extrem...
      data: ndarray [or something that could be turned into it]
        Image data that is supposed to be written.
      format: str
        Override argument for the target fileformat.
      meta: dict
        Any additional meta data that can not be determined from the
        'data' array properties. Any underlying writer might support a
        different set of meta data.
    """
    ...

This would be the user-visible API. The basic idea is to _not_ have
image classes at all, but operate purely on basic datatypes with ndarray
being the most complicated one. Anything more complex that that (e.g.
file tracking, image operations, ...) will be NiPy's duty.

Those two function above will obviously just be simple switches that
call an appropriate image reader/writer (or might even accept an
instance of such as an argument). Those classes might employ
any reasonable checks or tweaks to ensure proper, standard-compliant
files, but they nevertheless simply read or write -- not image data
management whatsoever. Therefore they could be really simple (or on the
otherside really complex -- who cares) and could be easily plugged into the main
interface.

Are there any use-cases which would significantly suffer if the main
data interface would be ndarray+dict?

Thoughts?

Michael

-- 
GPG key:  1024D/3144BE0F Michael Hanke
http://apsy.gse.uni-magdeburg.de/hanke
ICQ: 48230050



More information about the Pkg-exppsy-pynifti mailing list