From 04776080f37d62b6be6bff30251300c70092f9a3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 9 Jan 2025 16:04:11 +0000 Subject: [PATCH] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../atlas_scripts/kim_devccf_mouse.py | 180 ++++++++++++------ 1 file changed, 119 insertions(+), 61 deletions(-) diff --git a/brainglobe_atlasapi/atlas_generation/atlas_scripts/kim_devccf_mouse.py b/brainglobe_atlasapi/atlas_generation/atlas_scripts/kim_devccf_mouse.py index c60b8d1..559c51e 100644 --- a/brainglobe_atlasapi/atlas_generation/atlas_scripts/kim_devccf_mouse.py +++ b/brainglobe_atlasapi/atlas_generation/atlas_scripts/kim_devccf_mouse.py @@ -1,11 +1,10 @@ import argparse -import json import time from pathlib import Path -import pooch import numpy as np import pandas as pd +import pooch from brainglobe_utils.IO.image import load_nii from rich.progress import track @@ -15,7 +14,6 @@ create_region_mesh, ) from brainglobe_atlasapi.atlas_generation.wrapup import wrapup_atlas_from_data - from brainglobe_atlasapi.config import DEFAULT_WORKDIR from brainglobe_atlasapi.structure_tree_util import get_structures_tree @@ -29,101 +27,127 @@ PACKAGER = "Carlo Castoldi " ATLAS_FILE_URL = "https://doi.org/10.6084/m9.figshare.26377171.v1" -TIMEPOINTS = ( - "E11.5", - "E13.5", - "E15.5", - "E18.5", - "P04", - "P14", - "P56" -) +TIMEPOINTS = ("E11.5", "E13.5", "E15.5", "E18.5", "P04", "P14", "P56") MODALITIES = ( - "LSFM", # Light Sheet Fluorescence Microscopy + "LSFM", # Light Sheet Fluorescence Microscopy "MRI-adc", # MRI Apparent Diffusion Coefficient "MRI-dwi", # MRI Difusion Weighted Imaging - "MRI-fa", # MRI Fractional Anisotropy + "MRI-fa", # MRI Fractional Anisotropy "MRI-MTR", # MRI Magnetization Transfer Ratio - "MRI-T2" # MRI T2-weighted + "MRI-T2", # MRI T2-weighted ) + def pooch_init(download_dir_path: Path, timepoints: list[str]) -> pooch.Pooch: utils.check_internet_connection() - empty_registry = {a+".zip": None for a in [*timepoints, "DevCCFv1_OntologyStructure.xlsx"]} + empty_registry = { + a + ".zip": None + for a in [*timepoints, "DevCCFv1_OntologyStructure.xlsx"] + } p = pooch.create( path=download_dir_path, base_url="doi:10.6084/m9.figshare.26377171.v1/", - registry=empty_registry + registry=empty_registry, + ) + p.load_registry( + Path(__file__).parent.parent / "hashes" / (ATLAS_NAME + ".txt") ) - p.load_registry(Path(__file__).parent.parent/"hashes"/(ATLAS_NAME+".txt")) return p + def fetch_animal(pooch_: pooch.Pooch, age: str, modality: str): assert age in TIMEPOINTS, f"Unknown age timepoint: '{age}'" - archive = age+".zip" + archive = age + ".zip" if modality == "LSFM": resolution_um = 20 elif modality in MODALITIES: match age: case "E11.5": resolution_um = 31.5 - raise RuntimeError("Can't generate an atlas at embryonic stage with MRI reference images.") + raise RuntimeError( + "Can't generate an atlas at embryonic stage with MRI reference images." + ) case "E13.5": resolution_um = 34 - raise RuntimeError("Can't generate an atlas at embryonic stage with MRI reference images.") + raise RuntimeError( + "Can't generate an atlas at embryonic stage with MRI reference images." + ) case "E15.5": resolution_um = 37.5 - raise RuntimeError("Can't generate an atlas at embryonic stage with MRI reference images.") + raise RuntimeError( + "Can't generate an atlas at embryonic stage with MRI reference images." + ) case "E18.5": resolution_um = 40 - raise RuntimeError("Can't generate an atlas at embryonic stage with MRI reference images.") + raise RuntimeError( + "Can't generate an atlas at embryonic stage with MRI reference images." + ) case _: resolution_um = 50 else: raise RuntimeError(f"Unknown reference image modality: {modality}") members = [ f"{age}/{age.replace('.','-')}_DevCCF_Annotations_{resolution_um}um.nii.gz", - f"{age}/{age.replace('.','-')}_{modality}_{resolution_um}um.nii.gz" + f"{age}/{age.replace('.','-')}_{modality}_{resolution_um}um.nii.gz", ] - annotations_path, reference_path = pooch_.fetch(archive, - progressbar=True, - processor=pooch.Unzip(extract_dir=".", members=members) - ) + annotations_path, reference_path = pooch_.fetch( + archive, + progressbar=True, + processor=pooch.Unzip(extract_dir=".", members=members), + ) annotations = load_nii(annotations_path, as_array=True) reference = load_nii(reference_path, as_array=True) return annotations, reference, resolution_um + def fetch_ontology(pooch_: pooch.Pooch): - devccfv1_path = pooch_.fetch("DevCCFv1_OntologyStructure.xlsx", progressbar=True) + devccfv1_path = pooch_.fetch( + "DevCCFv1_OntologyStructure.xlsx", progressbar=True + ) xl = pd.ExcelFile(devccfv1_path) # xl.sheet_names # it has two excel sheets - # 'DevCCFv1_Ontology', 'README' + # 'DevCCFv1_Ontology', 'README' df = xl.parse("DevCCFv1_Ontology", header=1) df = df[["Acronym", "ID16", "Name", "Structure ID Path16", "R", "G", "B"]] - df.rename(columns={ - "Acronym": "acronym", - "ID16": "id", - "Name": "name", - "Structure ID Path16": "structure_id_path", - "R": "r", - "G": "g", - "B": "b" - }, inplace=True) + df.rename( + columns={ + "Acronym": "acronym", + "ID16": "id", + "Name": "name", + "Structure ID Path16": "structure_id_path", + "R": "r", + "G": "g", + "B": "b", + }, + inplace=True, + ) structures = list(df.to_dict(orient="index").values()) for structure in structures: if structure["acronym"] == "mouse": structure["acronym"] = "root" structure_path = structure["structure_id_path"] - structure["structure_id_path"] = [int(id) for id in structure_path.strip("/").split("/")] - structure["rgb_triplet"] = [structure["r"], structure["g"], structure["b"]] + structure["structure_id_path"] = [ + int(id) for id in structure_path.strip("/").split("/") + ] + structure["rgb_triplet"] = [ + structure["r"], + structure["g"], + structure["b"], + ] del structure["r"] del structure["g"] del structure["b"] return structures -def create_meshes(output_path: str|Path, - structures, annotation_volume, root_id, decimate_fraction): + +def create_meshes( + output_path: str | Path, + structures, + annotation_volume, + root_id, + decimate_fraction, +): if not isinstance(output_path, Path): output_path = Path(output_path) output_path.mkdir(exist_ok=True) @@ -150,7 +174,7 @@ def create_meshes(output_path: str|Path, # total=5, description="Creating meshes", ): - output_file = output_path/f"{node.identifier}.obj" + output_file = output_path / f"{node.identifier}.obj" if output_file.exists(): # print(f"mesh already existing: {output_file.exists()} - {output_file}") continue @@ -175,6 +199,7 @@ def create_meshes(output_path: str|Path, ) return output_path + def create_mesh_dict(structures, meshes_dir_path): meshes_dict = dict() structures_with_mesh = [] @@ -197,21 +222,25 @@ def create_mesh_dict(structures, meshes_dir_path): ) return meshes_dict, structures_with_mesh + class HideChoicesRawTextHelpFormatter(argparse.RawTextHelpFormatter): def _get_help_string(self, action): help_text = action.help if action.choices: - help_text = help_text.split('(choices')[0].strip() + help_text = help_text.split("(choices")[0].strip() return help_text def _format_action_invocation(self, action): if action.option_strings: - return ', '.join(action.option_strings) + return ", ".join(action.option_strings) if action.metavar: return action.metavar return super()._format_action_invocation(action) -arg_parser = argparse.ArgumentParser(formatter_class=HideChoicesRawTextHelpFormatter) + +arg_parser = argparse.ArgumentParser( + formatter_class=HideChoicesRawTextHelpFormatter +) timepoints_help = """the age timepoint at which the atlas will be generated. Options are: - E11.5 ⅂ @@ -221,7 +250,7 @@ def _format_action_invocation(self, action): - P04 ⅂ - P14 |- Postnatal day - P56 ⅃ - + By default, it generates an atlas for each timepoint. """ modalities_help = """the acquisition modalities with which the reference image was captured. @@ -236,6 +265,8 @@ def _format_action_invocation(self, action): By default, LSFM """ decimate_fraction_help = "fraction of the original number of meshes' vertices to be kept. Must be a number > 0 and <= 1.\nBy default, 0.2" + + def decimate_fraction_type(arg): try: f = float(arg) @@ -243,10 +274,35 @@ def decimate_fraction_type(arg): return f except ValueError: pass - raise argparse.ArgumentTypeError(f"invalid value: '{arg}' (must be a number > 0 and <= 1)") -arg_parser.add_argument("-t", "--timepoints", default=TIMEPOINTS, type=str, nargs="+", choices=TIMEPOINTS, help=timepoints_help) -arg_parser.add_argument("-m", "--modality", default="LSFM", type=str, choices=MODALITIES, help=modalities_help) -arg_parser.add_argument("-d", "--decimate-fraction", default=0.2, type=decimate_fraction_type, help=decimate_fraction_help) + raise argparse.ArgumentTypeError( + f"invalid value: '{arg}' (must be a number > 0 and <= 1)" + ) + + +arg_parser.add_argument( + "-t", + "--timepoints", + default=TIMEPOINTS, + type=str, + nargs="+", + choices=TIMEPOINTS, + help=timepoints_help, +) +arg_parser.add_argument( + "-m", + "--modality", + default="LSFM", + type=str, + choices=MODALITIES, + help=modalities_help, +) +arg_parser.add_argument( + "-d", + "--decimate-fraction", + default=0.2, + type=decimate_fraction_type, + help=decimate_fraction_help, +) if __name__ == "__main__": params = vars(arg_parser.parse_args()) @@ -254,26 +310,28 @@ def decimate_fraction_type(arg): modality = params["modality"] decimate_fraction = params["decimate_fraction"] atlas_name = f"{ATLAS_NAME}_{modality}" - bg_root_dir = DEFAULT_WORKDIR/atlas_name - download_dir_path = bg_root_dir/"downloads" + bg_root_dir = DEFAULT_WORKDIR / atlas_name + download_dir_path = bg_root_dir / "downloads" download_dir_path.mkdir(exist_ok=True, parents=True) pooch_ = pooch_init(download_dir_path, timepoints) structures = fetch_ontology(pooch_) for age in timepoints: atlas_name = f"{atlas_name}_{age.replace('.', '-')}" - annotation_volume, reference_volume, resolution_um = fetch_animal(pooch_, age, modality) - atlas_dir = bg_root_dir/atlas_name + annotation_volume, reference_volume, resolution_um = fetch_animal( + pooch_, age, modality + ) + atlas_dir = bg_root_dir / atlas_name atlas_dir.mkdir(exist_ok=True) print(f"Saving atlas data at {atlas_dir}") # Create meshes: - meshes_dir_path = atlas_dir/"meshes" + meshes_dir_path = atlas_dir / "meshes" create_meshes( meshes_dir_path, structures, annotation_volume, ROOT_ID, - decimate_fraction + decimate_fraction, ) meshes_dict, structures_with_mesh = create_mesh_dict( structures, meshes_dir_path @@ -286,7 +344,7 @@ def decimate_fraction_type(arg): citation=CITATION, atlas_link=ATLAS_LINK, species=SPECIES, - resolution=(resolution_um,)*3, + resolution=(resolution_um,) * 3, orientation=ORIENTATION, root_id=ROOT_ID, reference_stack=reference_volume, @@ -295,9 +353,9 @@ def decimate_fraction_type(arg): meshes_dict=meshes_dict, working_dir=atlas_dir, atlas_packager=PACKAGER, - hemispheres_stack=None, # it is symmetric + hemispheres_stack=None, # it is symmetric cleanup_files=False, compress=True, scale_meshes=True, ) - print("Done. Atlas generated at: ", output_filename) \ No newline at end of file + print("Done. Atlas generated at: ", output_filename)