-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce image volumes as an input for feature query (#480)
* remove slicing operator for building volumes of interest from Space objects * remove setting __repr__ to name in Region * introduce NIfTI FeatureMaps as Location subclass and move assignment logic from AnatomicalAnchor to Region/Location classes * deal more consistently with points that could not be warped * still accept Map.get_index() for multiple matches in case there is one exact match. * introduce spatialmap as a location object; simplify matching in live queries * WIP: introduce LocationFilter, make Volume a LocationFilter; use LocationFilters for feature queries; move providers to subfolder of Volume; rename fetch_regional_map to get_regional_map; return Nifti1Image objects only on fetch * first attempt to re-enable feature query by region object - still testing and needs profiling * introducde SpaceWapringFailedException; remove contains implementation in Region * fix sparsemap.fetch, small bug fixes * _assign_image deal with updated commons.split_components api * Region.spatial_props accept modified get_regional_map function * fix coordinate selection in Volume.points_inside critical error: used voxels in wapred space instead original coordinates. * fix collecting coordinates for feature anchor * fix syntax error * fix typo * avoid redundant calls of child region maps in Region.get_regional_map * raise proper exception in volume.warp * Fix recursion error due to locationfilter.assign. Replace __contains__ with contains * overwrite LocationFilter.assign() in Region to handle all cases * fix order of "in" operator * remove debug output * allow quering receptor with a nifti volume * accept volumes for intersection computations * rename LocationFilter to BrainStructure * some description what a brain structure is as opposed to a brain region * fix issues caused by contains->__contains__ * Use tuple instead of subscripted generics in isinstance As of python 3.7 Subscripted generics cannot be used with class and instance checks * Fix import errors in tests * allow sampling and clustering from volumes - new method draw_samples() for (volumetric) volumes - new methods find_clusters and label_colors for PointSet - new method siibra.volumes.from_pointset * add hdbscan to requirements, make label colors a property of pointset * use sigma_mm of pointset for volume.from_points * If volume intersection results in zeroslike, return None * add find_peaks method to all volumes * Fix image feature query (case: inverse assignment is None) * fix from_pointset function in volume * a few fixes * a few fixes * Fix small bugs and tests * add matplotlib to test requirements * More fixes * Fix some bugs, examples, e2e tests, and all unit tests. Add hdbscan to setup requirements * use scikit-learn HDBSCAN instead of hdbscan * map.assign takes locations. _assign_image->_assign_volume * Bug fix: connected_components has no element == 0 * Fix fetch cache for volumes * Fix assignment of location to regions If a region does not have a valid mask on a space, check if warp the locations to supported spaces of regional mask until the assignment qualification can be checked. * Array conversion with `item` (Deprecation warning NumPy 1.25) * Check child region masks for intersection if affine of the children does not match * Use neuroglancer format if not format is given but resolution_mm is given - Resolution selection is not implemented for nifti. - This is important because there is a bug that alters which format is selected cyclically. (Could not pinpoint the source yet) * Todo artifact and typo fix * fix fetch format selection, format order. add _maintain_fetch_cache * add notes to volume.fetch and protect against poisoning _FETCH_CACHE * Array conversion with `item` (Deprecation warning NumPy 1.25) * maint: parcmap BUG report: _assign_volume does not work * Maint: anchor * sparsemap._assigne_image -> _assign_volume * Clean up map._assing_volume. fetch_iter goes through fragments as well * fix volume.points_inside * feat: add maps from nifti and label information This is meant to be a preparation for querying features with volumes. The previous iterations required computation of the relations to the defined maps. With ability top query with volumes, this computation is unnecessary. In addition, this PR allows creating a map from multiple volumes and supplying parcellation specification. TODO: - [] a method for adding custom parcellations. - [] a method for adding custom space. - [] a method to extracting these custom atlas concepts as json preconfiguration * Use AICHA atlas as an example * Anchor: use a species specific match cache key Solves the bug of fetching ebrains dataset features wrongly * Use volume for querying image in 03.000 example * carry from_volume to parcellationmap submodule * Remove strict requirement of scikit-learn>=1.3.0 for finding clusters in pointsets * remove hdbscan from requirements * remove volume._maintain_fetch_cache * hide volum.points_inside * fix several bugs from the merge with 0.5a01 * Add unit to tqdm for building_objects * Allow merging volumes from volume submodule * Fix: Region.intersection(Location) if region map is not available on Locations.space but child regions are. * Fix RegionRelationAssessments * maint: location.union * add some documentation to boundingbox * Fix assignment.Qualification.inverse * Fix: Volume.intersection(PointSet) BrainStructure.intersects check for not None so return None if intersection has no points, not an empty PointSet * Test: fetching a map with multiple volumes wo args and volume.merge * Maint tests, fix volume.intersection, organize TODOs * get_uuid -> generate_uuid * Add tests: check region-volume intersection, centroid containednedness * Make BigBrainIntensityProfile.location a property and refer to its anchor * Remove gifit import from volumes package * Remove redundant tests from e2e\feature\test_get * Make Location a BrainStructure. Use this to ensure implementation of hash, eq, and repr * update str and repr of core concepts * Several bug fixes - Fix fetch cache - fix region.fetch_cache -> getmap_cache - Clean up get_regional_map - Add names to volumes when extacting volumes (important for hashing) * no name field bug fix volume.from_nifti * further volume name adjustments for get_regional map * Fix PointSet.intersection (rewrite) also fix bounding box import * Fix Point le and ge. Use other's intersection in intersection when not clear (this is established in all others) * Fix boundingbox.intersection * Remove non-convex region maps from volume tests * fix try-except block of region assignment to locations * Update compound feature _export * Remove redundant `bigbrain._choose_space` and tidy bigbrain.py up * add/correct type hints in anchor.py * Use location's space for region assignment first. region.supported_spaces is now a sorted list by default Fixes issues with reproducibility. * Example 03-000: use region object for PLI feature query * maint: allen query * fix test_voi and enable more unit tests * version bump v1.0a01 --------- Co-authored-by: Timo Dickscheid <[email protected]>
- Loading branch information
1 parent
53938ca
commit d182ffd
Showing
61 changed files
with
2,130 additions
and
1,514 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import siibra | ||
from siibra.volumes import Volume | ||
from siibra.core.region import Region | ||
import numpy as np | ||
import pytest | ||
# TODO write a test for the volume-region and volume-volume intersection | ||
|
||
|
||
# add more to the list when centroids can be calculated for non-convex regions as well | ||
selected_regions = [ | ||
(siibra.get_region('julich 2.9', 'CA2 (Hippocampus) right'), 'mni152'), | ||
(siibra.get_region('julich 2.9', 'CA2 (Hippocampus) left'), 'colin27'), | ||
(siibra.get_region('julich 2.9', 'hoc1 left'), 'mni152'), | ||
(siibra.get_region('julich 3', 'sts'), 'mni152') | ||
] | ||
|
||
|
||
@pytest.mark.parametrize("region, space", selected_regions) | ||
def test_region_intersection_with_its_own_volume(region, space): | ||
assert isinstance(region, Region) | ||
volume = region.get_regional_map(space) | ||
intersection = region.intersection(volume) | ||
assert isinstance(intersection, Volume) | ||
assert np.all( | ||
np.equal(intersection.fetch().dataobj, volume.fetch().dataobj) | ||
), "Intersection of a regional map with its region object should be the same volume." | ||
|
||
|
||
@pytest.mark.parametrize("region, space", selected_regions) | ||
def test_region_intersection_with_its_centroid(region, space): | ||
assert isinstance(region, Region) | ||
centroids = region.compute_centroids(space) | ||
assert centroids in region | ||
assert region.intersection(centroids) == centroids | ||
assert centroids.intersection(region) == centroids |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,4 +77,3 @@ | |
surf_map=thicknesses[4], | ||
symmetric_cmap=False, cmap='magma', vmax=0.3 | ||
) | ||
# %% |
83 changes: 83 additions & 0 deletions
83
examples/02_maps_and_templates/007_adding_custom_parcellation.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# Copyright 2018-2023 | ||
# Institute of Neuroscience and Medicine (INM-1), Forschungszentrum Jülich GmbH | ||
|
||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
|
||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
""" | ||
Adding a custom parcellation map | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
Sometimes you might want to use a custom parcellation map to perform feature | ||
queries in siibra. For this example, we retrieve a freely available AICHA - | ||
Atlas of Intrinsic Connectivity of Homotopic Areas (Tzourio-Mazoyer N, Landeau B, | ||
Papathanassiou D, Crivello F, Etard O, Delcroix N, Mazoyer B, Joliot M (2002) | ||
Automated anatomical labeling of activations in SPM using a macroscopic | ||
anatomical parcellation of the MNI MRI single-subject brain. Neuroimage | ||
15:273-289.). This atlas provided in the MNI ICBM 152 space. | ||
""" | ||
|
||
|
||
# %% | ||
import siibra | ||
from nilearn import plotting | ||
|
||
# %% | ||
# Load the custom parcellation map from the online resource. For the retrieval, | ||
# siibra's zipfile connector is very helpful. We can use the resulting NIfTI | ||
# to create a custom parcellation map inside siibra. | ||
|
||
# connect to the online zip file | ||
conn = siibra.retrieval.ZipfileConnector( | ||
"http://www.gin.cnrs.fr/wp-content/uploads/aicha_v1.zip" | ||
) | ||
|
||
# the NIfTI file is easily retrieved: | ||
nifti = conn.get("AICHA/AICHA.nii") | ||
# and create a volume on space MNI152 (note that this assumes our | ||
# external knowledge that the map is in MNI152 space) | ||
volume = siibra.volumes.from_nifti(nifti, 'mni152', "AICHA") | ||
|
||
# The text file with label mappings has a custom format. We provide a tsv | ||
# decoder to extract the list of region/label pairs since the txt file is tab | ||
# seperated. | ||
volume_info = conn.get("AICHA/AICHA_vol1.txt", decode_func=siibra.retrieval.requests.DECODERS['.tsv']) | ||
volume_info | ||
|
||
# %% | ||
# Now we use this to add a custom map to siibra. | ||
regionnames = [ | ||
name.replace('-R', ' right').replace('-L', ' left') | ||
for name in volume_info['nom_l'] | ||
] | ||
labels = [int(label) for label in volume_info['color']] | ||
custom_map = siibra.volumes.parcellationmap.from_volume( | ||
name="AICHA - Atlas of Intrinsic Connectivity of Homotopic Areas", | ||
volume=volume, | ||
regionnames=regionnames, | ||
regionlabels=labels | ||
) | ||
|
||
# %% | ||
# let's plot the final map | ||
plotting.plot_roi(custom_map.fetch()) | ||
|
||
|
||
# %% | ||
# We can already use this map to find spatial features, such as BigBrain | ||
# intensity profiles. | ||
region = custom_map.parcellation.get_region('S_Rolando-1 left') | ||
profiles = siibra.features.get( | ||
region, | ||
siibra.features.cellular.BigBrainIntensityProfile | ||
)[0] | ||
print(f"{len(profiles)} intensity profiles found.") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.