Skip to content
This repository was archived by the owner on Feb 26, 2025. It is now read-only.

Commit 8780abc

Browse files
asoplataAustin E. Soplataarnaudon
authored
Update thalamus (#11)
* Overhaul the thalamus into steps, and add docs Load thalamus meshes from CLI input, clean CLI * Improve Blender instructions * Change thalamus region list regex This updates the regular expression used for thalamus placement-hints to be in a different format that has been tested successfully, excludes habenular and peripeduncular subregions, and to be valid for the hierarchy/annotation used at its appropriate step in the Atlas pipeline. For information on which regions were chosen and this list was created, see the internal BBP Confluence page located at "Circuits > Mouse Thalamus > Atlas-based Whole-thalamus subregion selection". This regex has been built from the region list of the desired and present thalamus regions as of the "final" version of the hierarchy and annotation built by the Atlas pipeline, which is the output of the rule `split_barrel_ccfv3_l23split`. This change is meant to go in tandem with BlueBrain/atlas-direction-vectors#27 . * Update layer names to be Atlas-Pipeline-compatible * Fix formatting errors * Attempt to update tests for new thal workflow * Replace part of test anno with region in metadata * fix test + format * format * Fix final linting issues This does a lot of small things for passing the linting. For mypy, I had to add additional ignores for the Trimesh returned types, since the ignore on the module as a whole wasn't preventing mypy from expecting `load_mesh` to return a Geometry object, which is a grandparent of Trimesh objects. I don't know if Trimesh changed their API, I couldn't figure it out from the docs, and I don't know why mypy was raising this now. In all the cases I could test or see, a proper "Trimesh" object was returned instead of the more generic Geometry. I don't think we need to worry about this. For the pylint disable W0613 (unused-argument), I needed some polymorphism for the thalamus case, but I wasn't sure how to handle that alongside the linters' type-checking. I think this is the simplest solution and is harmless. Everything else is minor. * Make Alexis changes to CLI * Apply MG code review changes --------- Co-authored-by: Austin E. Soplata <[email protected]> Co-authored-by: arnaudon <[email protected]>
1 parent 11e099b commit 8780abc

File tree

8 files changed

+440
-64
lines changed

8 files changed

+440
-64
lines changed

atlas_placement_hints/app/metadata/thalamus_metadata.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77

88
},
99
"layers": {
10-
"names": ["RT", "THnotRT"],
11-
"queries": ["RT", "@^\\bAD|AM|AMd|AMv|ATN|AV|CL|CM|DORpm|DORsm|EPI|Eth|GENd|GENv|IAD|IAM|IGL|ILM|IMD|IntG|LAT|LD|LGd|LGd-co|LGd-ip|LGd-sh|LGv|LGvl|LGvm|LH|LP|MD|MDc|MDl|MDm|MED|MG|MGd|MGm|MGv|MH|MTN|PCN|PF|PIL|PIN|PO|POL|PP|PR|PT|PVT|PoT|RE|REth|RH|SGN|SMT|SPA|SPF|SPFm|SPFp|SubG|TH|VAL|VENT|VM|VP|VPL|VPLpc|VPM|VPMpc|Xi\\b$"],
10+
"names": ["layer_1", "layer_2"],
11+
"queries": ["RT",
12+
"@^(?:AD|AMd|AMv|AV|CL|CM|Eth|IAD|IAM|IGL|IMD|IntG|LD|LGd-co|LGd-ip|LGd-sh|LGv_O|LP|MD_O|MGd|MGm|MGv|PCN|PF|PIL|PO|POL|PR|PT|PVT|PoT|RE|RH|SGN|SMT|SPA|SPFm|SPFp|SubG|TH_O|VAL|VM|VPL|VPLpc|VPM|VPMpc|Xi)$"],
1213
"attribute": "acronym",
1314
"with_descendants": false
1415
}
15-
}
16+
}

atlas_placement_hints/app/placement_hints.py

