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.

Files changed (83) hide show
  1. siibra/VERSION +1 -1
  2. siibra/__init__.py +20 -12
  3. siibra/commons.py +145 -90
  4. siibra/configuration/__init__.py +1 -1
  5. siibra/configuration/configuration.py +22 -17
  6. siibra/configuration/factory.py +177 -128
  7. siibra/core/__init__.py +1 -8
  8. siibra/core/{relation_qualification.py → assignment.py} +17 -14
  9. siibra/core/atlas.py +66 -35
  10. siibra/core/concept.py +81 -39
  11. siibra/core/parcellation.py +83 -67
  12. siibra/core/region.py +569 -263
  13. siibra/core/space.py +7 -39
  14. siibra/core/structure.py +111 -0
  15. siibra/exceptions.py +63 -0
  16. siibra/experimental/__init__.py +19 -0
  17. siibra/experimental/contour.py +61 -0
  18. siibra/experimental/cortical_profile_sampler.py +57 -0
  19. siibra/experimental/patch.py +98 -0
  20. siibra/experimental/plane3d.py +256 -0
  21. siibra/explorer/__init__.py +16 -0
  22. siibra/explorer/url.py +112 -52
  23. siibra/explorer/util.py +31 -9
  24. siibra/features/__init__.py +73 -8
  25. siibra/features/anchor.py +75 -196
  26. siibra/features/connectivity/__init__.py +1 -1
  27. siibra/features/connectivity/functional_connectivity.py +2 -2
  28. siibra/features/connectivity/regional_connectivity.py +99 -10
  29. siibra/features/connectivity/streamline_counts.py +1 -1
  30. siibra/features/connectivity/streamline_lengths.py +1 -1
  31. siibra/features/connectivity/tracing_connectivity.py +1 -1
  32. siibra/features/dataset/__init__.py +1 -1
  33. siibra/features/dataset/ebrains.py +3 -3
  34. siibra/features/feature.py +219 -110
  35. siibra/features/image/__init__.py +1 -1
  36. siibra/features/image/image.py +21 -13
  37. siibra/features/image/sections.py +1 -1
  38. siibra/features/image/volume_of_interest.py +1 -1
  39. siibra/features/tabular/__init__.py +1 -1
  40. siibra/features/tabular/bigbrain_intensity_profile.py +24 -13
  41. siibra/features/tabular/cell_density_profile.py +111 -69
  42. siibra/features/tabular/cortical_profile.py +82 -16
  43. siibra/features/tabular/gene_expression.py +117 -6
  44. siibra/features/tabular/layerwise_bigbrain_intensities.py +7 -9
  45. siibra/features/tabular/layerwise_cell_density.py +9 -24
  46. siibra/features/tabular/receptor_density_fingerprint.py +11 -6
  47. siibra/features/tabular/receptor_density_profile.py +12 -15
  48. siibra/features/tabular/regional_timeseries_activity.py +74 -18
  49. siibra/features/tabular/tabular.py +17 -8
  50. siibra/livequeries/__init__.py +1 -7
  51. siibra/livequeries/allen.py +139 -77
  52. siibra/livequeries/bigbrain.py +104 -128
  53. siibra/livequeries/ebrains.py +7 -4
  54. siibra/livequeries/query.py +1 -2
  55. siibra/locations/__init__.py +32 -25
  56. siibra/locations/boundingbox.py +153 -127
  57. siibra/locations/location.py +45 -80
  58. siibra/locations/point.py +97 -83
  59. siibra/locations/pointcloud.py +349 -0
  60. siibra/retrieval/__init__.py +1 -1
  61. siibra/retrieval/cache.py +107 -13
  62. siibra/retrieval/datasets.py +9 -14
  63. siibra/retrieval/exceptions/__init__.py +2 -1
  64. siibra/retrieval/repositories.py +147 -53
  65. siibra/retrieval/requests.py +64 -29
  66. siibra/vocabularies/__init__.py +2 -2
  67. siibra/volumes/__init__.py +7 -9
  68. siibra/volumes/parcellationmap.py +396 -253
  69. siibra/volumes/providers/__init__.py +20 -0
  70. siibra/volumes/providers/freesurfer.py +113 -0
  71. siibra/volumes/{gifti.py → providers/gifti.py} +29 -18
  72. siibra/volumes/{neuroglancer.py → providers/neuroglancer.py} +204 -92
  73. siibra/volumes/{nifti.py → providers/nifti.py} +64 -44
  74. siibra/volumes/providers/provider.py +107 -0
  75. siibra/volumes/sparsemap.py +159 -260
  76. siibra/volumes/volume.py +720 -152
  77. {siibra-0.5a2.dist-info → siibra-1.0.0a1.dist-info}/METADATA +25 -28
  78. siibra-1.0.0a1.dist-info/RECORD +84 -0
  79. {siibra-0.5a2.dist-info → siibra-1.0.0a1.dist-info}/WHEEL +1 -1
  80. siibra/locations/pointset.py +0 -198
  81. siibra-0.5a2.dist-info/RECORD +0 -74
  82. {siibra-0.5a2.dist-info → siibra-1.0.0a1.dist-info}/LICENSE +0 -0
  83. {siibra-0.5a2.dist-info → siibra-1.0.0a1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,20 @@
1
+ # Copyright 2018-2024
2
+ # Institute of Neuroscience and Medicine (INM-1), Forschungszentrum Jülich GmbH
3
+
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ """Subpackage handling the digestion of different volume and mesh types"""
16
+
17
+ from .neuroglancer import NeuroglancerProvider, NeuroglancerMesh
18
+ from .nifti import NiftiProvider
19
+ from .gifti import GiftiSurfaceLabeling, GiftiMesh
20
+ from .freesurfer import ZippedFreesurferAnnot, FreesurferAnnot
@@ -0,0 +1,113 @@
1
+ # Copyright 2018-2024
2
+ # Institute of Neuroscience and Medicine (INM-1), Forschungszentrum Jülich GmbH
3
+
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ """Handles reading and preparing gii files."""
16
+
17
+ from . import provider as _provider
18
+
19
+ from ...retrieval.requests import HttpRequest, ZipfileRequest
20
+
21
+ import numpy as np
22
+ from typing import Union, Dict, TYPE_CHECKING
23
+
24
+ if TYPE_CHECKING:
25
+ from ...locations import boundingbox as _boundingbox
26
+
27
+
28
+ class FreesurferAnnot(_provider.VolumeProvider, srctype="freesurfer-annot"):
29
+ def __init__(self, url: Union[str, dict]):
30
+ self._init_url = url
31
+ if isinstance(url, str): # single mesh labelling
32
+ self._loaders = {None: HttpRequest(url)}
33
+ elif isinstance(url, dict): # named label fragments
34
+ self._loaders = {lbl: HttpRequest(u) for lbl, u in url.items()}
35
+ else:
36
+ raise NotImplementedError(f"Urls for {self.__class__.__name__} are expected to be of type str.")
37
+
38
+ def fetch(self, fragment: str = None, label: int = None, **kwargs):
39
+ """Returns a 1D numpy array of label indices."""
40
+ vertex_labels = []
41
+ if fragment is None:
42
+ matched_frags = list(self._loaders.keys())
43
+ else:
44
+ matched_frags = [frg for frg in self._loaders.keys() if fragment.lower() in frg.lower()]
45
+ if len(matched_frags) != 1:
46
+ raise ValueError(
47
+ f"Requested fragment '{fragment}' could not be matched uniquely "
48
+ f"to [{', '.join(self._loaders)}]"
49
+ )
50
+ for frag in matched_frags:
51
+ frag_labels, *_ = self._loaders[frag].data
52
+ if label is not None: # create the mask
53
+ selected_label = frag_labels == label
54
+ frag_labels[selected_label] = 1
55
+ frag_labels[~selected_label] = 0
56
+ else:
57
+ frag_labels[frag_labels == -1] = 0 # annot files store backgorund as -1 while siibra uses 0
58
+ vertex_labels.append(frag_labels)
59
+
60
+ return {"labels": np.hstack(vertex_labels)}
61
+
62
+ def get_boundingbox(self, clip=False, background=0.0) -> '_boundingbox.BoundingBox':
63
+ raise NotImplementedError(
64
+ f"Bounding box access to {self.__class__.__name__} objects not yet implemented."
65
+ )
66
+
67
+ @property
68
+ def _url(self) -> Union[str, Dict[str, str]]:
69
+ return self._init_url
70
+
71
+
72
+ class ZippedFreesurferAnnot(_provider.VolumeProvider, srctype="zip/freesurfer-annot"):
73
+ def __init__(self, url: Union[str, dict]):
74
+ self._init_url = url
75
+ if isinstance(url, str): # single mesh labelling
76
+ self._loaders = {None: ZipfileRequest(*url.split(" "))}
77
+ elif isinstance(url, dict): # named label fragments
78
+ self._loaders = {lbl: ZipfileRequest(*u.split(" ")) for lbl, u in url.items()}
79
+ else:
80
+ raise NotImplementedError(f"Urls for {self.__class__.__name__} are expected to be of type str.")
81
+
82
+ def fetch(self, fragment: str = None, label: int = None, **kwargs):
83
+ """Returns a 1D numpy array of label indices."""
84
+ vertex_labels = []
85
+ if fragment is None:
86
+ matched_frags = list(self._loaders.keys())
87
+ else:
88
+ matched_frags = [frg for frg in self._loaders.keys() if fragment.lower() in frg.lower()]
89
+ if len(matched_frags) != 1:
90
+ raise ValueError(
91
+ f"Requested fragment '{fragment}' could not be matched uniquely "
92
+ f"to [{', '.join(self._loaders)}]"
93
+ )
94
+ for frag in matched_frags:
95
+ frag_labels, *_ = self._loaders[frag].data
96
+ if label is not None: # create the mask
97
+ selected_label = frag_labels == label
98
+ frag_labels[selected_label] = 1
99
+ frag_labels[~selected_label] = 0
100
+ else:
101
+ frag_labels[frag_labels == -1] = 0 # annot files store backgorund as -1 while siibra uses 0
102
+ vertex_labels.append(frag_labels)
103
+
104
+ return {"labels": np.hstack(vertex_labels)}
105
+
106
+ def get_boundingbox(self, clip=False, background=0.0) -> '_boundingbox.BoundingBox':
107
+ raise NotImplementedError(
108
+ f"Bounding box access to {self.__class__.__name__} objects not yet implemented."
109
+ )
110
+
111
+ @property
112
+ def _url(self) -> Union[str, Dict[str, str]]:
113
+ return self._init_url
@@ -1,4 +1,4 @@
1
- # Copyright 2018-2021
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");
@@ -14,17 +14,17 @@
14
14
  # limitations under the License.
15
15
  """Handles reading and preparing gii files."""
16
16
 
17
- from . import volume
17
+ from . import provider as _provider
18
18
 
19
- from ..retrieval import requests
20
- from ..commons import logger, merge_meshes
21
- from ..locations import boundingbox as _boundingbox
19
+ from ...retrieval import requests
20
+ from ...commons import logger, merge_meshes
21
+ from ...locations import boundingbox as _boundingbox
22
22
 
23
23
  import numpy as np
24
24
  from typing import Union, Dict
25
25
 
26
26
 
27
- class GiftiMesh(volume.VolumeProvider, srctype="gii-mesh"):
27
+ class GiftiMesh(_provider.VolumeProvider, srctype="gii-mesh"):
28
28
  """
29
29
  One or more surface mesh fragments in Gifti format.
30
30
  """
@@ -44,8 +44,10 @@ class GiftiMesh(volume.VolumeProvider, srctype="gii-mesh"):
44
44
  def _url(self) -> Union[str, Dict[str, str]]:
45
45
  return self._init_url
46
46
 
47
- @property
48
- def boundingbox(self) -> _boundingbox.BoundingBox:
47
+ def get_boundingbox(self, clip=False, background=0.0, **fetch_kwargs) -> '_boundingbox.BoundingBox':
48
+ """
49
+ Bounding box calculation is not yet implemented for meshes.
50
+ """
49
51
  raise NotImplementedError(
50
52
  f"Bounding box access to {self.__class__.__name__} objects not yet implemented."
51
53
  )
@@ -118,7 +120,7 @@ class GiftiMesh(volume.VolumeProvider, srctype="gii-mesh"):
118
120
  return (self.fetch(v) for v in self.variants)
119
121
 
120
122
 
121
- class GiftiSurfaceLabeling(volume.VolumeProvider, srctype="gii-label"):
123
+ class GiftiSurfaceLabeling(_provider.VolumeProvider, srctype="gii-label"):
122
124
  """
123
125
  A mesh labeling, specified by a gifti file.
124
126
  """
@@ -132,21 +134,30 @@ class GiftiSurfaceLabeling(volume.VolumeProvider, srctype="gii-label"):
132
134
  else:
133
135
  raise NotImplementedError(f"Urls for {self.__class__.__name__} are expected to be of type str or dict.")
134
136
 
135
- def fetch(self, fragment: str = None, **kwargs):
137
+ def fetch(self, fragment: str = None, label: int = None, **kwargs):
136
138
  """Returns a 1D numpy array of label indices."""
137
139
  labels = []
138
- for fragment_name, loader in self._loaders.items():
139
- if fragment is not None and fragment.lower() not in fragment_name.lower():
140
- continue
141
- assert len(loader.data.darrays) == 1
142
- labels.append(loader.data.darrays[0].data)
140
+ if fragment is None:
141
+ matched_frags = list(self._loaders.keys())
142
+ else:
143
+ matched_frags = [frg for frg in self._loaders.keys() if fragment.lower() in frg.lower()]
144
+ if len(matched_frags) != 1:
145
+ raise ValueError(
146
+ f"Requested fragment '{fragment}' could not be matched uniquely "
147
+ f"to [{', '.join(self._loaders)}]"
148
+ )
149
+ for frag in matched_frags:
150
+ assert len(self._loaders[frag].data.darrays) == 1
151
+ if label is not None:
152
+ labels.append((self._loaders[frag].data.darrays[0].data == label).astype('uint8'))
153
+ else:
154
+ labels.append(self._loaders[frag].data.darrays[0].data)
143
155
 
144
156
  return {"labels": np.hstack(labels)}
145
157
 
146
- @property
147
- def boundingbox(self) -> _boundingbox.BoundingBox:
158
+ def get_boundingbox(self, clip=False, background=0.0) -> '_boundingbox.BoundingBox':
148
159
  raise NotImplementedError(
149
- f"Bounding boxes of {self.__class__.__name__} objects not defined."
160
+ f"Bounding box access to {self.__class__.__name__} objects not yet implemented."
150
161
  )
151
162
 
152
163
  @property