diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a568e300..1d74212b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: - id: requirements-txt-fixer - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.5.6 + rev: v0.6.3 hooks: - id: ruff - repo: https://github.com/psf/black diff --git a/README.md b/README.md index ed896b0b..449a7245 100644 --- a/README.md +++ b/README.md @@ -23,20 +23,23 @@ The brainglobe atlas API (brainglobe-atlasapi) provides a common interface for p A number of atlases are in development, but those available currently are: -- [Allen Mouse Brain Atlas](https://doi.org/10.1016/j.cell.2020.04.007) at 10, 25, 50 and 100 micron resolutions -- [Allen Human Brain Atlas](https://www.brain-map.org) at 100 micron resolution -- [Max Planck Zebrafish Brain Atlas](http://fishatlas.neuro.mpg.de) at 1 micron resolution -- [Enhanced and Unified Mouse Brain Atlas](https://kimlab.io/brain-map/atlas/) at 10, 25, 50 and 100 micron resolutions -- [Smoothed version of the Kim et al. mouse reference atlas](https://doi.org/10.1016/j.celrep.2014.12.014) at 10, 25, 50 and 100 micron resolutions -- [Gubra's LSFM mouse brain atlas](https://doi.org/10.1007/s12021-020-09490-8) at 20 micron resolution -- [3D version of the Allen mouse spinal cord atlas](https://doi.org/10.1101/2021.05.06.443008) at 20 x 10 x 10 micron resolution -- [AZBA: A 3D Adult Zebrafish Brain Atlas](https://doi.org/10.1101/2021.05.04.442625) at 4 micron resolution -- [Waxholm Space atlas of the Sprague Dawley rat brain](https://doi.org/10.1038/s41592-023-02034-3) at 39 micron resolution -- [3D Edge-Aware Refined Atlases Derived from the Allen Developing Mouse Brain Atlases](https://doi.org/10.7554/eLife.61408) (E13, E15, E18, P4, P14, P28 & P56) -- [Princeton Mouse Brain Atlas](https://brainmaps.princeton.edu/2020/09/princeton-mouse-brain-atlas-links) at 20 micron resolution -- [Kim Lab Developmental CCF (P56)](https://data.mendeley.com/datasets/2svx788ddf/1) at 10 micron resolution with 8 reference images - STP, LSFM (iDISCO) and MRI (a0, adc, dwo, fa, MTR, T2) -- [Blind Mexican Cavefish Brain Atlas](https://doi.org/10.7554/eLife.80777) at 2 micron resolution -- [BlueBrain Barrel Cortex Atlas](https://doi.org/10.1162/imag_a_00209) at 10 and 25 micron resolution +| Atlas Name | Resolution | Ages | Reference Images +| --- | --- | --- | --- | +| [Allen Mouse Brain Atlas](https://doi.org/10.1016/j.cell.2020.04.007) | 10, 25, 50, and 100 micron | P56 | STPT +| [Allen Human Brain Atlas](https://www.brain-map.org) | 500 micron | Adult | MRI +| [Max Planck Zebrafish Brain Atlas](http://fishatlas.neuro.mpg.de) | 1 micron | 6-dpf | FISH +| [Enhanced and Unified Mouse Brain Atlas](https://kimlab.io/brain-map/atlas/) | 10, 25, 50, and 100 micron | P56 | STPT +| [Smoothed version of the Kim et al. mouse reference atlas](https://doi.org/10.1016/j.celrep.2014.12.014) | 10, 25, 50 and 100 micron | P56 | STPT +| [Gubra's LSFM mouse brain atlas](https://doi.org/10.1007/s12021-020-09490-8) | 20 micron | 8 to 10 weeks post natal | LSFM +| [3D version of the Allen mouse spinal cord atlas](https://doi.org/10.1101/2021.05.06.443008) | 20 x 10 x 10 micron | Adult | Nissl +| [AZBA: A 3D Adult Zebrafish Brain Atlas](https://doi.org/10.1101/2021.05.04.442625) | 4 micron | 15-16 weeks post natal | LSFM +| [Waxholm Space atlas of the Sprague Dawley rat brain](https://doi.org/10.1038/s41592-023-02034-3) | 39 micron | P80 | MRI +| [3D Edge-Aware Refined Atlases Derived from the Allen Developing Mouse Brain Atlases](https://doi.org/10.7554/eLife.61408) | 16, 16.75, and 25 micron | E13, E15, E18, P4, P14, P28 & P56 | Nissl +| [Princeton Mouse Brain Atlas](https://brainmaps.princeton.edu/2020/09/princeton-mouse-brain-atlas-links) | 20 micron | >P56 (older animals included) | LSFM +| [Kim Lab Developmental CCF](https://data.mendeley.com/datasets/2svx788ddf/1) | 10 micron | P56 | STP, LSFM (iDISCO) and MRI (a0, adc, dwo, fa, MTR, T2) +| [Blind Mexican Cavefish Brain Atlas](https://doi.org/10.7554/eLife.80777) | 2 micron | 1 year | IHC +| [BlueBrain Barrel Cortex Atlas](https://doi.org/10.1162/imag_a_00209) | 10 and 25 micron | P56 | STPT +| [UNAM Axolotl Brain Atlas](https://doi.org/10.1038/s41598-021-89357-3) | 40 micron | ~ 3 months post hatching | MRI ## Installation diff --git a/brainglobe_atlasapi/atlas_generation/atlas_scripts/axolotl_atlas.py b/brainglobe_atlasapi/atlas_generation/atlas_scripts/axolotl_atlas.py index 198ad7b3..1c390f9e 100644 --- a/brainglobe_atlasapi/atlas_generation/atlas_scripts/axolotl_atlas.py +++ b/brainglobe_atlasapi/atlas_generation/atlas_scripts/axolotl_atlas.py @@ -10,6 +10,9 @@ import pooch from brainglobe_utils.IO.image import load_nii from rich.progress import track +from skimage.filters.rank import modal +from skimage.measure import label, regionprops +from skimage.morphology import ball from brainglobe_atlasapi import utils from brainglobe_atlasapi.atlas_generation.mesh_utils import ( @@ -24,11 +27,10 @@ def create_atlas(working_dir, resolution): ATLAS_NAME = "unam_axolotl" SPECIES = "Ambystoma mexicanum" - ATLAS_LINK = "https://www.nature.com/articles/s41598-021-89357-3" + ATLAS_LINK = "https://zenodo.org/records/4595016" CITATION = ( "Lazcano, I. et al. 2021, https://doi.org/10.1038/s41598-021-89357-3" ) - ATLAS_FILE_URL = "https://zenodo.org/records/4595016" ORIENTATION = "lpi" ROOT_ID = 999 ATLAS_PACKAGER = "Saima Abdus, David Perez-Suarez, Alessandro Felder" @@ -57,7 +59,7 @@ def create_atlas(working_dir, resolution): } for filename, hash in list_files.items(): pooch.retrieve( - url=f"{ATLAS_FILE_URL}/files/{filename}", + url=f"{ATLAS_LINK}/files/{filename}", known_hash=hash, path=atlas_path, progressbar=True, @@ -76,6 +78,21 @@ def create_atlas(working_dir, resolution): reference_image = (reference_image - dmin) * dscale reference_image = reference_image.astype(np.uint16) + # mask: put 1 where there is an annotation + annotation_mask = np.zeros(annotation_image.shape) + annotation_mask[annotation_image > 0] = 1 + + # find the connected regions in the mask + labeled_image = label(annotation_mask) + regions = regionprops(labeled_image) + + # find the pixels belonging to the largest region + largest_region = max(regions, key=lambda region: region.area) + largest_mask = labeled_image == largest_region.label + + # keep only annotations in the largest connected region + annotation_image = annotation_image * largest_mask + hierarchy = [] # create dictionaries # create dictionary from data read from the CSV file @@ -165,13 +182,19 @@ def create_structure_id_path(main_structure): node.data = Region(is_label) # Mesh creation parameters - closing_n_iters = 5 - decimate_fraction = 0.1 + closing_n_iters = 10 + decimate_fraction = 0.6 smooth = True meshes_dir_path = working_dir / "meshes" meshes_dir_path.mkdir(exist_ok=True) + # pass a smoothed version of the annotations for meshing + smoothed_annotations = annotation_image.copy() + smoothed_annotations = modal( + smoothed_annotations.astype(np.uint8), ball(5) + ) + # Measure duration of mesh creation start = time.time() @@ -188,7 +211,7 @@ def create_structure_id_path(main_structure): node, tree, labels, - annotation_image, + smoothed_annotations, ROOT_ID, closing_n_iters, decimate_fraction, diff --git a/brainglobe_atlasapi/atlas_generation/atlas_scripts/whs_sd_rat.py b/brainglobe_atlasapi/atlas_generation/atlas_scripts/whs_sd_rat.py index 2f36817a..8cabb19d 100644 --- a/brainglobe_atlasapi/atlas_generation/atlas_scripts/whs_sd_rat.py +++ b/brainglobe_atlasapi/atlas_generation/atlas_scripts/whs_sd_rat.py @@ -1,15 +1,16 @@ -__version__ = "0" +__version__ = "2" __atlas__ = "whs_sd_rat" + import json import multiprocessing as mp import time from pathlib import Path -import imio import numpy as np import pooch import xmltodict +from brainglobe_utils.IO.image import load_any from rich.progress import track from brainglobe_atlasapi import utils @@ -201,15 +202,14 @@ def create_atlas(working_dir): ATLAS_NAME = "whs_sd_rat" SPECIES = "Rattus norvegicus" ATLAS_LINK = "https://www.nitrc.org/projects/whs-sd-atlas" - CITATION = ( - "Papp et al 2014, https://doi.org/10.1016/j.neuroimage.2014.04.001" - ) + CITATION = "Kleven et al 2023, https://doi.org/10.1038/s41592-023-02034-3" ORIENTATION = "lpi" RESOLUTION = (39, 39, 39) ROOT_ID = 10000 - ATLAS_FILE_URL = "https://www.nitrc.org/frs/download.php/12263/MBAT_WHS_SD_rat_atlas_v4_pack.zip" + REFERENCE_URL = "https://www.nitrc.org/frs/download.php/12263/MBAT_WHS_SD_rat_atlas_v4_pack.zip" + ANNOTATION_URL = "https://www.nitrc.org/frs/download.php/13400/MBAT_WHS_SD_rat_atlas_v4.01.zip//?i_agree=1&download_now=1" ATLAS_PACKAGER = ( - "Ben Kantor, Tel Aviv University, Israel, benkantor@mail.tau.ac.il" + "Harry Carey, University of Oslo, Norway, harry.carey@medisin.uio.no" ) assert len(ORIENTATION) == 3, ( @@ -217,7 +217,7 @@ def create_atlas(working_dir): ) assert len(RESOLUTION) == 3, "Resolution is not correct, Got " + RESOLUTION assert ( - ATLAS_FILE_URL + REFERENCE_URL ), "No download link provided for atlas in ATLAS_FILE_URL" # Generated atlas path: @@ -228,22 +228,30 @@ def create_atlas(working_dir): download_dir_path.mkdir(exist_ok=True) # Download atlas files from link provided - print("Downloading atlas from link: ", ATLAS_FILE_URL) + atlas_files_dir = download_atlas_files( download_dir_path, ATLAS_FILE_URL, __atlas__ + ) atlas_files_dir = atlas_files_dir / "MBAT_WHS_SD_rat_atlas_v4_pack/Data" + annotation_files_dir = download_atlas_files( + download_dir_path, ANNOTATION_URL, ATLAS_NAME + "_annotation" + ) + annotation_files_dir = ( + annotation_files_dir / "MBAT_WHS_SD_rat_atlas_v4.01/Data" + ) + # Parse structure metadata structures = parse_structures( - atlas_files_dir / "WHS_SD_rat_atlas_v4_labels.ilf" + annotation_files_dir / "WHS_SD_rat_atlas_v4.01_labels.ilf" ) # Load files - annotation_stack = imio.load_any( - atlas_files_dir / "WHS_SD_rat_atlas_v4.nii.gz", as_numpy=True + annotation_stack = load_any( + annotation_files_dir / "WHS_SD_rat_atlas_v4.01.nii.gz", as_numpy=True ).astype(np.int64) - reference_stack = imio.load_any( + reference_stack = load_any( atlas_files_dir / "WHS_SD_rat_T2star_v1.01.nii.gz", as_numpy=True ) diff --git a/brainglobe_atlasapi/bg_atlas.py b/brainglobe_atlasapi/bg_atlas.py index 13c14917..5aafdb22 100644 --- a/brainglobe_atlasapi/bg_atlas.py +++ b/brainglobe_atlasapi/bg_atlas.py @@ -8,7 +8,11 @@ from rich.console import Console from brainglobe_atlasapi import config, core, descriptors, utils -from brainglobe_atlasapi.utils import _rich_atlas_metadata +from brainglobe_atlasapi.utils import ( + _rich_atlas_metadata, + check_gin_status, + check_internet_connection, +) COMPRESSED_FILENAME = "atlas.tar.gz" @@ -80,13 +84,13 @@ def __init__( # Look for this atlas in local brainglobe folder: if self.local_full_name is None: if self.remote_version is None: - raise ValueError(f"{atlas_name} is not a valid atlas name!") + check_internet_connection(raise_error=True) + check_gin_status(raise_error=True) - rprint( - f"[magenta2]brainglobe_atlasapi: {self.atlas_name} " - "not found locally. Downloading...[magenta2]" - ) - self.download_extract_file() + # If internet and GIN are up, then the atlas name was invalid + raise ValueError(f"{atlas_name} is not a valid atlas name!") + else: + self.download_extract_file() # Instantiate after eventual download: super().__init__(self.brainglobe_dir / self.local_full_name) @@ -113,11 +117,11 @@ def remote_version(self): """ remote_url = self._remote_url_base.format("last_versions.conf") - # Grasp remote version if a connection is available: try: + # Grasp remote version versions_conf = utils.conf_from_url(remote_url) except requests.ConnectionError: - return + return None try: return _version_tuple_from_str( @@ -161,7 +165,8 @@ def remote_url(self): def download_extract_file(self): """Download and extract atlas from remote url.""" - utils.check_internet_connection() + check_internet_connection() + check_gin_status() # Get path to folder where data will be saved destination_path = self.interm_download_dir / COMPRESSED_FILENAME diff --git a/brainglobe_atlasapi/list_atlases.py b/brainglobe_atlasapi/list_atlases.py index 5924d7d5..9a5da303 100644 --- a/brainglobe_atlasapi/list_atlases.py +++ b/brainglobe_atlasapi/list_atlases.py @@ -51,12 +51,20 @@ def get_local_atlas_version(atlas_name): def get_all_atlases_lastversions(): - """Read from URL all available last versions""" - available_atlases = utils.conf_from_url( - descriptors.remote_url_base.format("last_versions.conf") - ) - available_atlases = dict(available_atlases["atlases"]) - return available_atlases + """Read from URL or local cache all available last versions""" + cache_path = config.get_brainglobe_dir() / "last_versions.conf" + + if utils.check_internet_connection( + raise_error=False + ) and utils.check_gin_status(raise_error=False): + available_atlases = utils.conf_from_url( + descriptors.remote_url_base.format("last_versions.conf") + ) + else: + print("Cannot fetch latest atlas versions from the server.") + available_atlases = utils.conf_from_file(cache_path) + + return dict(available_atlases["atlases"]) def get_atlases_lastversions(): diff --git a/brainglobe_atlasapi/utils.py b/brainglobe_atlasapi/utils.py index 591ab491..2ef6d0dc 100644 --- a/brainglobe_atlasapi/utils.py +++ b/brainglobe_atlasapi/utils.py @@ -2,6 +2,7 @@ import json import logging import re +from pathlib import Path from typing import Callable, Optional import requests @@ -19,6 +20,8 @@ from rich.table import Table from rich.text import Text +from brainglobe_atlasapi import config + logging.getLogger("urllib3").setLevel(logging.WARNING) @@ -119,15 +122,41 @@ def check_internet_connection( try: _ = requests.get(url, timeout=timeout) + return True - except requests.ConnectionError: + except requests.ConnectionError as e: if not raise_error: print("No internet connection available.") else: raise ConnectionError( "No internet connection, try again when you are " "connected to the internet." - ) + ) from e + + return False + + +def check_gin_status(timeout=5, raise_error=True): + """Check that the GIN server is up. + + timeout : int + timeout to wait for [in seconds] (Default value = 5). + raise_error : bool + if false, warning but no error. + """ + url = "https://gin.g-node.org/" + + try: + _ = requests.get(url, timeout=timeout) + + return True + except requests.ConnectionError as e: + error_message = "GIN server is down." + if not raise_error: + print(error_message) + else: + raise ConnectionError(error_message) from e + return False @@ -163,9 +192,9 @@ def retrieve_over_http( ) CHUNK_SIZE = 4096 - response = requests.get(url, stream=True) try: + response = requests.get(url, stream=True) with progress: tot = int(response.headers.get("content-length", 0)) @@ -188,9 +217,7 @@ def retrieve_over_http( fout.write(chunk) adv = len(chunk) completed += adv - progress.update( - task_id, completed=min(completed, tot), refresh=True - ) + progress.update(task_id, completed=min(completed, tot)) if fn_update: # update handler with completed and total bytes @@ -263,8 +290,8 @@ def get_download_size(url: str) -> int: raise IndexError("Improperly formatted URL") -def conf_from_url(url): - """Read conf file from an URL. +def conf_from_url(url) -> configparser.ConfigParser: + """Read conf file from an URL. And cache a copy in the brainglobe dir. Parameters ---------- url : str @@ -276,6 +303,38 @@ def conf_from_url(url): """ text = requests.get(url).text + config_obj = configparser.ConfigParser() + config_obj.read_string(text) + cache_path = config.get_brainglobe_dir() / "last_versions.conf" + + if not cache_path.parent.exists(): + cache_path.parent.mkdir(parents=True, exist_ok=True) + + # Cache the available atlases + with open(cache_path, "w") as f_out: + config_obj.write(f_out) + + return config_obj + + +def conf_from_file(file_path: Path) -> configparser.ConfigParser: + """Read conf file from a local file path. + Parameters + ---------- + file_path : Path + conf file path (obtained from config.get_brainglobe_dir()) + + Returns + ------- + conf object if file available + + """ + if not file_path.exists(): + raise FileNotFoundError("Last versions cache file not found.") + + with open(file_path, "r") as file: + text = file.read() + config = configparser.ConfigParser() config.read_string(text) diff --git a/pyproject.toml b/pyproject.toml index ec0e5083..a240b5ec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -105,6 +105,9 @@ fix = true [tool.ruff.lint] select = ["I", "E", "F"] +[tool.ruff.lint.per-file-ignores] +"*.ipynb" = ["E501"] + [tool.tox] legacy_tox_ini = """ [tox] diff --git a/tests/atlasapi/test_list_atlases.py b/tests/atlasapi/test_list_atlases.py index afa7b581..945357e6 100644 --- a/tests/atlasapi/test_list_atlases.py +++ b/tests/atlasapi/test_list_atlases.py @@ -1,4 +1,8 @@ +from unittest import mock + +from brainglobe_atlasapi import config from brainglobe_atlasapi.list_atlases import ( + get_all_atlases_lastversions, get_atlases_lastversions, get_downloaded_atlases, get_local_atlas_version, @@ -39,3 +43,71 @@ def test_lastversions(): def test_show_atlases(): # TODO add more valid testing than just look for errors when running: show_atlases(show_local_path=True) + + +def test_get_all_atlases_lastversions(): + last_versions = get_all_atlases_lastversions() + + assert "example_mouse_100um" in last_versions + assert "osten_mouse_50um" in last_versions + assert "allen_mouse_25um" in last_versions + + +def test_get_all_atlases_lastversions_offline(): + cleanup_cache = False + cache_path = config.get_brainglobe_dir() / "last_versions.conf" + + if not cache_path.exists(): + cache_path.touch() + cache_path.write_text( + """ + [atlases] + example_mouse_100um = 1.0 + osten_mouse_50um = 1.0 + allen_mouse_25um = 1.0 + """ + ) + cleanup_cache = True + + with mock.patch( + "brainglobe_atlasapi.utils.check_internet_connection" + ) as mock_check_internet_connection: + mock_check_internet_connection.return_value = False + last_versions = get_all_atlases_lastversions() + + assert "example_mouse_100um" in last_versions + assert "osten_mouse_50um" in last_versions + assert "allen_mouse_25um" in last_versions + + if cleanup_cache: + cache_path.unlink() + + +def test_get_all_atlases_lastversions_gin_down(): + cleanup_cache = False + cache_path = config.get_brainglobe_dir() / "last_versions.conf" + + if not cache_path.exists(): + cache_path.touch() + cache_path.write_text( + """ + [atlases] + example_mouse_100um = 1.0 + osten_mouse_50um = 1.0 + allen_mouse_25um = 1.0 + """ + ) + cleanup_cache = True + + with mock.patch( + "brainglobe_atlasapi.utils.check_gin_status" + ) as mock_check_internet_connection: + mock_check_internet_connection.return_value = False + last_versions = get_all_atlases_lastversions() + + assert "example_mouse_100um" in last_versions + assert "osten_mouse_50um" in last_versions + assert "allen_mouse_25um" in last_versions + + if cleanup_cache: + cache_path.unlink() diff --git a/tests/atlasapi/test_utils.py b/tests/atlasapi/test_utils.py index abd6e310..148ead82 100644 --- a/tests/atlasapi/test_utils.py +++ b/tests/atlasapi/test_utils.py @@ -81,3 +81,60 @@ def test_get_download_size_HTTPError(): with pytest.raises(HTTPError): utils.get_download_size(test_url) + + +def test_check_gin_status(): + # Test with requests.get returning a valid response + with mock.patch("requests.get", autospec=True) as mock_request: + mock_response = mock.Mock(spec=requests.Response) + mock_response.status_code = 200 + mock_request.return_value = mock_response + + assert utils.check_gin_status() + + +def test_check_gin_status_down(): + # Test with requests.get returning a 404 response + with mock.patch("requests.get", autospec=True) as mock_request: + mock_request.side_effect = requests.ConnectionError() + + with pytest.raises(ConnectionError) as e: + utils.check_gin_status() + assert "GIN server is down" == e.value + + +def test_check_gin_status_down_no_error(): + # Test with requests.get returning a 404 response + with mock.patch("requests.get", autospec=True) as mock_request: + mock_request.side_effect = requests.ConnectionError() + + assert not utils.check_gin_status(raise_error=False) + + +def test_conf_from_file(temp_path): + conf_path = temp_path / "conf.conf" + content = ( + "[atlases]\n" + "example_mouse_100um = 1.2\n" + "allen_mouse_10um = 1.2\n" + "allen_mouse_25um = 1.2" + ) + conf_path.write_text(content) + # Test with a valid file + conf = utils.conf_from_file(conf_path) + + assert dict(conf["atlases"]) == { + "example_mouse_100um": "1.2", + "allen_mouse_10um": "1.2", + "allen_mouse_25um": "1.2", + } + + +def test_conf_from_file_no_file(temp_path): + conf_path = temp_path / "conf.conf" + + # Test with a non-existing file + with pytest.raises(FileNotFoundError) as e: + utils.conf_from_file(conf_path) + + assert "Last versions cache file not found." == str(e) diff --git a/tutorials/Atlas API usage.ipynb b/tutorials/Atlas API usage.ipynb index 21bb8a1a..9c942c86 100644 --- a/tutorials/Atlas API usage.ipynb +++ b/tutorials/Atlas API usage.ipynb @@ -1,1715 +1,1718 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Introduction to the `BrainGlobeAtlas` class" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 0. Creating a `BrainGlobeAtlas` object and listing available options" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To instantiate a `BrainGlobeAtlas` object, we need to instantiate it with the atlas name. The first time we use it, a version of this atlas will be downloaded from the [remote GIN repository](http://gin.g-node.org/brainglobe/atlases) and stored on your local machine (by default, in .../Users/username/.brainglobe):" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "allen mouse atlas (res. 100um)\n", - "From: http://www.brain-map.org (Wang et al 2020, https://doi.org/10.1016/j.cell.2020.04.007 )\n" - ] - } - ], - "source": [ - "import numpy as np\n", - "from brainglobe_atlasapi import BrainGlobeAtlas\n", - "from pprint import pprint\n", - "\n", - "bg_atlas = BrainGlobeAtlas(\"allen_mouse_100um\", check_latest=False)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To know what atlases are available through BrainGlobe, we can use the `show_atlases` function (we need to be online):" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
                                                                                  \n",
