siibra 1.0.1a0__py3-none-any.whl → 1.0.1a1__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 +4 -4
- siibra/commons.py +8 -7
- siibra/configuration/__init__.py +1 -1
- siibra/configuration/configuration.py +1 -1
- siibra/configuration/factory.py +1 -1
- siibra/core/__init__.py +1 -1
- siibra/core/assignment.py +1 -1
- siibra/core/atlas.py +1 -1
- siibra/core/concept.py +3 -3
- siibra/core/parcellation.py +6 -6
- siibra/core/region.py +59 -49
- siibra/core/space.py +1 -1
- siibra/core/structure.py +2 -2
- siibra/exceptions.py +6 -2
- siibra/experimental/__init__.py +1 -1
- siibra/experimental/contour.py +2 -2
- siibra/experimental/cortical_profile_sampler.py +1 -1
- siibra/experimental/patch.py +1 -1
- siibra/experimental/plane3d.py +4 -4
- siibra/explorer/__init__.py +1 -1
- siibra/explorer/url.py +2 -2
- siibra/explorer/util.py +1 -1
- siibra/features/__init__.py +1 -1
- siibra/features/anchor.py +2 -2
- siibra/features/connectivity/__init__.py +1 -1
- siibra/features/connectivity/functional_connectivity.py +1 -1
- siibra/features/connectivity/regional_connectivity.py +2 -2
- 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 +1 -1
- siibra/features/feature.py +10 -10
- siibra/features/image/__init__.py +1 -1
- siibra/features/image/image.py +2 -2
- 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 +1 -1
- siibra/features/tabular/cell_density_profile.py +2 -2
- siibra/features/tabular/cortical_profile.py +3 -3
- siibra/features/tabular/gene_expression.py +1 -1
- siibra/features/tabular/layerwise_bigbrain_intensities.py +1 -1
- siibra/features/tabular/layerwise_cell_density.py +1 -1
- siibra/features/tabular/receptor_density_fingerprint.py +13 -10
- siibra/features/tabular/receptor_density_profile.py +1 -1
- siibra/features/tabular/regional_timeseries_activity.py +2 -2
- siibra/features/tabular/tabular.py +7 -5
- siibra/livequeries/__init__.py +1 -1
- siibra/livequeries/allen.py +3 -3
- siibra/livequeries/bigbrain.py +15 -6
- siibra/livequeries/ebrains.py +1 -1
- siibra/livequeries/query.py +2 -2
- siibra/locations/__init__.py +2 -2
- siibra/locations/boundingbox.py +3 -7
- siibra/locations/location.py +1 -1
- siibra/locations/point.py +3 -3
- siibra/locations/pointcloud.py +9 -14
- siibra/retrieval/__init__.py +1 -1
- siibra/retrieval/cache.py +1 -1
- siibra/retrieval/datasets.py +4 -4
- siibra/retrieval/exceptions/__init__.py +1 -1
- siibra/retrieval/repositories.py +4 -4
- siibra/retrieval/requests.py +6 -6
- siibra/vocabularies/__init__.py +1 -1
- siibra/volumes/__init__.py +1 -1
- siibra/volumes/parcellationmap.py +31 -10
- siibra/volumes/providers/__init__.py +1 -1
- siibra/volumes/providers/freesurfer.py +3 -3
- siibra/volumes/providers/gifti.py +1 -1
- siibra/volumes/providers/neuroglancer.py +6 -6
- siibra/volumes/providers/nifti.py +1 -1
- siibra/volumes/providers/provider.py +1 -1
- siibra/volumes/sparsemap.py +1 -1
- siibra/volumes/volume.py +12 -12
- {siibra-1.0.1a0.dist-info → siibra-1.0.1a1.dist-info}/METADATA +12 -3
- siibra-1.0.1a1.dist-info/RECORD +84 -0
- {siibra-1.0.1a0.dist-info → siibra-1.0.1a1.dist-info}/WHEEL +1 -1
- siibra-1.0.1a0.dist-info/RECORD +0 -84
- {siibra-1.0.1a0.dist-info → siibra-1.0.1a1.dist-info}/LICENSE +0 -0
- {siibra-1.0.1a0.dist-info → siibra-1.0.1a1.dist-info}/top_level.txt +0 -0
siibra/features/feature.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2018-
|
|
1
|
+
# Copyright 2018-2025
|
|
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");
|
|
@@ -53,7 +53,7 @@ _README_TMPL = """
|
|
|
53
53
|
Downloaded from siibra toolsuite.
|
|
54
54
|
siibra-python version: {version}
|
|
55
55
|
|
|
56
|
-
All
|
|
56
|
+
All related resources (e.g. doi, web resources) are categorized under publications.
|
|
57
57
|
|
|
58
58
|
Name
|
|
59
59
|
----
|
|
@@ -199,9 +199,9 @@ class Feature:
|
|
|
199
199
|
@property
|
|
200
200
|
def authors(self):
|
|
201
201
|
return [
|
|
202
|
-
|
|
202
|
+
contributor['name']
|
|
203
203
|
for ds in self.datasets
|
|
204
|
-
for
|
|
204
|
+
for contributor in ds.contributors
|
|
205
205
|
]
|
|
206
206
|
|
|
207
207
|
@property
|
|
@@ -256,7 +256,7 @@ class Feature:
|
|
|
256
256
|
concept: Union[structure.BrainStructure, space.Space],
|
|
257
257
|
) -> bool:
|
|
258
258
|
"""
|
|
259
|
-
Match the features anatomical anchor
|
|
259
|
+
Match the features anatomical anchor against the given query concept.
|
|
260
260
|
Record the most recently matched concept for inspection by the caller.
|
|
261
261
|
"""
|
|
262
262
|
# TODO: storing the last matched concept. It is not ideal, might cause problems in multithreading
|
|
@@ -509,7 +509,7 @@ class Feature:
|
|
|
509
509
|
This will
|
|
510
510
|
- call Feature.match(concept) for any registered preconfigured features
|
|
511
511
|
- run any registered live queries
|
|
512
|
-
The preconfigured and live query instances are merged and
|
|
512
|
+
The preconfigured and live query instances are merged and returned as a list.
|
|
513
513
|
|
|
514
514
|
If multiple feature types are given, recurse for each of them.
|
|
515
515
|
|
|
@@ -519,7 +519,7 @@ class Feature:
|
|
|
519
519
|
concept: AtlasConcept
|
|
520
520
|
An anatomical concept, typically a brain region or parcellation.
|
|
521
521
|
feature_type: subclass of Feature, str
|
|
522
|
-
|
|
522
|
+
specifies the type of features ("modality")
|
|
523
523
|
"""
|
|
524
524
|
if isinstance(feature_type, list):
|
|
525
525
|
# a list of feature types is given, collect match results on those
|
|
@@ -604,7 +604,7 @@ class Feature:
|
|
|
604
604
|
if inst.id == feature_id
|
|
605
605
|
]
|
|
606
606
|
if len(candidates) == 0:
|
|
607
|
-
raise NotFoundException(f"No feature instance
|
|
607
|
+
raise NotFoundException(f"No feature instance with {feature_id} found.")
|
|
608
608
|
if len(candidates) == 1:
|
|
609
609
|
return candidates[0]
|
|
610
610
|
else:
|
|
@@ -719,7 +719,7 @@ class Compoundable(ABC):
|
|
|
719
719
|
"""
|
|
720
720
|
Compute the merge data and create a merged instance from a set of
|
|
721
721
|
elements of this class. This will be used by CompoundFeature to
|
|
722
|
-
create the
|
|
722
|
+
create the aggregated data and plot it. For example, to compute an
|
|
723
723
|
average connectivity matrix from a set of subfeatures, we create a
|
|
724
724
|
RegionalConnectivty feature.
|
|
725
725
|
"""
|
|
@@ -728,7 +728,7 @@ class Compoundable(ABC):
|
|
|
728
728
|
|
|
729
729
|
class CompoundFeature(Feature):
|
|
730
730
|
"""
|
|
731
|
-
A compound aggregating
|
|
731
|
+
A compound aggregating multiple features of the same type, forming its
|
|
732
732
|
elements. The anatomical anchors and data of the features is merged.
|
|
733
733
|
Features need to subclass "Compoundable" to allow aggregation
|
|
734
734
|
into a compound feature.
|
siibra/features/image/image.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2018-
|
|
1
|
+
# Copyright 2018-2025
|
|
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");
|
|
@@ -44,7 +44,7 @@ class ImageAnchor(_anchor.AnatomicalAnchor):
|
|
|
44
44
|
if self._location_cached is None:
|
|
45
45
|
self._location_cached = self.volume.get_boundingbox(
|
|
46
46
|
clip=False
|
|
47
|
-
) # use unclipped to
|
|
47
|
+
) # use unclipped to preserve existing behaviour
|
|
48
48
|
return self._location_cached
|
|
49
49
|
|
|
50
50
|
@property
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2018-
|
|
1
|
+
# Copyright 2018-2025
|
|
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");
|
|
@@ -60,7 +60,7 @@ class PolyLine:
|
|
|
60
60
|
return sum(self.lengths)
|
|
61
61
|
|
|
62
62
|
def sample(self, d: Union[Iterable[float], np.ndarray, float]):
|
|
63
|
-
# if d is
|
|
63
|
+
# if d is iterable, we assume a list of sample positions
|
|
64
64
|
try:
|
|
65
65
|
iter(d)
|
|
66
66
|
except TypeError:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2018-
|
|
1
|
+
# Copyright 2018-2025
|
|
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");
|
|
@@ -37,7 +37,7 @@ class CorticalProfile(tabular.Tabular, Compoundable):
|
|
|
37
37
|
Optionally, the depth coordinates of layer boundaries can be specified.
|
|
38
38
|
|
|
39
39
|
Most attributes are modelled as properties, so dervide classes are able
|
|
40
|
-
to implement lazy loading instead of direct
|
|
40
|
+
to implement lazy loading instead of direct initialization.
|
|
41
41
|
|
|
42
42
|
"""
|
|
43
43
|
|
|
@@ -151,7 +151,7 @@ class CorticalProfile(tabular.Tabular, Compoundable):
|
|
|
151
151
|
|
|
152
152
|
@property
|
|
153
153
|
def _layers(self):
|
|
154
|
-
"""List of layers assigned to each
|
|
154
|
+
"""List of layers assigned to each measurements,
|
|
155
155
|
if layer boundaries are available for this features.
|
|
156
156
|
"""
|
|
157
157
|
if self.boundaries_mapped:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2018-
|
|
1
|
+
# Copyright 2018-2025
|
|
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");
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
from .. import anchor as _anchor
|
|
17
17
|
from . import tabular
|
|
18
18
|
|
|
19
|
-
from ... import
|
|
19
|
+
from ...commons import logger
|
|
20
|
+
from ...vocabularies import RECEPTOR_SYMBOLS
|
|
20
21
|
from ...retrieval import requests
|
|
21
22
|
|
|
22
23
|
import pandas as pd
|
|
@@ -34,7 +35,7 @@ class ReceptorDensityFingerprint(
|
|
|
34
35
|
DESCRIPTION = (
|
|
35
36
|
"Fingerprint of densities (in fmol/mg protein) of receptors for classical neurotransmitters "
|
|
36
37
|
"obtained by means of quantitative in vitro autoradiography. The fingerprint provides average "
|
|
37
|
-
"density
|
|
38
|
+
"density measurements for different receptors measured in tissue samples from different subjects "
|
|
38
39
|
"together with the corresponding standard deviations. "
|
|
39
40
|
)
|
|
40
41
|
|
|
@@ -75,9 +76,9 @@ class ReceptorDensityFingerprint(
|
|
|
75
76
|
# Likely ill-formed tsv's
|
|
76
77
|
return [
|
|
77
78
|
"{} ({})".format(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
) if t in
|
|
79
|
+
RECEPTOR_SYMBOLS[t]['neurotransmitter']['label'],
|
|
80
|
+
RECEPTOR_SYMBOLS[t]['neurotransmitter']['name'],
|
|
81
|
+
) if t in RECEPTOR_SYMBOLS else
|
|
81
82
|
f"{t} (undeciphered)"
|
|
82
83
|
for t in self.receptors
|
|
83
84
|
]
|
|
@@ -107,7 +108,7 @@ class ReceptorDensityFingerprint(
|
|
|
107
108
|
std = [data[_]["density (sd)"] for _ in labels]
|
|
108
109
|
except KeyError as e:
|
|
109
110
|
print(str(e))
|
|
110
|
-
|
|
111
|
+
logger.error("Could not parse fingerprint from this dictionary")
|
|
111
112
|
return {
|
|
112
113
|
'unit': next(iter(units)),
|
|
113
114
|
'labels': labels,
|
|
@@ -124,9 +125,11 @@ class ReceptorDensityFingerprint(
|
|
|
124
125
|
if backend == "matplotlib":
|
|
125
126
|
try:
|
|
126
127
|
import matplotlib.pyplot as plt
|
|
127
|
-
except ImportError:
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
except ImportError as e:
|
|
129
|
+
logger.error(
|
|
130
|
+
"matplotlib not available. Please install matplotlib or use or another backend such as plotly."
|
|
131
|
+
)
|
|
132
|
+
raise e
|
|
130
133
|
from collections import deque
|
|
131
134
|
|
|
132
135
|
# default args
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2018-
|
|
1
|
+
# Copyright 2018-2025
|
|
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");
|
|
@@ -239,7 +239,7 @@ class RegionalTimeseriesActivity(tabular.Tabular, Compoundable):
|
|
|
239
239
|
backend="plotly", **kwargs
|
|
240
240
|
):
|
|
241
241
|
"""
|
|
242
|
-
Create a carpet plot
|
|
242
|
+
Create a carpet plot of the timeseries data per region.
|
|
243
243
|
|
|
244
244
|
Parameters
|
|
245
245
|
----------
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2018-
|
|
1
|
+
# Copyright 2018-2025
|
|
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");
|
|
@@ -19,7 +19,7 @@ from .. import feature
|
|
|
19
19
|
|
|
20
20
|
from .. import anchor as _anchor
|
|
21
21
|
|
|
22
|
-
from ... import
|
|
22
|
+
from ...commons import logger
|
|
23
23
|
|
|
24
24
|
import pandas as pd
|
|
25
25
|
from textwrap import wrap
|
|
@@ -91,9 +91,11 @@ class Tabular(feature.Feature):
|
|
|
91
91
|
if backend == "matplotlib":
|
|
92
92
|
try:
|
|
93
93
|
import matplotlib.pyplot as plt
|
|
94
|
-
except ImportError:
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
except ImportError as e:
|
|
95
|
+
logger.error(
|
|
96
|
+
"matplotlib not available. Please install matplotlib or use or another backend such as plotly."
|
|
97
|
+
)
|
|
98
|
+
raise e
|
|
97
99
|
# default kwargs
|
|
98
100
|
if kwargs.get("error_y") is None:
|
|
99
101
|
kwargs["yerr"] = kwargs.get("yerr", 'std' if 'std' in self.data.columns else None)
|
siibra/livequeries/__init__.py
CHANGED
siibra/livequeries/allen.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2018-
|
|
1
|
+
# Copyright 2018-2025
|
|
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");
|
|
@@ -66,7 +66,7 @@ class AllenBrainAtlasQuery(LiveQuery, args=['gene'], FeatureType=GeneExpressions
|
|
|
66
66
|
- Each sample was subject to multiple (in fact 4) different probes.
|
|
67
67
|
- The probe data structures contain the list of gene expression of a
|
|
68
68
|
particular gene measured in each sample. Therefore the length of the gene
|
|
69
|
-
expression list in a probe
|
|
69
|
+
expression list in a probe corresponds to the number of samples taken in
|
|
70
70
|
the corresponding donor for the given gene.
|
|
71
71
|
"""
|
|
72
72
|
|
|
@@ -114,7 +114,7 @@ class AllenBrainAtlasQuery(LiveQuery, args=['gene'], FeatureType=GeneExpressions
|
|
|
114
114
|
Each sample is linked to a donor, brain structure, and
|
|
115
115
|
ICBM coordinate.
|
|
116
116
|
When querying with a brain structure, the ICBM coordinates
|
|
117
|
-
will be tested
|
|
117
|
+
will be tested against the region mask in ICBM space
|
|
118
118
|
to produce a table of outputs.
|
|
119
119
|
"""
|
|
120
120
|
LiveQuery.__init__(self, **kwargs)
|
siibra/livequeries/bigbrain.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2018-
|
|
1
|
+
# Copyright 2018-2025
|
|
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");
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
|
-
"""Matches BigBrain
|
|
15
|
+
"""Matches BigBrain intensity profiles extracted by Wagstyl et al. to volumes."""
|
|
16
16
|
|
|
17
17
|
from . import query
|
|
18
18
|
|
|
19
19
|
from ..features.tabular import bigbrain_intensity_profile, layerwise_bigbrain_intensities
|
|
20
20
|
from ..features import anchor as _anchor
|
|
21
21
|
from ..commons import logger
|
|
22
|
-
from ..locations import point, pointcloud
|
|
22
|
+
from ..locations import point, pointcloud, location
|
|
23
23
|
from ..core import structure
|
|
24
24
|
from ..retrieval import requests, cache
|
|
25
25
|
from ..retrieval.datasets import GenericDataset
|
|
@@ -123,11 +123,16 @@ class BigBrainProfileQuery(query.LiveQuery, args=[], FeatureType=bigbrain_intens
|
|
|
123
123
|
matched = concept.intersection(mesh_vertices) # returns a reduced PointCloud with og indices as labels
|
|
124
124
|
if matched is None:
|
|
125
125
|
return []
|
|
126
|
+
if isinstance(matched, point.Point):
|
|
127
|
+
matched = pointcloud.from_points([matched])
|
|
126
128
|
assert isinstance(matched, pointcloud.PointCloud)
|
|
129
|
+
if isinstance(concept, location.Location):
|
|
130
|
+
mesh_as_list = mesh_vertices.as_list()
|
|
131
|
+
matched.labels = [mesh_as_list.index(v.coordinate) for v in matched]
|
|
127
132
|
indices = matched.labels
|
|
128
133
|
assert indices is not None
|
|
129
134
|
features = []
|
|
130
|
-
for i in
|
|
135
|
+
for i in indices:
|
|
131
136
|
anchor = _anchor.AnatomicalAnchor(
|
|
132
137
|
location=point.Point(loader._vertices[i], space='bigbrain'),
|
|
133
138
|
region=str(concept),
|
|
@@ -160,12 +165,16 @@ class LayerwiseBigBrainIntensityQuery(query.LiveQuery, args=[], FeatureType=laye
|
|
|
160
165
|
|
|
161
166
|
loader = WagstylProfileLoader()
|
|
162
167
|
mesh_vertices = pointcloud.PointCloud(loader._vertices, space='bigbrain')
|
|
163
|
-
matched = concept.intersection(mesh_vertices) # returns a reduced PointCloud with og indices as labels
|
|
168
|
+
matched = concept.intersection(mesh_vertices) # returns a reduced PointCloud with og indices as labels if the concept is a region
|
|
164
169
|
if matched is None:
|
|
165
170
|
return []
|
|
171
|
+
if isinstance(matched, point.Point):
|
|
172
|
+
matched = pointcloud.from_points([matched])
|
|
166
173
|
assert isinstance(matched, pointcloud.PointCloud)
|
|
174
|
+
if isinstance(concept, location.Location):
|
|
175
|
+
mesh_as_list = mesh_vertices.as_list()
|
|
176
|
+
matched.labels = [mesh_as_list.index(v.coordinate) for v in matched]
|
|
167
177
|
indices = matched.labels
|
|
168
|
-
assert indices is not None
|
|
169
178
|
matched_profiles = loader._profiles[indices, :]
|
|
170
179
|
boundary_depths = loader._boundary_depths[indices, :]
|
|
171
180
|
# compute array of layer labels for all coefficients in profiles_left
|
siibra/livequeries/ebrains.py
CHANGED
siibra/livequeries/query.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2018-
|
|
1
|
+
# Copyright 2018-2025
|
|
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");
|
|
@@ -46,4 +46,4 @@ class LiveQuery(ABC):
|
|
|
46
46
|
|
|
47
47
|
@abstractmethod
|
|
48
48
|
def query(self, concept: AtlasConcept, **kwargs) -> List[Feature]:
|
|
49
|
-
raise NotImplementedError(f"
|
|
49
|
+
raise NotImplementedError(f"Derived class {self.__class__} needs to implement query()")
|
siibra/locations/__init__.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2018-
|
|
1
|
+
# Copyright 2018-2025
|
|
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");
|
|
@@ -22,7 +22,7 @@ from .boundingbox import BoundingBox
|
|
|
22
22
|
|
|
23
23
|
def reassign_union(loc0: 'Location', loc1: 'Location') -> 'Location':
|
|
24
24
|
"""
|
|
25
|
-
Add two locations of same or
|
|
25
|
+
Add two locations of same or different type to find their union as a
|
|
26
26
|
Location object.
|
|
27
27
|
Note
|
|
28
28
|
----
|
siibra/locations/boundingbox.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2018-
|
|
1
|
+
# Copyright 2018-2025
|
|
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");
|
|
@@ -148,11 +148,7 @@ class BoundingBox(location.Location):
|
|
|
148
148
|
points_inside = [p for p in other if self.intersects(p)]
|
|
149
149
|
if len(points_inside) == 0:
|
|
150
150
|
return None
|
|
151
|
-
result = pointcloud.
|
|
152
|
-
points_inside,
|
|
153
|
-
space=other.space,
|
|
154
|
-
sigma_mm=[p.sigma for p in points_inside]
|
|
155
|
-
)
|
|
151
|
+
result = pointcloud.from_points(points_inside)
|
|
156
152
|
return result[0] if len(result) == 1 else result # if PointCloud has single point return as a Point
|
|
157
153
|
|
|
158
154
|
return other.intersection(self)
|
|
@@ -213,7 +209,7 @@ class BoundingBox(location.Location):
|
|
|
213
209
|
X, Y, Z = np.where(mask.get_fdata() > threshold)
|
|
214
210
|
h = np.ones(len(X))
|
|
215
211
|
|
|
216
|
-
# array of
|
|
212
|
+
# array of homogeneous physical nonzero voxel coordinates
|
|
217
213
|
coords = np.dot(mask.affine, np.vstack((X, Y, Z, h)))[:3, :].T
|
|
218
214
|
minpoint = [min(self.minpoint[i], self.maxpoint[i]) for i in range(3)]
|
|
219
215
|
maxpoint = [max(self.minpoint[i], self.maxpoint[i]) for i in range(3)]
|
siibra/locations/location.py
CHANGED
siibra/locations/point.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2018-
|
|
1
|
+
# Copyright 2018-2025
|
|
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");
|
|
@@ -108,7 +108,7 @@ class Point(location.Location):
|
|
|
108
108
|
|
|
109
109
|
@property
|
|
110
110
|
def homogeneous(self):
|
|
111
|
-
"""The
|
|
111
|
+
"""The homogeneous coordinate of this point as a 4-tuple,
|
|
112
112
|
obtained by appending '1' to the original 3-tuple."""
|
|
113
113
|
return np.atleast_2d(self.coordinate + (1,))
|
|
114
114
|
|
|
@@ -157,7 +157,7 @@ class Point(location.Location):
|
|
|
157
157
|
return self.sigma**3 * np.pi * 4. / 3.
|
|
158
158
|
|
|
159
159
|
def __sub__(self, other):
|
|
160
|
-
"""
|
|
160
|
+
"""Subtract the coordinates of two points to get
|
|
161
161
|
a new point representing the offset vector. Alternatively,
|
|
162
162
|
subtract an integer from the all coordinates of this point
|
|
163
163
|
to create a new one.
|
siibra/locations/pointcloud.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2018-
|
|
1
|
+
# Copyright 2018-2025
|
|
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");
|
|
@@ -32,7 +32,7 @@ except ImportError:
|
|
|
32
32
|
_HAS_HDBSCAN = False
|
|
33
33
|
logger.warning(
|
|
34
34
|
f"HDBSCAN is not available with your version {sklearn.__version__} of sckit-learn."
|
|
35
|
-
"`PointCloud.find_clusters()` will not be
|
|
35
|
+
"`PointCloud.find_clusters()` will not be available."
|
|
36
36
|
)
|
|
37
37
|
|
|
38
38
|
|
|
@@ -120,18 +120,13 @@ class PointCloud(location.Location):
|
|
|
120
120
|
if not isinstance(other, (point.Point, PointCloud, _boundingbox.BoundingBox)):
|
|
121
121
|
return other.intersection(self)
|
|
122
122
|
|
|
123
|
-
|
|
124
|
-
|
|
123
|
+
if isinstance(other, PointCloud):
|
|
124
|
+
intersecting_points = [p for p in self if p.coordinate in other.coordinates]
|
|
125
|
+
else:
|
|
126
|
+
intersecting_points = [p for p in self if p.intersects(other)]
|
|
127
|
+
if len(intersecting_points) == 0:
|
|
125
128
|
return None
|
|
126
|
-
|
|
127
|
-
labels = None if self.labels is None else [self.labels[i] for i in ids]
|
|
128
|
-
sigma = [p.sigma for p in points]
|
|
129
|
-
intersection = PointCloud(
|
|
130
|
-
points,
|
|
131
|
-
space=self.space,
|
|
132
|
-
sigma_mm=sigma,
|
|
133
|
-
labels=labels
|
|
134
|
-
)
|
|
129
|
+
intersection = from_points(intersecting_points)
|
|
135
130
|
return intersection[0] if len(intersection) == 1 else intersection
|
|
136
131
|
|
|
137
132
|
@property
|
|
@@ -320,7 +315,7 @@ class PointCloud(location.Location):
|
|
|
320
315
|
if not _HAS_HDBSCAN:
|
|
321
316
|
raise RuntimeError(
|
|
322
317
|
f"HDBSCAN is not available with your version {sklearn.__version__} "
|
|
323
|
-
"of sckit-learn. `PointCloud.find_clusters()` will not be
|
|
318
|
+
"of sckit-learn. `PointCloud.find_clusters()` will not be available."
|
|
324
319
|
)
|
|
325
320
|
points = np.array(self.as_list())
|
|
326
321
|
N = points.shape[0]
|
siibra/retrieval/__init__.py
CHANGED
siibra/retrieval/cache.py
CHANGED
siibra/retrieval/datasets.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2018-
|
|
1
|
+
# Copyright 2018-2025
|
|
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");
|
|
@@ -319,12 +319,12 @@ class EbrainsV3Dataset(EbrainsBaseDataset):
|
|
|
319
319
|
@property
|
|
320
320
|
def contributors(self):
|
|
321
321
|
if self._contributers is None:
|
|
322
|
-
|
|
322
|
+
contributors = {}
|
|
323
323
|
for version_id in self.version_ids:
|
|
324
|
-
|
|
324
|
+
contributors.update(
|
|
325
325
|
{c['@id']: c for c in EbrainsV3DatasetVersion(version_id).contributors}
|
|
326
326
|
)
|
|
327
|
-
self._contributers = list(
|
|
327
|
+
self._contributers = list(contributors.values())
|
|
328
328
|
return self._contributers
|
|
329
329
|
|
|
330
330
|
@property
|
siibra/retrieval/repositories.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2018-
|
|
1
|
+
# Copyright 2018-2025
|
|
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");
|
|
@@ -196,7 +196,7 @@ class GithubConnector(RepositoryConnector):
|
|
|
196
196
|
if len(matched_reftags) == 1:
|
|
197
197
|
self._want_commit_cached = matched_reftags[0]["commit"]
|
|
198
198
|
else:
|
|
199
|
-
raise RuntimeError(f"Found {len(matched_reftags)}
|
|
199
|
+
raise RuntimeError(f"Found {len(matched_reftags)} matches to {reftag}")
|
|
200
200
|
self._tag_checked = True
|
|
201
201
|
except Exception:
|
|
202
202
|
logger.warning("Could not connect to GitHub repository.", exc_info=1)
|
|
@@ -258,7 +258,7 @@ class GitlabConnector(RepositoryConnector):
|
|
|
258
258
|
n.b. only archive_mode should only be set for trusted domains. Extraction of archive can result in files created outside the path
|
|
259
259
|
see https://docs.python.org/3/library/tarfile.html#tarfile.TarFile.extractall
|
|
260
260
|
"""
|
|
261
|
-
# TODO: the query builder needs to check
|
|
261
|
+
# TODO: the query builder needs to check whether the reftag is a branch, and then not cache.
|
|
262
262
|
assert server.startswith("http")
|
|
263
263
|
RepositoryConnector.__init__(
|
|
264
264
|
self, base_url=f"{server}/api/v4/projects/{project}/repository"
|
|
@@ -584,7 +584,7 @@ class EbrainsPublicDatasetConnector(RepositoryConnector):
|
|
|
584
584
|
Part of dataset title as an alternative dataset specification (will ignore dataset_id then)
|
|
585
585
|
in_progress: bool (default:False)
|
|
586
586
|
If true, will request datasets that are still under curation.
|
|
587
|
-
Will only work when
|
|
587
|
+
Will only work when authenticated with an appropriately privileged
|
|
588
588
|
user account.
|
|
589
589
|
"""
|
|
590
590
|
self.dataset_id = dataset_id
|