Transforming data between FAFB14 and FlyWire#

Units matter!#

Before we get started there is one very important thing to keep in mind:

Spatial data can be in physical space (e.g. microns or nanometers) or in voxels. For FAFB, you will typically find stuff to be in either nanometers or in 4x4x40nm voxels. Some simple rules of thumb:

  1. Data (neurons, connectors, etc.) in CATMAID are in nanometers

  2. Data (neuron meshes) in FlyWire are in nanometers

  3. The CATMAID interface shows both physical units [nm] and voxels

  4. The FlyWire neuroglancer interface typically uses voxels

Bottom line: you need to be aware of the units of the object you are trying to transform.

Transforming coordinates#

There are two ways to transform spatial data (neurons, meshes, x/y/z coordinates) between FAFB14 and FlyWire space (also called “FAFB14.1”). The most convenient way is to use navis built-in transform system.

As soon as you import fafbseg, the following transforms become available to navis:


../../_images/fafbseg_bridging_graph.png

Let’s take it for a spin:

>>> import fafbseg
>>> import navis

First example: map a single location from FAFB14 to FlyWire.

In CATMAID, left-click on the little pin icon in the upper right (next to the `Pos, Id, ` field) to copy the current location (in nanometers) to the clipboard. Note that holding shift while clicking on the icon copies the location in voxels.

>>> import numpy as np

>>> # The location from the clipboard
>>> pos = np.array([[249960, 184691.375, 174240]])

Looking at above bridging graph, our coordinates are in "FAFB14" (nm) space and we want to go to "FLYWIREraw" (voxel) so that we can copy-paste the coordinates into the FlyWire neuroglancer”:

>>> navis.xform_brain(pos, source="FAFB14", target="FLYWIREraw")
Transform path: FAFB14 -> FAFB14raw -> FLYWIREraw
array([[62648.5    , 46291.34375,  4356.     ]])

If you copy the above coordinates into the FlyWire neuroglancer, they should get you exactly to the same location.

The advantage of navis.xform_brain is that it ties in with other available transforms. So in theory, you could go from FLYWIRE all the way to JRC2018F with a command.

The alternative to navis.xform_brain is to use a lower-level function: fafbseg.xform.fafb14_to_flywire(). This function and its inverse counterpart fafbseg.xform.flywire_to_fafb14() give you a bit more control over the transform.

>>> fafbseg.xform.fafb14_to_flywire(pos, coordinates="nm")
array([[250594.  , 185165.38, 174240.  ]], dtype=float32)

Note that these lower-level functions always return in the same space - hence above result is also in nanometers.

Second example: transforming a neuron

>>> import pymaid

>>> # Connect to the VirtualFlyBrain's public CATMAID instance
>>> cn = pymaid.CatmaidInstance(
...     server="https://fafb.catmaid.virtualflybrain.org/", project_id=1, api_token=None
... )

>>> # Load a neuron
>>> n = pymaid.get_neuron(16)

>>> # Xform the neuron - note we stay in nanometer space for now
>>> xf = navis.xform_brain(n, source="FAFB14", target="FLYWIRE")
INFO  : Global CATMAID instance set. Caching is ON. (pymaid)
Transform path: FAFB14 -> FAFB14raw -> FLYWIREraw -> FLYWIRE
>>> # Co-visualize the original (FAFB space) and the transformed (FlyWire space) neurons
>>> fig, ax = navis.plot2d([n, xf], color=["r", "c"], lw=0.5, method='3d_complex')
>>> ax.azim = ax.elev = -90
../../_images/transforming_10_1.png

As you can see, the offsets are rather small - probably most obvious in the soma tract.