-                            "                                                                                  \n",
-                            "                                Brainglobe Atlases                                \n",
-                            "╭──────────────────────────────────┬────────────┬───────────────┬────────────────╮\n",
-                            "│ Name                              Downloaded  Local version  Latest version │\n",
-                            "├──────────────────────────────────┼────────────┼───────────────┼────────────────┤\n",
-                            "│ whs_sd_rat_39um      │      1.0      │      1.0       │\n",
-                            "│ allen_mouse_25um      │      1.2      │      1.2       │\n",
-                            "│ allen_mouse_100um      │      1.2      │      1.2       │\n",
-                            "│ allen_mouse_50um      │      1.2      │      1.2       │\n",
-                            "│ example_mouse_100um------      │      1.2       │\n",
-                            "│ allen_mouse_10um------      │      1.2       │\n",
-                            "│ mpin_zfish_1um------      │      1.0       │\n",
-                            "│ allen_human_500um------      │      0.1       │\n",
-                            "│ kim_mouse_10um------      │      1.0       │\n",
-                            "│ kim_mouse_25um------      │      1.0       │\n",
-                            "│ kim_mouse_50um------      │      1.0       │\n",
-                            "│ kim_mouse_100um------      │      1.0       │\n",
-                            "│ osten_mouse_10um------      │      1.1       │\n",
-                            "│ osten_mouse_25um------      │      1.1       │\n",
-                            "│ osten_mouse_50um------      │      1.1       │\n",
-                            "│ osten_mouse_100um------      │      1.1       │\n",
-                            "│ allen_cord_20um------      │      1.0       │\n",
-                            "│ azba_zfish_4um------      │      1.1       │\n",
-                            "│ perens_lsfm_mouse_20um------      │      1.0       │\n",
-                            "│ admba_3d_e11_5_mouse_16um------      │      1.0       │\n",
-                            "│ admba_3d_e13_5_mouse_16um------      │      1.0       │\n",
-                            "│ admba_3d_e15_5_mouse_16um------      │      1.0       │\n",
-                            "│ admba_3d_e18_5_mouse_16um------      │      1.0       │\n",
-                            "│ admba_3d_p4_mouse_16.752um------      │      1.0       │\n",
-                            "│ admba_3d_p14_mouse_16.752um------      │      1.0       │\n",
-                            "│ admba_3d_p28_mouse_16.752um------      │      1.0       │\n",
-                            "│ admba_3d_p56_mouse_25um------      │      1.0       │\n",
-                            "╰──────────────────────────────────┴────────────┴───────────────┴────────────────╯\n",
-                            "
\n" - ], - "text/plain": [ - "\u001b[3m \u001b[0m\n", - "\u001b[3m \u001b[0m\n", - "\u001b[3m Brainglobe Atlases \u001b[0m\n", - "╭──────────────────────────────────┬────────────┬───────────────┬────────────────╮\n", - "│\u001b[1;32m \u001b[0m\u001b[1;32mName \u001b[0m\u001b[1;32m \u001b[0m│\u001b[1;32m \u001b[0m\u001b[1;32mDownloaded\u001b[0m\u001b[1;32m \u001b[0m│\u001b[1;32m \u001b[0m\u001b[1;32mLocal version\u001b[0m\u001b[1;32m \u001b[0m│\u001b[1;32m \u001b[0m\u001b[1;32mLatest version\u001b[0m\u001b[1;32m \u001b[0m│\n", - "├──────────────────────────────────┼────────────┼───────────────┼────────────────┤\n", - "│ \u001b[1mwhs_sd_rat_39um\u001b[0m │ \u001b[32m✔\u001b[0m │ 1.0 │ 1.0 │\n", - "│ \u001b[1mallen_mouse_25um\u001b[0m │ \u001b[32m✔\u001b[0m │ 1.2 │ 1.2 │\n", - "│ \u001b[1mallen_mouse_100um\u001b[0m │ \u001b[32m✔\u001b[0m │ 1.2 │ 1.2 │\n", - "│ \u001b[1mallen_mouse_50um\u001b[0m │ \u001b[32m✔\u001b[0m │ 1.2 │ 1.2 │\n", - "│ \u001b[1mexample_mouse_100um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.2 │\n", - "│ \u001b[1mallen_mouse_10um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.2 │\n", - "│ \u001b[1mmpin_zfish_1um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", - "│ \u001b[1mallen_human_500um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 0.1 │\n", - "│ \u001b[1mkim_mouse_10um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", - "│ \u001b[1mkim_mouse_25um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", - "│ \u001b[1mkim_mouse_50um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", - "│ \u001b[1mkim_mouse_100um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", - "│ \u001b[1mosten_mouse_10um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.1 │\n", - "│ \u001b[1mosten_mouse_25um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.1 │\n", - "│ \u001b[1mosten_mouse_50um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.1 │\n", - "│ \u001b[1mosten_mouse_100um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.1 │\n", - "│ \u001b[1mallen_cord_20um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", - "│ \u001b[1mazba_zfish_4um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.1 │\n", - "│ \u001b[1mperens_lsfm_mouse_20um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", - "│ \u001b[1madmba_3d_e11_5_mouse_16um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", - "│ \u001b[1madmba_3d_e13_5_mouse_16um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", - "│ \u001b[1madmba_3d_e15_5_mouse_16um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", - "│ \u001b[1madmba_3d_e18_5_mouse_16um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", - "│ \u001b[1madmba_3d_p4_mouse_16.752um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", - "│ \u001b[1madmba_3d_p14_mouse_16.752um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", - "│ \u001b[1madmba_3d_p28_mouse_16.752um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", - "│ \u001b[1madmba_3d_p56_mouse_25um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", - "╰──────────────────────────────────┴────────────┴───────────────┴────────────────╯\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from brainglobe_atlasapi import show_atlases\n", - "show_atlases()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 1. Using a `BrainGlobe` atlas" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A BrainGlobe atlas is a convenient API for interacting with an anatomical atlas. BrainGlobe atlases contain:\n", - " * Metadata\n", - " * The reference anatomical stack used for the registration itself\n", - " * Region annotation stack (the segmented atlas image that occupies the same space as the reference stack)\n", - " * Hemisphere annotation stack which denotes left and right\n", - " * Description of the region hierarchy\n", - " * Meshes for the regions" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 1.0 Metadata" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "All atlases have a standard set of medatata describing their source, species, resolution, etc:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'name': 'allen_mouse',\n", - " 'citation': 'Wang et al 2020, https://doi.org/10.1016/j.cell.2020.04.007',\n", - " 'atlas_link': 'http://www.brain-map.org',\n", - " 'species': 'Mus musculus',\n", - " 'symmetric': True,\n", - " 'resolution': [100.0, 100.0, 100.0],\n", - " 'orientation': 'asr',\n", - " 'version': '1.2',\n", - " 'shape': [132, 80, 114],\n", - " 'trasform_to_bg': [[1.0, 0.0, 0.0, 0.0],\n", - " [0.0, 1.0, 0.0, 0.0],\n", - " [0.0, 0.0, 1.0, 0.0],\n", - " [0.0, 0.0, 0.0, 1.0]],\n", - " 'additional_references': []}" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "bg_atlas.metadata" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 1.1 Reference, annotation and hemispheres stack" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "from matplotlib import pyplot as plt" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Reference stack:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "space = bg_atlas.space\n", - "stack = bg_atlas.reference\n", - "\n", - "f, axs = plt.subplots(1,3, figsize=(12, 3))\n", - "for i, (plane, labels) in enumerate(zip(space.sections, space.axis_labels)):\n", - " mid_index = stack.shape[i]//2\n", - " axs[i].imshow(np.moveaxis(stack,i,0)[mid_index,:,:], cmap=\"gray\",clim=(0,250))\n", - " axs[i].set_title(f\"{plane.capitalize()} view\")\n", - " axs[i].set_ylabel(labels[0])\n", - " axs[i].set_xlabel(labels[1])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Annotation stack:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "space = bg_atlas.space\n", - "stack = bg_atlas.annotation\n", - "\n", - "f, axs = plt.subplots(1,3, figsize=(12, 3))\n", - "for i, (plane, labels) in enumerate(zip(space.sections, space.axis_labels)):\n", - " mid_index = stack.shape[i]//2\n", - " axs[i].imshow(np.moveaxis(stack,i,0)[mid_index,:,:], cmap=\"gray\",clim=(0,1250))\n", - " axs[i].set_title(f\"{plane.capitalize()} view\")\n", - " axs[i].set_ylabel(labels[0])\n", - " axs[i].set_xlabel(labels[1])\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Hemispheres stack:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "space = bg_atlas.space\n", - "stack = bg_atlas.hemispheres\n", - "\n", - "f, axs = plt.subplots(1,3, figsize=(12, 3))\n", - "for i, (plane, labels) in enumerate(zip(space.sections, space.axis_labels)):\n", - " axs[i].imshow(stack.max(i), cmap=\"gray\")\n", - " axs[i].set_title(f\"{plane.capitalize()} view\")\n", - " axs[i].set_ylabel(labels[0])\n", - " axs[i].set_xlabel(labels[1])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 1.2 Regions hierarchy" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The atlas comes with a description of the hierarchy of brain structures. To have an overview:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "root (997)\n", - "├── VS (73)\n", - "│ ├── AQ (140)\n", - "│ ├── V3 (129)\n", - "│ ├── V4 (145)\n", - "│ │ └── V4r (153)\n", - "│ ├── VL (81)\n", - "│ │ ├── SEZ (98)\n", - "│ │ └── chpl (108)\n", - "│ └── c (164)\n", - "├── fiber tracts (1009)\n", - "│ ├── cbf (960)\n", - "│ │ ├── arb (728)\n", - "│ │ ├── cbc (744)\n", - "│ │ └── cbp (752)\n", - "│ │ ├── icp (1123)\n", - "│ │ │ └── sctd (553)\n", - "│ │ ├── mcp (78)\n", - "│ │ └── scp (326)\n", - "│ │ ├── dscp (812)\n", - "│ │ ├── sctv (866)\n", - "│ │ └── uf (850)\n", - "│ ├── cm (967)\n", - "│ │ ├── IIIn (832)\n", - "│ │ │ ├── mlf (62)\n", - "│ │ │ └── pc (158)\n", - "│ │ ├── IIn (848)\n", - "│ │ │ ├── bsc (916)\n", - "│ │ │ ├── csc (336)\n", - "│ │ │ ├── och (117)\n", - "│ │ │ └── opt (125)\n", - "│ │ ├── IVn (911)\n", - "│ │ ├── In (840)\n", - "│ │ │ ├── aco (900)\n", - "│ │ │ ├── lotg (21)\n", - "│ │ │ │ ├── lot (665)\n", - "│ │ │ │ └── lotd (538)\n", - "│ │ │ └── onl (1016)\n", - "│ │ ├── VIIIn (933)\n", - "│ │ │ ├── cVIIIn (948)\n", - "│ │ │ │ ├── bic (482)\n", - "│ │ │ │ ├── cic (633)\n", - "│ │ │ │ ├── das (506)\n", - "│ │ │ │ ├── ll (658)\n", - "│ │ │ │ └── tb (841)\n", - "│ │ │ └── vVIIIn (413)\n", - "│ │ ├── VIIn (798)\n", - "│ │ │ └── gVIIn (1116)\n", - "│ │ ├── Vn (901)\n", - "│ │ │ ├── moV (93)\n", - "│ │ │ └── sV (229)\n", - "│ │ │ └── sptV (794)\n", - "│ │ ├── Xn (917)\n", - "│ │ │ └── ts (237)\n", - "│ │ ├── drt (792)\n", - "│ │ │ └── cett (932)\n", - "│ │ │ ├── dc (514)\n", - "│ │ │ │ └── cuf (380)\n", - "│ │ │ └── ml (697)\n", - "│ │ └── von (949)\n", - "│ ├── eps (1000)\n", - "│ │ ├── epsc (760)\n", - "│ │ │ └── nst (102)\n", - "│ │ ├── rust (863)\n", - "│ │ │ └── vtd (397)\n", - "│ │ └── tsp (877)\n", - "│ │ ├── dtd (1060)\n", - "│ │ ├── tspc (1043)\n", - "│ │ └── tspd (1051)\n", - "│ ├── lfbs (983)\n", - "│ │ ├── cc (776)\n", - "│ │ │ ├── ccb (484682516)\n", - "│ │ │ ├── ccg (1108)\n", - "│ │ │ ├── ccs (986)\n", - "│ │ │ ├── ee (964)\n", - "│ │ │ ├── fa (956)\n", - "│ │ │ │ └── ec (579)\n", - "│ │ │ └── fp (971)\n", - "│ │ ├── cst (784)\n", - "│ │ │ ├── cpd (924)\n", - "│ │ │ ├── int (6)\n", - "│ │ │ ├── py (190)\n", - "│ │ │ └── pyd (198)\n", - "│ │ └── lfbst (896)\n", - "│ │ ├── ar (484682524)\n", - "│ │ ├── em (1092)\n", - "│ │ └── or (484682520)\n", - "│ ├── mfbs (991)\n", - "│ │ ├── mfbc (768)\n", - "│ │ │ ├── act (908)\n", - "│ │ │ ├── amc (884)\n", - "│ │ │ ├── cing (940)\n", - "│ │ │ ├── fxs (1099)\n", - "│ │ │ │ ├── alv (466)\n", - "│ │ │ │ ├── df (530)\n", - "│ │ │ │ ├── fi (603)\n", - "│ │ │ │ ├── fxpo (737)\n", - "│ │ │ │ │ ├── fx (436)\n", - "│ │ │ │ │ └── mct (428)\n", - "│ │ │ │ └── hc (618)\n", - "│ │ │ │ ├── dhc (443)\n", - "│ │ │ │ └── vhc (449)\n", - "│ │ │ └── st (301)\n", - "│ │ │ └── stc (484682528)\n", - "│ │ └── mfsbshy (824)\n", - "│ │ ├── mfb (54)\n", - "│ │ ├── mfbse (1083)\n", - "│ │ │ ├── fr (595)\n", - "│ │ │ ├── hbc (611)\n", - "│ │ │ └── sm (802)\n", - "│ │ ├── mfbsma (46)\n", - "│ │ │ ├── mp (673)\n", - "│ │ │ ├── mtg (681)\n", - "│ │ │ ├── mtt (690)\n", - "│ │ │ └── pm (753)\n", - "│ │ └── sup (349)\n", - "│ └── scwm (484682512)\n", - "└── grey (8)\n", - " ├── BS (343)\n", - " │ ├── HB (1065)\n", - " │ │ ├── MY (354)\n", - " │ │ │ ├── MY-mot (370)\n", - " │ │ │ │ ├── ACVII (576)\n", - " │ │ │ │ ├── AMB (135)\n", - " │ │ │ │ │ ├── AMBd (939)\n", - " │ │ │ │ │ └── AMBv (143)\n", - " │ │ │ │ ├── DMX (839)\n", - " │ │ │ │ ├── GRN (1048)\n", - " │ │ │ │ ├── ICB (372)\n", - " │ │ │ │ ├── IO (83)\n", - " │ │ │ │ ├── IRN (136)\n", - " │ │ │ │ ├── ISN (106)\n", - " │ │ │ │ ├── LIN (203)\n", - " │ │ │ │ ├── LRN (235)\n", - " │ │ │ │ │ ├── LRNm (955)\n", - " │ │ │ │ │ └── LRNp (963)\n", - " │ │ │ │ ├── MARN (307)\n", - " │ │ │ │ ├── MDRN (395)\n", - " │ │ │ │ │ ├── MDRNd (1098)\n", - " │ │ │ │ │ └── MDRNv (1107)\n", - " │ │ │ │ ├── PARN (852)\n", - " │ │ │ │ ├── PAS (859)\n", - " │ │ │ │ ├── PGRN (938)\n", - " │ │ │ │ │ ├── PGRNd (970)\n", - " │ │ │ │ │ └── PGRNl (978)\n", - " │ │ │ │ ├── PHY (154)\n", - " │ │ │ │ │ ├── NR (177)\n", - " │ │ │ │ │ └── PRP (169)\n", - " │ │ │ │ ├── PPY (1069)\n", - " │ │ │ │ ├── VI (653)\n", - " │ │ │ │ ├── VII (661)\n", - " │ │ │ │ ├── VNC (701)\n", - " │ │ │ │ │ ├── LAV (209)\n", - " │ │ │ │ │ ├── MV (202)\n", - " │ │ │ │ │ ├── SPIV (225)\n", - " │ │ │ │ │ └── SUV (217)\n", - " │ │ │ │ ├── XII (773)\n", - " │ │ │ │ ├── x (765)\n", - " │ │ │ │ └── y (781)\n", - " │ │ │ ├── MY-sat (379)\n", - " │ │ │ │ ├── RM (206)\n", - " │ │ │ │ ├── RO (222)\n", - " │ │ │ │ └── RPA (230)\n", - " │ │ │ └── MY-sen (386)\n", - " │ │ │ ├── AP (207)\n", - " │ │ │ ├── CN (607)\n", - " │ │ │ │ ├── DCO (96)\n", - " │ │ │ │ └── VCO (101)\n", - " │ │ │ ├── DCN (720)\n", - " │ │ │ │ ├── CU (711)\n", - " │ │ │ │ └── GR (1039)\n", - " │ │ │ ├── ECU (903)\n", - " │ │ │ ├── NTB (642)\n", - " │ │ │ ├── NTS (651)\n", - " │ │ │ ├── Pa5 (589508451)\n", - " │ │ │ ├── SPVC (429)\n", - " │ │ │ ├── SPVI (437)\n", - " │ │ │ └── SPVO (445)\n", - " │ │ └── P (771)\n", - " │ │ ├── P-mot (987)\n", - " │ │ │ ├── Acs5 (549009219)\n", - " │ │ │ ├── B (280)\n", - " │ │ │ ├── DTN (880)\n", - " │ │ │ ├── I5 (549009227)\n", - " │ │ │ ├── P5 (549009215)\n", - " │ │ │ ├── PC5 (549009223)\n", - " │ │ │ ├── PCG (898)\n", - " │ │ │ ├── PDTg (599626927)\n", - " │ │ │ ├── PG (931)\n", - " │ │ │ ├── PRNc (1093)\n", - " │ │ │ ├── SG (318)\n", - " │ │ │ ├── SUT (534)\n", - " │ │ │ ├── TRN (574)\n", - " │ │ │ └── V (621)\n", - " │ │ ├── P-sat (1117)\n", - " │ │ │ ├── CS (679)\n", - " │ │ │ ├── LC (147)\n", - " │ │ │ ├── LDT (162)\n", - " │ │ │ ├── NI (604)\n", - " │ │ │ ├── PRNr (146)\n", - " │ │ │ ├── RPO (238)\n", - " │ │ │ ├── SLC (350)\n", - " │ │ │ └── SLD (358)\n", - " │ │ └── P-sen (1132)\n", - " │ │ ├── NLL (612)\n", - " │ │ ├── PB (867)\n", - " │ │ │ └── KF (123)\n", - " │ │ ├── PSV (7)\n", - " │ │ └── SOC (398)\n", - " │ │ ├── POR (122)\n", - " │ │ ├── SOCl (114)\n", - " │ │ └── SOCm (105)\n", - " │ ├── IB (1129)\n", - " │ │ ├── HY (1097)\n", - " │ │ │ ├── LZ (290)\n", - " │ │ │ │ ├── LHA (194)\n", - " │ │ │ │ ├── LPO (226)\n", - " │ │ │ │ ├── PST (356)\n", - " │ │ │ │ ├── PSTN (364)\n", - " │ │ │ │ ├── PeF (576073704)\n", - " │ │ │ │ ├── RCH (173)\n", - " │ │ │ │ ├── STN (470)\n", - " │ │ │ │ ├── TU (614)\n", - " │ │ │ │ └── ZI (797)\n", - " │ │ │ │ └── FF (804)\n", - " │ │ │ ├── ME (10671)\n", - " │ │ │ ├── MEZ (467)\n", - " │ │ │ │ ├── AHN (88)\n", - " │ │ │ │ ├── MBO (331)\n", - " │ │ │ │ │ ├── LM (210)\n", - " │ │ │ │ │ ├── MM (491)\n", - " │ │ │ │ │ │ ├── MMd (606826659)\n", - " │ │ │ │ │ │ ├── MMl (606826647)\n", - " │ │ │ │ │ │ ├── MMm (606826651)\n", - " │ │ │ │ │ │ ├── MMme (732)\n", - " │ │ │ │ │ │ └── MMp (606826655)\n", - " │ │ │ │ │ ├── SUM (525)\n", - " │ │ │ │ │ └── TM (557)\n", - " │ │ │ │ │ ├── TMd (1126)\n", - " │ │ │ │ │ └── TMv (1)\n", - " │ │ │ │ ├── MPN (515)\n", - " │ │ │ │ ├── PH (946)\n", - " │ │ │ │ ├── PMd (980)\n", - " │ │ │ │ ├── PMv (1004)\n", - " │ │ │ │ ├── PVHd (63)\n", - " │ │ │ │ └── VMH (693)\n", - " │ │ │ ├── PVR (141)\n", - " │ │ │ │ ├── ADP (72)\n", - " │ │ │ │ ├── AVP (263)\n", - " │ │ │ │ ├── AVPV (272)\n", - " │ │ │ │ ├── DMH (830)\n", - " │ │ │ │ ├── MEPO (452)\n", - " │ │ │ │ ├── MPO (523)\n", - " │ │ │ │ ├── OV (763)\n", - " │ │ │ │ ├── PD (914)\n", - " │ │ │ │ ├── PS (1109)\n", - " │ │ │ │ ├── PVp (126)\n", - " │ │ │ │ ├── PVpo (133)\n", - " │ │ │ │ ├── SBPV (347)\n", - " │ │ │ │ ├── SCH (286)\n", - " │ │ │ │ ├── SFO (338)\n", - " │ │ │ │ ├── VLPO (689)\n", - " │ │ │ │ └── VMPO (576073699)\n", - " │ │ │ └── PVZ (157)\n", - " │ │ │ ├── ARH (223)\n", - " │ │ │ ├── ASO (332)\n", - " │ │ │ ├── PVH (38)\n", - " │ │ │ ├── PVa (30)\n", - " │ │ │ ├── PVi (118)\n", - " │ │ │ └── SO (390)\n", - " │ │ └── TH (549)\n", - " │ │ ├── DORpm (856)\n", - " │ │ │ ├── ATN (239)\n", - " │ │ │ │ ├── AD (64)\n", - " │ │ │ │ ├── AM (127)\n", - " │ │ │ │ │ ├── AMd (1096)\n", - " │ │ │ │ │ └── AMv (1104)\n", - " │ │ │ │ ├── AV (255)\n", - " │ │ │ │ ├── IAD (1113)\n", - " │ │ │ │ ├── IAM (1120)\n", - " │ │ │ │ └── LD (155)\n", - " │ │ │ ├── EPI (958)\n", - " │ │ │ │ ├── LH (186)\n", - " │ │ │ │ └── MH (483)\n", - " │ │ │ ├── GENv (1014)\n", - " │ │ │ │ ├── IGL (27)\n", - " │ │ │ │ ├── IntG (563807439)\n", - " │ │ │ │ ├── LGv (178)\n", - " │ │ │ │ └── SubG (321)\n", - " │ │ │ ├── ILM (51)\n", - " │ │ │ │ ├── CL (575)\n", - " │ │ │ │ ├── CM (599)\n", - " │ │ │ │ ├── PCN (907)\n", - " │ │ │ │ ├── PF (930)\n", - " │ │ │ │ ├── PIL (560581563)\n", - " │ │ │ │ └── RH (189)\n", - " │ │ │ ├── LAT (138)\n", - " │ │ │ │ ├── Eth (560581551)\n", - " │ │ │ │ ├── LP (218)\n", - " │ │ │ │ ├── PO (1020)\n", - " │ │ │ │ ├── POL (1029)\n", - " │ │ │ │ └── SGN (325)\n", - " │ │ │ ├── MED (444)\n", - " │ │ │ │ ├── IMD (59)\n", - " │ │ │ │ ├── MD (362)\n", - " │ │ │ │ ├── PR (1077)\n", - " │ │ │ │ └── SMT (366)\n", - " │ │ │ ├── MTN (571)\n", - " │ │ │ │ ├── PT (15)\n", - " │ │ │ │ ├── PVT (149)\n", - " │ │ │ │ ├── RE (181)\n", - " │ │ │ │ └── Xi (560581559)\n", - " │ │ │ └── RT (262)\n", - " │ │ └── DORsm (864)\n", - " │ │ ├── GENd (1008)\n", - " │ │ │ ├── LGd (170)\n", - " │ │ │ │ ├── LGd-co (496345668)\n", - " │ │ │ │ ├── LGd-ip (496345672)\n", - " │ │ │ │ └── LGd-sh (496345664)\n", - " │ │ │ └── MG (475)\n", - " │ │ │ ├── MGd (1072)\n", - " │ │ │ ├── MGm (1088)\n", - " │ │ │ └── MGv (1079)\n", - " │ │ ├── PP (1044)\n", - " │ │ ├── SPA (609)\n", - " │ │ ├── SPF (406)\n", - " │ │ │ ├── SPFm (414)\n", - " │ │ │ └── SPFp (422)\n", - " │ │ └── VENT (637)\n", - " │ │ ├── PoT (563807435)\n", - " │ │ ├── VAL (629)\n", - " │ │ ├── VM (685)\n", - " │ │ └── VP (709)\n", - " │ │ ├── VPL (718)\n", - " │ │ ├── VPLpc (725)\n", - " │ │ ├── VPM (733)\n", - " │ │ └── VPMpc (741)\n", - " │ └── MB (313)\n", - " │ ├── MBmot (323)\n", - " │ │ ├── AT (231)\n", - " │ │ ├── CUN (616)\n", - " │ │ ├── DT (75)\n", - " │ │ ├── EW (975)\n", - " │ │ ├── III (35)\n", - " │ │ ├── IV (115)\n", - " │ │ ├── LT (66)\n", - " │ │ ├── MA3 (549009211)\n", - " │ │ ├── MRN (128)\n", - " │ │ ├── MT (58)\n", - " │ │ ├── PAG (795)\n", - " │ │ │ ├── INC (67)\n", - " │ │ │ ├── ND (587)\n", - " │ │ │ ├── PRC (50)\n", - " │ │ │ └── Su3 (614454277)\n", - " │ │ ├── PN (607344830)\n", - " │ │ ├── PRT (1100)\n", - " │ │ │ ├── APN (215)\n", - " │ │ │ ├── MPT (531)\n", - " │ │ │ ├── NOT (628)\n", - " │ │ │ ├── NPC (634)\n", - " │ │ │ ├── OP (706)\n", - " │ │ │ ├── PPT (1061)\n", - " │ │ │ └── RPF (549009203)\n", - " │ │ ├── Pa4 (606826663)\n", - " │ │ ├── RN (214)\n", - " │ │ ├── RR (246)\n", - " │ │ ├── SCm (294)\n", - " │ │ │ ├── SCdg (26)\n", - " │ │ │ ├── SCdw (42)\n", - " │ │ │ ├── SCig (10)\n", - " │ │ │ └── SCiw (17)\n", - " │ │ ├── SNr (381)\n", - " │ │ ├── VTA (749)\n", - " │ │ └── VTN (757)\n", - " │ ├── MBsen (339)\n", - " │ │ ├── IC (4)\n", - " │ │ │ ├── ICc (811)\n", - " │ │ │ ├── ICd (820)\n", - " │ │ │ └── ICe (828)\n", - " │ │ ├── MEV (460)\n", - " │ │ ├── NB (580)\n", - " │ │ ├── PBG (874)\n", - " │ │ ├── SAG (271)\n", - " │ │ ├── SCO (599626923)\n", - " │ │ └── SCs (302)\n", - " │ │ ├── SCop (851)\n", - " │ │ ├── SCsg (842)\n", - " │ │ └── SCzo (834)\n", - " │ └── MBsta (348)\n", - " │ ├── PPN (1052)\n", - " │ ├── RAmb (165)\n", - " │ │ ├── CLI (591)\n", - " │ │ ├── DR (872)\n", - " │ │ ├── IF (12)\n", - " │ │ ├── IPN (100)\n", - " │ │ │ ├── IPA (607344842)\n", - " │ │ │ ├── IPC (607344838)\n", - " │ │ │ ├── IPDL (607344858)\n", - " │ │ │ ├── IPDM (607344854)\n", - " │ │ │ ├── IPI (607344850)\n", - " │ │ │ ├── IPL (607344846)\n", - " │ │ │ ├── IPR (607344834)\n", - " │ │ │ └── IPRL (607344862)\n", - " │ │ └── RL (197)\n", - " │ └── SNc (374)\n", - " ├── CB (512)\n", - " │ ├── CBN (519)\n", - " │ │ ├── DN (846)\n", - " │ │ ├── FN (989)\n", - " │ │ ├── IP (91)\n", - " │ │ └── VeCB (589508455)\n", - " │ └── CBX (528)\n", - " │ ├── HEM (1073)\n", - " │ │ ├── AN (1017)\n", - " │ │ │ ├── ANcr1 (1056)\n", - " │ │ │ └── ANcr2 (1064)\n", - " │ │ ├── COPY (1033)\n", - " │ │ ├── FL (1049)\n", - " │ │ ├── PFL (1041)\n", - " │ │ ├── PRM (1025)\n", - " │ │ └── SIM (1007)\n", - " │ └── VERM (645)\n", - " │ ├── CENT (920)\n", - " │ │ ├── CENT2 (976)\n", - " │ │ └── CENT3 (984)\n", - " │ ├── CUL (928)\n", - " │ │ └── CUL4, 5 (1091)\n", - " │ ├── DEC (936)\n", - " │ ├── FOTU (944)\n", - " │ ├── LING (912)\n", - " │ ├── NOD (968)\n", - " │ ├── PYR (951)\n", - " │ └── UVU (957)\n", - " └── CH (567)\n", - " ├── CNU (623)\n", - " │ ├── PAL (803)\n", - " │ │ ├── PALc (809)\n", - " │ │ │ ├── BAC (287)\n", - " │ │ │ └── BST (351)\n", - " │ │ ├── PALd (818)\n", - " │ │ │ ├── GPe (1022)\n", - " │ │ │ └── GPi (1031)\n", - " │ │ ├── PALm (826)\n", - " │ │ │ ├── MSC (904)\n", - " │ │ │ │ ├── MS (564)\n", - " │ │ │ │ └── NDB (596)\n", - " │ │ │ └── TRS (581)\n", - " │ │ └── PALv (835)\n", - " │ │ ├── MA (298)\n", - " │ │ └── SI (342)\n", - " │ └── STR (477)\n", - " │ ├── LSX (275)\n", - " │ │ ├── LS (242)\n", - " │ │ │ ├── LSc (250)\n", - " │ │ │ ├── LSr (258)\n", - " │ │ │ └── LSv (266)\n", - " │ │ ├── SF (310)\n", - " │ │ └── SH (333)\n", - " │ ├── STRd (485)\n", - " │ │ └── CP (672)\n", - " │ ├── STRv (493)\n", - " │ │ ├── ACB (56)\n", - " │ │ ├── FS (998)\n", - " │ │ └── OT (754)\n", - " │ └── sAMY (278)\n", - " │ ├── AAA (23)\n", - " │ ├── BA (292)\n", - " │ ├── CEA (536)\n", - " │ │ ├── CEAc (544)\n", - " │ │ ├── CEAl (551)\n", - " │ │ └── CEAm (559)\n", - " │ ├── IA (1105)\n", - " │ └── MEA (403)\n", - " └── CTX (688)\n", - " ├── CTXpl (695)\n", - " │ ├── HPF (1089)\n", - " │ │ ├── HIP (1080)\n", - " │ │ │ ├── CA (375)\n", - " │ │ │ │ ├── CA1 (382)\n", - " │ │ │ │ ├── CA2 (423)\n", - " │ │ │ │ └── CA3 (463)\n", - " │ │ │ ├── DG (726)\n", - " │ │ │ │ ├── DG-mo (10703)\n", - " │ │ │ │ ├── DG-po (10704)\n", - " │ │ │ │ └── DG-sg (632)\n", - " │ │ │ ├── FC (982)\n", - " │ │ │ └── IG (19)\n", - " │ │ └── RHP (822)\n", - " │ │ ├── APr (484682508)\n", - " │ │ ├── ENT (909)\n", - " │ │ │ ├── ENTl (918)\n", - " │ │ │ │ ├── ENTl1 (1121)\n", - " │ │ │ │ ├── ENTl2 (20)\n", - " │ │ │ │ ├── ENTl3 (52)\n", - " │ │ │ │ ├── ENTl5 (139)\n", - " │ │ │ │ └── ENTl6a (28)\n", - " │ │ │ └── ENTm (926)\n", - " │ │ │ ├── ENTm1 (526)\n", - " │ │ │ ├── ENTm2 (543)\n", - " │ │ │ ├── ENTm3 (664)\n", - " │ │ │ ├── ENTm5 (727)\n", - " │ │ │ └── ENTm6 (743)\n", - " │ │ ├── HATA (589508447)\n", - " │ │ ├── PAR (843)\n", - " │ │ ├── POST (1037)\n", - " │ │ ├── PRE (1084)\n", - " │ │ ├── ProS (484682470)\n", - " │ │ └── SUB (502)\n", - " │ ├── Isocortex (315)\n", - " │ │ ├── ACA (31)\n", - " │ │ │ ├── ACAd (39)\n", - " │ │ │ │ ├── ACAd1 (935)\n", - " │ │ │ │ ├── ACAd2/3 (211)\n", - " │ │ │ │ ├── ACAd5 (1015)\n", - " │ │ │ │ ├── ACAd6a (919)\n", - " │ │ │ │ └── ACAd6b (927)\n", - " │ │ │ └── ACAv (48)\n", - " │ │ │ ├── ACAv1 (588)\n", - " │ │ │ ├── ACAv2/3 (296)\n", - " │ │ │ ├── ACAv5 (772)\n", - " │ │ │ ├── ACAv6a (810)\n", - " │ │ │ └── ACAv6b (819)\n", - " │ │ ├── AI (95)\n", - " │ │ │ ├── AId (104)\n", - " │ │ │ │ ├── AId1 (996)\n", - " │ │ │ │ ├── AId2/3 (328)\n", - " │ │ │ │ ├── AId5 (1101)\n", - " │ │ │ │ ├── AId6a (783)\n", - " │ │ │ │ └── AId6b (831)\n", - " │ │ │ ├── AIp (111)\n", - " │ │ │ │ ├── AIp1 (120)\n", - " │ │ │ │ ├── AIp2/3 (163)\n", - " │ │ │ │ ├── AIp5 (344)\n", - " │ │ │ │ ├── AIp6a (314)\n", - " │ │ │ │ └── AIp6b (355)\n", - " │ │ │ └── AIv (119)\n", - " │ │ │ ├── AIv1 (704)\n", - " │ │ │ ├── AIv2/3 (694)\n", - " │ │ │ ├── AIv5 (800)\n", - " │ │ │ ├── AIv6a (675)\n", - " │ │ │ └── AIv6b (699)\n", - " │ │ ├── AUD (247)\n", - " │ │ │ ├── AUDd (1011)\n", - " │ │ │ │ ├── AUDd1 (527)\n", - " │ │ │ │ ├── AUDd2/3 (600)\n", - " │ │ │ │ ├── AUDd4 (678)\n", - " │ │ │ │ ├── AUDd5 (252)\n", - " │ │ │ │ ├── AUDd6a (156)\n", - " │ │ │ │ └── AUDd6b (243)\n", - " │ │ │ ├── AUDp (1002)\n", - " │ │ │ │ ├── AUDp1 (735)\n", - " │ │ │ │ ├── AUDp2/3 (251)\n", - " │ │ │ │ ├── AUDp4 (816)\n", - " │ │ │ │ ├── AUDp5 (847)\n", - " │ │ │ │ ├── AUDp6a (954)\n", - " │ │ │ │ └── AUDp6b (1005)\n", - " │ │ │ ├── AUDpo (1027)\n", - " │ │ │ │ ├── AUDpo1 (696)\n", - " │ │ │ │ ├── AUDpo2/3 (643)\n", - " │ │ │ │ ├── AUDpo4 (759)\n", - " │ │ │ │ ├── AUDpo5 (791)\n", - " │ │ │ │ ├── AUDpo6a (249)\n", - " │ │ │ │ └── AUDpo6b (456)\n", - " │ │ │ └── AUDv (1018)\n", - " │ │ │ ├── AUDv1 (959)\n", - " │ │ │ ├── AUDv2/3 (755)\n", - " │ │ │ ├── AUDv4 (990)\n", - " │ │ │ ├── AUDv5 (1023)\n", - " │ │ │ ├── AUDv6a (520)\n", - " │ │ │ └── AUDv6b (598)\n", - " │ │ ├── ECT (895)\n", - " │ │ │ ├── ECT1 (836)\n", - " │ │ │ ├── ECT2/3 (427)\n", - " │ │ │ ├── ECT5 (988)\n", - " │ │ │ ├── ECT6a (977)\n", - " │ │ │ └── ECT6b (1045)\n", - " │ │ ├── FRP (184)\n", - " │ │ │ ├── FRP1 (68)\n", - " │ │ │ ├── FRP2/3 (667)\n", - " │ │ │ ├── FRP5 (526157192)\n", - " │ │ │ ├── FRP6a (526157196)\n", - " │ │ │ └── FRP6b (526322264)\n", - " │ │ ├── GU (1057)\n", - " │ │ │ ├── GU1 (36)\n", - " │ │ │ ├── GU2/3 (180)\n", - " │ │ │ ├── GU4 (148)\n", - " │ │ │ ├── GU5 (187)\n", - " │ │ │ ├── GU6a (638)\n", - " │ │ │ └── GU6b (662)\n", - " │ │ ├── ILA (44)\n", - " │ │ │ ├── ILA1 (707)\n", - " │ │ │ ├── ILA2/3 (556)\n", - " │ │ │ ├── ILA5 (827)\n", - " │ │ │ ├── ILA6a (1054)\n", - " │ │ │ └── ILA6b (1081)\n", - " │ │ ├── MO (500)\n", - " │ │ │ ├── MOp (985)\n", - " │ │ │ │ ├── MOp1 (320)\n", - " │ │ │ │ ├── MOp2/3 (943)\n", - " │ │ │ │ ├── MOp5 (648)\n", - " │ │ │ │ ├── MOp6a (844)\n", - " │ │ │ │ └── MOp6b (882)\n", - " │ │ │ └── MOs (993)\n", - " │ │ │ ├── MOs1 (656)\n", - " │ │ │ ├── MOs2/3 (962)\n", - " │ │ │ ├── MOs5 (767)\n", - " │ │ │ ├── MOs6a (1021)\n", - " │ │ │ └── MOs6b (1085)\n", - " │ │ ├── ORB (714)\n", - " │ │ │ ├── ORBl (723)\n", - " │ │ │ │ ├── ORBl1 (448)\n", - " │ │ │ │ ├── ORBl2/3 (412)\n", - " │ │ │ │ ├── ORBl5 (630)\n", - " │ │ │ │ ├── ORBl6a (440)\n", - " │ │ │ │ └── ORBl6b (488)\n", - " │ │ │ ├── ORBm (731)\n", - " │ │ │ │ ├── ORBm1 (484)\n", - " │ │ │ │ ├── ORBm2/3 (582)\n", - " │ │ │ │ ├── ORBm5 (620)\n", - " │ │ │ │ ├── ORBm6a (910)\n", - " │ │ │ │ └── ORBm6b (527696977)\n", - " │ │ │ └── ORBvl (746)\n", - " │ │ │ ├── ORBvl1 (969)\n", - " │ │ │ ├── ORBvl2/3 (288)\n", - " │ │ │ ├── ORBvl5 (1125)\n", - " │ │ │ ├── ORBvl6a (608)\n", - " │ │ │ └── ORBvl6b (680)\n", - " │ │ ├── PERI (922)\n", - " │ │ │ ├── PERI1 (540)\n", - " │ │ │ ├── PERI2/3 (888)\n", - " │ │ │ ├── PERI5 (692)\n", - " │ │ │ ├── PERI6a (335)\n", - " │ │ │ └── PERI6b (368)\n", - " │ │ ├── PL (972)\n", - " │ │ │ ├── PL1 (171)\n", - " │ │ │ ├── PL2/3 (304)\n", - " │ │ │ ├── PL5 (363)\n", - " │ │ │ ├── PL6a (84)\n", - " │ │ │ └── PL6b (132)\n", - " │ │ ├── PTLp (22)\n", - " │ │ │ ├── VISa (312782546)\n", - " │ │ │ │ ├── VISa1 (312782550)\n", - " │ │ │ │ ├── VISa2/3 (312782554)\n", - " │ │ │ │ ├── VISa4 (312782558)\n", - " │ │ │ │ ├── VISa5 (312782562)\n", - " │ │ │ │ ├── VISa6a (312782566)\n", - " │ │ │ │ └── VISa6b (312782570)\n", - " │ │ │ └── VISrl (417)\n", - " │ │ │ ├── VISrl1 (312782604)\n", - " │ │ │ ├── VISrl2/3 (312782608)\n", - " │ │ │ ├── VISrl4 (312782612)\n", - " │ │ │ ├── VISrl5 (312782616)\n", - " │ │ │ ├── VISrl6a (312782620)\n", - " │ │ │ └── VISrl6b (312782624)\n", - " │ │ ├── RSP (254)\n", - " │ │ │ ├── RSPagl (894)\n", - " │ │ │ │ ├── RSPagl1 (671)\n", - " │ │ │ │ ├── RSPagl2/3 (965)\n", - " │ │ │ │ ├── RSPagl5 (774)\n", - " │ │ │ │ ├── RSPagl6a (906)\n", - " │ │ │ │ └── RSPagl6b (279)\n", - " │ │ │ ├── RSPd (879)\n", - " │ │ │ │ ├── RSPd1 (442)\n", - " │ │ │ │ ├── RSPd2/3 (434)\n", - " │ │ │ │ ├── RSPd4 (545)\n", - " │ │ │ │ ├── RSPd5 (610)\n", - " │ │ │ │ ├── RSPd6a (274)\n", - " │ │ │ │ └── RSPd6b (330)\n", - " │ │ │ └── RSPv (886)\n", - " │ │ │ ├── RSPv1 (542)\n", - " │ │ │ ├── RSPv2/3 (430)\n", - " │ │ │ ├── RSPv5 (687)\n", - " │ │ │ ├── RSPv6a (590)\n", - " │ │ │ └── RSPv6b (622)\n", - " │ │ ├── SS (453)\n", - " │ │ │ ├── SSp (322)\n", - " │ │ │ │ ├── SSp-bfd (329)\n", - " │ │ │ │ │ ├── SSp-bfd1 (981)\n", - " │ │ │ │ │ ├── SSp-bfd2/3 (201)\n", - " │ │ │ │ │ ├── SSp-bfd4 (1047)\n", - " │ │ │ │ │ ├── SSp-bfd5 (1070)\n", - " │ │ │ │ │ ├── SSp-bfd6a (1038)\n", - " │ │ │ │ │ └── SSp-bfd6b (1062)\n", - " │ │ │ │ ├── SSp-ll (337)\n", - " │ │ │ │ │ ├── SSp-ll1 (1030)\n", - " │ │ │ │ │ ├── SSp-ll2/3 (113)\n", - " │ │ │ │ │ ├── SSp-ll4 (1094)\n", - " │ │ │ │ │ ├── SSp-ll5 (1128)\n", - " │ │ │ │ │ ├── SSp-ll6a (478)\n", - " │ │ │ │ │ └── SSp-ll6b (510)\n", - " │ │ │ │ ├── SSp-m (345)\n", - " │ │ │ │ │ ├── SSp-m1 (878)\n", - " │ │ │ │ │ ├── SSp-m2/3 (657)\n", - " │ │ │ │ │ ├── SSp-m4 (950)\n", - " │ │ │ │ │ ├── SSp-m5 (974)\n", - " │ │ │ │ │ ├── SSp-m6a (1102)\n", - " │ │ │ │ │ └── SSp-m6b (2)\n", - " │ │ │ │ ├── SSp-n (353)\n", - " │ │ │ │ │ ├── SSp-n1 (558)\n", - " │ │ │ │ │ ├── SSp-n2/3 (838)\n", - " │ │ │ │ │ ├── SSp-n4 (654)\n", - " │ │ │ │ │ ├── SSp-n5 (702)\n", - " │ │ │ │ │ ├── SSp-n6a (889)\n", - " │ │ │ │ │ └── SSp-n6b (929)\n", - " │ │ │ │ ├── SSp-tr (361)\n", - " │ │ │ │ │ ├── SSp-tr1 (1006)\n", - " │ │ │ │ │ ├── SSp-tr2/3 (670)\n", - " │ │ │ │ │ ├── SSp-tr4 (1086)\n", - " │ │ │ │ │ ├── SSp-tr5 (1111)\n", - " │ │ │ │ │ ├── SSp-tr6a (9)\n", - " │ │ │ │ │ └── SSp-tr6b (461)\n", - " │ │ │ │ ├── SSp-ul (369)\n", - " │ │ │ │ │ ├── SSp-ul1 (450)\n", - " │ │ │ │ │ ├── SSp-ul2/3 (854)\n", - " │ │ │ │ │ ├── SSp-ul4 (577)\n", - " │ │ │ │ │ ├── SSp-ul5 (625)\n", - " │ │ │ │ │ ├── SSp-ul6a (945)\n", - " │ │ │ │ │ └── SSp-ul6b (1026)\n", - " │ │ │ │ └── SSp-un (182305689)\n", - " │ │ │ │ ├── SSp-un1 (182305693)\n", - " │ │ │ │ ├── SSp-un2/3 (182305697)\n", - " │ │ │ │ ├── SSp-un4 (182305701)\n", - " │ │ │ │ ├── SSp-un5 (182305705)\n", - " │ │ │ │ ├── SSp-un6a (182305709)\n", - " │ │ │ │ └── SSp-un6b (182305713)\n", - " │ │ │ └── SSs (378)\n", - " │ │ │ ├── SSs1 (873)\n", - " │ │ │ ├── SSs2/3 (806)\n", - " │ │ │ ├── SSs4 (1035)\n", - " │ │ │ ├── SSs5 (1090)\n", - " │ │ │ ├── SSs6a (862)\n", - " │ │ │ └── SSs6b (893)\n", - " │ │ ├── TEa (541)\n", - " │ │ │ ├── TEa1 (97)\n", - " │ │ │ ├── TEa2/3 (1127)\n", - " │ │ │ ├── TEa4 (234)\n", - " │ │ │ ├── TEa5 (289)\n", - " │ │ │ ├── TEa6a (729)\n", - " │ │ │ └── TEa6b (786)\n", - " │ │ ├── VIS (669)\n", - " │ │ │ ├── VISal (402)\n", - " │ │ │ │ ├── VISal1 (1074)\n", - " │ │ │ │ ├── VISal2/3 (905)\n", - " │ │ │ │ ├── VISal4 (1114)\n", - " │ │ │ │ ├── VISal5 (233)\n", - " │ │ │ │ ├── VISal6a (601)\n", - " │ │ │ │ └── VISal6b (649)\n", - " │ │ │ ├── VISam (394)\n", - " │ │ │ │ ├── VISam1 (281)\n", - " │ │ │ │ ├── VISam2/3 (1066)\n", - " │ │ │ │ ├── VISam4 (401)\n", - " │ │ │ │ ├── VISam5 (433)\n", - " │ │ │ │ ├── VISam6a (1046)\n", - " │ │ │ │ └── VISam6b (441)\n", - " │ │ │ ├── VISl (409)\n", - " │ │ │ │ ├── VISl1 (421)\n", - " │ │ │ │ ├── VISl2/3 (973)\n", - " │ │ │ │ ├── VISl4 (573)\n", - " │ │ │ │ ├── VISl5 (613)\n", - " │ │ │ │ ├── VISl6a (74)\n", - " │ │ │ │ └── VISl6b (121)\n", - " │ │ │ ├── VISli (312782574)\n", - " │ │ │ │ ├── VISli1 (312782578)\n", - " │ │ │ │ ├── VISli2/3 (312782582)\n", - " │ │ │ │ ├── VISli4 (312782586)\n", - " │ │ │ │ ├── VISli5 (312782590)\n", - " │ │ │ │ ├── VISli6a (312782594)\n", - " │ │ │ │ └── VISli6b (312782598)\n", - " │ │ │ ├── VISp (385)\n", - " │ │ │ │ ├── VISp1 (593)\n", - " │ │ │ │ ├── VISp2/3 (821)\n", - " │ │ │ │ ├── VISp4 (721)\n", - " │ │ │ │ ├── VISp5 (778)\n", - " │ │ │ │ ├── VISp6a (33)\n", - " │ │ │ │ └── VISp6b (305)\n", - " │ │ │ ├── VISpl (425)\n", - " │ │ │ │ ├── VISpl1 (750)\n", - " │ │ │ │ ├── VISpl2/3 (269)\n", - " │ │ │ │ ├── VISpl4 (869)\n", - " │ │ │ │ ├── VISpl5 (902)\n", - " │ │ │ │ ├── VISpl6a (377)\n", - " │ │ │ │ └── VISpl6b (393)\n", - " │ │ │ ├── VISpm (533)\n", - " │ │ │ │ ├── VISpm1 (805)\n", - " │ │ │ │ ├── VISpm2/3 (41)\n", - " │ │ │ │ ├── VISpm4 (501)\n", - " │ │ │ │ ├── VISpm5 (565)\n", - " │ │ │ │ ├── VISpm6a (257)\n", - " │ │ │ │ └── VISpm6b (469)\n", - " │ │ │ └── VISpor (312782628)\n", - " │ │ │ ├── VISpor1 (312782632)\n", - " │ │ │ ├── VISpor2/3 (312782636)\n", - " │ │ │ ├── VISpor4 (312782640)\n", - " │ │ │ ├── VISpor5 (312782644)\n", - " │ │ │ ├── VISpor6a (312782648)\n", - " │ │ │ └── VISpor6b (312782652)\n", - " │ │ └── VISC (677)\n", - " │ │ ├── VISC1 (897)\n", - " │ │ ├── VISC2/3 (1106)\n", - " │ │ ├── VISC4 (1010)\n", - " │ │ ├── VISC5 (1058)\n", - " │ │ ├── VISC6a (857)\n", - " │ │ └── VISC6b (849)\n", - " │ └── OLF (698)\n", - " │ ├── AOB (151)\n", - " │ │ ├── AOBgl (188)\n", - " │ │ ├── AOBgr (196)\n", - " │ │ └── AOBmi (204)\n", - " │ ├── AON (159)\n", - " │ ├── COA (631)\n", - " │ │ ├── COAa (639)\n", - " │ │ └── COAp (647)\n", - " │ │ ├── COApl (655)\n", - " │ │ └── COApm (663)\n", - " │ ├── DP (814)\n", - " │ ├── MOB (507)\n", - " │ ├── NLOT (619)\n", - " │ │ ├── NLOT1 (260)\n", - " │ │ ├── NLOT2 (268)\n", - " │ │ └── NLOT3 (1139)\n", - " │ ├── PAA (788)\n", - " │ ├── PIR (961)\n", - " │ ├── TR (566)\n", - " │ └── TT (589)\n", - " │ ├── TTd (597)\n", - " │ └── TTv (605)\n", - " └── CTXsp (703)\n", - " ├── BLA (295)\n", - " │ ├── BLAa (303)\n", - " │ ├── BLAp (311)\n", - " │ └── BLAv (451)\n", - " ├── BMA (319)\n", - " │ ├── BMAa (327)\n", - " │ └── BMAp (334)\n", - " ├── CLA (583)\n", - " ├── EP (942)\n", - " │ ├── EPd (952)\n", - " │ └── EPv (966)\n", - " ├── LA (131)\n", - " └── PA (780)" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "bg_atlas.structures" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The structures attribute is a custom dictionary that can be queried by region number or acronym, and contains all the information for a given structure:" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'acronym': 'root',\n", - " 'id': 997,\n", - " 'mesh': None,\n", - " 'mesh_filename': PosixPath('/home/rob/.brainglobe/allen_mouse_100um_v1.2/meshes/997.obj'),\n", - " 'name': 'root',\n", - " 'rgb_triplet': [255, 255, 255],\n", - " 'structure_id_path': [997]}\n" - ] - } - ], - "source": [ - "pprint(bg_atlas.structures[\"root\"])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In particular, the `structure_id_path` key contains a list description of the path in the hierarchy up to a particular region, and can be used for queries on the hierarchy." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[997, 8, 567]" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "bg_atlas.structures[\"CH\"][\"structure_id_path\"]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can use the `bg_atlas.get_structure_descendants` and `bg_atlas.get_structure_ancestors` methods to explore the hierarchy:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['VISC1', 'VISC2/3', 'VISC4', 'VISC5', 'VISC6a', 'VISC6b']" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "bg_atlas.get_structure_descendants(\"VISC\")" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['root', 'grey', 'CH', 'CTX', 'CTXpl', 'Isocortex', 'VISC']" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "bg_atlas.get_structure_ancestors(\"VISC6a\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---\n", - "**NOTE**: \n", - "The levels of the hierarchy depend on the underlying atlas, so we cannot ensure the goodness and consistency of their hierarchy tree.\n", - "---" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There is a higher level description of the structures hierarchy that is built using the [treelib](https://treelib.readthedocs.io/en/latest/) package, and is available as: " - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "bg_atlas.structures.tree" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For most applications though, the methods described above and the list path of each region should be sufficient to query the hierarchy without additional layers of complication." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 1.3 Region masks" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `get_structure_mask` method returns a mask volume where all voxels belonging to an area or to the descendants of that area are non-zero. All other voxels are zero. We will generate the structure mask for the primary visual cortex to see how this works. \n", - "\n", - "Primary visual cortex (`VISp`) has an ID value of `385`, but no voxels in the annotation image actually have that value:" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'acronym': 'VISp',\n", - " 'id': 385,\n", - " 'mesh': None,\n", - " 'mesh_filename': PosixPath('/home/rob/.brainglobe/allen_mouse_100um_v1.2/meshes/385.obj'),\n", - " 'name': 'Primary visual area',\n", - " 'rgb_triplet': [8, 133, 140],\n", - " 'structure_id_path': [997, 8, 567, 688, 695, 315, 669, 385]}\n" - ] - } - ], - "source": [ - "pprint(bg_atlas.structures[\"VISp\"])" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# No voxels in the annotation volume are labelled as being VISp\n", - "(bg_atlas.annotation==385).sum()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The reason no VISp voxels exist is because the annotation volume is segmented more finely. In this case `VISp` is divided into cortical layers and the IDs associated with these layers are the ones that are present in the annotation volume." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['VISp1', 'VISp2/3', 'VISp4', 'VISp5', 'VISp6a', 'VISp6b']" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# The descendants (children) of VISp are cortical layers\n", - "bg_atlas.get_structure_descendants(\"VISp\")" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "VISp1\t593\n", - "VISp2/3\t821\n", - "VISp4\t721\n", - "VISp5\t778\n", - "VISp6a\t33\n", - "VISp6b\t305\n" - ] - } - ], - "source": [ - "# The IDs associated with each layer in primary visual cortex\n", - "layers = bg_atlas.get_structure_descendants(\"VISp\")\n", - "layer_ids = [bg_atlas.structures[this_layer]['id'] for this_layer in layers]\n", - "\n", - "for (this_layer, this_id) in zip(layers, layer_ids):\n", - " print(\"%s\\t%s\" % (this_layer, this_id))\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "These IDs are indeed present in the annotation volume:" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1565" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# For example, we find over a thousand voxels associated with primary visual cortex layer 6\n", - "# in the annotation volume\n", - "(bg_atlas.annotation==778).sum()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "So let's use `get_structure_mask` to return a mask volume that retains only `VISp`." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [], - "source": [ - "mask_VISp = bg_atlas.get_structure_mask('VISp')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f, axs = plt.subplots(1,3, figsize=(12, 3))\n", - "for i, (plane, labels) in enumerate(zip(space.sections, space.axis_labels)):\n", - " axs[i].imshow(mask_VISp.max(i), cmap=\"gray\")\n", - " axs[i].set_title(f\"{plane.capitalize()} view\")\n", - " axs[i].set_ylabel(labels[0])\n", - " axs[i].set_xlabel(labels[1])\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `root` node encompasses the whole brain and we can use this to provide a background image for the above area." - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "mask_root = bg_atlas.get_structure_mask('root')\n", - "\n", - "# The mask images have pixel values equal to the ID of the parent area, so we change these for\n", - "# plotting purposes. \n", - "mask_root[mask_root>0]=5\n", - "mask_VISp[mask_VISp>0]=2\n", - "mask_VISp_root = mask_VISp + mask_root" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "space = bg_atlas.space\n", - "\n", - "f, axs = plt.subplots(1,3, figsize=(12, 3))\n", - "for i, (plane, labels) in enumerate(zip(space.sections, space.axis_labels)):\n", - " axs[i].imshow(mask_VISp_root.max(i), cmap=\"gray\")\n", - " axs[i].set_title(f\"{plane.capitalize()} view\")\n", - " axs[i].set_ylabel(labels[0])\n", - " axs[i].set_xlabel(labels[1])\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 1.3 Regions meshes" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If we need to access the structure meshes, we can either query for the file (e.g., if we need to load the file through some library like `vedo`):" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "PosixPath('/home/rob/.brainglobe/allen_mouse_100um_v1.2/meshes/567.obj')" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "bg_atlas.meshfile_from_structure(\"CH\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Or directly obtain the mesh, as a mesh object of the `meshio` library:" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - " Number of points: 56703\n", - " Number of cells:\n", - " triangle: 112948\n", - " Point data: obj:vn\n", - " Cell data: obj:group_ids" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "bg_atlas.mesh_from_structure(\"CH\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 2 Query the `BrainGlobeAtlas`" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 2.0 Query for structures:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A very convenient feature of the `BrainGlobeAtlas` API is the simplicity of querying for the identity of the structure or the hemisphere at a given location, either from stack indexes or space coordinates, and even cutting the hierarchy at some higher level:" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "By index: CP\n", - "By coordinates: CP\n", - "Higher hierarchy level: CH\n" - ] - } - ], - "source": [ - "# Ask for identity of some indexes in the stack:\n", - "print(\"By index:\", bg_atlas.structure_from_coords((50, 40, 30), \n", - " as_acronym=True))\n", - "\n", - "# Now give coordinates in microns\n", - "print(\"By coordinates:\", bg_atlas.structure_from_coords((5000, 4000, 3000), \n", - " as_acronym=True, \n", - " microns=True))\n", - "\n", - "# Now cut hierarchy at some level\n", - "print(\"Higher hierarchy level:\", bg_atlas.structure_from_coords((5000, 4000, 3000), \n", - " as_acronym=True, \n", - " microns=True, \n", - " hierarchy_lev=2))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 2.1 Query for hemispheres" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A very similar method can be used for hemispheres. 0 corresponds to outside the brain, and 1 and 2 to left and right hemispheres respectively - but we can just ask for the hemisphere name instead of the number:" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "By index: 2\n", - "By coordinates: 2\n", - "By : 2\n" - ] - } - ], - "source": [ - "# Ask for identity of some indexes in the stack:\n", - "print(\"By index:\", bg_atlas.hemisphere_from_coords((50, 40, 30)))\n", - "\n", - "# Now give coordinates in microns\n", - "print(\"By coordinates:\", bg_atlas.hemisphere_from_coords((5000, 4000, 3000), microns=True))\n", - "\n", - "# Now print side string\n", - "print(\"By :\", bg_atlas.hemisphere_from_coords((5000, 4000, 3000), microns=True))" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.4" - } - }, - "nbformat": 4, - "nbformat_minor": 4 + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Introduction to the `BrainGlobeAtlas` class" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 0. Creating a `BrainGlobeAtlas` object and listing available options" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To instantiate a `BrainGlobeAtlas` object, we need to instantiate it with the atlas name. The first time we use it, a version of this atlas will be downloaded from the [remote GIN repository](http://gin.g-node.org/brainglobe/atlases) and stored on your local machine (by default, in .../Users/username/.brainglobe):" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "allen mouse atlas (res. 100um)\n", + "From: http://www.brain-map.org (Wang et al 2020, https://doi.org/10.1016/j.cell.2020.04.007 )\n" + ] + } + ], + "source": [ + "from pprint import pprint\n", + "\n", + "import numpy as np\n", + "\n", + "from brainglobe_atlasapi import BrainGlobeAtlas\n", + "\n", + "bg_atlas = BrainGlobeAtlas(\"allen_mouse_100um\", check_latest=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To know what atlases are available through BrainGlobe, we can use the `show_atlases` function (we need to be online):" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
                                                                                  \n",
+       "                                                                                  \n",
+       "                                Brainglobe Atlases                                \n",
+       "╭──────────────────────────────────┬────────────┬───────────────┬────────────────╮\n",
+       "│ Name                              Downloaded  Local version  Latest version │\n",
+       "├──────────────────────────────────┼────────────┼───────────────┼────────────────┤\n",
+       "│ whs_sd_rat_39um      │      1.0      │      1.0       │\n",
+       "│ allen_mouse_25um      │      1.2      │      1.2       │\n",
+       "│ allen_mouse_100um      │      1.2      │      1.2       │\n",
+       "│ allen_mouse_50um      │      1.2      │      1.2       │\n",
+       "│ example_mouse_100um------      │      1.2       │\n",
+       "│ allen_mouse_10um------      │      1.2       │\n",
+       "│ mpin_zfish_1um------      │      1.0       │\n",
+       "│ allen_human_500um------      │      0.1       │\n",
+       "│ kim_mouse_10um------      │      1.0       │\n",
+       "│ kim_mouse_25um------      │      1.0       │\n",
+       "│ kim_mouse_50um------      │      1.0       │\n",
+       "│ kim_mouse_100um------      │      1.0       │\n",
+       "│ osten_mouse_10um------      │      1.1       │\n",
+       "│ osten_mouse_25um------      │      1.1       │\n",
+       "│ osten_mouse_50um------      │      1.1       │\n",
+       "│ osten_mouse_100um------      │      1.1       │\n",
+       "│ allen_cord_20um------      │      1.0       │\n",
+       "│ azba_zfish_4um------      │      1.1       │\n",
+       "│ perens_lsfm_mouse_20um------      │      1.0       │\n",
+       "│ admba_3d_e11_5_mouse_16um------      │      1.0       │\n",
+       "│ admba_3d_e13_5_mouse_16um------      │      1.0       │\n",
+       "│ admba_3d_e15_5_mouse_16um------      │      1.0       │\n",
+       "│ admba_3d_e18_5_mouse_16um------      │      1.0       │\n",
+       "│ admba_3d_p4_mouse_16.752um------      │      1.0       │\n",
+       "│ admba_3d_p14_mouse_16.752um------      │      1.0       │\n",
+       "│ admba_3d_p28_mouse_16.752um------      │      1.0       │\n",
+       "│ admba_3d_p56_mouse_25um------      │      1.0       │\n",
+       "╰──────────────────────────────────┴────────────┴───────────────┴────────────────╯\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[3m \u001b[0m\n", + "\u001b[3m \u001b[0m\n", + "\u001b[3m Brainglobe Atlases \u001b[0m\n", + "╭──────────────────────────────────┬────────────┬───────────────┬────────────────╮\n", + "│\u001b[1;32m \u001b[0m\u001b[1;32mName \u001b[0m\u001b[1;32m \u001b[0m│\u001b[1;32m \u001b[0m\u001b[1;32mDownloaded\u001b[0m\u001b[1;32m \u001b[0m│\u001b[1;32m \u001b[0m\u001b[1;32mLocal version\u001b[0m\u001b[1;32m \u001b[0m│\u001b[1;32m \u001b[0m\u001b[1;32mLatest version\u001b[0m\u001b[1;32m \u001b[0m│\n", + "├──────────────────────────────────┼────────────┼───────────────┼────────────────┤\n", + "│ \u001b[1mwhs_sd_rat_39um\u001b[0m │ \u001b[32m✔\u001b[0m │ 1.0 │ 1.0 │\n", + "│ \u001b[1mallen_mouse_25um\u001b[0m │ \u001b[32m✔\u001b[0m │ 1.2 │ 1.2 │\n", + "│ \u001b[1mallen_mouse_100um\u001b[0m │ \u001b[32m✔\u001b[0m │ 1.2 │ 1.2 │\n", + "│ \u001b[1mallen_mouse_50um\u001b[0m │ \u001b[32m✔\u001b[0m │ 1.2 │ 1.2 │\n", + "│ \u001b[1mexample_mouse_100um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.2 │\n", + "│ \u001b[1mallen_mouse_10um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.2 │\n", + "│ \u001b[1mmpin_zfish_1um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", + "│ \u001b[1mallen_human_500um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 0.1 │\n", + "│ \u001b[1mkim_mouse_10um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", + "│ \u001b[1mkim_mouse_25um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", + "│ \u001b[1mkim_mouse_50um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", + "│ \u001b[1mkim_mouse_100um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", + "│ \u001b[1mosten_mouse_10um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.1 │\n", + "│ \u001b[1mosten_mouse_25um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.1 │\n", + "│ \u001b[1mosten_mouse_50um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.1 │\n", + "│ \u001b[1mosten_mouse_100um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.1 │\n", + "│ \u001b[1mallen_cord_20um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", + "│ \u001b[1mazba_zfish_4um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.1 │\n", + "│ \u001b[1mperens_lsfm_mouse_20um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", + "│ \u001b[1madmba_3d_e11_5_mouse_16um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", + "│ \u001b[1madmba_3d_e13_5_mouse_16um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", + "│ \u001b[1madmba_3d_e15_5_mouse_16um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", + "│ \u001b[1madmba_3d_e18_5_mouse_16um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", + "│ \u001b[1madmba_3d_p4_mouse_16.752um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", + "│ \u001b[1madmba_3d_p14_mouse_16.752um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", + "│ \u001b[1madmba_3d_p28_mouse_16.752um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", + "│ \u001b[1madmba_3d_p56_mouse_25um\u001b[0m │ \u001b[31m---\u001b[0m │ \u001b[31m---\u001b[0m │ 1.0 │\n", + "╰──────────────────────────────────┴────────────┴───────────────┴────────────────╯\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from brainglobe_atlasapi import show_atlases\n", + "\n", + "show_atlases()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Using a `BrainGlobe` atlas" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A BrainGlobe atlas is a convenient API for interacting with an anatomical atlas. BrainGlobe atlases contain:\n", + " * Metadata\n", + " * The reference anatomical stack used for the registration itself\n", + " * Region annotation stack (the segmented atlas image that occupies the same space as the reference stack)\n", + " * Hemisphere annotation stack which denotes left and right\n", + " * Description of the region hierarchy\n", + " * Meshes for the regions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1.0 Metadata" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "All atlases have a standard set of medatata describing their source, species, resolution, etc:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'name': 'allen_mouse',\n", + " 'citation': 'Wang et al 2020, https://doi.org/10.1016/j.cell.2020.04.007',\n", + " 'atlas_link': 'http://www.brain-map.org',\n", + " 'species': 'Mus musculus',\n", + " 'symmetric': True,\n", + " 'resolution': [100.0, 100.0, 100.0],\n", + " 'orientation': 'asr',\n", + " 'version': '1.2',\n", + " 'shape': [132, 80, 114],\n", + " 'trasform_to_bg': [[1.0, 0.0, 0.0, 0.0],\n", + " [0.0, 1.0, 0.0, 0.0],\n", + " [0.0, 0.0, 1.0, 0.0],\n", + " [0.0, 0.0, 0.0, 1.0]],\n", + " 'additional_references': []}" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bg_atlas.metadata" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1.1 Reference, annotation and hemispheres stack" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "from matplotlib import pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Reference stack:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "space = bg_atlas.space\n", + "stack = bg_atlas.reference\n", + "\n", + "f, axs = plt.subplots(1,3, figsize=(12, 3))\n", + "for i, (plane, labels) in enumerate(zip(space.sections, space.axis_labels)):\n", + " mid_index = stack.shape[i]//2\n", + " axs[i].imshow(np.moveaxis(stack,i,0)[mid_index,:,:], cmap=\"gray\",clim=(0,250))\n", + " axs[i].set_title(f\"{plane.capitalize()} view\")\n", + " axs[i].set_ylabel(labels[0])\n", + " axs[i].set_xlabel(labels[1])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Annotation stack:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "space = bg_atlas.space\n", + "stack = bg_atlas.annotation\n", + "\n", + "f, axs = plt.subplots(1,3, figsize=(12, 3))\n", + "for i, (plane, labels) in enumerate(zip(space.sections, space.axis_labels)):\n", + " mid_index = stack.shape[i]//2\n", + " axs[i].imshow(np.moveaxis(stack,i,0)[mid_index,:,:], cmap=\"gray\",clim=(0,1250))\n", + " axs[i].set_title(f\"{plane.capitalize()} view\")\n", + " axs[i].set_ylabel(labels[0])\n", + " axs[i].set_xlabel(labels[1])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Hemispheres stack:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "space = bg_atlas.space\n", + "stack = bg_atlas.hemispheres\n", + "\n", + "f, axs = plt.subplots(1,3, figsize=(12, 3))\n", + "for i, (plane, labels) in enumerate(zip(space.sections, space.axis_labels)):\n", + " axs[i].imshow(stack.max(i), cmap=\"gray\")\n", + " axs[i].set_title(f\"{plane.capitalize()} view\")\n", + " axs[i].set_ylabel(labels[0])\n", + " axs[i].set_xlabel(labels[1])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1.2 Regions hierarchy" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The atlas comes with a description of the hierarchy of brain structures. To have an overview:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "root (997)\n", + "├── VS (73)\n", + "│ ├── AQ (140)\n", + "│ ├── V3 (129)\n", + "│ ├── V4 (145)\n", + "│ │ └── V4r (153)\n", + "│ ├── VL (81)\n", + "│ │ ├── SEZ (98)\n", + "│ │ └── chpl (108)\n", + "│ └── c (164)\n", + "├── fiber tracts (1009)\n", + "│ ├── cbf (960)\n", + "│ │ ├── arb (728)\n", + "│ │ ├── cbc (744)\n", + "│ │ └── cbp (752)\n", + "│ │ ├── icp (1123)\n", + "│ │ │ └── sctd (553)\n", + "│ │ ├── mcp (78)\n", + "│ │ └── scp (326)\n", + "│ │ ├── dscp (812)\n", + "│ │ ├── sctv (866)\n", + "│ │ └── uf (850)\n", + "│ ├── cm (967)\n", + "│ │ ├── IIIn (832)\n", + "│ │ │ ├── mlf (62)\n", + "│ │ │ └── pc (158)\n", + "│ │ ├── IIn (848)\n", + "│ │ │ ├── bsc (916)\n", + "│ │ │ ├── csc (336)\n", + "│ │ │ ├── och (117)\n", + "│ │ │ └── opt (125)\n", + "│ │ ├── IVn (911)\n", + "│ │ ├── In (840)\n", + "│ │ │ ├── aco (900)\n", + "│ │ │ ├── lotg (21)\n", + "│ │ │ │ ├── lot (665)\n", + "│ │ │ │ └── lotd (538)\n", + "│ │ │ └── onl (1016)\n", + "│ │ ├── VIIIn (933)\n", + "│ │ │ ├── cVIIIn (948)\n", + "│ │ │ │ ├── bic (482)\n", + "│ │ │ │ ├── cic (633)\n", + "│ │ │ │ ├── das (506)\n", + "│ │ │ │ ├── ll (658)\n", + "│ │ │ │ └── tb (841)\n", + "│ │ │ └── vVIIIn (413)\n", + "│ │ ├── VIIn (798)\n", + "│ │ │ └── gVIIn (1116)\n", + "│ │ ├── Vn (901)\n", + "│ │ │ ├── moV (93)\n", + "│ │ │ └── sV (229)\n", + "│ │ │ └── sptV (794)\n", + "│ │ ├── Xn (917)\n", + "│ │ │ └── ts (237)\n", + "│ │ ├── drt (792)\n", + "│ │ │ └── cett (932)\n", + "│ │ │ ├── dc (514)\n", + "│ │ │ │ └── cuf (380)\n", + "│ │ │ └── ml (697)\n", + "│ │ └── von (949)\n", + "│ ├── eps (1000)\n", + "│ │ ├── epsc (760)\n", + "│ │ │ └── nst (102)\n", + "│ │ ├── rust (863)\n", + "│ │ │ └── vtd (397)\n", + "│ │ └── tsp (877)\n", + "│ │ ├── dtd (1060)\n", + "│ │ ├── tspc (1043)\n", + "│ │ └── tspd (1051)\n", + "│ ├── lfbs (983)\n", + "│ │ ├── cc (776)\n", + "│ │ │ ├── ccb (484682516)\n", + "│ │ │ ├── ccg (1108)\n", + "│ │ │ ├── ccs (986)\n", + "│ │ │ ├── ee (964)\n", + "│ │ │ ├── fa (956)\n", + "│ │ │ │ └── ec (579)\n", + "│ │ │ └── fp (971)\n", + "│ │ ├── cst (784)\n", + "│ │ │ ├── cpd (924)\n", + "│ │ │ ├── int (6)\n", + "│ │ │ ├── py (190)\n", + "│ │ │ └── pyd (198)\n", + "│ │ └── lfbst (896)\n", + "│ │ ├── ar (484682524)\n", + "│ │ ├── em (1092)\n", + "│ │ └── or (484682520)\n", + "│ ├── mfbs (991)\n", + "│ │ ├── mfbc (768)\n", + "│ │ │ ├── act (908)\n", + "│ │ │ ├── amc (884)\n", + "│ │ │ ├── cing (940)\n", + "│ │ │ ├── fxs (1099)\n", + "│ │ │ │ ├── alv (466)\n", + "│ │ │ │ ├── df (530)\n", + "│ │ │ │ ├── fi (603)\n", + "│ │ │ │ ├── fxpo (737)\n", + "│ │ │ │ │ ├── fx (436)\n", + "│ │ │ │ │ └── mct (428)\n", + "│ │ │ │ └── hc (618)\n", + "│ │ │ │ ├── dhc (443)\n", + "│ │ │ │ └── vhc (449)\n", + "│ │ │ └── st (301)\n", + "│ │ │ └── stc (484682528)\n", + "│ │ └── mfsbshy (824)\n", + "│ │ ├── mfb (54)\n", + "│ │ ├── mfbse (1083)\n", + "│ │ │ ├── fr (595)\n", + "│ │ │ ├── hbc (611)\n", + "│ │ │ └── sm (802)\n", + "│ │ ├── mfbsma (46)\n", + "│ │ │ ├── mp (673)\n", + "│ │ │ ├── mtg (681)\n", + "│ │ │ ├── mtt (690)\n", + "│ │ │ └── pm (753)\n", + "│ │ └── sup (349)\n", + "│ └── scwm (484682512)\n", + "└── grey (8)\n", + " ├── BS (343)\n", + " │ ├── HB (1065)\n", + " │ │ ├── MY (354)\n", + " │ │ │ ├── MY-mot (370)\n", + " │ │ │ │ ├── ACVII (576)\n", + " │ │ │ │ ├── AMB (135)\n", + " │ │ │ │ │ ├── AMBd (939)\n", + " │ │ │ │ │ └── AMBv (143)\n", + " │ │ │ │ ├── DMX (839)\n", + " │ │ │ │ ├── GRN (1048)\n", + " │ │ │ │ ├── ICB (372)\n", + " │ │ │ │ ├── IO (83)\n", + " │ │ │ │ ├── IRN (136)\n", + " │ │ │ │ ├── ISN (106)\n", + " │ │ │ │ ├── LIN (203)\n", + " │ │ │ │ ├── LRN (235)\n", + " │ │ │ │ │ ├── LRNm (955)\n", + " │ │ │ │ │ └── LRNp (963)\n", + " │ │ │ │ ├── MARN (307)\n", + " │ │ │ │ ├── MDRN (395)\n", + " │ │ │ │ │ ├── MDRNd (1098)\n", + " │ │ │ │ │ └── MDRNv (1107)\n", + " │ │ │ │ ├── PARN (852)\n", + " │ │ │ │ ├── PAS (859)\n", + " │ │ │ │ ├── PGRN (938)\n", + " │ │ │ │ │ ├── PGRNd (970)\n", + " │ │ │ │ │ └── PGRNl (978)\n", + " │ │ │ │ ├── PHY (154)\n", + " │ │ │ │ │ ├── NR (177)\n", + " │ │ │ │ │ └── PRP (169)\n", + " │ │ │ │ ├── PPY (1069)\n", + " │ │ │ │ ├── VI (653)\n", + " │ │ │ │ ├── VII (661)\n", + " │ │ │ │ ├── VNC (701)\n", + " │ │ │ │ │ ├── LAV (209)\n", + " │ │ │ │ │ ├── MV (202)\n", + " │ │ │ │ │ ├── SPIV (225)\n", + " │ │ │ │ │ └── SUV (217)\n", + " │ │ │ │ ├── XII (773)\n", + " │ │ │ │ ├── x (765)\n", + " │ │ │ │ └── y (781)\n", + " │ │ │ ├── MY-sat (379)\n", + " │ │ │ │ ├── RM (206)\n", + " │ │ │ │ ├── RO (222)\n", + " │ │ │ │ └── RPA (230)\n", + " │ │ │ └── MY-sen (386)\n", + " │ │ │ ├── AP (207)\n", + " │ │ │ ├── CN (607)\n", + " │ │ │ │ ├── DCO (96)\n", + " │ │ │ │ └── VCO (101)\n", + " │ │ │ ├── DCN (720)\n", + " │ │ │ │ ├── CU (711)\n", + " │ │ │ │ └── GR (1039)\n", + " │ │ │ ├── ECU (903)\n", + " │ │ │ ├── NTB (642)\n", + " │ │ │ ├── NTS (651)\n", + " │ │ │ ├── Pa5 (589508451)\n", + " │ │ │ ├── SPVC (429)\n", + " │ │ │ ├── SPVI (437)\n", + " │ │ │ └── SPVO (445)\n", + " │ │ └── P (771)\n", + " │ │ ├── P-mot (987)\n", + " │ │ │ ├── Acs5 (549009219)\n", + " │ │ │ ├── B (280)\n", + " │ │ │ ├── DTN (880)\n", + " │ │ │ ├── I5 (549009227)\n", + " │ │ │ ├── P5 (549009215)\n", + " │ │ │ ├── PC5 (549009223)\n", + " │ │ │ ├── PCG (898)\n", + " │ │ │ ├── PDTg (599626927)\n", + " │ │ │ ├── PG (931)\n", + " │ │ │ ├── PRNc (1093)\n", + " │ │ │ ├── SG (318)\n", + " │ │ │ ├── SUT (534)\n", + " │ │ │ ├── TRN (574)\n", + " │ │ │ └── V (621)\n", + " │ │ ├── P-sat (1117)\n", + " │ │ │ ├── CS (679)\n", + " │ │ │ ├── LC (147)\n", + " │ │ │ ├── LDT (162)\n", + " │ │ │ ├── NI (604)\n", + " │ │ │ ├── PRNr (146)\n", + " │ │ │ ├── RPO (238)\n", + " │ │ │ ├── SLC (350)\n", + " │ │ │ └── SLD (358)\n", + " │ │ └── P-sen (1132)\n", + " │ │ ├── NLL (612)\n", + " │ │ ├── PB (867)\n", + " │ │ │ └── KF (123)\n", + " │ │ ├── PSV (7)\n", + " │ │ └── SOC (398)\n", + " │ │ ├── POR (122)\n", + " │ │ ├── SOCl (114)\n", + " │ │ └── SOCm (105)\n", + " │ ├── IB (1129)\n", + " │ │ ├── HY (1097)\n", + " │ │ │ ├── LZ (290)\n", + " │ │ │ │ ├── LHA (194)\n", + " │ │ │ │ ├── LPO (226)\n", + " │ │ │ │ ├── PST (356)\n", + " │ │ │ │ ├── PSTN (364)\n", + " │ │ │ │ ├── PeF (576073704)\n", + " │ │ │ │ ├── RCH (173)\n", + " │ │ │ │ ├── STN (470)\n", + " │ │ │ │ ├── TU (614)\n", + " │ │ │ │ └── ZI (797)\n", + " │ │ │ │ └── FF (804)\n", + " │ │ │ ├── ME (10671)\n", + " │ │ │ ├── MEZ (467)\n", + " │ │ │ │ ├── AHN (88)\n", + " │ │ │ │ ├── MBO (331)\n", + " │ │ │ │ │ ├── LM (210)\n", + " │ │ │ │ │ ├── MM (491)\n", + " │ │ │ │ │ │ ├── MMd (606826659)\n", + " │ │ │ │ │ │ ├── MMl (606826647)\n", + " │ │ │ │ │ │ ├── MMm (606826651)\n", + " │ │ │ │ │ │ ├── MMme (732)\n", + " │ │ │ │ │ │ └── MMp (606826655)\n", + " │ │ │ │ │ ├── SUM (525)\n", + " │ │ │ │ │ └── TM (557)\n", + " │ │ │ │ │ ├── TMd (1126)\n", + " │ │ │ │ │ └── TMv (1)\n", + " │ │ │ │ ├── MPN (515)\n", + " │ │ │ │ ├── PH (946)\n", + " │ │ │ │ ├── PMd (980)\n", + " │ │ │ │ ├── PMv (1004)\n", + " │ │ │ │ ├── PVHd (63)\n", + " │ │ │ │ └── VMH (693)\n", + " │ │ │ ├── PVR (141)\n", + " │ │ │ │ ├── ADP (72)\n", + " │ │ │ │ ├── AVP (263)\n", + " │ │ │ │ ├── AVPV (272)\n", + " │ │ │ │ ├── DMH (830)\n", + " │ │ │ │ ├── MEPO (452)\n", + " │ │ │ │ ├── MPO (523)\n", + " │ │ │ │ ├── OV (763)\n", + " │ │ │ │ ├── PD (914)\n", + " │ │ │ │ ├── PS (1109)\n", + " │ │ │ │ ├── PVp (126)\n", + " │ │ │ │ ├── PVpo (133)\n", + " │ │ │ │ ├── SBPV (347)\n", + " │ │ │ │ ├── SCH (286)\n", + " │ │ │ │ ├── SFO (338)\n", + " │ │ │ │ ├── VLPO (689)\n", + " │ │ │ │ └── VMPO (576073699)\n", + " │ │ │ └── PVZ (157)\n", + " │ │ │ ├── ARH (223)\n", + " │ │ │ ├── ASO (332)\n", + " │ │ │ ├── PVH (38)\n", + " │ │ │ ├── PVa (30)\n", + " │ │ │ ├── PVi (118)\n", + " │ │ │ └── SO (390)\n", + " │ │ └── TH (549)\n", + " │ │ ├── DORpm (856)\n", + " │ │ │ ├── ATN (239)\n", + " │ │ │ │ ├── AD (64)\n", + " │ │ │ │ ├── AM (127)\n", + " │ │ │ │ │ ├── AMd (1096)\n", + " │ │ │ │ │ └── AMv (1104)\n", + " │ │ │ │ ├── AV (255)\n", + " │ │ │ │ ├── IAD (1113)\n", + " │ │ │ │ ├── IAM (1120)\n", + " │ │ │ │ └── LD (155)\n", + " │ │ │ ├── EPI (958)\n", + " │ │ │ │ ├── LH (186)\n", + " │ │ │ │ └── MH (483)\n", + " │ │ │ ├── GENv (1014)\n", + " │ │ │ │ ├── IGL (27)\n", + " │ │ │ │ ├── IntG (563807439)\n", + " │ │ │ │ ├── LGv (178)\n", + " │ │ │ │ └── SubG (321)\n", + " │ │ │ ├── ILM (51)\n", + " │ │ │ │ ├── CL (575)\n", + " │ │ │ │ ├── CM (599)\n", + " │ │ │ │ ├── PCN (907)\n", + " │ │ │ │ ├── PF (930)\n", + " │ │ │ │ ├── PIL (560581563)\n", + " │ │ │ │ └── RH (189)\n", + " │ │ │ ├── LAT (138)\n", + " │ │ │ │ ├── Eth (560581551)\n", + " │ │ │ │ ├── LP (218)\n", + " │ │ │ │ ├── PO (1020)\n", + " │ │ │ │ ├── POL (1029)\n", + " │ │ │ │ └── SGN (325)\n", + " │ │ │ ├── MED (444)\n", + " │ │ │ │ ├── IMD (59)\n", + " │ │ │ │ ├── MD (362)\n", + " │ │ │ │ ├── PR (1077)\n", + " │ │ │ │ └── SMT (366)\n", + " │ │ │ ├── MTN (571)\n", + " │ │ │ │ ├── PT (15)\n", + " │ │ │ │ ├── PVT (149)\n", + " │ │ │ │ ├── RE (181)\n", + " │ │ │ │ └── Xi (560581559)\n", + " │ │ │ └── RT (262)\n", + " │ │ └── DORsm (864)\n", + " │ │ ├── GENd (1008)\n", + " │ │ │ ├── LGd (170)\n", + " │ │ │ │ ├── LGd-co (496345668)\n", + " │ │ │ │ ├── LGd-ip (496345672)\n", + " │ │ │ │ └── LGd-sh (496345664)\n", + " │ │ │ └── MG (475)\n", + " │ │ │ ├── MGd (1072)\n", + " │ │ │ ├── MGm (1088)\n", + " │ │ │ └── MGv (1079)\n", + " │ │ ├── PP (1044)\n", + " │ │ ├── SPA (609)\n", + " │ │ ├── SPF (406)\n", + " │ │ │ ├── SPFm (414)\n", + " │ │ │ └── SPFp (422)\n", + " │ │ └── VENT (637)\n", + " │ │ ├── PoT (563807435)\n", + " │ │ ├── VAL (629)\n", + " │ │ ├── VM (685)\n", + " │ │ └── VP (709)\n", + " │ │ ├── VPL (718)\n", + " │ │ ├── VPLpc (725)\n", + " │ │ ├── VPM (733)\n", + " │ │ └── VPMpc (741)\n", + " │ └── MB (313)\n", + " │ ├── MBmot (323)\n", + " │ │ ├── AT (231)\n", + " │ │ ├── CUN (616)\n", + " │ │ ├── DT (75)\n", + " │ │ ├── EW (975)\n", + " │ │ ├── III (35)\n", + " │ │ ├── IV (115)\n", + " │ │ ├── LT (66)\n", + " │ │ ├── MA3 (549009211)\n", + " │ │ ├── MRN (128)\n", + " │ │ ├── MT (58)\n", + " │ │ ├── PAG (795)\n", + " │ │ │ ├── INC (67)\n", + " │ │ │ ├── ND (587)\n", + " │ │ │ ├── PRC (50)\n", + " │ │ │ └── Su3 (614454277)\n", + " │ │ ├── PN (607344830)\n", + " │ │ ├── PRT (1100)\n", + " │ │ │ ├── APN (215)\n", + " │ │ │ ├── MPT (531)\n", + " │ │ │ ├── NOT (628)\n", + " │ │ │ ├── NPC (634)\n", + " │ │ │ ├── OP (706)\n", + " │ │ │ ├── PPT (1061)\n", + " │ │ │ └── RPF (549009203)\n", + " │ │ ├── Pa4 (606826663)\n", + " │ │ ├── RN (214)\n", + " │ │ ├── RR (246)\n", + " │ │ ├── SCm (294)\n", + " │ │ │ ├── SCdg (26)\n", + " │ │ │ ├── SCdw (42)\n", + " │ │ │ ├── SCig (10)\n", + " │ │ │ └── SCiw (17)\n", + " │ │ ├── SNr (381)\n", + " │ │ ├── VTA (749)\n", + " │ │ └── VTN (757)\n", + " │ ├── MBsen (339)\n", + " │ │ ├── IC (4)\n", + " │ │ │ ├── ICc (811)\n", + " │ │ │ ├── ICd (820)\n", + " │ │ │ └── ICe (828)\n", + " │ │ ├── MEV (460)\n", + " │ │ ├── NB (580)\n", + " │ │ ├── PBG (874)\n", + " │ │ ├── SAG (271)\n", + " │ │ ├── SCO (599626923)\n", + " │ │ └── SCs (302)\n", + " │ │ ├── SCop (851)\n", + " │ │ ├── SCsg (842)\n", + " │ │ └── SCzo (834)\n", + " │ └── MBsta (348)\n", + " │ ├── PPN (1052)\n", + " │ ├── RAmb (165)\n", + " │ │ ├── CLI (591)\n", + " │ │ ├── DR (872)\n", + " │ │ ├── IF (12)\n", + " │ │ ├── IPN (100)\n", + " │ │ │ ├── IPA (607344842)\n", + " │ │ │ ├── IPC (607344838)\n", + " │ │ │ ├── IPDL (607344858)\n", + " │ │ │ ├── IPDM (607344854)\n", + " │ │ │ ├── IPI (607344850)\n", + " │ │ │ ├── IPL (607344846)\n", + " │ │ │ ├── IPR (607344834)\n", + " │ │ │ └── IPRL (607344862)\n", + " │ │ └── RL (197)\n", + " │ └── SNc (374)\n", + " ├── CB (512)\n", + " │ ├── CBN (519)\n", + " │ │ ├── DN (846)\n", + " │ │ ├── FN (989)\n", + " │ │ ├── IP (91)\n", + " │ │ └── VeCB (589508455)\n", + " │ └── CBX (528)\n", + " │ ├── HEM (1073)\n", + " │ │ ├── AN (1017)\n", + " │ │ │ ├── ANcr1 (1056)\n", + " │ │ │ └── ANcr2 (1064)\n", + " │ │ ├── COPY (1033)\n", + " │ │ ├── FL (1049)\n", + " │ │ ├── PFL (1041)\n", + " │ │ ├── PRM (1025)\n", + " │ │ └── SIM (1007)\n", + " │ └── VERM (645)\n", + " │ ├── CENT (920)\n", + " │ │ ├── CENT2 (976)\n", + " │ │ └── CENT3 (984)\n", + " │ ├── CUL (928)\n", + " │ │ └── CUL4, 5 (1091)\n", + " │ ├── DEC (936)\n", + " │ ├── FOTU (944)\n", + " │ ├── LING (912)\n", + " │ ├── NOD (968)\n", + " │ ├── PYR (951)\n", + " │ └── UVU (957)\n", + " └── CH (567)\n", + " ├── CNU (623)\n", + " │ ├── PAL (803)\n", + " │ │ ├── PALc (809)\n", + " │ │ │ ├── BAC (287)\n", + " │ │ │ └── BST (351)\n", + " │ │ ├── PALd (818)\n", + " │ │ │ ├── GPe (1022)\n", + " │ │ │ └── GPi (1031)\n", + " │ │ ├── PALm (826)\n", + " │ │ │ ├── MSC (904)\n", + " │ │ │ │ ├── MS (564)\n", + " │ │ │ │ └── NDB (596)\n", + " │ │ │ └── TRS (581)\n", + " │ │ └── PALv (835)\n", + " │ │ ├── MA (298)\n", + " │ │ └── SI (342)\n", + " │ └── STR (477)\n", + " │ ├── LSX (275)\n", + " │ │ ├── LS (242)\n", + " │ │ │ ├── LSc (250)\n", + " │ │ │ ├── LSr (258)\n", + " │ │ │ └── LSv (266)\n", + " │ │ ├── SF (310)\n", + " │ │ └── SH (333)\n", + " │ ├── STRd (485)\n", + " │ │ └── CP (672)\n", + " │ ├── STRv (493)\n", + " │ │ ├── ACB (56)\n", + " │ │ ├── FS (998)\n", + " │ │ └── OT (754)\n", + " │ └── sAMY (278)\n", + " │ ├── AAA (23)\n", + " │ ├── BA (292)\n", + " │ ├── CEA (536)\n", + " │ │ ├── CEAc (544)\n", + " │ │ ├── CEAl (551)\n", + " │ │ └── CEAm (559)\n", + " │ ├── IA (1105)\n", + " │ └── MEA (403)\n", + " └── CTX (688)\n", + " ├── CTXpl (695)\n", + " │ ├── HPF (1089)\n", + " │ │ ├── HIP (1080)\n", + " │ │ │ ├── CA (375)\n", + " │ │ │ │ ├── CA1 (382)\n", + " │ │ │ │ ├── CA2 (423)\n", + " │ │ │ │ └── CA3 (463)\n", + " │ │ │ ├── DG (726)\n", + " │ │ │ │ ├── DG-mo (10703)\n", + " │ │ │ │ ├── DG-po (10704)\n", + " │ │ │ │ └── DG-sg (632)\n", + " │ │ │ ├── FC (982)\n", + " │ │ │ └── IG (19)\n", + " │ │ └── RHP (822)\n", + " │ │ ├── APr (484682508)\n", + " │ │ ├── ENT (909)\n", + " │ │ │ ├── ENTl (918)\n", + " │ │ │ │ ├── ENTl1 (1121)\n", + " │ │ │ │ ├── ENTl2 (20)\n", + " │ │ │ │ ├── ENTl3 (52)\n", + " │ │ │ │ ├── ENTl5 (139)\n", + " │ │ │ │ └── ENTl6a (28)\n", + " │ │ │ └── ENTm (926)\n", + " │ │ │ ├── ENTm1 (526)\n", + " │ │ │ ├── ENTm2 (543)\n", + " │ │ │ ├── ENTm3 (664)\n", + " │ │ │ ├── ENTm5 (727)\n", + " │ │ │ └── ENTm6 (743)\n", + " │ │ ├── HATA (589508447)\n", + " │ │ ├── PAR (843)\n", + " │ │ ├── POST (1037)\n", + " │ │ ├── PRE (1084)\n", + " │ │ ├── ProS (484682470)\n", + " │ │ └── SUB (502)\n", + " │ ├── Isocortex (315)\n", + " │ │ ├── ACA (31)\n", + " │ │ │ ├── ACAd (39)\n", + " │ │ │ │ ├── ACAd1 (935)\n", + " │ │ │ │ ├── ACAd2/3 (211)\n", + " │ │ │ │ ├── ACAd5 (1015)\n", + " │ │ │ │ ├── ACAd6a (919)\n", + " │ │ │ │ └── ACAd6b (927)\n", + " │ │ │ └── ACAv (48)\n", + " │ │ │ ├── ACAv1 (588)\n", + " │ │ │ ├── ACAv2/3 (296)\n", + " │ │ │ ├── ACAv5 (772)\n", + " │ │ │ ├── ACAv6a (810)\n", + " │ │ │ └── ACAv6b (819)\n", + " │ │ ├── AI (95)\n", + " │ │ │ ├── AId (104)\n", + " │ │ │ │ ├── AId1 (996)\n", + " │ │ │ │ ├── AId2/3 (328)\n", + " │ │ │ │ ├── AId5 (1101)\n", + " │ │ │ │ ├── AId6a (783)\n", + " │ │ │ │ └── AId6b (831)\n", + " │ │ │ ├── AIp (111)\n", + " │ │ │ │ ├── AIp1 (120)\n", + " │ │ │ │ ├── AIp2/3 (163)\n", + " │ │ │ │ ├── AIp5 (344)\n", + " │ │ │ │ ├── AIp6a (314)\n", + " │ │ │ │ └── AIp6b (355)\n", + " │ │ │ └── AIv (119)\n", + " │ │ │ ├── AIv1 (704)\n", + " │ │ │ ├── AIv2/3 (694)\n", + " │ │ │ ├── AIv5 (800)\n", + " │ │ │ ├── AIv6a (675)\n", + " │ │ │ └── AIv6b (699)\n", + " │ │ ├── AUD (247)\n", + " │ │ │ ├── AUDd (1011)\n", + " │ │ │ │ ├── AUDd1 (527)\n", + " │ │ │ │ ├── AUDd2/3 (600)\n", + " │ │ │ │ ├── AUDd4 (678)\n", + " │ │ │ │ ├── AUDd5 (252)\n", + " │ │ │ │ ├── AUDd6a (156)\n", + " │ │ │ │ └── AUDd6b (243)\n", + " │ │ │ ├── AUDp (1002)\n", + " │ │ │ │ ├── AUDp1 (735)\n", + " │ │ │ │ ├── AUDp2/3 (251)\n", + " │ │ │ │ ├── AUDp4 (816)\n", + " │ │ │ │ ├── AUDp5 (847)\n", + " │ │ │ │ ├── AUDp6a (954)\n", + " │ │ │ │ └── AUDp6b (1005)\n", + " │ │ │ ├── AUDpo (1027)\n", + " │ │ │ │ ├── AUDpo1 (696)\n", + " │ │ │ │ ├── AUDpo2/3 (643)\n", + " │ │ │ │ ├── AUDpo4 (759)\n", + " │ │ │ │ ├── AUDpo5 (791)\n", + " │ │ │ │ ├── AUDpo6a (249)\n", + " │ │ │ │ └── AUDpo6b (456)\n", + " │ │ │ └── AUDv (1018)\n", + " │ │ │ ├── AUDv1 (959)\n", + " │ │ │ ├── AUDv2/3 (755)\n", + " │ │ │ ├── AUDv4 (990)\n", + " │ │ │ ├── AUDv5 (1023)\n", + " │ │ │ ├── AUDv6a (520)\n", + " │ │ │ └── AUDv6b (598)\n", + " │ │ ├── ECT (895)\n", + " │ │ │ ├── ECT1 (836)\n", + " │ │ │ ├── ECT2/3 (427)\n", + " │ │ │ ├── ECT5 (988)\n", + " │ │ │ ├── ECT6a (977)\n", + " │ │ │ └── ECT6b (1045)\n", + " │ │ ├── FRP (184)\n", + " │ │ │ ├── FRP1 (68)\n", + " │ │ │ ├── FRP2/3 (667)\n", + " │ │ │ ├── FRP5 (526157192)\n", + " │ │ │ ├── FRP6a (526157196)\n", + " │ │ │ └── FRP6b (526322264)\n", + " │ │ ├── GU (1057)\n", + " │ │ │ ├── GU1 (36)\n", + " │ │ │ ├── GU2/3 (180)\n", + " │ │ │ ├── GU4 (148)\n", + " │ │ │ ├── GU5 (187)\n", + " │ │ │ ├── GU6a (638)\n", + " │ │ │ └── GU6b (662)\n", + " │ │ ├── ILA (44)\n", + " │ │ │ ├── ILA1 (707)\n", + " │ │ │ ├── ILA2/3 (556)\n", + " │ │ │ ├── ILA5 (827)\n", + " │ │ │ ├── ILA6a (1054)\n", + " │ │ │ └── ILA6b (1081)\n", + " │ │ ├── MO (500)\n", + " │ │ │ ├── MOp (985)\n", + " │ │ │ │ ├── MOp1 (320)\n", + " │ │ │ │ ├── MOp2/3 (943)\n", + " │ │ │ │ ├── MOp5 (648)\n", + " │ │ │ │ ├── MOp6a (844)\n", + " │ │ │ │ └── MOp6b (882)\n", + " │ │ │ └── MOs (993)\n", + " │ │ │ ├── MOs1 (656)\n", + " │ │ │ ├── MOs2/3 (962)\n", + " │ │ │ ├── MOs5 (767)\n", + " │ │ │ ├── MOs6a (1021)\n", + " │ │ │ └── MOs6b (1085)\n", + " │ │ ├── ORB (714)\n", + " │ │ │ ├── ORBl (723)\n", + " │ │ │ │ ├── ORBl1 (448)\n", + " │ │ │ │ ├── ORBl2/3 (412)\n", + " │ │ │ │ ├── ORBl5 (630)\n", + " │ │ │ │ ├── ORBl6a (440)\n", + " │ │ │ │ └── ORBl6b (488)\n", + " │ │ │ ├── ORBm (731)\n", + " │ │ │ │ ├── ORBm1 (484)\n", + " │ │ │ │ ├── ORBm2/3 (582)\n", + " │ │ │ │ ├── ORBm5 (620)\n", + " │ │ │ │ ├── ORBm6a (910)\n", + " │ │ │ │ └── ORBm6b (527696977)\n", + " │ │ │ └── ORBvl (746)\n", + " │ │ │ ├── ORBvl1 (969)\n", + " │ │ │ ├── ORBvl2/3 (288)\n", + " │ │ │ ├── ORBvl5 (1125)\n", + " │ │ │ ├── ORBvl6a (608)\n", + " │ │ │ └── ORBvl6b (680)\n", + " │ │ ├── PERI (922)\n", + " │ │ │ ├── PERI1 (540)\n", + " │ │ │ ├── PERI2/3 (888)\n", + " │ │ │ ├── PERI5 (692)\n", + " │ │ │ ├── PERI6a (335)\n", + " │ │ │ └── PERI6b (368)\n", + " │ │ ├── PL (972)\n", + " │ │ │ ├── PL1 (171)\n", + " │ │ │ ├── PL2/3 (304)\n", + " │ │ │ ├── PL5 (363)\n", + " │ │ │ ├── PL6a (84)\n", + " │ │ │ └── PL6b (132)\n", + " │ │ ├── PTLp (22)\n", + " │ │ │ ├── VISa (312782546)\n", + " │ │ │ │ ├── VISa1 (312782550)\n", + " │ │ │ │ ├── VISa2/3 (312782554)\n", + " │ │ │ │ ├── VISa4 (312782558)\n", + " │ │ │ │ ├── VISa5 (312782562)\n", + " │ │ │ │ ├── VISa6a (312782566)\n", + " │ │ │ │ └── VISa6b (312782570)\n", + " │ │ │ └── VISrl (417)\n", + " │ │ │ ├── VISrl1 (312782604)\n", + " │ │ │ ├── VISrl2/3 (312782608)\n", + " │ │ │ ├── VISrl4 (312782612)\n", + " │ │ │ ├── VISrl5 (312782616)\n", + " │ │ │ ├── VISrl6a (312782620)\n", + " │ │ │ └── VISrl6b (312782624)\n", + " │ │ ├── RSP (254)\n", + " │ │ │ ├── RSPagl (894)\n", + " │ │ │ │ ├── RSPagl1 (671)\n", + " │ │ │ │ ├── RSPagl2/3 (965)\n", + " │ │ │ │ ├── RSPagl5 (774)\n", + " │ │ │ │ ├── RSPagl6a (906)\n", + " │ │ │ │ └── RSPagl6b (279)\n", + " │ │ │ ├── RSPd (879)\n", + " │ │ │ │ ├── RSPd1 (442)\n", + " │ │ │ │ ├── RSPd2/3 (434)\n", + " │ │ │ │ ├── RSPd4 (545)\n", + " │ │ │ │ ├── RSPd5 (610)\n", + " │ │ │ │ ├── RSPd6a (274)\n", + " │ │ │ │ └── RSPd6b (330)\n", + " │ │ │ └── RSPv (886)\n", + " │ │ │ ├── RSPv1 (542)\n", + " │ │ │ ├── RSPv2/3 (430)\n", + " │ │ │ ├── RSPv5 (687)\n", + " │ │ │ ├── RSPv6a (590)\n", + " │ │ │ └── RSPv6b (622)\n", + " │ │ ├── SS (453)\n", + " │ │ │ ├── SSp (322)\n", + " │ │ │ │ ├── SSp-bfd (329)\n", + " │ │ │ │ │ ├── SSp-bfd1 (981)\n", + " │ │ │ │ │ ├── SSp-bfd2/3 (201)\n", + " │ │ │ │ │ ├── SSp-bfd4 (1047)\n", + " │ │ │ │ │ ├── SSp-bfd5 (1070)\n", + " │ │ │ │ │ ├── SSp-bfd6a (1038)\n", + " │ │ │ │ │ └── SSp-bfd6b (1062)\n", + " │ │ │ │ ├── SSp-ll (337)\n", + " │ │ │ │ │ ├── SSp-ll1 (1030)\n", + " │ │ │ │ │ ├── SSp-ll2/3 (113)\n", + " │ │ │ │ │ ├── SSp-ll4 (1094)\n", + " │ │ │ │ │ ├── SSp-ll5 (1128)\n", + " │ │ │ │ │ ├── SSp-ll6a (478)\n", + " │ │ │ │ │ └── SSp-ll6b (510)\n", + " │ │ │ │ ├── SSp-m (345)\n", + " │ │ │ │ │ ├── SSp-m1 (878)\n", + " │ │ │ │ │ ├── SSp-m2/3 (657)\n", + " │ │ │ │ │ ├── SSp-m4 (950)\n", + " │ │ │ │ │ ├── SSp-m5 (974)\n", + " │ │ │ │ │ ├── SSp-m6a (1102)\n", + " │ │ │ │ │ └── SSp-m6b (2)\n", + " │ │ │ │ ├── SSp-n (353)\n", + " │ │ │ │ │ ├── SSp-n1 (558)\n", + " │ │ │ │ │ ├── SSp-n2/3 (838)\n", + " │ │ │ │ │ ├── SSp-n4 (654)\n", + " │ │ │ │ │ ├── SSp-n5 (702)\n", + " │ │ │ │ │ ├── SSp-n6a (889)\n", + " │ │ │ │ │ └── SSp-n6b (929)\n", + " │ │ │ │ ├── SSp-tr (361)\n", + " │ │ │ │ │ ├── SSp-tr1 (1006)\n", + " │ │ │ │ │ ├── SSp-tr2/3 (670)\n", + " │ │ │ │ │ ├── SSp-tr4 (1086)\n", + " │ │ │ │ │ ├── SSp-tr5 (1111)\n", + " │ │ │ │ │ ├── SSp-tr6a (9)\n", + " │ │ │ │ │ └── SSp-tr6b (461)\n", + " │ │ │ │ ├── SSp-ul (369)\n", + " │ │ │ │ │ ├── SSp-ul1 (450)\n", + " │ │ │ │ │ ├── SSp-ul2/3 (854)\n", + " │ │ │ │ │ ├── SSp-ul4 (577)\n", + " │ │ │ │ │ ├── SSp-ul5 (625)\n", + " │ │ │ │ │ ├── SSp-ul6a (945)\n", + " │ │ │ │ │ └── SSp-ul6b (1026)\n", + " │ │ │ │ └── SSp-un (182305689)\n", + " │ │ │ │ ├── SSp-un1 (182305693)\n", + " │ │ │ │ ├── SSp-un2/3 (182305697)\n", + " │ │ │ │ ├── SSp-un4 (182305701)\n", + " │ │ │ │ ├── SSp-un5 (182305705)\n", + " │ │ │ │ ├── SSp-un6a (182305709)\n", + " │ │ │ │ └── SSp-un6b (182305713)\n", + " │ │ │ └── SSs (378)\n", + " │ │ │ ├── SSs1 (873)\n", + " │ │ │ ├── SSs2/3 (806)\n", + " │ │ │ ├── SSs4 (1035)\n", + " │ │ │ ├── SSs5 (1090)\n", + " │ │ │ ├── SSs6a (862)\n", + " │ │ │ └── SSs6b (893)\n", + " │ │ ├── TEa (541)\n", + " │ │ │ ├── TEa1 (97)\n", + " │ │ │ ├── TEa2/3 (1127)\n", + " │ │ │ ├── TEa4 (234)\n", + " │ │ │ ├── TEa5 (289)\n", + " │ │ │ ├── TEa6a (729)\n", + " │ │ │ └── TEa6b (786)\n", + " │ │ ├── VIS (669)\n", + " │ │ │ ├── VISal (402)\n", + " │ │ │ │ ├── VISal1 (1074)\n", + " │ │ │ │ ├── VISal2/3 (905)\n", + " │ │ │ │ ├── VISal4 (1114)\n", + " │ │ │ │ ├── VISal5 (233)\n", + " │ │ │ │ ├── VISal6a (601)\n", + " │ │ │ │ └── VISal6b (649)\n", + " │ │ │ ├── VISam (394)\n", + " │ │ │ │ ├── VISam1 (281)\n", + " │ │ │ │ ├── VISam2/3 (1066)\n", + " │ │ │ │ ├── VISam4 (401)\n", + " │ │ │ │ ├── VISam5 (433)\n", + " │ │ │ │ ├── VISam6a (1046)\n", + " │ │ │ │ └── VISam6b (441)\n", + " │ │ │ ├── VISl (409)\n", + " │ │ │ │ ├── VISl1 (421)\n", + " │ │ │ │ ├── VISl2/3 (973)\n", + " │ │ │ │ ├── VISl4 (573)\n", + " │ │ │ │ ├── VISl5 (613)\n", + " │ │ │ │ ├── VISl6a (74)\n", + " │ │ │ │ └── VISl6b (121)\n", + " │ │ │ ├── VISli (312782574)\n", + " │ │ │ │ ├── VISli1 (312782578)\n", + " │ │ │ │ ├── VISli2/3 (312782582)\n", + " │ │ │ │ ├── VISli4 (312782586)\n", + " │ │ │ │ ├── VISli5 (312782590)\n", + " │ │ │ │ ├── VISli6a (312782594)\n", + " │ │ │ │ └── VISli6b (312782598)\n", + " │ │ │ ├── VISp (385)\n", + " │ │ │ │ ├── VISp1 (593)\n", + " │ │ │ │ ├── VISp2/3 (821)\n", + " │ │ │ │ ├── VISp4 (721)\n", + " │ │ │ │ ├── VISp5 (778)\n", + " │ │ │ │ ├── VISp6a (33)\n", + " │ │ │ │ └── VISp6b (305)\n", + " │ │ │ ├── VISpl (425)\n", + " │ │ │ │ ├── VISpl1 (750)\n", + " │ │ │ │ ├── VISpl2/3 (269)\n", + " │ │ │ │ ├── VISpl4 (869)\n", + " │ │ │ │ ├── VISpl5 (902)\n", + " │ │ │ │ ├── VISpl6a (377)\n", + " │ │ │ │ └── VISpl6b (393)\n", + " │ │ │ ├── VISpm (533)\n", + " │ │ │ │ ├── VISpm1 (805)\n", + " │ │ │ │ ├── VISpm2/3 (41)\n", + " │ │ │ │ ├── VISpm4 (501)\n", + " │ │ │ │ ├── VISpm5 (565)\n", + " │ │ │ │ ├── VISpm6a (257)\n", + " │ │ │ │ └── VISpm6b (469)\n", + " │ │ │ └── VISpor (312782628)\n", + " │ │ │ ├── VISpor1 (312782632)\n", + " │ │ │ ├── VISpor2/3 (312782636)\n", + " │ │ │ ├── VISpor4 (312782640)\n", + " │ │ │ ├── VISpor5 (312782644)\n", + " │ │ │ ├── VISpor6a (312782648)\n", + " │ │ │ └── VISpor6b (312782652)\n", + " │ │ └── VISC (677)\n", + " │ │ ├── VISC1 (897)\n", + " │ │ ├── VISC2/3 (1106)\n", + " │ │ ├── VISC4 (1010)\n", + " │ │ ├── VISC5 (1058)\n", + " │ │ ├── VISC6a (857)\n", + " │ │ └── VISC6b (849)\n", + " │ └── OLF (698)\n", + " │ ├── AOB (151)\n", + " │ │ ├── AOBgl (188)\n", + " │ │ ├── AOBgr (196)\n", + " │ │ └── AOBmi (204)\n", + " │ ├── AON (159)\n", + " │ ├── COA (631)\n", + " │ │ ├── COAa (639)\n", + " │ │ └── COAp (647)\n", + " │ │ ├── COApl (655)\n", + " │ │ └── COApm (663)\n", + " │ ├── DP (814)\n", + " │ ├── MOB (507)\n", + " │ ├── NLOT (619)\n", + " │ │ ├── NLOT1 (260)\n", + " │ │ ├── NLOT2 (268)\n", + " │ │ └── NLOT3 (1139)\n", + " │ ├── PAA (788)\n", + " │ ├── PIR (961)\n", + " │ ├── TR (566)\n", + " │ └── TT (589)\n", + " │ ├── TTd (597)\n", + " │ └── TTv (605)\n", + " └── CTXsp (703)\n", + " ├── BLA (295)\n", + " │ ├── BLAa (303)\n", + " │ ├── BLAp (311)\n", + " │ └── BLAv (451)\n", + " ├── BMA (319)\n", + " │ ├── BMAa (327)\n", + " │ └── BMAp (334)\n", + " ├── CLA (583)\n", + " ├── EP (942)\n", + " │ ├── EPd (952)\n", + " │ └── EPv (966)\n", + " ├── LA (131)\n", + " └── PA (780)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bg_atlas.structures" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The structures attribute is a custom dictionary that can be queried by region number or acronym, and contains all the information for a given structure:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'acronym': 'root',\n", + " 'id': 997,\n", + " 'mesh': None,\n", + " 'mesh_filename': PosixPath('/home/rob/.brainglobe/allen_mouse_100um_v1.2/meshes/997.obj'),\n", + " 'name': 'root',\n", + " 'rgb_triplet': [255, 255, 255],\n", + " 'structure_id_path': [997]}\n" + ] + } + ], + "source": [ + "pprint(bg_atlas.structures[\"root\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In particular, the `structure_id_path` key contains a list description of the path in the hierarchy up to a particular region, and can be used for queries on the hierarchy." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[997, 8, 567]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bg_atlas.structures[\"CH\"][\"structure_id_path\"]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can use the `bg_atlas.get_structure_descendants` and `bg_atlas.get_structure_ancestors` methods to explore the hierarchy:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['VISC1', 'VISC2/3', 'VISC4', 'VISC5', 'VISC6a', 'VISC6b']" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bg_atlas.get_structure_descendants(\"VISC\")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['root', 'grey', 'CH', 'CTX', 'CTXpl', 'Isocortex', 'VISC']" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bg_atlas.get_structure_ancestors(\"VISC6a\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "**NOTE**: \n", + "The levels of the hierarchy depend on the underlying atlas, so we cannot ensure the goodness and consistency of their hierarchy tree.\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There is a higher level description of the structures hierarchy that is built using the [treelib](https://treelib.readthedocs.io/en/latest/) package, and is available as: " + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bg_atlas.structures.tree" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For most applications though, the methods described above and the list path of each region should be sufficient to query the hierarchy without additional layers of complication." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1.3 Region masks" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `get_structure_mask` method returns a mask volume where all voxels belonging to an area or to the descendants of that area are non-zero. All other voxels are zero. We will generate the structure mask for the primary visual cortex to see how this works. \n", + "\n", + "Primary visual cortex (`VISp`) has an ID value of `385`, but no voxels in the annotation image actually have that value:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'acronym': 'VISp',\n", + " 'id': 385,\n", + " 'mesh': None,\n", + " 'mesh_filename': PosixPath('/home/rob/.brainglobe/allen_mouse_100um_v1.2/meshes/385.obj'),\n", + " 'name': 'Primary visual area',\n", + " 'rgb_triplet': [8, 133, 140],\n", + " 'structure_id_path': [997, 8, 567, 688, 695, 315, 669, 385]}\n" + ] + } + ], + "source": [ + "pprint(bg_atlas.structures[\"VISp\"])" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# No voxels in the annotation volume are labelled as being VISp\n", + "(bg_atlas.annotation==385).sum()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The reason no VISp voxels exist is because the annotation volume is segmented more finely. In this case `VISp` is divided into cortical layers and the IDs associated with these layers are the ones that are present in the annotation volume." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['VISp1', 'VISp2/3', 'VISp4', 'VISp5', 'VISp6a', 'VISp6b']" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# The descendants (children) of VISp are cortical layers\n", + "bg_atlas.get_structure_descendants(\"VISp\")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "VISp1\t593\n", + "VISp2/3\t821\n", + "VISp4\t721\n", + "VISp5\t778\n", + "VISp6a\t33\n", + "VISp6b\t305\n" + ] + } + ], + "source": [ + "# The IDs associated with each layer in primary visual cortex\n", + "layers = bg_atlas.get_structure_descendants(\"VISp\")\n", + "layer_ids = [bg_atlas.structures[this_layer]['id'] for this_layer in layers]\n", + "\n", + "for (this_layer, this_id) in zip(layers, layer_ids):\n", + " print(\"%s\\t%s\" % (this_layer, this_id))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These IDs are indeed present in the annotation volume:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1565" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# For example, we find over a thousand voxels associated with primary visual cortex layer 6\n", + "# in the annotation volume\n", + "(bg_atlas.annotation==778).sum()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So let's use `get_structure_mask` to return a mask volume that retains only `VISp`." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "mask_VISp = bg_atlas.get_structure_mask('VISp')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "f, axs = plt.subplots(1,3, figsize=(12, 3))\n", + "for i, (plane, labels) in enumerate(zip(space.sections, space.axis_labels)):\n", + " axs[i].imshow(mask_VISp.max(i), cmap=\"gray\")\n", + " axs[i].set_title(f\"{plane.capitalize()} view\")\n", + " axs[i].set_ylabel(labels[0])\n", + " axs[i].set_xlabel(labels[1])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `root` node encompasses the whole brain and we can use this to provide a background image for the above area." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "mask_root = bg_atlas.get_structure_mask('root')\n", + "\n", + "# The mask images have pixel values equal to the ID of the parent area, so we change these for\n", + "# plotting purposes. \n", + "mask_root[mask_root>0]=5\n", + "mask_VISp[mask_VISp>0]=2\n", + "mask_VISp_root = mask_VISp + mask_root" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "space = bg_atlas.space\n", + "\n", + "f, axs = plt.subplots(1,3, figsize=(12, 3))\n", + "for i, (plane, labels) in enumerate(zip(space.sections, space.axis_labels)):\n", + " axs[i].imshow(mask_VISp_root.max(i), cmap=\"gray\")\n", + " axs[i].set_title(f\"{plane.capitalize()} view\")\n", + " axs[i].set_ylabel(labels[0])\n", + " axs[i].set_xlabel(labels[1])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1.3 Regions meshes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If we need to access the structure meshes, we can either query for the file (e.g., if we need to load the file through some library like `vedo`):" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "PosixPath('/home/rob/.brainglobe/allen_mouse_100um_v1.2/meshes/567.obj')" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bg_atlas.meshfile_from_structure(\"CH\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or directly obtain the mesh, as a mesh object of the `meshio` library:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\n", + " Number of points: 56703\n", + " Number of cells:\n", + " triangle: 112948\n", + " Point data: obj:vn\n", + " Cell data: obj:group_ids" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bg_atlas.mesh_from_structure(\"CH\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2 Query the `BrainGlobeAtlas`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.0 Query for structures:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A very convenient feature of the `BrainGlobeAtlas` API is the simplicity of querying for the identity of the structure or the hemisphere at a given location, either from stack indexes or space coordinates, and even cutting the hierarchy at some higher level:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "By index: CP\n", + "By coordinates: CP\n", + "Higher hierarchy level: CH\n" + ] + } + ], + "source": [ + "# Ask for identity of some indexes in the stack:\n", + "print(\"By index:\", bg_atlas.structure_from_coords((50, 40, 30), \n", + " as_acronym=True))\n", + "\n", + "# Now give coordinates in microns\n", + "print(\"By coordinates:\", bg_atlas.structure_from_coords((5000, 4000, 3000), \n", + " as_acronym=True, \n", + " microns=True))\n", + "\n", + "# Now cut hierarchy at some level\n", + "print(\"Higher hierarchy level:\", bg_atlas.structure_from_coords((5000, 4000, 3000), \n", + " as_acronym=True, \n", + " microns=True, \n", + " hierarchy_lev=2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.1 Query for hemispheres" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A very similar method can be used for hemispheres. 0 corresponds to outside the brain, and 1 and 2 to left and right hemispheres respectively - but we can just ask for the hemisphere name instead of the number:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "By index: 2\n", + "By coordinates: 2\n", + "By : 2\n" + ] + } + ], + "source": [ + "# Ask for identity of some indexes in the stack:\n", + "print(\"By index:\", bg_atlas.hemisphere_from_coords((50, 40, 30)))\n", + "\n", + "# Now give coordinates in microns\n", + "print(\"By coordinates:\", bg_atlas.hemisphere_from_coords((5000, 4000, 3000), microns=True))\n", + "\n", + "# Now print side string\n", + "print(\"By :\", bg_atlas.hemisphere_from_coords((5000, 4000, 3000), microns=True))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 }