Skip to main content

Docs Get in Touch DOI License Tests Codecov Python Version PyPI Conda Downloads Code Style: Ruff Pre-commit Contributions Welcome

brainglobe-space

Anatomical space conventions made easy.

Working with anatomical images, one often encounters the problem of matching the orientation of stacks with different conventions about axes orientation and order. Moreover, when multiple swaps and flips are involved, it can be annoying to map the same transformations to volumes and points (e.g., coordinates or meshes).

brainglobe-space provides a neat way of defining an anatomical space, and of operating stacks and point transformations between spaces.

Installation

You can install brainglobe-space with:

pip install brainglobe-space

Usage

To define a new anatomical space, it is sufficient to give the directions of the stack origin position:

source_origin = ("Left", "Superior", "Anterior")
target_origin = ("Inferior", "Posterior", "Right")

A stack can be then easily transformed from the source to the target space:

import brainglobe_space as bg
import numpy as np
stack = np.random.rand(3, 2, 4)

mapped_stack = bg.map_stack_to(source_origin, target_origin, stack)

The transformation is handled only with numpy index operations; i.e., no complex image affine transformations are applied. This is often useful as the preparatory step for starting any kind of image registration.

A shortened syntax can be used to define a space using initials of the origin directions:

mapped_stack = bg.map_stack_to("lsa", "ipr", stack)

NOTE

When you work with a stack, the origin is the upper left corner when you show the first element stack[0, :, :] with matplotlib or when you open the stack with ImageJ. First dimension is the one that you are slicing, the second the height of the image, and the third the width of the image.


The AnatomicalSpace class

Sometimes, together with the stack we have to move a set of points (cell coordinates, meshes, etc.). This introduces the additional complexity of keeping track, together with the axes swaps and flips, of the change of the origin offset.

To handle this situation, we can define a source space using the AnatomicalSpace class, specifying also the stack shape:

stack = np.random.rand(3, 2, 4)  # a stack in source space
annotations = np.array([[0, 0, 0], [2, 1, 3]])  # related point annotations

source_space = bg.AnatomicalSpace(source_origin, stack.shape)

mapped_stack = source_space.map_stack_to("ipr", stack)  # transform the stack
mapped_annotations = source_space.map_points_to("ipr", annotations)  # transform the points

The points are transformed through the generation of a transformation matrix. Finally, if we want to log this matrix (e.g., to reconstruct the full transformations sequence of a registration), we can get it:

target_space = bg.AnatomicalSpace("ipr", stack.shape)
transformation_matrix = source_space.transformation_matrix_to(target_space)
# equivalent to:
transformation_matrix = source_space.transformation_matrix_to("ipr", stack.shape)

The target get always be defined as a bg.AnatomicalSpace object, or a valid origin specification plus a shape (the shape is required only if axes flips are required).

Matching space resolutions and offsets

The AnatomicalSpace class can deal also with stack resampling/padding/cropping. This requires simply specifying values for resolutions and offsets when instantiating a AnatomicalSpace object. Once that is done, using AnatomicalSpace.transformation_matrix_to creating affine transformation matrices from one space to the other will be a piece of cake!

source_space = bgs.AnatomicalSpace("asl", resolution=(2, 1, 2), offset=(1, 0, 0))
target_space = bgs.AnatomicalSpace("sal", resolution=(1, 1, 1), offset=(0, 0, 2))
source_space.transformation_matrix_to(target_space)

Moreover, we can now use those space objects to resample stacks, and to generate stacks matching a target shape with the correct padding/cropping simply by specifying a target offset:

source_space = bgs.AnatomicalSpace("asl", resolution=(2, 1, 2), offset=(1, 0, 0))
target_space = bgs.AnatomicalSpace("asl", resolution=(1, 1, 1), shape=(5, 4, 2))  # we need a target shape
source_space.transformation_matrix_to(target_space, stack, to_target_shape=True)

Easy iteration over projections

Finally, another convenient feature of BGSpace is the possibility of iterating easily through the projections of the stack and generate section names and axes labels:

sc = bg.AnatomicalSpace("asl")  # origin for the stack to be plotted

for i, (plane, labels) in enumerate(zip(sc.sections, sc.axis_labels)):
    axs[i].imshow(stack.mean(i))

    axs[i].set_title(f"{plane.capitalize()} view")
    axs[i].set_ylabel(labels[0])
    axs[i].set_xlabel(labels[1])

Projection illustrations

Seeking help or contributing

We are always happy to help users of our tools, and welcome any contributions. If you would like to get in contact with us for any reason, please see the contact page of our website.

Citation

If you find brainglobe-space useful, please cite the following DOI:

Petrucco, L., & BrainGlobe Developers. (2024). brainglobe-space. Zenodo. https://zenodo.org/doi/10.5281/zenodo.4552536

Metadata

Release files for brainglobe-space 1.0.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for brainglobe-space 1.0.4
File Size Uploaded
brainglobe_space-1.0.4.tar.gz 15.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for brainglobe-space 1.0.4
File Interpreter ABI Platform
brainglobe_space-1.0.4-py3-none-any.whl Python 3 none any Details

Total release size: 26.9 kB

Release files / brainglobe_space-1.0.4.tar.gz

Download URL brainglobe_space-1.0.4.tar.gz
Size 15.6 kB
Tags Source
SHA-256 checksum
How to use checksums
a4c0adad1dd28db483e02e9d2c4540cacfa21310deb78a088a2c62eae14473ad
BLAKE2b-256 checksum
How to use checksums
d4d4bc532d628892840207661e7e2b6198c0bcbc70e1edb1d54fdcc1a2382dd3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / brainglobe_space-1.0.4-py3-none-any.whl

Download URL brainglobe_space-1.0.4-py3-none-any.whl
Size 11.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6ebdb03248c1d4b081c901c6deef93a9c0a89be4bcd271ee49bdb20427847fc2
BLAKE2b-256 checksum
How to use checksums
3a02e7aea82ee1cb4a26c1d4c626c22e58902c23d88a4f68368a9176665cbb55
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

1.0.4 This release

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page