Skip to content

Commit 990d43d

Browse files
authored
Merge pull request #21 from int-brain-lab/depth_lookup
Depth lookup
2 parents 6582b3d + a3e0c3c commit 990d43d

File tree

7 files changed

+106
-28
lines changed

7 files changed

+106
-28
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## [0.7.0]
2+
### Added
3+
- `iblatlas.atlas.xyz_to_depth` a lookup from xyz coord to depth in cortex
4+
### Modified
5+
- Moved `iblatlas.plots.get_bc10` to `iblatlas.atlas.get_bc`
6+
17
## [0.6.0]
28
### Added
39
- `iblatlas.genomics.agea` option to load pre-processed volume

iblatlas/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,4 +194,4 @@
194194
.. [10] Allen Mouse Common Coordinate Framework Technical White Paper (October 2017 v3)
195195
http://help.brain-map.org/download/attachments/8323525/Mouse_Common_Coordinate_Framework.pdf
196196
"""
197-
__version__ = '0.6.0'
197+
__version__ = '0.7.0'

iblatlas/atlas.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1723,3 +1723,81 @@ def _read_volume(file_volume):
17231723
raise ValueError(
17241724
f'"{file_volume.suffix}" files not supported, must be either ".nrrd" or ".npz"')
17251725
return volume
1726+
1727+
1728+
def get_bc(res_um=10):
1729+
"""
1730+
Get BrainCoordinates object for Allen Atlas with bregma origin without reading in volumes
1731+
1732+
Parameters
1733+
----------
1734+
res_um : float or int
1735+
The resolution of the brain coordinates object to return in um. Options are 50, 25 or 10
1736+
1737+
Returns
1738+
-------
1739+
BrainCoordinates object with bregma origin
1740+
"""
1741+
1742+
dims2xyz = np.array([1, 0, 2])
1743+
scaling = np.array([1, 1, 1])
1744+
sf = 50 / res_um
1745+
im_shape = np.array([int(264 * sf), int(228 * sf), int(160 * sf)])
1746+
iorigin = (ALLEN_CCF_LANDMARKS_MLAPDV_UM['bregma'] / res_um)
1747+
dxyz = res_um * 1e-6 * np.array([1, -1, -1]) * scaling
1748+
nxyz = np.array(im_shape)[dims2xyz]
1749+
bc = BrainCoordinates(nxyz=nxyz, xyz0=(0, 0, 0), dxyz=dxyz)
1750+
bc = BrainCoordinates(nxyz=nxyz, xyz0=-bc.i2xyz(iorigin), dxyz=dxyz)
1751+
1752+
return bc
1753+
1754+
1755+
def _download_depth_files(file_name):
1756+
"""
1757+
These files have been generated using this script
1758+
https://github.com/int-brain-lab/ibldevtools/blob/master/Mayo/flatmaps/2025-03-20_depths_from_streamlines.py
1759+
:param file_name:
1760+
:return:
1761+
"""
1762+
file_path = BrainAtlas._get_cache_dir().joinpath('depths', file_name)
1763+
if not file_path.exists():
1764+
file_path.parent.mkdir(exist_ok=True, parents=True)
1765+
aws.s3_download_file(f'atlas/depths/{file_path.name}', file_path)
1766+
1767+
return np.load(file_path)
1768+
1769+
1770+
def xyz_to_depth(xyz, res_um=25):
1771+
"""
1772+
For a given xyz coordinates find the depth from the surface of the cortex. Note the lookup will only
1773+
work for xyz cooordinates that are in the Isocortex of the Allen volume. If coordinates outside of this
1774+
region are given then the depth is returned as nan.
1775+
1776+
Parameters
1777+
----------
1778+
xyz : numpy.array
1779+
An (n, 3) array of Cartesian coordinates. The order is ML, AP, DV and coordinates should be given in meters
1780+
relative to bregma.
1781+
1782+
res_um : float or int
1783+
The resolution of the brain atlas to do the depth lookup
1784+
1785+
Returns
1786+
-------
1787+
numpy.array
1788+
The depths from the surface of the cortex for each cartesian coordinate. If the coordinate does not lie within
1789+
the Isocortex, depth value returned is nan
1790+
"""
1791+
1792+
ind_flat = _download_depth_files(f'depths_ind_{res_um}.npy')
1793+
depths = _download_depth_files(f'depths_um_{res_um}.npy')
1794+
bc = get_bc(res_um=res_um)
1795+
1796+
ixyz = bc.xyz2i(xyz, mode='clip')
1797+
iravel = np.ravel_multi_index((ixyz[:, 1], ixyz[:, 0], ixyz[:, 2]), (bc.ny, bc.nx, bc.nz))
1798+
a, b = ismember(ind_flat, iravel)
1799+
1800+
lookup_depths = np.full(iravel.shape, np.nan, dtype=np.float32)
1801+
lookup_depths[b] = depths[a]
1802+
1803+
return lookup_depths

iblatlas/genomics/gene_expression_scrapping/06-denoise-impute.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def compute_agea_ppca(input_memmap, atlas_agea, output_memmap=None, ppca_n_compo
7878
gexps[gexps < 0] = np.nan
7979
C, ss, M, X, Ye = pyppca.ppca(gexps, d=ppca_n_components, dia=True)
8080
output_memmap = np.copy(input_memmap) if output_memmap is None else output_memmap
81-
output_memmap[:, *np.unravel_index(inside_idx, input_memmap.shape[1:])] = Ye.T
81+
output_memmap[:, *np.unravel_index(inside_idx, input_memmap.shape[1:])] = Ye.T # noqa
8282
output_memmap[:, *outside_idx] = input_memmap[:, *outside_idx]
8383
return output_memmap
8484

iblatlas/gui/atlasview.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ def cursor2xyamp(self, qpoint):
467467
region = None
468468
i = ctrl.atlas._lookup(xyz, mode='clip')
469469
vol = ctrl.atlas.image if isinstance(ctrl.volume, str) else ctrl.volume
470-
v = vol[*np.unravel_index(i, vol.shape)]
470+
v = vol[*np.unravel_index(i, vol.shape)] # noqa
471471
return iw, ih, w, h, v, region
472472

473473

iblatlas/plots.py

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,33 +18,11 @@
1818

1919
from iblatlas.flatmaps import FlatMap, _swanson_labels_positions, swanson, swanson_json
2020
from iblatlas.regions import BrainRegions
21-
from iblatlas.atlas import AllenAtlas, BrainCoordinates, ALLEN_CCF_LANDMARKS_MLAPDV_UM
21+
from iblatlas.atlas import AllenAtlas, get_bc
2222

2323
_logger = logging.getLogger(__name__)
2424

2525

26-
def get_bc_10():
27-
"""
28-
Get BrainCoordinates object for 10um Allen Atlas
29-
30-
Returns
31-
-------
32-
BrainCoordinates object
33-
"""
34-
dims2xyz = np.array([1, 0, 2])
35-
res_um = 10
36-
scaling = np.array([1, 1, 1])
37-
image_10 = np.array([1320, 1140, 800])
38-
39-
iorigin = (ALLEN_CCF_LANDMARKS_MLAPDV_UM['bregma'] / res_um)
40-
dxyz = res_um * 1e-6 * np.array([1, -1, -1]) * scaling
41-
nxyz = np.array(image_10)[dims2xyz]
42-
bc = BrainCoordinates(nxyz=nxyz, xyz0=(0, 0, 0), dxyz=dxyz)
43-
bc = BrainCoordinates(nxyz=nxyz, xyz0=-bc.i2xyz(iorigin), dxyz=dxyz)
44-
45-
return bc
46-
47-
4826
def plot_polygon(ax, xy, color, reg_id, edgecolor='k', linewidth=0.3, alpha=1):
4927
"""
5028
Function to plot matplotlib polygon on an axis
@@ -295,7 +273,7 @@ def _plot_slice_vector(coords, slice, values, mapping, empty_color='silver', mas
295273
if ba.res_um == 10:
296274
bc10 = ba.bc
297275
else:
298-
bc10 = get_bc_10()
276+
bc10 = get_bc(res_um=10)
299277

300278
if ax is None:
301279
fig, ax = plt.subplots()

iblatlas/tests/test_atlas.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import unittest
2+
from unittest import mock
23

34
import numpy as np
45
import matplotlib.pyplot as plt
56

67
from iblatlas.atlas import (BrainCoordinates, cart2sph, sph2cart, Trajectory, BrainAtlas,
7-
Insertion, ALLEN_CCF_LANDMARKS_MLAPDV_UM, AllenAtlas)
8+
Insertion, ALLEN_CCF_LANDMARKS_MLAPDV_UM, AllenAtlas, get_bc, xyz_to_depth)
89
from iblatlas.regions import BrainRegions, FranklinPaxinosRegions
910
from iblatlas.plots import prepare_lr_data, reorder_data
1011
from iblutil.numerical import ismember
@@ -729,5 +730,20 @@ def test_conversions(self):
729730
np.testing.assert_equal(self.frs.acronym2id('LO-2/3'), np.array([]))
730731

731732

733+
class TestDepths(unittest.TestCase):
734+
735+
@mock.patch('iblatlas.atlas._download_depth_files',
736+
side_effect=[np.array([35838117, 41837813]), np.array([400, 600])])
737+
def test_depth_lookup(self, mock_file):
738+
bc = get_bc(25)
739+
# First two coordinates in isocortex, third in thalamus
740+
idx = np.array([[245, 274, 37], [286, 327, 53], [225, 287, 170]]) # ap, ml, dv
741+
xyz = np.c_[bc.i2x(idx[:, 1]), bc.i2y(idx[:, 0]), bc.i2z(idx[:, 2])]
742+
743+
depths = xyz_to_depth(xyz)
744+
745+
assert np.array_equal(depths, np.array([400, 600, np.nan]), equal_nan=True)
746+
747+
732748
if __name__ == "__main__":
733749
unittest.main(exit=False, verbosity=2)

0 commit comments

Comments
 (0)