siibra 0.5a2__py3-none-any.whl → 1.0.0a1__py3-none-any.whl
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/VERSION +1 -1
- siibra/__init__.py +20 -12
- siibra/commons.py +145 -90
- siibra/configuration/__init__.py +1 -1
- siibra/configuration/configuration.py +22 -17
- siibra/configuration/factory.py +177 -128
- siibra/core/__init__.py +1 -8
- siibra/core/{relation_qualification.py → assignment.py} +17 -14
- siibra/core/atlas.py +66 -35
- siibra/core/concept.py +81 -39
- siibra/core/parcellation.py +83 -67
- siibra/core/region.py +569 -263
- siibra/core/space.py +7 -39
- siibra/core/structure.py +111 -0
- siibra/exceptions.py +63 -0
- siibra/experimental/__init__.py +19 -0
- siibra/experimental/contour.py +61 -0
- siibra/experimental/cortical_profile_sampler.py +57 -0
- siibra/experimental/patch.py +98 -0
- siibra/experimental/plane3d.py +256 -0
- siibra/explorer/__init__.py +16 -0
- siibra/explorer/url.py +112 -52
- siibra/explorer/util.py +31 -9
- siibra/features/__init__.py +73 -8
- siibra/features/anchor.py +75 -196
- siibra/features/connectivity/__init__.py +1 -1
- siibra/features/connectivity/functional_connectivity.py +2 -2
- siibra/features/connectivity/regional_connectivity.py +99 -10
- siibra/features/connectivity/streamline_counts.py +1 -1
- siibra/features/connectivity/streamline_lengths.py +1 -1
- siibra/features/connectivity/tracing_connectivity.py +1 -1
- siibra/features/dataset/__init__.py +1 -1
- siibra/features/dataset/ebrains.py +3 -3
- siibra/features/feature.py +219 -110
- siibra/features/image/__init__.py +1 -1
- siibra/features/image/image.py +21 -13
- siibra/features/image/sections.py +1 -1
- siibra/features/image/volume_of_interest.py +1 -1
- siibra/features/tabular/__init__.py +1 -1
- siibra/features/tabular/bigbrain_intensity_profile.py +24 -13
- siibra/features/tabular/cell_density_profile.py +111 -69
- siibra/features/tabular/cortical_profile.py +82 -16
- siibra/features/tabular/gene_expression.py +117 -6
- siibra/features/tabular/layerwise_bigbrain_intensities.py +7 -9
- siibra/features/tabular/layerwise_cell_density.py +9 -24
- siibra/features/tabular/receptor_density_fingerprint.py +11 -6
- siibra/features/tabular/receptor_density_profile.py +12 -15
- siibra/features/tabular/regional_timeseries_activity.py +74 -18
- siibra/features/tabular/tabular.py +17 -8
- siibra/livequeries/__init__.py +1 -7
- siibra/livequeries/allen.py +139 -77
- siibra/livequeries/bigbrain.py +104 -128
- siibra/livequeries/ebrains.py +7 -4
- siibra/livequeries/query.py +1 -2
- siibra/locations/__init__.py +32 -25
- siibra/locations/boundingbox.py +153 -127
- siibra/locations/location.py +45 -80
- siibra/locations/point.py +97 -83
- siibra/locations/pointcloud.py +349 -0
- siibra/retrieval/__init__.py +1 -1
- siibra/retrieval/cache.py +107 -13
- siibra/retrieval/datasets.py +9 -14
- siibra/retrieval/exceptions/__init__.py +2 -1
- siibra/retrieval/repositories.py +147 -53
- siibra/retrieval/requests.py +64 -29
- siibra/vocabularies/__init__.py +2 -2
- siibra/volumes/__init__.py +7 -9
- siibra/volumes/parcellationmap.py +396 -253
- siibra/volumes/providers/__init__.py +20 -0
- siibra/volumes/providers/freesurfer.py +113 -0
- siibra/volumes/{gifti.py → providers/gifti.py} +29 -18
- siibra/volumes/{neuroglancer.py → providers/neuroglancer.py} +204 -92
- siibra/volumes/{nifti.py → providers/nifti.py} +64 -44
- siibra/volumes/providers/provider.py +107 -0
- siibra/volumes/sparsemap.py +159 -260
- siibra/volumes/volume.py +720 -152
- {siibra-0.5a2.dist-info → siibra-1.0.0a1.dist-info}/METADATA +25 -28
- siibra-1.0.0a1.dist-info/RECORD +84 -0
- {siibra-0.5a2.dist-info → siibra-1.0.0a1.dist-info}/WHEEL +1 -1
- siibra/locations/pointset.py +0 -198
- siibra-0.5a2.dist-info/RECORD +0 -74
- {siibra-0.5a2.dist-info → siibra-1.0.0a1.dist-info}/LICENSE +0 -0
- {siibra-0.5a2.dist-info → siibra-1.0.0a1.dist-info}/top_level.txt +0 -0
siibra/core/parcellation.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2018-
|
|
1
|
+
# Copyright 2018-2024
|
|
2
2
|
# Institute of Neuroscience and Medicine (INM-1), Forschungszentrum Jülich GmbH
|
|
3
3
|
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -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,
|
|
@@ -82,6 +90,7 @@ class Parcellation(region.Region, configuration_folder="parcellations"):
|
|
|
82
90
|
modality: str = None,
|
|
83
91
|
publications: list = [],
|
|
84
92
|
datasets: list = [],
|
|
93
|
+
prerelease: bool = False,
|
|
85
94
|
):
|
|
86
95
|
"""
|
|
87
96
|
Constructs a new parcellation object.
|
|
@@ -118,7 +127,8 @@ class Parcellation(region.Region, configuration_folder="parcellations"):
|
|
|
118
127
|
description=description,
|
|
119
128
|
publications=publications,
|
|
120
129
|
datasets=datasets,
|
|
121
|
-
modality=modality
|
|
130
|
+
modality=modality,
|
|
131
|
+
prerelease=prerelease,
|
|
122
132
|
)
|
|
123
133
|
self._species_cached = Species.decode(species)
|
|
124
134
|
self._id = identifier
|
|
@@ -129,15 +139,21 @@ class Parcellation(region.Region, configuration_folder="parcellations"):
|
|
|
129
139
|
return self._id
|
|
130
140
|
|
|
131
141
|
def matches(self, spec):
|
|
132
|
-
if
|
|
133
|
-
if
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
142
|
+
if spec not in self._CACHED_MATCHES:
|
|
143
|
+
if isinstance(spec, str):
|
|
144
|
+
if all(
|
|
145
|
+
w in self.shortname.lower()
|
|
146
|
+
for w in re.split(r'\s+', spec.lower())
|
|
147
|
+
):
|
|
148
|
+
self._CACHED_MATCHES[spec] = True
|
|
138
149
|
return super().matches(spec)
|
|
139
150
|
|
|
140
|
-
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
|
+
):
|
|
141
157
|
"""
|
|
142
158
|
Get the maps for the parcellation in the requested template space.
|
|
143
159
|
|
|
@@ -150,8 +166,8 @@ class Parcellation(region.Region, configuration_folder="parcellations"):
|
|
|
150
166
|
Parameters
|
|
151
167
|
----------
|
|
152
168
|
space: Space or str
|
|
153
|
-
|
|
154
|
-
maptype: MapType
|
|
169
|
+
reference space specification such as name, id, or a `Space` instance.
|
|
170
|
+
maptype: MapType or str
|
|
155
171
|
Type of map requested (e.g., statistical or labelled).
|
|
156
172
|
Use MapType.STATISTICAL to request probability maps.
|
|
157
173
|
Defaults to MapType.LABELLED.
|
|
@@ -166,26 +182,24 @@ class Parcellation(region.Region, configuration_folder="parcellations"):
|
|
|
166
182
|
A ParcellationMap representing the volumetric map or
|
|
167
183
|
a SparseMap representing the list of statistical maps.
|
|
168
184
|
"""
|
|
169
|
-
if
|
|
185
|
+
if isinstance(maptype, str):
|
|
170
186
|
maptype = MapType[maptype.upper()]
|
|
187
|
+
assert isinstance(maptype, MapType), "Possible values of `maptype` are `MapType`s, 'labelled', 'statistical'."
|
|
171
188
|
|
|
172
189
|
candidates = [
|
|
173
190
|
m for m in parcellationmap.Map.registry()
|
|
174
191
|
if m.space.matches(space)
|
|
175
192
|
and m.maptype == maptype
|
|
176
|
-
and m.parcellation
|
|
177
193
|
and m.parcellation.matches(self)
|
|
178
194
|
]
|
|
179
195
|
if len(candidates) == 0:
|
|
180
|
-
|
|
181
|
-
return None
|
|
196
|
+
raise NoMapMatchingValues(f"No '{maptype}' map in '{space}' available for {str(self)}")
|
|
182
197
|
if len(candidates) > 1:
|
|
183
198
|
spec_candidates = [
|
|
184
|
-
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())
|
|
185
200
|
]
|
|
186
201
|
if len(spec_candidates) == 0:
|
|
187
|
-
|
|
188
|
-
return None
|
|
202
|
+
raise NoMapMatchingValues(f"'{spec}' does not match any options from {[c.name for c in candidates]}.")
|
|
189
203
|
if len(spec_candidates) > 1:
|
|
190
204
|
logger.warning(
|
|
191
205
|
f"Multiple maps are available in this specification of space, parcellation, and map type.\n"
|
|
@@ -194,43 +208,6 @@ class Parcellation(region.Region, configuration_folder="parcellations"):
|
|
|
194
208
|
return spec_candidates[0]
|
|
195
209
|
return candidates[0]
|
|
196
210
|
|
|
197
|
-
@staticmethod
|
|
198
|
-
def find_regions(region_spec: str, parents_only=True):
|
|
199
|
-
"""
|
|
200
|
-
Find regions that match the given region specification in the subtree
|
|
201
|
-
headed by each parcellation in the registry.
|
|
202
|
-
Note
|
|
203
|
-
----
|
|
204
|
-
Use Region.find() to search for a region in an instance of a
|
|
205
|
-
parcellation.
|
|
206
|
-
|
|
207
|
-
Parameters
|
|
208
|
-
----------
|
|
209
|
-
regionspec: str
|
|
210
|
-
a string with a possibly inexact name, which is matched both
|
|
211
|
-
against the name and the identifier key,
|
|
212
|
-
parents_only: bool
|
|
213
|
-
If true, children of matched parents will not be returned
|
|
214
|
-
Returns
|
|
215
|
-
-------
|
|
216
|
-
List[Region]
|
|
217
|
-
list of matching regions
|
|
218
|
-
"""
|
|
219
|
-
MEM = Parcellation._CACHED_REGION_SEARCHES
|
|
220
|
-
if region_spec not in MEM:
|
|
221
|
-
MEM[region_spec] = [
|
|
222
|
-
r
|
|
223
|
-
for p in Parcellation.registry()
|
|
224
|
-
for r in p.find(regionspec=region_spec)
|
|
225
|
-
]
|
|
226
|
-
if parents_only:
|
|
227
|
-
return [
|
|
228
|
-
r for r in MEM[region_spec]
|
|
229
|
-
if (r.parent is None) or (r.parent not in MEM[region_spec])
|
|
230
|
-
]
|
|
231
|
-
else:
|
|
232
|
-
return MEM[region_spec]
|
|
233
|
-
|
|
234
211
|
@property
|
|
235
212
|
def is_newest_version(self):
|
|
236
213
|
return (self.version is None) or (self.version.next_id is None)
|
|
@@ -260,7 +237,7 @@ class Parcellation(region.Region, configuration_folder="parcellations"):
|
|
|
260
237
|
def get_region(
|
|
261
238
|
self,
|
|
262
239
|
regionspec: Union[str, region.Region],
|
|
263
|
-
find_topmost: bool =
|
|
240
|
+
find_topmost: bool = False,
|
|
264
241
|
allow_tuple: bool = False
|
|
265
242
|
):
|
|
266
243
|
"""
|
|
@@ -278,7 +255,7 @@ class Parcellation(region.Region, configuration_folder="parcellations"):
|
|
|
278
255
|
regionspec: str, Region
|
|
279
256
|
- a string with a possibly inexact name (matched both against the name and the identifier key)
|
|
280
257
|
- a Region object
|
|
281
|
-
find_topmost: bool, default:
|
|
258
|
+
find_topmost: bool, default: False
|
|
282
259
|
If True, will automatically return the parent of a decoded region
|
|
283
260
|
the decoded region is its only child.
|
|
284
261
|
allow_tuple: bool, default: False
|
|
@@ -308,7 +285,11 @@ class Parcellation(region.Region, configuration_folder="parcellations"):
|
|
|
308
285
|
|
|
309
286
|
# if there exist an exact match of region spec to region name, return
|
|
310
287
|
if isinstance(regionspec, str):
|
|
311
|
-
exact_match = [
|
|
288
|
+
exact_match = [
|
|
289
|
+
region
|
|
290
|
+
for region in self
|
|
291
|
+
if region.name == regionspec or region.key == regionspec
|
|
292
|
+
]
|
|
312
293
|
if len(exact_match) == 1:
|
|
313
294
|
return exact_match[0]
|
|
314
295
|
if len(exact_match) > 1:
|
|
@@ -346,12 +327,6 @@ class Parcellation(region.Region, configuration_folder="parcellations"):
|
|
|
346
327
|
f"Spec {regionspec!r} resulted in multiple matches: {', '.join(r.name for r in candidates)}."
|
|
347
328
|
)
|
|
348
329
|
|
|
349
|
-
def __str__(self):
|
|
350
|
-
return self.name
|
|
351
|
-
|
|
352
|
-
def __repr__(self):
|
|
353
|
-
return self.name
|
|
354
|
-
|
|
355
330
|
def __getitem__(self, regionspec: Union[str, int]):
|
|
356
331
|
"""
|
|
357
332
|
Retrieve a region object from the parcellation by labelindex or partial name.
|
|
@@ -369,3 +344,44 @@ class Parcellation(region.Region, configuration_folder="parcellations"):
|
|
|
369
344
|
)
|
|
370
345
|
return self.name < other.name
|
|
371
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
|