Synchronization

One of the main goals of atldld is to replicate some of the behavior of Allen Brain Synchronization locally. This in turn allows for synchronization of a large number of coordinates in a reasonable amount of time. The synchronization logic is implemented in the atldl.sync module.

Reference-To-Image

Reference-To-Image API

For each dataset the Allen Brain Institute provides a matrix \(A_{trv}\) that encodes a 3D affine transformation.

\[\begin{split}A_{trv} = \begin{pmatrix} a_{1,1} & a_{1,2} & a_{1,3} & a_{1,4}\\ a_{2,1} & a_{2,2} & a_{2,3} & a_{2,4}\\ a_{3,1} & a_{3,2} & a_{3,3} & a_{3,4}\\ \end{pmatrix}\end{split}\]

Additionally, each section image has a matrix \(B_{tvs}\) that encodes a 2D affine transformation.

\[\begin{split}B_{tvs} = \begin{pmatrix} b_{1,1} & b_{1,2} & b_{1,3}\\ b_{2,1} & b_{2,2} & b_{2,3}\\ \end{pmatrix}\end{split}\]

They can be used to map any point \((p, i, r)\) from the reference space to a corresponding point \((x, y)\) in the image space. Specifically, the exact mapping looks like this

\[\begin{split}\begin{pmatrix} x\\ y\\ s\\ \end{pmatrix} = \begin{pmatrix} b_{1,1} & b_{1,2} & 0 & b_{1,3}\\ b_{2,1} & b_{2,2} & 0 & b_{2,3}\\ 0 & 0 & 1 & 0\\ \end{pmatrix} \begin{pmatrix} a_{1,1} & a_{1,2} & a_{1,3} & a_{1,4}\\ a_{2,1} & a_{2,2} & a_{2,3} & a_{2,4}\\ a_{3,1} & a_{3,2} & a_{3,3} & a_{3,4}\\ 0 & 0 & 0 & 1\\ \end{pmatrix} \begin{pmatrix} p\\ i\\ r\\ 1\\ \end{pmatrix}\end{split}\]

Note that \(s\) represents the theoretical section number multiplied by the dataset thickness.

The above described logic is implemented inside of atldl.sync.pir_to_xy. See below a small example.

from atldld.sync import pir_to_xy
import numpy as np

affine_2d = np.array(
    [
        [1, 0, 0],
        [0, 1, 0],
    ]
)  # should be downloaded from the Allen Brain API
affine_3d = np.array(
     [
        [1, 0, 0, 0],
        [0, 2, 0, 0],
        [0, 0, 1, 0],
     ]
)  # should be downloaded from the Allen Brain API

coords_ref = np.array(
     [
           [2, 1],
           [5, 2],
           [7, 5],
     ]
)  # (3, n_coords)

coords_img = pir_to_xy(coords_ref, affine_2d, affine_3d)

print(coords_img)
[[ 2.  1.]
 [10.  4.]
 [ 7.  5.]]

Note that the shape of coords_ref is (3, n_coords=2). However, n_coords can be much larger and in fact the user is encouraged to make it as large as possible to get a speedup.

Image-To-Reference

Image-To-Reference API

For each dataset the Allen Brain Institute provides a matrix \(A_{tvr}\) that encodes a 3D affine transformation.

\[\begin{split}A_{tvr} = \begin{pmatrix} a_{1,1} & a_{1,2} & a_{1,3} & a_{1,4}\\ a_{2,1} & a_{2,2} & a_{2,3} & a_{2,4}\\ a_{3,1} & a_{3,2} & a_{3,3} & a_{3,4}\\ \end{pmatrix}\end{split}\]

Additionally, each section image has a matrix \(B_{tsv}\) that encodes a 2D affine transformation.

\[\begin{split}B_{tsv} = \begin{pmatrix} b_{1,1} & b_{1,2} & b_{1,3}\\ b_{2,1} & b_{2,2} & b_{2,3}\\ \end{pmatrix}\end{split}\]

They can be used to map any point \((x, y)\) from the image space to a corresponding point \((p, i, r)\) in the reference space. Specifically, the exact mapping looks like this

\[\begin{split}\begin{pmatrix} p\\ i\\ r\\ \end{pmatrix} = \begin{pmatrix} a_{1,1} & a_{1,2} & a_{1,3} & a_{1,4}\\ a_{2,1} & a_{2,2} & a_{2,3} & a_{2,4}\\ a_{3,1} & a_{3,2} & a_{3,3} & a_{3,4}\\ \end{pmatrix} \begin{pmatrix} b_{1,1} & b_{1,2} & 0 & b_{1,3}\\ b_{2,1} & b_{2,2} & 0 & b_{2,3}\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1\\ \end{pmatrix} \begin{pmatrix} x\\ y\\ s\\ 1\\ \end{pmatrix}\end{split}\]

Note that \(s\) is a product of the section thickness (dataset specific) and the section number (image specific). Both of these values can be retrieved from the Allen Brain API.

The above described logic is implemented inside of atldl.sync.xy_to_pir. See below a small example.

from atldld.sync import xy_to_pir
import numpy as np

affine_2d = np.array(
    [
        [1, 0, 0],
        [0, 3, 0],
    ]
)  # should be downloaded from the Allen Brain API
affine_3d = np.array(
     [
        [1, 0, 0, 0],
        [0, 1, 0, 0],
        [0, 0, 1, 0],
     ]
)  # should be downloaded from the Allen Brain API

coords_img = np.array(
     [
           [2, 1, 5, 11, 0, 15],
           [5, 2, 10, 12, 0, 2],
           [7, 5, 2, 21, 0, 0],
     ]
)  # (3, n_coords)

coords_ref = xy_to_pir(coords_img, affine_2d, affine_3d)

print(coords_ref)
[[ 2.  1.  5. 11.  0. 15.]
 [15.  6. 30. 36.  0.  6.]
 [ 7.  5.  2. 21.  0.  0.]]

Note that the shape of coords_img is (3, n_coords=6). However, n_coords can be much larger and in fact the user is encouraged to make it as large as possible to get a speedup.

Source

source/synchronization.rst