Lines changed: 68 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ def _placement_hints( # pylint: disable=too-many-locals
7474
max_thicknesses: Optional[List[float]] = None,
7575
flip_direction_vectors: bool = False,
7676
has_hemispheres: bool = False,
77+
thalamus_meshes_dir: str = "",
7778
) -> None:
7879
"""
7980
Compute the placement hints for a laminar region of the mouse brain.
@@ -93,6 +94,10 @@ def _placement_hints( # pylint: disable=too-many-locals
9394
has_hemispheres: (optional) If True, split the volume into halves along the z-axis and
9495
handle each of theses 'hemispheres' separately. Otherwise the whole volume is handled.
9596
Defaults to True.
97+
thalamus_meshes_dir: (optional) Path of the directory to load thalamus meshes
98+
from. Currently only used for thalamus. Required if you are producing thalamus
99+
placement-hints. Defaults to None.
100+
96101
"""
97102
direction_vectors = voxcell.VoxelData.load_nrrd(direction_vectors_path)
98103
assert_meta_properties([direction_vectors, atlas.region])
@@ -106,6 +111,7 @@ def _placement_hints( # pylint: disable=too-many-locals
106111
max_thicknesses,
107112
flip_direction_vectors=flip_direction_vectors,
108113
has_hemispheres=has_hemispheres,
114+
thalamus_meshes_dir=thalamus_meshes_dir,
109115
)
110116
if not Path(output_dir).exists():
111117
os.makedirs(output_dir)
@@ -305,41 +311,84 @@ def isocortex(
305311
required=True,
306312
help="path of the directory to write. It will be created if it doesn't exist.",
307313
)
314+
@click.option(
315+
"--thalamus-meshes-dir",
316+
required=True,
317+
help="""Path of the directory to use for either saving or loading thalamus
318+
meshes. It will be created if it doesn't exist.""",
319+
)
320+
@click.option(
321+
"--load-cut-thalamus-meshes",
322+
required=False,
323+
help="""(Optional) Flag to load your custom thalamus meshes, and then use
324+
them to calculate placement-hints.""",
325+
default=False,
326+
is_flag=True,
327+
)
308328
@log_args(L)
329+
# pylint: disable=too-many-arguments
309330
def thalamus(
310-
verbose, annotation_path, hierarchy_path, metadata_path, direction_vectors_path, output_dir
331+
verbose,
332+
annotation_path,
333+
hierarchy_path,
334+
metadata_path,
335+
direction_vectors_path,
336+
output_dir,
337+
thalamus_meshes_dir,
338+
load_cut_thalamus_meshes,
311339
):
312340
"""Generate and save the placement hints of the mouse thalamus.
313341
314-
Placement hints are saved under the names sepecified in `app/metadata/thalamus_metadata.json`.
315-
Default to:
342+
First, call this without passing '--load-cut-thalamus-meshes' to
343+
create your region meshes, but not your placement-hints. Then, hand-cut
344+
your meshes according to the documentation in
345+
'atlas_placement_hints/layered_atlas.py::ThalamusAtlas'. Finally, call
346+
this again while passing '--load-cut-thalamus-meshes'.
347+
348+
Placement hints are saved under the names specified in
349+
`app/metadata/thalamus_metadata.json`. These default to:
316350
317351
\b
318352
- `[PH]y.nrrd`
319-
- `[PH]Rt.nrrd`, `[PH]VPL.nrrd`
353+
- `[PH]layer_1.nrrd` (This is the "top-most" layer, equivalent to "RT".
354+
This previously used the filename `[PH]RT.nrrd`)
355+
- `[PH]layer_2.nrrd` (This is the "deepest" layer, equivalent to the
356+
thalamus except the habenular, peripeduncular, and reticular regions.
357+
This previously used the filename `[PH]THnotRT.nrrd`)
320358
321-
A report together with an nrrd volume on problematic distance computations are generated
322-
in `output_dir` under the names:
359+
A report together with an nrrd volume on problematic distance computations
360+
are generated in `output_dir` under the names:
323361
324362
\b
325363
- `distance_report.json`
326-
- `<Thalamus>_problematic_voxel_mask.nrrd` (mask of the voxels for which the computed
327-
placement hints cannot be trusted). <Thalamus> is the region name specified in
328-
thalamus_metadata.json. Defaults to "Thalamus".
329-
330-
The annotation file can contain the thalamus or a superset.
331-
For the algorithm to work properly, some space should separate the boundary
332-
of the thalamus from the boundary of its enclosing array.
364+
- `<Thalamus>_problematic_voxel_mask.nrrd` (mask of the voxels for which
365+
the computed placement hints cannot be trusted). <Thalamus> is the
366+
region name specified in thalamus_metadata.json. Defaults to "Thalamus".
367+
368+
The annotation file can contain the thalamus or a superset. For the
369+
algorithm to work properly, some space should separate the boundary of the
370+
thalamus from the boundary of its enclosing array.
371+
372+
For instructions on all steps necessary to generate the thalamus' placement
373+
hints, see
374+
'atlas-placement-hints/atlas_placement_hints/layered_atlas.py::ThalamusAtlas'
375+
and its methods for details.
333376
"""
334377
set_verbose(L, verbose)
335378

