From a0e2682944cb7db878c62bc312c8ae376b5bd62a Mon Sep 17 00:00:00 2001 From: polarbean Date: Thu, 12 Sep 2024 15:00:14 +0200 Subject: [PATCH 01/14] added the australian mouse brain atlas --- .../atlas_scripts/australian_mouse_brain.py | 863 ++++++++++++++++++ 1 file changed, 863 insertions(+) create mode 100644 brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py diff --git a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py new file mode 100644 index 00000000..0e316e23 --- /dev/null +++ b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py @@ -0,0 +1,863 @@ +__version__ = "1" +import tarfile +import os +import json +import multiprocessing as mp +import time +from pathlib import Path +import requests +import numpy as np +import pandas as pd +import SimpleITK as sitk +from rich.progress import track +from brainglobe_atlasapi import utils +from brainglobe_atlasapi.atlas_generation.mesh_utils import ( + Region, + create_region_mesh, +) +from brainglobe_atlasapi.atlas_generation.wrapup import wrapup_atlas_from_data +from brainglobe_atlasapi.structure_tree_util import get_structures_tree + +from pathlib import Path + +from brainglobe_atlasapi.atlas_generation.wrapup import wrapup_atlas_from_data +import nibabel as nib + +# Copy-paste this script into a new file and fill in the functions to package +# your own atlas. + +### Metadata ### +__version__ = 0 +ATLAS_NAME = "australian_mouse" +CITATION = "lANKE et al. 2015, https://doi.org/10.1016/j.ymeth.2015.01.005" +SPECIES = "Mus musculus" +ATLAS_LINK = "https://imaging.org.au/AMBMC/" +ORIENTATION = "ial" +ROOT_ID = 9999 +RESOLUTION = 15 +BG_ROOT_DIR = Path.home() / "brainglobe_workingdir" / ATLAS_NAME +ANNOTATION_URLS = { + "basalganglia": "https://osf.io/download/xgj4h", + "cerebellum": "https://osf.io/download/su2a9", + "cortex": "https://osf.io/download/hr39a", + "hippocampus": "https://osf.io/download/tjazr", + "diencephalon": "https://osf.io/download/9atc7", +} +REGION_IDS = { + "basalganglia": 1001, + "cerebellum": 1002, + "cortex": 1003, + "hippocampus": 1004, + "diencephalon": 1005, +} +PARALLEL = False +acronym_dict = { + "diencephalon": { + "mfb": "Medial forebrain bundle", + "3N": "oculomotor nucleus", + "3PC": "oculomotor nucleus, parvicellular part", + "3V": "third ventricle", + "4N": "trochlear nucleus", + "ac": "anterior commissure", + "acp": "anterior commissure, posterior limb", + "AD": "anterodorsal thalamic nucleus", + "AM": "anteromedial thalamic nucleus", + "AMV": "anteromedial thalamic nucleus, ventral part", + "AngT": "angular thalamic nucleus", + "APT": "anterior pretectal nucleus", + "APTD": "anterior pretectal nucleus, dorsal part", + "APTV": "anterior pretectal nucleus, ventral part", + "Aq": "aqueduct", + "aur": "auditory radiation", + "AV": "anteroventral thalamic nucleus", + "AVDM": "anteroventral thalamic nucleus, dorsolateral part", + "AVVL": "anteroventral thalamic nucleus, ventrolateral part", + "B9": "B9 serotonin cells", + "bic": "brachium of the inferior colliculus", + "bsc": "brachium or the superior colliculus", + "CA1": "field CA1 of the hippocampus", + "CA2": "field CA2 of the hippocampus", + "CA3": "field CA3 of the hippocampus", + "cc": "corpus callosum", + "chp": "choroid plexus", + "CL": "centrolateral thalamic nucleus", + "CM": "central medial thalamic nucleus", + "cp": "cerebral peduncle", + "csc": "commissure of the superior colliculus", + "D3V": "dorsal 3rd ventricle", + "DG": "dentate gyrus", + "Dk": "nucleus of Darkschewitsch", + "DLG": "dorsal lateral geniculate nucleus", + "DpG": "deep gray layer of the superior colliculus", + "DpWh": "deep white layer of the superior colliculus", + "DR": "dorsal raphe nucleus", + "eml": "external medullary lamina", + "EP": "endopeduncular nucleus", + "Eth": "ethmoid thalamic nucleus", + "F": "nucleus of the field of Forel", + "f": "fornix", + "fi": "fimbria", + "fr": "fasciculus retroflexus", + "Gem": "gemini hypothalamic nucleus", + "GP": "globus pallidus", + "hbc": "habenular commissure", + "hif": "hippocampal fissure", + "IAD": "interanterodorsal thalamic nucleus", + "IAM": "interanteromedial thalamic nucleus", + "ic": "internal capsule", + "IF": "interfascicular nucleus", + "IGL": "intergeniculate leaflet", + "IMA": "intermedullary thalamic nucleus", + "IMD": "intermediodorsal thalamic nucleus", + "InC": "interstitial nucleus of Cajal", + "InCSh": "interstitial nucleus of Cajal, shell region", + "InG": "intermediate layer of the superior colliculus", + "InWh": "intermediate white layer of the superior colliculus", + "IPF": "interpeduncular fossa", + "IPC": "interpeduncular nucleus, caudal part", + "IPR": "interpeduncular nucleus, rostral part", + "isRt": "isthmic reticular formation", + "IVF": "interventricular foramen", + "JPLH": "juxtaparaventricular part of lateral hypothalamus", + "LD": "laterodorsal thalamic nucleus", + "LDDM": "laterodorsal thalamic nucleus, dorsomedial part", + "LDVL": "laterodorsal thalamic nucleus, ventrolateral part", + "LHb": "lateral habenular nucleus", + "LHbM": "lateral habenular nucleus, medial part", + "LHbL": "lateral habenular nucleus, lateral part", + "LP": "lateral posterior thalamic nucleus", + "LPAG": "lateral part of the periaqueductal gray", + "LPLC": "lateral posterior thalamic nucleus, laterocaudal part", + "LPLR": "lateral posterior thalamic nucleus, laterorostral part", + "LPMC": "lateral posterior thalamic nucleus, mediocaudal part", + "LPMR": "lateral posterior thalamic nucleus, mediorostral part", + "LT": "lateral terminal nucleus (pretectum)", + "Lth": "lithoid nucleus", + "LV": "lateral ventricle", + "MA3": "medial accessory oculomotor nucleus", + "MCPC": "magnocellular nucleus of the posterior commissure", + "mes": "mesencephalon", + "MD": "mediodorsal thalamic nucleus", + "MDC": "mediodorsal thalamic nucleus, central part", + "MDL": "mediodorsal thalamic nucleus, lateral part", + "MDM": "mediodorsal thalamic nucleus, medial part", + "MG": "medial geniculate nucleus", + "MGD": "medial geniculate nucleus, dorsal part", + "MGM": "medial geniculate nucleus, medial part", + "MGV": "medial geniculate nucleus, ventral part", + "MHb": "medial habenular nucleus", + "ml": "medial lemniscus", + "mlf": "medial longitudinal fasciculus", + "mp": "mamillary peduncle", + "MPT": "medial pretectal nucleus", + "MT": "medial terminal nucleus", + "mt": "mammillothalamic tract", + "ns": "nigrostriatal tract", + "Op": "optic nerve layer of the superior colliculus", + "OPC": "oval paracentral thalamic nucleus", + "OPT": "olivary pretectal nucleus", + "opt": "optic tract", + "OT": "nucleus of the optic tract", + "p1": "prosomere 1", + "p1Rt": "prosomere 1 reticular formation", + "p2": "prosomere 2", + "p3": "prosomere 3", + "Pa": "paraventricular hypothalamic nucleus", + "PaF": "parafascicular thalamic nucleus", + "PAG": "periaqueductal gray", + "PaPo": "paraventricular hypothalamic nucleus, posterior part", + "PaR": "pararubral nucleus", + "PaXi": "paraxiphoid nucleus", + "PBP": "parabrachial pigmented nucleus of the ventral tegmental area", + "pc": "paracentral thalamic nucleus", + "PC": "paracentral thalamic nucleus", + + "PCom": "nucleus of the posterior commissure", + "PF": "parafascicular thalamic nucleus", + "PH": "posterior hypothalamus", + "PIF": "parainterfascicular nucleus of the VTA", + "PIL": "posterior intralaminar thalamic nucleus", + "pm": "principal mammillary tract", + "PN": "paranigral nucleus", + "Po": "posterior thalamic nuclear group", + "PoT": "posterior thalamic nuclear group, triangular part", + "PP": "peripeduncular nucleus", + "PR": "prerubral field", + "PrC": "precommissural nucleus", + "PrEW": "pre-Edinger-Westphal nucleus", + "PrG": "pregnculate nucleus of the prethalamus", + "PSTh": "parasubthalamic nucleus", + "PT": "paratenial thalamic nucleus", + "PTg": "peduncular tegmental nucleus", + "PV": "paraventricular thalamic nucleus", + "PVA": "paraventricular thalamic nucleus, anterior part", + "PVP": "paraventricular thalamic nucleus, posterior part", + "Re": "reuniens thalamic nucleus", + "REth": "retroethmoid nucleus", + "Rh": "rhomboid thalamic nucleus", + "RI": "rostral interstitial nucleus", + "RLi": "rostral linear nucleus", + "RM": "retromamillary nucleus", + "RMC": "red nucleus, magnocellular part", + "RPC": "red nucleus, parvicellular part", + "RPF": "retroparafascicular nucleus", + "RRe": "retroreuniens nucleus", + "RRF/A8": "retrorubral field and A8 dopamine cells", + "Rt": "reticular nucleus (prethalamus)", + "Sag": "sagulum nucleus", + "SC": "superior colliculus", + "Sc": "scaphoid nucleus", + "scp": "superior cerebellar peduncle", + "SG": "suprageniculate nucleus", + "SM": "stria medullaris", + "sm": "stria medullaris", + "SNC": "substantia nigra, compact part", + "SNCD": "substantia nigra, compact part, dorsal tier", + "SNL": "substantia nigra, lateral part", + "SNR": "substantia nigra, reticular part", + "sox": "supraoptic descussation", + "SPF": "subparafascicular thalamic nucleus", + "SPFPC": "subparafascicular thalamic nucleus, parvicellular part", + "ST": "stria terminalis", + "STh": "subthalamic nucleus", + "str": "superior thalamic radiation", + "Su3": "supraoculomotor periaqueductal gray", + "Su3C": "supraoculomotor cap", + "Sub": "submedius thalamic nucleus", + "SubB": "subbrachial nucleus", + "SubG": "subgeniculate nucleus of the prethalamus (ventrolateral nucleus)", + "SuG": "superficial gray layer of the superior colliculus", + "Te": "terete hypothalamic nucleus", + "TG": "tectal gray", + "TS": "triangular septal nucleus", + "VA": "ventral anterior thalamic nucleus", + "vhc": "ventral hippocampal commissure", + "VL": "ventrolateral thalamic nucleus", + "VLi": "ventral linear nucleus", + "VM": "ventromedial thalamic nucleus", + "VPL": "ventral posterolateral thalamic nucleus", + "VPM": "ventral posteromedial thalamic nucleus", + "VPPC": "ventral posterior thalamic nucleus", + "VRe": "ventral reuniens thalamic nucleus", + "VTA": "ventral tegmental area", + "VTAR": "ventral tegmental area, rostral part", + "vtgx": "ventral tegmental decussation", + "Xi": "xiphoid nucleus", + "ZI": "zona incerta", + "ZIC": "zona incerta, central part", + "ZID": "zona incerta, dorsal part", + "ZIR": "zona incerta, rostral part", + "ZIV": "zona incerta, ventral part", + }, + "basalganglia": { + "aca": "Anterior limb of anterior commissure", + "AcbC": "Accumbens nucleus core", + "AcbSh": "Accumbens nucleus shell", + "acp": "Posterior limb of posterior commissure", + "ADC": "Apparent diffusion coefficient", + "AOP": "Anterior olfactory area", + "ASt": "Amygdalostriatal transition area", + "B": "Basal nucleus (Meynert)", + "cc/ec": "Corpus collosum/external capsule", + "Ce": "Central amygdaloid nucleus", + "CPu": "Caudate putamen", + "DWI": "Diffusion weighted imaging", + "EA": "Extended amygdala", + "EP": "Entopeduncular nucleus", + "f": "Fornix", + "FA": "Fractional anisotropy", + "FOD": "fiber orientation distributions", + "Fu": "Bed nucleus of stria terminalis, fusiform part", + "GP": "Globus pallidus", + "HDB": "Nucleus of the horizontal limb of the diagonal band", + "ic": "Internal capsule", + "ICjM": "Magna island of Calleja", + "IEn": "Intermediate nucleus of the endopiriform claustrum", + "IPAC": "Interstitial nucleus of the post limb of the anterior commissure", + "LAcbSh": "Accumbens nucleus shell, lateral part", + "LDB": "Lateral nucleus of the horizontal limb of the diagonal band", + "LH": "Lateral hypothalamus", + "LPO": "Lateral preoptic area", + "LSI": "Lateral septal nucleus", + "LSS": "Lateral striatal stripe", + "LV": "Lateral Ventricle", + "MDA": "Minimum deformation atlas", + "mfb": "Medial forebrain bundle", + "MS": "Medial septal nucleus", + "MRI": "Magnetic resonance imaging", + "ns": "Nigrostriatal bundle", + "opt": "Optic tract", + "ROI": "Region of interest", + "SIB": "Substantia innominate, part B", + "ST": "Bed nucleus of stria terminalis", + "st": "Stria terminalis", + "Tu": "Olfactory tubercle", + "VDB": "Nucleus of the vertical limb of the diagonal band", + "VP": "Ventral pallidum", + }, + "cerebellum": { + "IC": "Unclassified", + "1Cb": "Lobule 1", + "1/2Cb": "Lobules 1/2", + "2Cb": "Lobule 2", + "2/3Cb": "Lobules 2/3", + "3Cb": "Lobule 3", + "3/4Cb": "Lobules 3/4", + "4Cb": "Lobule 4", + "4/5Cb": "Lobules 4/5", + "5Cb": "Lobule 5", + "6Cb": "Lobule 6", + "7Cb": "Lobule 7", + "8Cb": "Lobule 8", + "9Cb": "Lobule 9", + "10Cb": "Lobule 10", + "Sim": "Simple lobule", + "Crus1": "Crus 1 of the ansiform lobule", + "Crus2": "Crus 2 of the ansiform lobule", + "PM": "Paramedian lobule", + "Cop": "Copula of the pyramis", + "PFl": "Paraflocculus", + "FL": "Flocculus", + "mlf": "Medial longitudinal fasciculus", + "scp": "Superior cerebellar peduncle", + "mcp": "Middle cerebellar peduncle", + "icp": "Inferior cerebellar peduncle", + "xscp": "Decussation of the superior cerebellar peduncle", + "Rbd": "Restiform body", + "vsc": "Ventral spinocerebellar tract", + "Med": "Medial cerebellar nucleus", + "MedDL": "Medial cerebellar nucleus, dorsolateral protuberance", + "MedL": "Medial cerebellar nucleus, lateral part", + "Lat": "Lateral cerebellar nucleus", + "LatPC": "Lateral cerebellar nucleus, parvicellular part", + "SMV": "Superior medullary velum", + "DC": "Dorsal cochlear nuclei", + "VCA": "Ventral cochlear nuclei, anterior part", + "VCP": "Ventral cochlear nuclei, posterior part", + "IntA": "Interposed cerebellar nucleus, anterior", + "IntDL": "Interposed cerebellar nucleus, dorsolateral hump", + "IntP": "Interposed cerebellar nucleus, posterior", + "IntPPC": "Interposed cerebellar nucleus, posterior parvicellular part", + "das": "Dorsal acoustic stria", + }, + "hippocampus": { + "CA1-Py":"CA1-Pyramidal cell layer", + "CA1-Or":"CA1-Pyramidal Oriens layer", + "CA1-Lmol":"CA1-Lacunosum Moleculare layer", + "CA1-Rad":"CA1-Radiatum layer", + "CA2-Py":"CA2-Pyramidal cell layer", + "CA2-Or":"CA2-Pyramidal Oriens layer", + "CA2-Lmol":"CA2-Lacunosum Moleculare layer", + "CA2-Rad":"CA2-Radiatum layer", + "CA3-Py-inner":"CA3-inner Pyramidal cell layer", + "CA3-Py-outer":"CA3-outer Pyramidal cell layer", + "CA3-Py":"CA3-Pyramidal cell layer", + "CA3-Or":"CA3-Pyramidal Oriens layer", + "CA3-Lmol":"CA3-Lacunosum Moleculare layer", + "CA3-Rad":"CA3-Radiatum layer", + "Or": "Oriens layer", + "Py": "Pyramidal cell layer", + "Rad": "Radiatum layer", + "LMol": "Lacunosum Moleculare layer", + "Stratum-Lu": "Stratum Lucidum", + "Dentate-Gyrus-MoDG": "Molecular layer of Dentate Gyrus", + "Dentate-Gyrus-GrDG": "Granule layer of Dentate Gyrus", + "Dentate-Gyrus-PoDG": "Polymorph layer of Dentate Gyrus", + "hif": "hippocampal fissure", + "FC": "Fasciola Cinereum", + "PRh": "Perirhinal Cortex", + "DLEnt": "Dorsolateral Entorhinal area", + "DIEnt": "Dorsal Intermediate Entorhinal area", + "VIEnt": "Ventral Intermediate Entorhinal area", + "MEnt": "Medial Entorhinal area", + "CEnt": "Caudomedial Entorhinal area", + "APir": "Amygdalopiriform transition area", + "PMCo": "Posteromedial cortical amygdaloid area", + "Pir": "Piriform cortex", + "DS": "Dorsal Subiculum", + "VS": "Ventral Subiculum", + "Post": "Post subiculum", + "STr": "Subiculum, transition area", + "PrS": "Presubiculum", + "PaS": "Parasubiculum", + "cc": "corpus callosum", + "ec": "external capsule", + "cg": "cingulum", + "LV": "Lateral Ventricle", + "3 V": "Third Ventricle", + "alv": "alveus", + "df": "dorsal fornix", + "fi": "fimbria", + "IG": "Indusium Griseum", + "dhc": "dorsal hippocampal commissure", + "RSD": "Retrosplenial Dysgranular cortex", + "RSGa": "Retrosplenial Granular cortex, a region", + "RSGb": "Retrosplenial Granular cortex, b region", + "RSGc": "Retrosplenial Granular cortex, c region", + }, + "cortex": { + "A24a": "Cingulate cortex, area 24a", + "A24a'": "Cingulate cortex, area 24a'", + "A24b": "Cingulate cortex, area 24b", + "A24b'": "Cingulate cortex, area 24b'", + "A25": "Cingulate cortex, area 25", + "A29a": "Cingulate cortex, area 29a", + "A29b": "Cingulate cortex, area 29b", + "A29c": "Cingulate cortex, area 29c", + "A30": "Cingulate cortex, area 30", + "A32": "Cingulate cortex, area 32", + "APir": "Ammon's horn/piriform cortex", + "Au1": "Primary auditory cortex", + "AuD": "Secondary auditory cortex, dorsal area", + "AuV": "Secondary auditory cortex, ventral area", + "cc/ec": "Corpus callosum/external capsule", + "CEnt": "Caudomedial entorhinal cortex", + "cg": "Cingulate gyrus", + "Cl": "Claustrum", + "CxA": "Cortex-amygdala transition area", + "DCl": "Dorsal claustrum", + "DEn": "Dorsal endopiriform nucleus", + "df": "Dorsal fornix", + "dhc": "Dorsal hippocampal commissure", + "DIEnt": "Dorsal intermediate entorhinal cortex", + "DLEnt": "Dorsolateral entorhinal cortex", + "DLO": "Dorsolateral orbital cortex", + "DS": "Dorsal subiculum", + "DTT": "Dorsal tenia tecta", + "Ect": "Ectorhinal cortex", + "fmi": "Forceps minor of the corpus callosum", + "Fr3": "Frontal cortex, area 3", + "FrA": "Frontal association cortex", + "IEn": "Intermediate endopiriform nucleus", + "Ins": "Insular region, not subdivided", + "LO": "Lateral orbital cortex", + "lo": "Lateral orbital cortex (orbital part)", + "LPtA": "Lateral parietal association cortex", + "M1": "Primary motor cortex", + "M2": "Secondary motor cortex", + "MEnt": "Medial entorhinal cortex", + "MO": "Medial orbital cortex", + "MPtA": "Medial parietal association cortex", + "PaS": "Parasubiculum", + "Pir": "Piriform cortex", + "PLCo": "Posterior lateral cortical amygdala", + "PMCo": "Posterior medial cortical amygdala", + "Post": "Postsubiculum", + "PRh": "Perirhinal cortex", + "PrS": "Presubiculum", + "PtPR": "Parietal cortex, posterior area, rostral part", + "RAPir": "Retro-allocortical piriform cortex", + "S1": "Primary somatosensory cortex", + "S1BF": "Primary somatosensory cortex, barrel field", + "S1DZ": "Primary somatosensory cortex, dysgranular zone", + "S1FL": "Primary somatosensory cortex, forelimb region", + "S1HL": "Primary somatosensory cortex, hindlimb region", + "S1J": "Primary somatosensory cortex, jaw region", + "S1Sh": "Primary somatosensory cortex, shoulder region", + "S1Tr": "Primary somatosensory cortex, trunk region", + "S1ULp": "Primary somatosensory cortex, upper lip region", + "S2": "Secondary somatosensory cortex", + "STr": "Subiculum transition area", + "TeA": "Temporal association cortex", + "V1": "Primary visual cortex", + "V1B": "Primary visual cortex, binocular area", + "V1M": "Primary visual cortex, monocular area", + "V2L": "Secondary visual cortex, lateral area", + "V2ML": "Secondary visual cortex, mediolateral area", + "V2MM": "Secondary visual cortex, mediomedial area", + "VCl": "Visual cortex, lateral area", + "VEn": "Ventral entorhinal cortex", + "VIEnt": "Ventral intermediate entorhinal cortex", + "VO": "Ventrolateral orbital cortex", + "VTT": "Ventral tenia tecta", + }, +} +TEMPLATE_STRING = "ambmc-c57bl6-label-{}_v0.8{}" + +def download_resources(): + download_dir_path = BG_ROOT_DIR / "downloads" + download_dir_path.mkdir(exist_ok=True) + atlas_files_dir = download_dir_path / "atlas_files" + ## Download atlas_file + utils.check_internet_connection() + destination_path = download_dir_path / f"template.nii.tar.gz" + if not os.path.isfile(destination_path): + response = requests.get(REFERENCE_URL, stream=True) + with open(destination_path, "wb") as f: + for chunk in response.iter_content(chunk_size=8192): + if chunk: + f.write(chunk) + with tarfile.open(destination_path, "r:gz") as tar: + tar.extractall(path=download_dir_path) + for region, url in ANNOTATION_URLS.items(): + destination_path = BG_ROOT_DIR / f"{region}.nii.tar.gz" + if not os.path.isfile(destination_path): + response = requests.get(url, stream=True) + with open(destination_path, "wb") as f: + for chunk in response.iter_content(chunk_size=8192): + if chunk: + f.write(chunk) + # Untar the file + with tarfile.open(destination_path, "r:gz") as tar: + tar.extractall(path=BG_ROOT_DIR) + return None + +def preprocess_annotations(): + """ + The annotations are split amongst multiple files, + in different formats, and are required to correct values + in the volumes themselves which are at times overlapping. + So this preprocessing function must be run before retrieving + the reference and annotation + """ + download_dir_path = BG_ROOT_DIR / "downloads" + for region in REGION_IDS.keys(): + label_path = f"{download_dir_path}/{TEMPLATE_STRING.format(region, '-nii')}/{TEMPLATE_STRING.format(region, '.idx')}" + label_list = [] + for region, url in ANNOTATION_URLS.items(): + path = f"{download_dir_path}/{TEMPLATE_STRING.format(region, '-nii')}/{TEMPLATE_STRING.format(region, '.nii')}" + img = sitk.ReadImage(path) + arr = sitk.GetArrayFromImage(img) + + label_path = f"{download_dir_path}/{TEMPLATE_STRING.format(region, '-nii')}/{TEMPLATE_STRING.format(region, '.idx')}" + if region == "hippocampus": + total_label = pd.concat(label_list) + label = pd.read_csv(label_path, sep="\t") + # correct misformatting + label["# Hippocampus labels"][ + label["# Hippocampus labels"] == "012 CA2 Py " + ] = "012 CA2-Py " + label = label["# Hippocampus labels"].str.split(" ", expand=True) + label = label.iloc[3:, :2].reset_index(drop=True) + label = label.rename(columns={"0": "id", "1": "acronym"}) + # Generate new RGB values + new_df = pd.DataFrame(columns=["r", "g", "b"]) + while len(new_df) < len( + label + ): + new_rgb = np.random.randint( + 0, 256, size=3 + ) # Generate a new RGB value + if not ( + (total_label[["r", "g", "b"]] == new_rgb).all(axis=1).any() + ): # If the RGB value doesn't exist in df + new_df = new_df._append( + pd.Series(new_rgb, index=["r", "g", "b"]), + ignore_index=True, + ) # Add it to new_df + label[["r", "g", "b"]] = new_df[["r", "g", "b"]] + label = label.rename(columns={0: "id", 1: "acronym"}) + label['id'] = np.arange(1,16) + else: + label = pd.read_csv(label_path, sep="\t", header=None) + label = label.rename( + columns={0: "id", 1: "r", 2: "g", 3: "b", 4: "acronym"} + ) + label = label[label["acronym"] != "Black (Background)"] + label = label[label["acronym"] != "White (White)"] + label["structure_id_path"] = label.apply( + lambda x: [ROOT_ID, REGION_IDS[region], x["id"]], axis=1 + ) + label['acronym'] = label['acronym'].str.strip() + #correct typo + label.loc[label['acronym'] == 'Zl', 'acronym'] = 'ZI' + label['name'] = label['acronym'].map(acronym_dict[region]) + label.loc[label['name'].isna(), 'name'] = label.loc[label['name'].isna(), 'acronym'] + label_path = f"{download_dir_path}/{TEMPLATE_STRING.format(region, '-nii')}/{TEMPLATE_STRING.format(region, '_new.idx')}" + label.to_csv(label_path) + label_list.append(label) + +def retrieve_reference_and_annotation(): + """ + Retrieve the desired reference and annotation as two numpy arrays. + + Returns: + tuple: A tuple containing two numpy arrays. The first array is the + reference volume, and the second array is the annotation volume. + """ + download_dir_path = BG_ROOT_DIR / "downloads" + filename = ( + download_dir_path + / "template.nii" + / "ambmc-c57bl6-model-symmet_v0.8-nii" + / "ambmc-c57bl6-model-symmet_v0.8.nii" + ) + reference = sitk.GetArrayFromImage(sitk.ReadImage(str(filename))) + ### This part is complex as the atlas segmentations are + ### Distributed through multiple files which we combine. + original_origin = np.array([5.07600021, 9.81449986, -3.72600007]) + annotation = np.zeros((499, 1311, 679)) + new_vals = 1 + for region in REGION_IDS.keys(): + filename = f"{BG_ROOT_DIR}/{TEMPLATE_STRING.format(region, '-nii')}/{TEMPLATE_STRING.format(region, '.nii')}" + label_path = f"{download_dir_path}/{TEMPLATE_STRING.format(region, '-nii')}/{TEMPLATE_STRING.format(region, '_new.idx')}" + label_data = pd.read_csv(label_path) + img = sitk.ReadImage(filename) + arr = sitk.GetArrayFromImage(img) + id_mapping = {} + #This has to be done because the ids in the labelfile are in + #correct order, but are not aligned with the volume + for i,idval in enumerate(label_data['id']): + arr[arr==(i+1)] = new_vals + id_mapping[idval] = new_vals + new_vals += 1 + # Assuming annotated_volume is a numpy array + new_label_data = label_data.copy() + new_label_data['id'] = new_label_data['id'].map(id_mapping) + output_path = f"{download_dir_path}/{TEMPLATE_STRING.format(region, '-nii')}/{TEMPLATE_STRING.format(region, '_renumbered.idx')}" + new_label_data.to_csv(output_path) + origin = np.array(img.GetOrigin()) + spacing = np.array(img.GetSpacing()) + origin_px = np.round((original_origin - origin) / spacing).astype(int) + segment = annotation[ + origin_px[0] : origin_px[0] + arr.shape[0], + origin_px[1] : origin_px[1] + arr.shape[1], + origin_px[2] : origin_px[2] + arr.shape[2], + ] + mask = arr != 0 + segment[mask] = arr[mask] + return annotation, reference + + +def retrieve_hemisphere_map(): + """ + Retrieve a hemisphere map for the atlas. + + If your atlas is asymmetrical, you may want to use a hemisphere map. + This is an array in the same shape as your template, + with 0's marking the left hemisphere, and 1's marking the right. + + If your atlas is symmetrical, ignore this function. + + Returns: + numpy.array or None: A numpy array representing the hemisphere map, + or None if the atlas is symmetrical. + """ + return None #Symmetrical atlas + + +def retrieve_structure_information(): + """ + This function should return a pandas DataFrame with information about your + atlas. + + The DataFrame should be in the following format: + + ╭────┬───────────────────┬─────────┬───────────────────┬─────────────────╮ + | id | name | acronym | structure_id_path | rgb_triplet | + | | | | | | + ├────┼───────────────────┼─────────┼───────────────────┼─────────────────┤ + | 997| root | root | [997] | [255, 255, 255] | + ├────┼───────────────────┼─────────┼───────────────────┼─────────────────┤ + | 8 | Basic cell groups | grey | [997, 8] | [191, 218, 227] | + ├────┼───────────────────┼─────────┼───────────────────┼─────────────────┤ + | 567| Cerebrum | CH | [997, 8, 567] | [176, 240, 255] | + ╰────┴───────────────────┴─────────┴───────────────────┴─────────────────╯ + + Returns: + pandas.DataFrame: A DataFrame containing the atlas information. + """ + download_dir_path = BG_ROOT_DIR / "downloads" + + hierarchical_labels = pd.DataFrame( + { + "id": [ROOT_ID, 1001, 1002, 1003, 1004, 1005], + "acronym": [ + "root", + "basalganglia", + "cerebellum", + "cortex", + "hippocampus", + "diencephalon", + ], + "name": [ + "root", + "basalganglia", + "cerebellum", + "cortex", + "hippocampus", + "diencephalon", + ], + "structure_id_path": [ + [ROOT_ID], + [ROOT_ID, 1001], + [ROOT_ID, 1002], + [ROOT_ID, 1003], + [ROOT_ID, 1004], + [ROOT_ID, 1005], + ], + } + ) + label_list = [] + for region in REGION_IDS.keys(): + file_path = f"{download_dir_path}/{TEMPLATE_STRING.format(region, '-nii')}/{TEMPLATE_STRING.format(region, '_renumbered.idx')}" + label_list.append(pd.read_csv(file_path)) + df = pd.concat(label_list).reset_index(drop=True) + new_df = pd.DataFrame(columns=["r", "g", "b"]) + while len(new_df) < len( + hierarchical_labels + ): # Change 1 to the number of new RGB values you want to generate + new_rgb = np.random.randint(0, 256, size=3) # Generate a new RGB value + if not ( + (df[["r", "g", "b"]] == new_rgb).all(axis=1).any() + ): # If the RGB value doesn't exist in df + new_df = new_df._append( + pd.Series(new_rgb, index=["r", "g", "b"]), + ignore_index=True, + ) # Add it to new_df + hierarchical_labels[["r", "g", "b"]] = new_df[["r", "g", "b"]] + hierarchical_labels.loc[ + hierarchical_labels["id"] == 0, ["r", "g", "b"] + ] = [0, 0, 0] + + rgb = [] + for index, row in df.iterrows(): + temp_id = row["id"] + + temp_rgb = [row["r"], row["g"], row["b"]] + rgb.append(temp_rgb) + + df = df.drop(columns=["r", "g", "b"]) + df = df.assign(rgb_triplet=rgb) + total_df = pd.concat([hierarchical_labels, df]) + total_df = total_df[['acronym', 'id', 'name', 'structure_id_path', 'rgb_triplet']] + structures = total_df.to_dict("records") + for s in structures: + if ( isinstance(s['structure_id_path'], str)): + s['structure_id_path'] = eval(s['structure_id_path']) + return structures + + +def retrieve_or_construct_meshes(annotated_volume, structures): + """ + This function should return a dictionary of ids and corresponding paths to + mesh files. Some atlases are packaged with mesh files, in these cases we + should use these files. Then this function should download those meshes. + In other cases we need to construct the meshes ourselves. For this we have + helper functions to achieve this. + """ + meshes_dir_path = BG_ROOT_DIR / "downloads" / "meshes" + meshes_dir_path.mkdir(exist_ok=True) + + tree = get_structures_tree(structures) + + labels = np.unique(annotated_volume).astype(np.int32) + for key, node in tree.nodes.items(): + if key in labels: + is_label = True + else: + is_label = False + + node.data = Region(is_label) + + # Mesh creation + closing_n_iters = 2 # not used for this atlas + decimate_fraction = 0 # not used for this atlas + + smooth = False + start = time.time() + if PARALLEL: + pool = mp.Pool(mp.cpu_count() - 2) + + try: + pool.map( + create_region_mesh, + [ + ( + meshes_dir_path, + node, + tree, + labels, + annotated_volume, + ROOT_ID, + closing_n_iters, + decimate_fraction, + smooth, + ) + for node in tree.nodes.values() + ], + ) + except mp.pool.MaybeEncodingError: + # error with returning results from pool.map but we don't care + pass + else: + for node in track( + tree.nodes.values(), + total=tree.size(), + description="Creating meshes", + ): + create_region_mesh( + ( + meshes_dir_path, + node, + tree, + labels, + annotated_volume, + ROOT_ID, + closing_n_iters, + decimate_fraction, + smooth, + ) + ) + + print( + "Finished mesh extraction in: ", + round((time.time() - start) / 60, 2), + " minutes", + ) + + # Create meshes dict + meshes_dict = dict() + structures_with_mesh = [] + for s in structures: + # Check if a mesh was created + mesh_path = meshes_dir_path / f'{s["id"]}.obj' + if not mesh_path.exists(): + print(f"No mesh file exists for: {s}, ignoring it") + continue + else: + # Check that the mesh actually exists (i.e. not empty) + if mesh_path.stat().st_size < 512: + print(f"obj file for {s} is too small, ignoring it.") + continue + + structures_with_mesh.append(s) + meshes_dict[s["id"]] = mesh_path + + print( + f"In the end, {len(structures_with_mesh)} " + "structures with mesh are kept" + ) + return meshes_dict + + +### If the code above this line has been filled correctly, nothing needs to be +### edited below (unless variables need to be passed between the functions). +if __name__ == "__main__": + BG_ROOT_DIR.mkdir(exist_ok=True) + download_resources() + preprocess_annotations() + template_volume, annotated_volume = retrieve_reference_and_annotation() + hemispheres_stack = retrieve_hemisphere_map() + structures = retrieve_structure_information() + meshes_dict = retrieve_or_construct_meshes(annotated_volume, structures) + + output_filename = wrapup_atlas_from_data( + atlas_name=ATLAS_NAME, + atlas_minor_version=__version__, + citation=CITATION, + atlas_link=ATLAS_LINK, + species=SPECIES, + resolution=(RESOLUTION,) * 3, + orientation=ORIENTATION, + root_id=ROOT_ID, + reference_stack=template_volume, + annotation_stack=annotated_volume, + structures_list=structures, + meshes_dict=meshes_dict, + working_dir=BG_ROOT_DIR, + hemispheres_stack=None, + cleanup_files=False, + compress=True, + scale_meshes=True, + ) \ No newline at end of file From ace6c8cb313f4e589dee7468a82e9d60e0c75863 Mon Sep 17 00:00:00 2001 From: polarbean Date: Thu, 12 Sep 2024 15:06:57 +0200 Subject: [PATCH 02/14] limit line length --- .../atlas_scripts/australian_mouse_brain.py | 120 ++++++++++-------- 1 file changed, 70 insertions(+), 50 deletions(-) diff --git a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py index 0e316e23..783d20b4 100644 --- a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py +++ b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py @@ -171,7 +171,6 @@ "PBP": "parabrachial pigmented nucleus of the ventral tegmental area", "pc": "paracentral thalamic nucleus", "PC": "paracentral thalamic nucleus", - "PCom": "nucleus of the posterior commissure", "PF": "parafascicular thalamic nucleus", "PH": "posterior hypothalamus", @@ -225,7 +224,8 @@ "Su3C": "supraoculomotor cap", "Sub": "submedius thalamic nucleus", "SubB": "subbrachial nucleus", - "SubG": "subgeniculate nucleus of the prethalamus (ventrolateral nucleus)", + "SubG": "subgeniculate nucleus of the prethalamus (ventrolateral \ + nucleus)", "SuG": "superficial gray layer of the superior colliculus", "Te": "terete hypothalamic nucleus", "TG": "tectal gray", @@ -273,7 +273,8 @@ "ic": "Internal capsule", "ICjM": "Magna island of Calleja", "IEn": "Intermediate nucleus of the endopiriform claustrum", - "IPAC": "Interstitial nucleus of the post limb of the anterior commissure", + "IPAC": "Interstitial nucleus of the post limb of the anterior \ + commissure", "LAcbSh": "Accumbens nucleus shell, lateral part", "LDB": "Lateral nucleus of the horizontal limb of the diagonal band", "LH": "Lateral hypothalamus", @@ -337,24 +338,25 @@ "IntA": "Interposed cerebellar nucleus, anterior", "IntDL": "Interposed cerebellar nucleus, dorsolateral hump", "IntP": "Interposed cerebellar nucleus, posterior", - "IntPPC": "Interposed cerebellar nucleus, posterior parvicellular part", + "IntPPC": "Interposed cerebellar nucleus, posterior parvicellular \ + part", "das": "Dorsal acoustic stria", }, "hippocampus": { - "CA1-Py":"CA1-Pyramidal cell layer", - "CA1-Or":"CA1-Pyramidal Oriens layer", - "CA1-Lmol":"CA1-Lacunosum Moleculare layer", - "CA1-Rad":"CA1-Radiatum layer", - "CA2-Py":"CA2-Pyramidal cell layer", - "CA2-Or":"CA2-Pyramidal Oriens layer", - "CA2-Lmol":"CA2-Lacunosum Moleculare layer", - "CA2-Rad":"CA2-Radiatum layer", - "CA3-Py-inner":"CA3-inner Pyramidal cell layer", - "CA3-Py-outer":"CA3-outer Pyramidal cell layer", - "CA3-Py":"CA3-Pyramidal cell layer", - "CA3-Or":"CA3-Pyramidal Oriens layer", - "CA3-Lmol":"CA3-Lacunosum Moleculare layer", - "CA3-Rad":"CA3-Radiatum layer", + "CA1-Py": "CA1-Pyramidal cell layer", + "CA1-Or": "CA1-Pyramidal Oriens layer", + "CA1-Lmol": "CA1-Lacunosum Moleculare layer", + "CA1-Rad": "CA1-Radiatum layer", + "CA2-Py": "CA2-Pyramidal cell layer", + "CA2-Or": "CA2-Pyramidal Oriens layer", + "CA2-Lmol": "CA2-Lacunosum Moleculare layer", + "CA2-Rad": "CA2-Radiatum layer", + "CA3-Py-inner": "CA3-inner Pyramidal cell layer", + "CA3-Py-outer": "CA3-outer Pyramidal cell layer", + "CA3-Py": "CA3-Pyramidal cell layer", + "CA3-Or": "CA3-Pyramidal Oriens layer", + "CA3-Lmol": "CA3-Lacunosum Moleculare layer", + "CA3-Rad": "CA3-Radiatum layer", "Or": "Oriens layer", "Py": "Pyramidal cell layer", "Rad": "Radiatum layer", @@ -474,6 +476,7 @@ } TEMPLATE_STRING = "ambmc-c57bl6-label-{}_v0.8{}" + def download_resources(): download_dir_path = BG_ROOT_DIR / "downloads" download_dir_path.mkdir(exist_ok=True) @@ -502,9 +505,10 @@ def download_resources(): tar.extractall(path=BG_ROOT_DIR) return None + def preprocess_annotations(): """ - The annotations are split amongst multiple files, + The annotations are split amongst multiple files, in different formats, and are required to correct values in the volumes themselves which are at times overlapping. So this preprocessing function must be run before retrieving @@ -512,14 +516,19 @@ def preprocess_annotations(): """ download_dir_path = BG_ROOT_DIR / "downloads" for region in REGION_IDS.keys(): - label_path = f"{download_dir_path}/{TEMPLATE_STRING.format(region, '-nii')}/{TEMPLATE_STRING.format(region, '.idx')}" + label_path = f"{download_dir_path}/\ + {TEMPLATE_STRING.format(region, '-nii')}/\ + {TEMPLATE_STRING.format(region, '.idx')}" label_list = [] for region, url in ANNOTATION_URLS.items(): - path = f"{download_dir_path}/{TEMPLATE_STRING.format(region, '-nii')}/{TEMPLATE_STRING.format(region, '.nii')}" + path = f"{download_dir_path}/{TEMPLATE_STRING.format(region, '-nii')}\ + /{TEMPLATE_STRING.format(region, '.nii')}" img = sitk.ReadImage(path) arr = sitk.GetArrayFromImage(img) - label_path = f"{download_dir_path}/{TEMPLATE_STRING.format(region, '-nii')}/{TEMPLATE_STRING.format(region, '.idx')}" + label_path = f"{download_dir_path}/\ + {TEMPLATE_STRING.format(region, '-nii')}/\ + {TEMPLATE_STRING.format(region, '.idx')}" if region == "hippocampus": total_label = pd.concat(label_list) label = pd.read_csv(label_path, sep="\t") @@ -532,9 +541,7 @@ def preprocess_annotations(): label = label.rename(columns={"0": "id", "1": "acronym"}) # Generate new RGB values new_df = pd.DataFrame(columns=["r", "g", "b"]) - while len(new_df) < len( - label - ): + while len(new_df) < len(label): new_rgb = np.random.randint( 0, 256, size=3 ) # Generate a new RGB value @@ -547,7 +554,7 @@ def preprocess_annotations(): ) # Add it to new_df label[["r", "g", "b"]] = new_df[["r", "g", "b"]] label = label.rename(columns={0: "id", 1: "acronym"}) - label['id'] = np.arange(1,16) + label["id"] = np.arange(1, 16) else: label = pd.read_csv(label_path, sep="\t", header=None) label = label.rename( @@ -558,15 +565,20 @@ def preprocess_annotations(): label["structure_id_path"] = label.apply( lambda x: [ROOT_ID, REGION_IDS[region], x["id"]], axis=1 ) - label['acronym'] = label['acronym'].str.strip() - #correct typo - label.loc[label['acronym'] == 'Zl', 'acronym'] = 'ZI' - label['name'] = label['acronym'].map(acronym_dict[region]) - label.loc[label['name'].isna(), 'name'] = label.loc[label['name'].isna(), 'acronym'] - label_path = f"{download_dir_path}/{TEMPLATE_STRING.format(region, '-nii')}/{TEMPLATE_STRING.format(region, '_new.idx')}" + label["acronym"] = label["acronym"].str.strip() + # correct typo + label.loc[label["acronym"] == "Zl", "acronym"] = "ZI" + label["name"] = label["acronym"].map(acronym_dict[region]) + label.loc[label["name"].isna(), "name"] = label.loc[ + label["name"].isna(), "acronym" + ] + label_path = f"{download_dir_path}/\ + {TEMPLATE_STRING.format(region, '-nii')}/\ + {TEMPLATE_STRING.format(region, '_new.idx')}" label.to_csv(label_path) label_list.append(label) + def retrieve_reference_and_annotation(): """ Retrieve the desired reference and annotation as two numpy arrays. @@ -583,28 +595,32 @@ def retrieve_reference_and_annotation(): / "ambmc-c57bl6-model-symmet_v0.8.nii" ) reference = sitk.GetArrayFromImage(sitk.ReadImage(str(filename))) - ### This part is complex as the atlas segmentations are - ### Distributed through multiple files which we combine. + ### This part is complex as the atlas segmentations are + ### Distributed through multiple files which we combine. original_origin = np.array([5.07600021, 9.81449986, -3.72600007]) annotation = np.zeros((499, 1311, 679)) - new_vals = 1 + new_vals = 1 for region in REGION_IDS.keys(): - filename = f"{BG_ROOT_DIR}/{TEMPLATE_STRING.format(region, '-nii')}/{TEMPLATE_STRING.format(region, '.nii')}" - label_path = f"{download_dir_path}/{TEMPLATE_STRING.format(region, '-nii')}/{TEMPLATE_STRING.format(region, '_new.idx')}" + filename = f"{BG_ROOT_DIR}/{TEMPLATE_STRING.format(region, '-nii')}/\ + {TEMPLATE_STRING.format(region, '.nii')}" + label_path = f"{download_dir_path}/{TEMPLATE_STRING.format(region, '-nii')}/\ + {TEMPLATE_STRING.format(region, '_new.idx')}" label_data = pd.read_csv(label_path) img = sitk.ReadImage(filename) arr = sitk.GetArrayFromImage(img) id_mapping = {} - #This has to be done because the ids in the labelfile are in - #correct order, but are not aligned with the volume - for i,idval in enumerate(label_data['id']): - arr[arr==(i+1)] = new_vals + # This has to be done because the ids in the labelfile are in + # correct order, but are not aligned with the volume + for i, idval in enumerate(label_data["id"]): + arr[arr == (i + 1)] = new_vals id_mapping[idval] = new_vals new_vals += 1 # Assuming annotated_volume is a numpy array new_label_data = label_data.copy() - new_label_data['id'] = new_label_data['id'].map(id_mapping) - output_path = f"{download_dir_path}/{TEMPLATE_STRING.format(region, '-nii')}/{TEMPLATE_STRING.format(region, '_renumbered.idx')}" + new_label_data["id"] = new_label_data["id"].map(id_mapping) + output_path = f"{download_dir_path}/\ + {TEMPLATE_STRING.format(region, '-nii')}/\ + {TEMPLATE_STRING.format(region, '_renumbered.idx')}" new_label_data.to_csv(output_path) origin = np.array(img.GetOrigin()) spacing = np.array(img.GetSpacing()) @@ -633,7 +649,7 @@ def retrieve_hemisphere_map(): numpy.array or None: A numpy array representing the hemisphere map, or None if the atlas is symmetrical. """ - return None #Symmetrical atlas + return None # Symmetrical atlas def retrieve_structure_information(): @@ -690,7 +706,9 @@ def retrieve_structure_information(): ) label_list = [] for region in REGION_IDS.keys(): - file_path = f"{download_dir_path}/{TEMPLATE_STRING.format(region, '-nii')}/{TEMPLATE_STRING.format(region, '_renumbered.idx')}" + file_path = f"{download_dir_path}/\ + {TEMPLATE_STRING.format(region, '-nii')}/\ + {TEMPLATE_STRING.format(region, '_renumbered.idx')}" label_list.append(pd.read_csv(file_path)) df = pd.concat(label_list).reset_index(drop=True) new_df = pd.DataFrame(columns=["r", "g", "b"]) @@ -720,11 +738,13 @@ def retrieve_structure_information(): df = df.drop(columns=["r", "g", "b"]) df = df.assign(rgb_triplet=rgb) total_df = pd.concat([hierarchical_labels, df]) - total_df = total_df[['acronym', 'id', 'name', 'structure_id_path', 'rgb_triplet']] + total_df = total_df[ + ["acronym", "id", "name", "structure_id_path", "rgb_triplet"] + ] structures = total_df.to_dict("records") - for s in structures: - if ( isinstance(s['structure_id_path'], str)): - s['structure_id_path'] = eval(s['structure_id_path']) + for s in structures: + if isinstance(s["structure_id_path"], str): + s["structure_id_path"] = eval(s["structure_id_path"]) return structures @@ -860,4 +880,4 @@ def retrieve_or_construct_meshes(annotated_volume, structures): cleanup_files=False, compress=True, scale_meshes=True, - ) \ No newline at end of file + ) From 8a03d93960ee9d04ae75177845e753478e30e979 Mon Sep 17 00:00:00 2001 From: polarbean Date: Thu, 12 Sep 2024 15:11:28 +0200 Subject: [PATCH 03/14] limit line length and fix formatting --- .../atlas_scripts/australian_mouse_brain.py | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py index 783d20b4..b9c394eb 100644 --- a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py +++ b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py @@ -1,15 +1,16 @@ __version__ = "1" -import tarfile -import os -import json import multiprocessing as mp +import os +import tarfile import time from pathlib import Path -import requests + import numpy as np import pandas as pd +import requests import SimpleITK as sitk from rich.progress import track + from brainglobe_atlasapi import utils from brainglobe_atlasapi.atlas_generation.mesh_utils import ( Region, @@ -18,11 +19,6 @@ from brainglobe_atlasapi.atlas_generation.wrapup import wrapup_atlas_from_data from brainglobe_atlasapi.structure_tree_util import get_structures_tree -from pathlib import Path - -from brainglobe_atlasapi.atlas_generation.wrapup import wrapup_atlas_from_data -import nibabel as nib - # Copy-paste this script into a new file and fill in the functions to package # your own atlas. @@ -43,6 +39,7 @@ "hippocampus": "https://osf.io/download/tjazr", "diencephalon": "https://osf.io/download/9atc7", } +REFERENCE_URL = "https://osf.io/download/g8p6a" REGION_IDS = { "basalganglia": 1001, "cerebellum": 1002, @@ -480,10 +477,9 @@ def download_resources(): download_dir_path = BG_ROOT_DIR / "downloads" download_dir_path.mkdir(exist_ok=True) - atlas_files_dir = download_dir_path / "atlas_files" ## Download atlas_file utils.check_internet_connection() - destination_path = download_dir_path / f"template.nii.tar.gz" + destination_path = download_dir_path / "template.nii.tar.gz" if not os.path.isfile(destination_path): response = requests.get(REFERENCE_URL, stream=True) with open(destination_path, "wb") as f: @@ -521,11 +517,6 @@ def preprocess_annotations(): {TEMPLATE_STRING.format(region, '.idx')}" label_list = [] for region, url in ANNOTATION_URLS.items(): - path = f"{download_dir_path}/{TEMPLATE_STRING.format(region, '-nii')}\ - /{TEMPLATE_STRING.format(region, '.nii')}" - img = sitk.ReadImage(path) - arr = sitk.GetArrayFromImage(img) - label_path = f"{download_dir_path}/\ {TEMPLATE_STRING.format(region, '-nii')}/\ {TEMPLATE_STRING.format(region, '.idx')}" @@ -603,7 +594,8 @@ def retrieve_reference_and_annotation(): for region in REGION_IDS.keys(): filename = f"{BG_ROOT_DIR}/{TEMPLATE_STRING.format(region, '-nii')}/\ {TEMPLATE_STRING.format(region, '.nii')}" - label_path = f"{download_dir_path}/{TEMPLATE_STRING.format(region, '-nii')}/\ + label_path = f"{download_dir_path}/\ + {TEMPLATE_STRING.format(region, '-nii')}/\ {TEMPLATE_STRING.format(region, '_new.idx')}" label_data = pd.read_csv(label_path) img = sitk.ReadImage(filename) @@ -730,8 +722,6 @@ def retrieve_structure_information(): rgb = [] for index, row in df.iterrows(): - temp_id = row["id"] - temp_rgb = [row["r"], row["g"], row["b"]] rgb.append(temp_rgb) @@ -742,6 +732,7 @@ def retrieve_structure_information(): ["acronym", "id", "name", "structure_id_path", "rgb_triplet"] ] structures = total_df.to_dict("records") + for s in structures: if isinstance(s["structure_id_path"], str): s["structure_id_path"] = eval(s["structure_id_path"]) From 66a88728b46c1cdc61dd79da90d3b021a43af1ba Mon Sep 17 00:00:00 2001 From: polarbean Date: Thu, 12 Sep 2024 17:00:49 +0200 Subject: [PATCH 04/14] formatting --- .../atlas_scripts/australian_mouse_brain.py | 95 +++++++++++-------- 1 file changed, 55 insertions(+), 40 deletions(-) diff --git a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py index b9c394eb..6f97853a 100644 --- a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py +++ b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py @@ -32,6 +32,8 @@ ROOT_ID = 9999 RESOLUTION = 15 BG_ROOT_DIR = Path.home() / "brainglobe_workingdir" / ATLAS_NAME +DOWNLOAD_DIR_PATH = BG_ROOT_DIR / "downloads" + ANNOTATION_URLS = { "basalganglia": "https://osf.io/download/xgj4h", "cerebellum": "https://osf.io/download/su2a9", @@ -221,8 +223,10 @@ "Su3C": "supraoculomotor cap", "Sub": "submedius thalamic nucleus", "SubB": "subbrachial nucleus", - "SubG": "subgeniculate nucleus of the prethalamus (ventrolateral \ - nucleus)", + "SubG": ( + "subgeniculate nucleus of the prethalamus " + "(ventrolateral nucleus)" + ), "SuG": "superficial gray layer of the superior colliculus", "Te": "terete hypothalamic nucleus", "TG": "tectal gray", @@ -270,8 +274,10 @@ "ic": "Internal capsule", "ICjM": "Magna island of Calleja", "IEn": "Intermediate nucleus of the endopiriform claustrum", - "IPAC": "Interstitial nucleus of the post limb of the anterior \ - commissure", + "IPAC": ( + "Interstitial nucleus of the post limb of the anterior " + "commissure" + ), "LAcbSh": "Accumbens nucleus shell, lateral part", "LDB": "Lateral nucleus of the horizontal limb of the diagonal band", "LH": "Lateral hypothalamus", @@ -335,8 +341,9 @@ "IntA": "Interposed cerebellar nucleus, anterior", "IntDL": "Interposed cerebellar nucleus, dorsolateral hump", "IntP": "Interposed cerebellar nucleus, posterior", - "IntPPC": "Interposed cerebellar nucleus, posterior parvicellular \ - part", + "IntPPC": ( + "Interposed cerebellar nucleus, " "posterior parvicellular part" + ), "das": "Dorsal acoustic stria", }, "hippocampus": { @@ -475,11 +482,10 @@ def download_resources(): - download_dir_path = BG_ROOT_DIR / "downloads" - download_dir_path.mkdir(exist_ok=True) + DOWNLOAD_DIR_PATH.mkdir(exist_ok=True) ## Download atlas_file utils.check_internet_connection() - destination_path = download_dir_path / "template.nii.tar.gz" + destination_path = DOWNLOAD_DIR_PATH / "template.nii.tar.gz" if not os.path.isfile(destination_path): response = requests.get(REFERENCE_URL, stream=True) with open(destination_path, "wb") as f: @@ -487,9 +493,9 @@ def download_resources(): if chunk: f.write(chunk) with tarfile.open(destination_path, "r:gz") as tar: - tar.extractall(path=download_dir_path) + tar.extractall(path=DOWNLOAD_DIR_PATH) for region, url in ANNOTATION_URLS.items(): - destination_path = BG_ROOT_DIR / f"{region}.nii.tar.gz" + destination_path = DOWNLOAD_DIR_PATH / f"{region}.nii.tar.gz" if not os.path.isfile(destination_path): response = requests.get(url, stream=True) with open(destination_path, "wb") as f: @@ -498,7 +504,7 @@ def download_resources(): f.write(chunk) # Untar the file with tarfile.open(destination_path, "r:gz") as tar: - tar.extractall(path=BG_ROOT_DIR) + tar.extractall(path=DOWNLOAD_DIR_PATH) return None @@ -510,16 +516,14 @@ def preprocess_annotations(): So this preprocessing function must be run before retrieving the reference and annotation """ - download_dir_path = BG_ROOT_DIR / "downloads" - for region in REGION_IDS.keys(): - label_path = f"{download_dir_path}/\ - {TEMPLATE_STRING.format(region, '-nii')}/\ - {TEMPLATE_STRING.format(region, '.idx')}" + label_list = [] for region, url in ANNOTATION_URLS.items(): - label_path = f"{download_dir_path}/\ - {TEMPLATE_STRING.format(region, '-nii')}/\ - {TEMPLATE_STRING.format(region, '.idx')}" + label_path = ( + DOWNLOAD_DIR_PATH + / TEMPLATE_STRING.format(region, "-nii") + / TEMPLATE_STRING.format(region, ".idx") + ) if region == "hippocampus": total_label = pd.concat(label_list) label = pd.read_csv(label_path, sep="\t") @@ -563,9 +567,11 @@ def preprocess_annotations(): label.loc[label["name"].isna(), "name"] = label.loc[ label["name"].isna(), "acronym" ] - label_path = f"{download_dir_path}/\ - {TEMPLATE_STRING.format(region, '-nii')}/\ - {TEMPLATE_STRING.format(region, '_new.idx')}" + label_path = ( + DOWNLOAD_DIR_PATH + / TEMPLATE_STRING.format(region, "-nii") + / TEMPLATE_STRING.format(region, "_new.idx") + ) label.to_csv(label_path) label_list.append(label) @@ -578,10 +584,8 @@ def retrieve_reference_and_annotation(): tuple: A tuple containing two numpy arrays. The first array is the reference volume, and the second array is the annotation volume. """ - download_dir_path = BG_ROOT_DIR / "downloads" filename = ( - download_dir_path - / "template.nii" + DOWNLOAD_DIR_PATH / "ambmc-c57bl6-model-symmet_v0.8-nii" / "ambmc-c57bl6-model-symmet_v0.8.nii" ) @@ -592,11 +596,19 @@ def retrieve_reference_and_annotation(): annotation = np.zeros((499, 1311, 679)) new_vals = 1 for region in REGION_IDS.keys(): - filename = f"{BG_ROOT_DIR}/{TEMPLATE_STRING.format(region, '-nii')}/\ - {TEMPLATE_STRING.format(region, '.nii')}" - label_path = f"{download_dir_path}/\ - {TEMPLATE_STRING.format(region, '-nii')}/\ - {TEMPLATE_STRING.format(region, '_new.idx')}" + + filename = ( + DOWNLOAD_DIR_PATH + / TEMPLATE_STRING.format(region, "-nii") + / TEMPLATE_STRING.format(region, ".nii") + ) + + label_path = ( + DOWNLOAD_DIR_PATH + / TEMPLATE_STRING.format(region, "-nii") + / TEMPLATE_STRING.format(region, "_new.idx") + ) + label_data = pd.read_csv(label_path) img = sitk.ReadImage(filename) arr = sitk.GetArrayFromImage(img) @@ -610,9 +622,11 @@ def retrieve_reference_and_annotation(): # Assuming annotated_volume is a numpy array new_label_data = label_data.copy() new_label_data["id"] = new_label_data["id"].map(id_mapping) - output_path = f"{download_dir_path}/\ - {TEMPLATE_STRING.format(region, '-nii')}/\ - {TEMPLATE_STRING.format(region, '_renumbered.idx')}" + output_path = ( + DOWNLOAD_DIR_PATH + / TEMPLATE_STRING.format(region, "-nii") + / TEMPLATE_STRING.format(region, "_renumbered.idx") + ) new_label_data.to_csv(output_path) origin = np.array(img.GetOrigin()) spacing = np.array(img.GetSpacing()) @@ -665,7 +679,6 @@ def retrieve_structure_information(): Returns: pandas.DataFrame: A DataFrame containing the atlas information. """ - download_dir_path = BG_ROOT_DIR / "downloads" hierarchical_labels = pd.DataFrame( { @@ -698,9 +711,11 @@ def retrieve_structure_information(): ) label_list = [] for region in REGION_IDS.keys(): - file_path = f"{download_dir_path}/\ - {TEMPLATE_STRING.format(region, '-nii')}/\ - {TEMPLATE_STRING.format(region, '_renumbered.idx')}" + file_path = ( + DOWNLOAD_DIR_PATH + / TEMPLATE_STRING.format(region, "-nii") + / TEMPLATE_STRING.format(region, "_renumbered.idx") + ) label_list.append(pd.read_csv(file_path)) df = pd.concat(label_list).reset_index(drop=True) new_df = pd.DataFrame(columns=["r", "g", "b"]) @@ -747,7 +762,7 @@ def retrieve_or_construct_meshes(annotated_volume, structures): In other cases we need to construct the meshes ourselves. For this we have helper functions to achieve this. """ - meshes_dir_path = BG_ROOT_DIR / "downloads" / "meshes" + meshes_dir_path = DOWNLOAD_DIR_PATH / "meshes" meshes_dir_path.mkdir(exist_ok=True) tree = get_structures_tree(structures) @@ -848,7 +863,7 @@ def retrieve_or_construct_meshes(annotated_volume, structures): BG_ROOT_DIR.mkdir(exist_ok=True) download_resources() preprocess_annotations() - template_volume, annotated_volume = retrieve_reference_and_annotation() + annotated_volume, template_volume = retrieve_reference_and_annotation() hemispheres_stack = retrieve_hemisphere_map() structures = retrieve_structure_information() meshes_dict = retrieve_or_construct_meshes(annotated_volume, structures) From e78ea2b6df212c942c9c960309fa95a166371975 Mon Sep 17 00:00:00 2001 From: polarbean Date: Sun, 15 Sep 2024 09:30:34 +0200 Subject: [PATCH 05/14] update orientation --- .../atlas_generation/atlas_scripts/australian_mouse_brain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py index 6f97853a..e5d2ea79 100644 --- a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py +++ b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py @@ -28,7 +28,7 @@ CITATION = "lANKE et al. 2015, https://doi.org/10.1016/j.ymeth.2015.01.005" SPECIES = "Mus musculus" ATLAS_LINK = "https://imaging.org.au/AMBMC/" -ORIENTATION = "ial" +ORIENTATION = "asl" ROOT_ID = 9999 RESOLUTION = 15 BG_ROOT_DIR = Path.home() / "brainglobe_workingdir" / ATLAS_NAME From f0b0a7fb4b95ab072e1ca9c706bd53c94e7fcb34 Mon Sep 17 00:00:00 2001 From: polarbean Date: Sun, 15 Sep 2024 11:57:42 +0200 Subject: [PATCH 06/14] update annotation and change template from float32 to uint16 --- .../atlas_scripts/australian_mouse_brain.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py index e5d2ea79..8be196da 100644 --- a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py +++ b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py @@ -11,7 +11,6 @@ import SimpleITK as sitk from rich.progress import track -from brainglobe_atlasapi import utils from brainglobe_atlasapi.atlas_generation.mesh_utils import ( Region, create_region_mesh, @@ -28,7 +27,7 @@ CITATION = "lANKE et al. 2015, https://doi.org/10.1016/j.ymeth.2015.01.005" SPECIES = "Mus musculus" ATLAS_LINK = "https://imaging.org.au/AMBMC/" -ORIENTATION = "asl" +ORIENTATION = "iar" ROOT_ID = 9999 RESOLUTION = 15 BG_ROOT_DIR = Path.home() / "brainglobe_workingdir" / ATLAS_NAME @@ -484,7 +483,7 @@ def download_resources(): DOWNLOAD_DIR_PATH.mkdir(exist_ok=True) ## Download atlas_file - utils.check_internet_connection() + # utils.check_internet_connection() destination_path = DOWNLOAD_DIR_PATH / "template.nii.tar.gz" if not os.path.isfile(destination_path): response = requests.get(REFERENCE_URL, stream=True) @@ -638,6 +637,10 @@ def retrieve_reference_and_annotation(): ] mask = arr != 0 segment[mask] = arr[mask] + reference = reference - reference.min() + reference = reference / reference.max() + reference = reference * 65535 + reference = reference.astype(np.uint16) return annotation, reference From 629c0364048fd3271f080711a5cba2c59d57b872 Mon Sep 17 00:00:00 2001 From: polarbean Date: Sun, 1 Dec 2024 05:23:04 +0100 Subject: [PATCH 07/14] fix issue with colours in herarchical regions --- .../atlas_scripts/australian_mouse_brain.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py index 8be196da..0475185a 100644 --- a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py +++ b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py @@ -710,6 +710,14 @@ def retrieve_structure_information(): [ROOT_ID, 1004], [ROOT_ID, 1005], ], + "rgb_triplet":[ + [255,255,255], + [255, 100, 30], + [100,255,30], + [30,100,255], + [100,30,255], + [0,255,0] + ] } ) label_list = [] From bfb2da1b1db61bcd72e88182567fcc886562e578 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 04:23:16 +0000 Subject: [PATCH 08/14] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../atlas_scripts/australian_mouse_brain.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py index 0475185a..171b9324 100644 --- a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py +++ b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py @@ -710,14 +710,14 @@ def retrieve_structure_information(): [ROOT_ID, 1004], [ROOT_ID, 1005], ], - "rgb_triplet":[ - [255,255,255], + "rgb_triplet": [ + [255, 255, 255], [255, 100, 30], - [100,255,30], - [30,100,255], - [100,30,255], - [0,255,0] - ] + [100, 255, 30], + [30, 100, 255], + [100, 30, 255], + [0, 255, 0], + ], } ) label_list = [] From c35a4153d1c8437c577f149b671d3eff7746b911 Mon Sep 17 00:00:00 2001 From: Harry Carey Date: Sun, 8 Dec 2024 02:19:50 +1100 Subject: [PATCH 09/14] Update brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py Co-authored-by: Alessandro Felder --- .../atlas_generation/atlas_scripts/australian_mouse_brain.py | 1 - 1 file changed, 1 deletion(-) diff --git a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py index 171b9324..274ce0f8 100644 --- a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py +++ b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py @@ -483,7 +483,6 @@ def download_resources(): DOWNLOAD_DIR_PATH.mkdir(exist_ok=True) ## Download atlas_file - # utils.check_internet_connection() destination_path = DOWNLOAD_DIR_PATH / "template.nii.tar.gz" if not os.path.isfile(destination_path): response = requests.get(REFERENCE_URL, stream=True) From 49834630a38f79b5e8b533b5bea5bb9d907fac89 Mon Sep 17 00:00:00 2001 From: Harry Carey Date: Sun, 8 Dec 2024 02:20:00 +1100 Subject: [PATCH 10/14] Update brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py Co-authored-by: Alessandro Felder --- .../atlas_generation/atlas_scripts/australian_mouse_brain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py index 274ce0f8..1239db67 100644 --- a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py +++ b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py @@ -24,7 +24,7 @@ ### Metadata ### __version__ = 0 ATLAS_NAME = "australian_mouse" -CITATION = "lANKE et al. 2015, https://doi.org/10.1016/j.ymeth.2015.01.005" +CITATION = "Janke et al. 2015, https://doi.org/10.1016/j.ymeth.2015.01.005" SPECIES = "Mus musculus" ATLAS_LINK = "https://imaging.org.au/AMBMC/" ORIENTATION = "iar" From d69de421941e12ca3421eef87ce37658526d529d Mon Sep 17 00:00:00 2001 From: Harry Carey Date: Sun, 8 Dec 2024 02:21:11 +1100 Subject: [PATCH 11/14] Update australian_mouse_brain.py --- .../atlas_generation/atlas_scripts/australian_mouse_brain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py index 1239db67..bb2e9d9a 100644 --- a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py +++ b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py @@ -487,7 +487,7 @@ def download_resources(): if not os.path.isfile(destination_path): response = requests.get(REFERENCE_URL, stream=True) with open(destination_path, "wb") as f: - for chunk in response.iter_content(chunk_size=8192): + for chunk in response.iter_content(chunk_size=8192): #chunk size is 1 kibibyte if chunk: f.write(chunk) with tarfile.open(destination_path, "r:gz") as tar: From 62ca3eced8b60a132b49ceedb4d1b60705ce33a5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 7 Dec 2024 15:21:19 +0000 Subject: [PATCH 12/14] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../atlas_generation/atlas_scripts/australian_mouse_brain.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py index bb2e9d9a..3dd5ff8e 100644 --- a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py +++ b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py @@ -487,7 +487,9 @@ def download_resources(): if not os.path.isfile(destination_path): response = requests.get(REFERENCE_URL, stream=True) with open(destination_path, "wb") as f: - for chunk in response.iter_content(chunk_size=8192): #chunk size is 1 kibibyte + for chunk in response.iter_content( + chunk_size=8192 + ): # chunk size is 1 kibibyte if chunk: f.write(chunk) with tarfile.open(destination_path, "r:gz") as tar: From 1f10af79bc90a001ea19170ce6e535d5385068fe Mon Sep 17 00:00:00 2001 From: Harry Carey Date: Sun, 8 Dec 2024 02:23:18 +1100 Subject: [PATCH 13/14] remove parallelism --- .../atlas_scripts/australian_mouse_brain.py | 61 ++++++------------- 1 file changed, 18 insertions(+), 43 deletions(-) diff --git a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py index 3dd5ff8e..d763062d 100644 --- a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py +++ b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py @@ -48,7 +48,6 @@ "hippocampus": 1004, "diencephalon": 1005, } -PARALLEL = False acronym_dict = { "diencephalon": { "mfb": "Medial forebrain bundle", @@ -794,49 +793,25 @@ def retrieve_or_construct_meshes(annotated_volume, structures): smooth = False start = time.time() - if PARALLEL: - pool = mp.Pool(mp.cpu_count() - 2) - - try: - pool.map( - create_region_mesh, - [ - ( - meshes_dir_path, - node, - tree, - labels, - annotated_volume, - ROOT_ID, - closing_n_iters, - decimate_fraction, - smooth, - ) - for node in tree.nodes.values() - ], - ) - except mp.pool.MaybeEncodingError: - # error with returning results from pool.map but we don't care - pass - else: - for node in track( - tree.nodes.values(), - total=tree.size(), - description="Creating meshes", - ): - create_region_mesh( - ( - meshes_dir_path, - node, - tree, - labels, - annotated_volume, - ROOT_ID, - closing_n_iters, - decimate_fraction, - smooth, - ) + + for node in track( + tree.nodes.values(), + total=tree.size(), + description="Creating meshes", + ): + create_region_mesh( + ( + meshes_dir_path, + node, + tree, + labels, + annotated_volume, + ROOT_ID, + closing_n_iters, + decimate_fraction, + smooth, ) + ) print( "Finished mesh extraction in: ", From 0947a806a402bab2519f9c319b9593aad0f37793 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 7 Dec 2024 15:23:25 +0000 Subject: [PATCH 14/14] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../atlas_generation/atlas_scripts/australian_mouse_brain.py | 1 - 1 file changed, 1 deletion(-) diff --git a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py index d763062d..26cd3218 100644 --- a/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py +++ b/brainglobe_atlasapi/atlas_generation/atlas_scripts/australian_mouse_brain.py @@ -1,5 +1,4 @@ __version__ = "1" -import multiprocessing as mp import os import tarfile import time