siibra 1.0a19__tar.gz → 1.0.1a0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of siibra might be problematic. Click here for more details.
- {siibra-1.0a19/siibra.egg-info → siibra-1.0.1a0}/PKG-INFO +15 -2
- {siibra-1.0a19 → siibra-1.0.1a0}/README.rst +14 -1
- siibra-1.0.1a0/siibra/VERSION +1 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/__init__.py +3 -3
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/commons.py +0 -46
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/configuration/factory.py +10 -20
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/core/atlas.py +20 -14
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/core/parcellation.py +67 -52
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/core/region.py +133 -123
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/exceptions.py +8 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/experimental/contour.py +6 -6
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/experimental/patch.py +2 -2
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/experimental/plane3d.py +8 -8
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/anchor.py +12 -13
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/connectivity/regional_connectivity.py +2 -2
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/feature.py +14 -16
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/tabular/bigbrain_intensity_profile.py +1 -1
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/tabular/cell_density_profile.py +97 -63
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/tabular/layerwise_cell_density.py +3 -22
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/tabular/regional_timeseries_activity.py +2 -2
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/livequeries/allen.py +39 -16
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/livequeries/bigbrain.py +8 -8
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/livequeries/query.py +0 -1
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/locations/__init__.py +9 -9
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/locations/boundingbox.py +29 -24
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/locations/point.py +4 -4
- siibra-1.0a19/siibra/locations/pointset.py → siibra-1.0.1a0/siibra/locations/pointcloud.py +30 -22
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/retrieval/repositories.py +9 -26
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/retrieval/requests.py +19 -2
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/volumes/__init__.py +1 -1
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/volumes/parcellationmap.py +88 -81
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/volumes/providers/neuroglancer.py +62 -36
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/volumes/providers/nifti.py +11 -25
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/volumes/sparsemap.py +124 -245
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/volumes/volume.py +141 -52
- {siibra-1.0a19 → siibra-1.0.1a0/siibra.egg-info}/PKG-INFO +15 -2
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra.egg-info/SOURCES.txt +1 -1
- siibra-1.0a19/siibra/VERSION +0 -1
- {siibra-1.0a19 → siibra-1.0.1a0}/LICENSE +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/MANIFEST.in +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/setup.cfg +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/setup.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/configuration/__init__.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/configuration/configuration.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/core/__init__.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/core/assignment.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/core/concept.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/core/space.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/core/structure.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/experimental/__init__.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/experimental/cortical_profile_sampler.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/explorer/__init__.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/explorer/url.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/explorer/util.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/__init__.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/connectivity/__init__.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/connectivity/functional_connectivity.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/connectivity/streamline_counts.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/connectivity/streamline_lengths.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/connectivity/tracing_connectivity.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/dataset/__init__.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/dataset/ebrains.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/image/__init__.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/image/image.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/image/sections.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/image/volume_of_interest.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/tabular/__init__.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/tabular/cortical_profile.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/tabular/gene_expression.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/tabular/layerwise_bigbrain_intensities.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/tabular/receptor_density_fingerprint.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/tabular/receptor_density_profile.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/features/tabular/tabular.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/livequeries/__init__.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/livequeries/ebrains.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/locations/location.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/retrieval/__init__.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/retrieval/cache.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/retrieval/datasets.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/retrieval/exceptions/__init__.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/vocabularies/__init__.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/vocabularies/gene_names.json +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/vocabularies/receptor_symbols.json +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/vocabularies/region_aliases.json +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/volumes/providers/__init__.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/volumes/providers/freesurfer.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/volumes/providers/gifti.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra/volumes/providers/provider.py +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra.egg-info/dependency_links.txt +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra.egg-info/requires.txt +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/siibra.egg-info/top_level.txt +0 -0
- {siibra-1.0a19 → siibra-1.0.1a0}/test/test_siibra.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: siibra
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.0.1a0
|
|
4
4
|
Summary: siibra - Software interfaces for interacting with brain atlases
|
|
5
5
|
Home-page: https://github.com/FZJ-INM1-BDA/siibra-python
|
|
6
6
|
Author: Big Data Analytics Group, Forschungszentrum Juelich, Institute of Neuroscience and Medicine (INM-1)
|
|
@@ -34,7 +34,7 @@ Requires-Dist: ebrains-drive>=0.6.0
|
|
|
34
34
|
siibra - Software interface for interacting with brain atlases
|
|
35
35
|
==============================================================
|
|
36
36
|
|
|
37
|
-
Copyright 2020-
|
|
37
|
+
Copyright 2020-2024, Forschungszentrum Jülich GmbH
|
|
38
38
|
|
|
39
39
|
*Authors: Big Data Analytics Group, Institute of Neuroscience and
|
|
40
40
|
Medicine (INM-1), Forschungszentrum Jülich GmbH*
|
|
@@ -145,3 +145,16 @@ https://doi.org/10.5281/zenodo.7885728`.
|
|
|
145
145
|
:target: https://siibra-python.readthedocs.io/en/latest/?badge=latest
|
|
146
146
|
.. |doi| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.7885728.svg
|
|
147
147
|
:target: https://doi.org/10.5281/zenodo.7885728
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
Versioning
|
|
151
|
+
==========
|
|
152
|
+
Given a version number MAJOR.MINOR.PATCH, increments imply:
|
|
153
|
+
- MAJOR: incompatible API changes
|
|
154
|
+
- MINOR: a functionality in a backward compatible manner is added
|
|
155
|
+
- PATCH: backward compatible bug fixes and new configuration added such as new maps or features
|
|
156
|
+
|
|
157
|
+
Pre-release
|
|
158
|
+
-----------
|
|
159
|
+
For x.y.z, a full release,
|
|
160
|
+
- `x.y.z-alpha.t` is the development prerelease. By changing `t`, different siibra-configurations are targeted.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
siibra - Software interface for interacting with brain atlases
|
|
5
5
|
==============================================================
|
|
6
6
|
|
|
7
|
-
Copyright 2020-
|
|
7
|
+
Copyright 2020-2024, Forschungszentrum Jülich GmbH
|
|
8
8
|
|
|
9
9
|
*Authors: Big Data Analytics Group, Institute of Neuroscience and
|
|
10
10
|
Medicine (INM-1), Forschungszentrum Jülich GmbH*
|
|
@@ -115,3 +115,16 @@ https://doi.org/10.5281/zenodo.7885728`.
|
|
|
115
115
|
:target: https://siibra-python.readthedocs.io/en/latest/?badge=latest
|
|
116
116
|
.. |doi| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.7885728.svg
|
|
117
117
|
:target: https://doi.org/10.5281/zenodo.7885728
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
Versioning
|
|
121
|
+
==========
|
|
122
|
+
Given a version number MAJOR.MINOR.PATCH, increments imply:
|
|
123
|
+
- MAJOR: incompatible API changes
|
|
124
|
+
- MINOR: a functionality in a backward compatible manner is added
|
|
125
|
+
- PATCH: backward compatible bug fixes and new configuration added such as new maps or features
|
|
126
|
+
|
|
127
|
+
Pre-release
|
|
128
|
+
-----------
|
|
129
|
+
For x.y.z, a full release,
|
|
130
|
+
- `x.y.z-alpha.t` is the development prerelease. By changing `t`, different siibra-configurations are targeted.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.0.1-alpha.0
|
|
@@ -39,7 +39,7 @@ from . import configuration
|
|
|
39
39
|
from . import experimental
|
|
40
40
|
from .configuration import factory
|
|
41
41
|
from . import features, livequeries
|
|
42
|
-
from siibra.locations import Point,
|
|
42
|
+
from siibra.locations import Point, PointCloud
|
|
43
43
|
|
|
44
44
|
import os as _os
|
|
45
45
|
logger.info(f"Version: {__version__}")
|
|
@@ -51,7 +51,7 @@ logger.info(
|
|
|
51
51
|
# forward access to some functions
|
|
52
52
|
set_ebrains_token = _EbrainsRequest.set_token
|
|
53
53
|
fetch_ebrains_token = _EbrainsRequest.fetch_token
|
|
54
|
-
find_regions = _parcellation.
|
|
54
|
+
find_regions = _parcellation.find_regions
|
|
55
55
|
from_json = factory.Factory.from_json
|
|
56
56
|
|
|
57
57
|
|
|
@@ -150,7 +150,7 @@ def __dir__():
|
|
|
150
150
|
"get_template",
|
|
151
151
|
"MapType",
|
|
152
152
|
"Point",
|
|
153
|
-
"
|
|
153
|
+
"PointCloud",
|
|
154
154
|
"QUIET",
|
|
155
155
|
"VERBOSE",
|
|
156
156
|
"fetch_ebrains_token",
|
|
@@ -366,9 +366,6 @@ class MapType(Enum):
|
|
|
366
366
|
STATISTICAL = 2
|
|
367
367
|
|
|
368
368
|
|
|
369
|
-
SIIBRA_DEFAULT_MAPTYPE = MapType.LABELLED
|
|
370
|
-
SIIBRA_DEFAULT_MAP_THRESHOLD = 0.0
|
|
371
|
-
|
|
372
369
|
REMOVE_FROM_NAME = [
|
|
373
370
|
"hemisphere",
|
|
374
371
|
" -",
|
|
@@ -586,49 +583,6 @@ def connected_components(
|
|
|
586
583
|
)
|
|
587
584
|
|
|
588
585
|
|
|
589
|
-
class PolyLine:
|
|
590
|
-
"""Simple polyline representation which allows equidistant sampling.."""
|
|
591
|
-
|
|
592
|
-
def __init__(self, pts):
|
|
593
|
-
self.pts = pts
|
|
594
|
-
self.lengths = [
|
|
595
|
-
np.sqrt(np.sum((pts[i, :] - pts[i - 1, :]) ** 2))
|
|
596
|
-
for i in range(1, pts.shape[0])
|
|
597
|
-
]
|
|
598
|
-
|
|
599
|
-
def length(self):
|
|
600
|
-
return sum(self.lengths)
|
|
601
|
-
|
|
602
|
-
def sample(self, d):
|
|
603
|
-
|
|
604
|
-
# if d is interable, we assume a list of sample positions
|
|
605
|
-
try:
|
|
606
|
-
iter(d)
|
|
607
|
-
except TypeError:
|
|
608
|
-
positions = [d]
|
|
609
|
-
else:
|
|
610
|
-
positions = d
|
|
611
|
-
|
|
612
|
-
samples = []
|
|
613
|
-
for s_ in positions:
|
|
614
|
-
s = min(max(s_, 0), 1)
|
|
615
|
-
target_distance = s * self.length()
|
|
616
|
-
current_distance = 0
|
|
617
|
-
for i, length in enumerate(self.lengths):
|
|
618
|
-
current_distance += length
|
|
619
|
-
if current_distance >= target_distance:
|
|
620
|
-
p1 = self.pts[i, :]
|
|
621
|
-
p2 = self.pts[i + 1, :]
|
|
622
|
-
r = (target_distance - current_distance + length) / length
|
|
623
|
-
samples.append(p1 + (p2 - p1) * r)
|
|
624
|
-
break
|
|
625
|
-
|
|
626
|
-
if len(samples) == 1:
|
|
627
|
-
return samples[0]
|
|
628
|
-
else:
|
|
629
|
-
return np.array(samples)
|
|
630
|
-
|
|
631
|
-
|
|
632
586
|
def unify_stringlist(L: list):
|
|
633
587
|
"""Adds asterisks to strings that appear multiple times, so the resulting
|
|
634
588
|
list has only unique strings but still the same length, order, and meaning.
|
|
@@ -24,7 +24,7 @@ from ..features.tabular import (
|
|
|
24
24
|
)
|
|
25
25
|
from ..features.image import sections, volume_of_interest
|
|
26
26
|
from ..core import atlas, parcellation, space, region
|
|
27
|
-
from ..locations import point,
|
|
27
|
+
from ..locations import point, pointcloud, boundingbox
|
|
28
28
|
from ..retrieval import datasets, repositories
|
|
29
29
|
from ..volumes import volume, sparsemap, parcellationmap
|
|
30
30
|
from ..volumes.providers.provider import VolumeProvider
|
|
@@ -302,25 +302,18 @@ class Factory:
|
|
|
302
302
|
@build_type("siibra/map/v0.0.1")
|
|
303
303
|
def build_map(cls, spec):
|
|
304
304
|
# maps have no configured identifier - we require the spec filename to build one
|
|
305
|
-
|
|
306
|
-
basename = path.splitext(path.basename(spec["filename"]))[0]
|
|
307
|
-
name = (
|
|
308
|
-
basename.replace("-", " ")
|
|
309
|
-
.replace("_", " ")
|
|
310
|
-
.replace("continuous", "statistical")
|
|
311
|
-
)
|
|
312
|
-
identifier = f"{spec['@type'].replace('/', '-')}_{basename}"
|
|
305
|
+
identifier = spec.get("@id")
|
|
313
306
|
volumes = cls.extract_volumes(
|
|
314
|
-
spec, space_id=spec["space"].get("@id"), name_prefix=
|
|
307
|
+
spec, space_id=spec["space"].get("@id"), name_prefix=identifier
|
|
315
308
|
)
|
|
316
309
|
|
|
317
|
-
if spec.get("
|
|
310
|
+
if spec.get("represented_as_sparsemap", False):
|
|
318
311
|
Maptype = sparsemap.SparseMap
|
|
319
312
|
else:
|
|
320
313
|
Maptype = parcellationmap.Map
|
|
321
314
|
return Maptype(
|
|
322
|
-
identifier=
|
|
323
|
-
name=spec.get("name"
|
|
315
|
+
identifier=identifier,
|
|
316
|
+
name=spec.get("name"),
|
|
324
317
|
space_spec=spec.get("space", {}),
|
|
325
318
|
parcellation_spec=spec.get("parcellation", {}),
|
|
326
319
|
indices=spec.get("indices", {}),
|
|
@@ -363,18 +356,18 @@ class Factory:
|
|
|
363
356
|
|
|
364
357
|
@classmethod
|
|
365
358
|
@build_type("tmp/poly")
|
|
366
|
-
@build_type("siibra/location/
|
|
367
|
-
def
|
|
359
|
+
@build_type("siibra/location/pointcloud/v0.1")
|
|
360
|
+
def build_pointcloud(cls, spec):
|
|
368
361
|
if spec.get("@type") == "tmp/poly":
|
|
369
362
|
space_id = spec["coordinateSpace"]["@id"]
|
|
370
363
|
coords = []
|
|
371
364
|
for coord in spec["coordinates"]:
|
|
372
365
|
assert all(c["unit"]["@id"] == "id.link/mm" for c in coord)
|
|
373
366
|
coords.append(list(np.float16(c["value"]) for c in coord))
|
|
374
|
-
elif spec.get("@type") == "siibra/location/
|
|
367
|
+
elif spec.get("@type") == "siibra/location/pointcloud/v0.1":
|
|
375
368
|
space_id = spec.get("space").get("@id")
|
|
376
369
|
coords = [tuple(c) for c in spec.get("coordinates")]
|
|
377
|
-
return
|
|
370
|
+
return pointcloud.PointCloud(coords, space=space_id)
|
|
378
371
|
|
|
379
372
|
@classmethod
|
|
380
373
|
@build_type("siibra/location/boundingbox/v0.1")
|
|
@@ -584,11 +577,8 @@ class Factory:
|
|
|
584
577
|
|
|
585
578
|
if isinstance(spec, str):
|
|
586
579
|
if path.isfile(spec):
|
|
587
|
-
fname = spec
|
|
588
580
|
with open(spec, "r") as f:
|
|
589
581
|
spec = json.load(f)
|
|
590
|
-
assert "filename" not in spec
|
|
591
|
-
spec["filename"] = fname
|
|
592
582
|
else:
|
|
593
583
|
spec = json.loads(spec)
|
|
594
584
|
|
|
@@ -197,27 +197,29 @@ class Atlas(concept.AtlasConcept, configuration_folder="atlases"):
|
|
|
197
197
|
|
|
198
198
|
def find_regions(
|
|
199
199
|
self,
|
|
200
|
-
regionspec,
|
|
201
|
-
all_versions=False,
|
|
202
|
-
filter_children=True,
|
|
203
|
-
|
|
200
|
+
regionspec: str,
|
|
201
|
+
all_versions: bool = False,
|
|
202
|
+
filter_children: bool = True,
|
|
203
|
+
find_topmost: bool = False
|
|
204
204
|
):
|
|
205
205
|
"""
|
|
206
|
-
Find regions with the given specification in all
|
|
207
|
-
|
|
208
|
-
are passed on to Parcellation.find().
|
|
206
|
+
Find regions with the given specification in all parcellations offered
|
|
207
|
+
by the atlas.
|
|
209
208
|
|
|
210
209
|
Parameters
|
|
211
210
|
----------
|
|
212
|
-
regionspec: str, regex
|
|
211
|
+
regionspec: str, regex
|
|
213
212
|
- a string with a possibly inexact name (matched both against the name and the identifier key)
|
|
214
213
|
- a string in '/pattern/flags' format to use regex search (acceptable flags: aiLmsux, see at https://docs.python.org/3/library/re.html#flags)
|
|
215
214
|
- a regex applied to region names
|
|
216
|
-
- a Region object
|
|
217
215
|
all_versions : Bool, default: False
|
|
218
216
|
If True, matched regions for all versions of a parcellation are returned.
|
|
219
217
|
filter_children : bool, default: True
|
|
220
218
|
If False, children of matched parents will be returned.
|
|
219
|
+
find_topmost : bool, default: False
|
|
220
|
+
If True (requires `filter_children=True`), will return parent
|
|
221
|
+
structures if all children are matched, even though the parent
|
|
222
|
+
itself might not match the specification.
|
|
221
223
|
|
|
222
224
|
Returns
|
|
223
225
|
-------
|
|
@@ -225,9 +227,13 @@ class Atlas(concept.AtlasConcept, configuration_folder="atlases"):
|
|
|
225
227
|
list of regions matching to the regionspec
|
|
226
228
|
"""
|
|
227
229
|
result = []
|
|
228
|
-
for p in self.
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
230
|
+
for p in self.parcellations:
|
|
231
|
+
if p.is_newest_version or all_versions:
|
|
232
|
+
result.extend(
|
|
233
|
+
p.find(
|
|
234
|
+
regionspec=regionspec,
|
|
235
|
+
filter_children=filter_children,
|
|
236
|
+
find_topmost=find_topmost
|
|
237
|
+
)
|
|
238
|
+
)
|
|
233
239
|
return result
|
|
@@ -17,11 +17,21 @@ from . import region
|
|
|
17
17
|
|
|
18
18
|
from ..commons import logger, MapType, Species
|
|
19
19
|
from ..volumes import parcellationmap
|
|
20
|
+
from ..exceptions import NoMapMatchingValues
|
|
20
21
|
|
|
21
|
-
from
|
|
22
|
+
from functools import lru_cache
|
|
22
23
|
import re
|
|
24
|
+
from typing import Union, List, TYPE_CHECKING
|
|
25
|
+
try:
|
|
26
|
+
from typing import Literal
|
|
27
|
+
except ImportError:
|
|
28
|
+
# support python 3.7
|
|
29
|
+
from typing_extensions import Literal
|
|
23
30
|
|
|
24
31
|
|
|
32
|
+
if TYPE_CHECKING:
|
|
33
|
+
from .space import Space
|
|
34
|
+
|
|
25
35
|
# NOTE : such code could be used to automatically resolve
|
|
26
36
|
# multiple matching parcellations for a short spec to the newset version:
|
|
27
37
|
# try:
|
|
@@ -68,8 +78,6 @@ class ParcellationVersion:
|
|
|
68
78
|
|
|
69
79
|
class Parcellation(region.Region, configuration_folder="parcellations"):
|
|
70
80
|
|
|
71
|
-
_CACHED_REGION_SEARCHES: Dict[str, List[region.Region]] = {}
|
|
72
|
-
|
|
73
81
|
def __init__(
|
|
74
82
|
self,
|
|
75
83
|
identifier: str,
|
|
@@ -140,7 +148,12 @@ class Parcellation(region.Region, configuration_folder="parcellations"):
|
|
|
140
148
|
self._CACHED_MATCHES[spec] = True
|
|
141
149
|
return super().matches(spec)
|
|
142
150
|
|
|
143
|
-
def get_map(
|
|
151
|
+
def get_map(
|
|
152
|
+
self,
|
|
153
|
+
space: Union[str, "Space"],
|
|
154
|
+
maptype: Union[Literal['labelled', 'statistical'], MapType] = MapType.LABELLED,
|
|
155
|
+
spec: str = ""
|
|
156
|
+
):
|
|
144
157
|
"""
|
|
145
158
|
Get the maps for the parcellation in the requested template space.
|
|
146
159
|
|
|
@@ -153,8 +166,8 @@ class Parcellation(region.Region, configuration_folder="parcellations"):
|
|
|
153
166
|
Parameters
|
|
154
167
|
----------
|
|
155
168
|
space: Space or str
|
|
156
|
-
|
|
157
|
-
maptype: MapType
|
|
169
|
+
reference space specification such as name, id, or a `Space` instance.
|
|
170
|
+
maptype: MapType or str
|
|
158
171
|
Type of map requested (e.g., statistical or labelled).
|
|
159
172
|
Use MapType.STATISTICAL to request probability maps.
|
|
160
173
|
Defaults to MapType.LABELLED.
|
|
@@ -169,26 +182,24 @@ class Parcellation(region.Region, configuration_folder="parcellations"):
|
|
|
169
182
|
A ParcellationMap representing the volumetric map or
|
|
170
183
|
a SparseMap representing the list of statistical maps.
|
|
171
184
|
"""
|
|
172
|
-
if
|
|
185
|
+
if isinstance(maptype, str):
|
|
173
186
|
maptype = MapType[maptype.upper()]
|
|
187
|
+
assert isinstance(maptype, MapType), "Possible values of `maptype` are `MapType`s, 'labelled', 'statistical'."
|
|
174
188
|
|
|
175
189
|
candidates = [
|
|
176
190
|
m for m in parcellationmap.Map.registry()
|
|
177
191
|
if m.space.matches(space)
|
|
178
192
|
and m.maptype == maptype
|
|
179
|
-
and m.parcellation
|
|
180
193
|
and m.parcellation.matches(self)
|
|
181
194
|
]
|
|
182
195
|
if len(candidates) == 0:
|
|
183
|
-
|
|
184
|
-
return None
|
|
196
|
+
raise NoMapMatchingValues(f"No '{maptype}' map in '{space}' available for {str(self)}")
|
|
185
197
|
if len(candidates) > 1:
|
|
186
198
|
spec_candidates = [
|
|
187
|
-
c for c in candidates if all(w.lower() in c.
|
|
199
|
+
c for c in candidates if all(w.lower() in c.id.lower() for w in spec.split())
|
|
188
200
|
]
|
|
189
201
|
if len(spec_candidates) == 0:
|
|
190
|
-
|
|
191
|
-
return None
|
|
202
|
+
raise NoMapMatchingValues(f"'{spec}' does not match any options from {[c.name for c in candidates]}.")
|
|
192
203
|
if len(spec_candidates) > 1:
|
|
193
204
|
logger.warning(
|
|
194
205
|
f"Multiple maps are available in this specification of space, parcellation, and map type.\n"
|
|
@@ -197,43 +208,6 @@ class Parcellation(region.Region, configuration_folder="parcellations"):
|
|
|
197
208
|
return spec_candidates[0]
|
|
198
209
|
return candidates[0]
|
|
199
210
|
|
|
200
|
-
@staticmethod
|
|
201
|
-
def find_regions(region_spec: str, parents_only=True):
|
|
202
|
-
"""
|
|
203
|
-
Find regions that match the given region specification in the subtree
|
|
204
|
-
headed by each parcellation in the registry.
|
|
205
|
-
Note
|
|
206
|
-
----
|
|
207
|
-
Use Region.find() to search for a region in an instance of a
|
|
208
|
-
parcellation.
|
|
209
|
-
|
|
210
|
-
Parameters
|
|
211
|
-
----------
|
|
212
|
-
regionspec: str
|
|
213
|
-
a string with a possibly inexact name, which is matched both
|
|
214
|
-
against the name and the identifier key,
|
|
215
|
-
parents_only: bool
|
|
216
|
-
If true, children of matched parents will not be returned
|
|
217
|
-
Returns
|
|
218
|
-
-------
|
|
219
|
-
List[Region]
|
|
220
|
-
list of matching regions
|
|
221
|
-
"""
|
|
222
|
-
MEM = Parcellation._CACHED_REGION_SEARCHES
|
|
223
|
-
if region_spec not in MEM:
|
|
224
|
-
MEM[region_spec] = [
|
|
225
|
-
r
|
|
226
|
-
for p in Parcellation.registry()
|
|
227
|
-
for r in p.find(regionspec=region_spec)
|
|
228
|
-
]
|
|
229
|
-
if parents_only:
|
|
230
|
-
return [
|
|
231
|
-
r for r in MEM[region_spec]
|
|
232
|
-
if (r.parent is None) or (r.parent not in MEM[region_spec])
|
|
233
|
-
]
|
|
234
|
-
else:
|
|
235
|
-
return MEM[region_spec]
|
|
236
|
-
|
|
237
211
|
@property
|
|
238
212
|
def is_newest_version(self):
|
|
239
213
|
return (self.version is None) or (self.version.next_id is None)
|
|
@@ -263,7 +237,7 @@ class Parcellation(region.Region, configuration_folder="parcellations"):
|
|
|
263
237
|
def get_region(
|
|
264
238
|
self,
|
|
265
239
|
regionspec: Union[str, region.Region],
|
|
266
|
-
find_topmost: bool =
|
|
240
|
+
find_topmost: bool = False,
|
|
267
241
|
allow_tuple: bool = False
|
|
268
242
|
):
|
|
269
243
|
"""
|
|
@@ -281,7 +255,7 @@ class Parcellation(region.Region, configuration_folder="parcellations"):
|
|
|
281
255
|
regionspec: str, Region
|
|
282
256
|
- a string with a possibly inexact name (matched both against the name and the identifier key)
|
|
283
257
|
- a Region object
|
|
284
|
-
find_topmost: bool, default:
|
|
258
|
+
find_topmost: bool, default: False
|
|
285
259
|
If True, will automatically return the parent of a decoded region
|
|
286
260
|
the decoded region is its only child.
|
|
287
261
|
allow_tuple: bool, default: False
|
|
@@ -370,3 +344,44 @@ class Parcellation(region.Region, configuration_folder="parcellations"):
|
|
|
370
344
|
)
|
|
371
345
|
return self.name < other.name
|
|
372
346
|
return self.version.__lt__(other.version)
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
@lru_cache(maxsize=128)
|
|
350
|
+
def find_regions(
|
|
351
|
+
regionspec: str,
|
|
352
|
+
filter_children=True,
|
|
353
|
+
find_topmost=False
|
|
354
|
+
):
|
|
355
|
+
"""
|
|
356
|
+
Find regions matching the given region specification across all parcellation
|
|
357
|
+
instances in the registery.
|
|
358
|
+
|
|
359
|
+
Parameters
|
|
360
|
+
----------
|
|
361
|
+
regionspec: str, regex, Region
|
|
362
|
+
- a string with a possibly inexact name (matched both against the name and the identifier key)
|
|
363
|
+
- a string in '/pattern/flags' format to use regex search (acceptable flags: aiLmsux) (see https://docs.python.org/3/library/re.html#flags)
|
|
364
|
+
- a regex applied to region names
|
|
365
|
+
- a Region object
|
|
366
|
+
filter_children : bool, default: True
|
|
367
|
+
If True, children of matched parents will not be returned
|
|
368
|
+
find_topmost : bool, default: False
|
|
369
|
+
If True (requires `filter_children=True`), will return parent
|
|
370
|
+
structures if all children are matched, even though the parent
|
|
371
|
+
itself might not match the specification.
|
|
372
|
+
|
|
373
|
+
Returns
|
|
374
|
+
-------
|
|
375
|
+
list[Region]
|
|
376
|
+
list of regions matching to the regionspec
|
|
377
|
+
"""
|
|
378
|
+
result = []
|
|
379
|
+
for p in Parcellation.registry():
|
|
380
|
+
result.extend(
|
|
381
|
+
p.find(
|
|
382
|
+
regionspec=regionspec,
|
|
383
|
+
filter_children=filter_children,
|
|
384
|
+
find_topmost=find_topmost
|
|
385
|
+
)
|
|
386
|
+
)
|
|
387
|
+
return result
|