336379
atlas = _create_layered_atlas(annotation_path, hierarchy_path, metadata_path)
337-
_placement_hints(
338-
atlas,
339-
direction_vectors_path,
340-
output_dir,
341-
has_hemispheres=True,
342-
)
380+
381+
if load_cut_thalamus_meshes:
382+
_placement_hints(
383+
atlas,
384+
direction_vectors_path,
385+
output_dir,
386+
thalamus_meshes_dir=thalamus_meshes_dir,
387+
has_hemispheres=True,
388+
)
389+
else:
390+
Path(thalamus_meshes_dir).mkdir(parents=True, exist_ok=True)
391+
atlas.create_uncut_thalamus_meshes(thalamus_meshes_dir)
343392

344393

345394
@app.command()

atlas_placement_hints/compute_placement_hints.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ def compute_placement_hints(
2727
max_thicknesses: Optional[List[float]] = None,
2828
flip_direction_vectors: bool = False,
2929
has_hemispheres: bool = True,
30+
thalamus_meshes_dir: str = "",
3031
) -> Tuple[DistanceInfo, Dict]:
3132
"""
3233
Compute the placement hints for a laminar region of the mouse brain.
@@ -43,6 +44,9 @@ def compute_placement_hints(
4344
has_hemispheres: (optional) If True, split the volume into halves along the z-axis and
4445
handle each of theses 'hemispheres' separately. Otherwise the whole volume is
4546
handled. Defaults to True.
47+
thalamus_meshes_dir: (optional) Path of the directory to load thalamus meshes
48+
from. Currently only used for thalamus. Required if you are producing thalamus
49+
placement-hints. Defaults to None.
4650
4751
Returns:
4852
Tuple with the following items.
@@ -70,6 +74,7 @@ def compute_placement_hints(
7074
direction_vectors,
7175
flip_direction_vectors=flip_direction_vectors,
7276
has_hemispheres=has_hemispheres,
77+
thalamus_meshes_dir=thalamus_meshes_dir,
7378
)
7479

7580
distances_to_meshes = distances_info["distances_to_layer_boundaries"]

atlas_placement_hints/distances/create_watertight_mesh.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ def create_watertight_trimesh(
210210
optimized_mesh = trimesh.load_mesh(output_filepath_opt)
211211

212212
if optimization_info:
213-
log_mesh_optimization_info(optimized_mesh, unoptimized_mesh)
213+
log_mesh_optimization_info(optimized_mesh, unoptimized_mesh) # type: ignore
214214

215-
optimized_mesh.fix_normals()
216-
return optimized_mesh
215+
optimized_mesh.fix_normals() # type: ignore
216+
return optimized_mesh # type: ignore

0 commit comments

Comments
 (0)