siibra 1.0.1a0__py3-none-any.whl → 1.0.1a2__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 +11 -20
- siibra/commons.py +17 -14
- siibra/configuration/__init__.py +1 -1
- siibra/configuration/configuration.py +6 -6
- siibra/configuration/factory.py +10 -9
- siibra/core/__init__.py +2 -2
- siibra/core/assignment.py +2 -1
- siibra/core/atlas.py +4 -4
- siibra/core/concept.py +7 -5
- siibra/core/parcellation.py +10 -10
- siibra/core/region.py +82 -73
- siibra/core/space.py +5 -7
- siibra/core/structure.py +4 -4
- siibra/exceptions.py +6 -2
- 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 +4 -6
- siibra/features/connectivity/__init__.py +1 -1
- siibra/features/connectivity/functional_connectivity.py +1 -1
- siibra/features/connectivity/regional_connectivity.py +12 -15
- 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 +2 -2
- siibra/features/feature.py +31 -28
- siibra/features/image/__init__.py +5 -3
- siibra/features/image/image.py +4 -6
- siibra/features/image/sections.py +82 -3
- siibra/features/image/volume_of_interest.py +1 -9
- siibra/features/tabular/__init__.py +2 -2
- siibra/features/tabular/bigbrain_intensity_profile.py +3 -2
- siibra/features/tabular/cell_density_profile.py +10 -11
- siibra/features/tabular/cortical_profile.py +9 -9
- siibra/features/tabular/gene_expression.py +7 -6
- siibra/features/tabular/layerwise_bigbrain_intensities.py +5 -4
- siibra/features/tabular/layerwise_cell_density.py +5 -7
- siibra/features/tabular/receptor_density_fingerprint.py +47 -19
- siibra/features/tabular/receptor_density_profile.py +2 -3
- siibra/features/tabular/regional_timeseries_activity.py +9 -9
- siibra/features/tabular/tabular.py +10 -9
- siibra/livequeries/__init__.py +1 -1
- siibra/livequeries/allen.py +23 -25
- siibra/livequeries/bigbrain.py +252 -55
- siibra/livequeries/ebrains.py +14 -11
- siibra/livequeries/query.py +5 -5
- siibra/locations/__init__.py +19 -10
- siibra/locations/boundingbox.py +10 -13
- siibra/{experimental/plane3d.py → locations/experimental.py} +117 -17
- siibra/locations/location.py +11 -13
- siibra/locations/point.py +10 -19
- siibra/locations/pointcloud.py +59 -23
- siibra/retrieval/__init__.py +1 -1
- siibra/retrieval/cache.py +2 -1
- siibra/retrieval/datasets.py +23 -17
- siibra/retrieval/exceptions/__init__.py +1 -1
- siibra/retrieval/repositories.py +14 -15
- siibra/retrieval/requests.py +32 -30
- siibra/vocabularies/__init__.py +2 -3
- siibra/volumes/__init__.py +5 -4
- siibra/volumes/parcellationmap.py +55 -20
- siibra/volumes/providers/__init__.py +1 -1
- siibra/volumes/providers/freesurfer.py +7 -7
- siibra/volumes/providers/gifti.py +5 -5
- siibra/volumes/providers/neuroglancer.py +25 -28
- siibra/volumes/providers/nifti.py +7 -7
- siibra/volumes/providers/provider.py +4 -3
- siibra/volumes/sparsemap.py +8 -7
- siibra/volumes/volume.py +33 -40
- {siibra-1.0.1a0.dist-info → siibra-1.0.1a2.dist-info}/METADATA +21 -8
- siibra-1.0.1a2.dist-info/RECORD +80 -0
- {siibra-1.0.1a0.dist-info → siibra-1.0.1a2.dist-info}/WHEEL +1 -1
- siibra/experimental/__init__.py +0 -19
- siibra/experimental/contour.py +0 -61
- siibra/experimental/cortical_profile_sampler.py +0 -57
- siibra/experimental/patch.py +0 -98
- siibra-1.0.1a0.dist-info/RECORD +0 -84
- {siibra-1.0.1a0.dist-info → siibra-1.0.1a2.dist-info}/LICENSE +0 -0
- {siibra-1.0.1a0.dist-info → siibra-1.0.1a2.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");
|
|
@@ -14,12 +14,6 @@
|
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
"""Handles multimodal data features and related queries."""
|
|
16
16
|
|
|
17
|
-
from . import anchor as _anchor
|
|
18
|
-
|
|
19
|
-
from ..commons import logger, InstanceTable, siibra_tqdm, __version__
|
|
20
|
-
from ..core import concept, space, region, parcellation, structure
|
|
21
|
-
from ..volumes import volume
|
|
22
|
-
|
|
23
17
|
from typing import Union, TYPE_CHECKING, List, Dict, Type, Tuple, BinaryIO, Any, Iterator
|
|
24
18
|
from hashlib import md5
|
|
25
19
|
from collections import defaultdict
|
|
@@ -28,6 +22,11 @@ from abc import ABC, abstractmethod
|
|
|
28
22
|
from re import sub
|
|
29
23
|
from textwrap import wrap
|
|
30
24
|
|
|
25
|
+
from . import anchor as _anchor
|
|
26
|
+
from ..commons import logger, InstanceTable, siibra_tqdm, __version__
|
|
27
|
+
from ..core import concept, space, region, parcellation, structure
|
|
28
|
+
from ..volumes import volume
|
|
29
|
+
|
|
31
30
|
if TYPE_CHECKING:
|
|
32
31
|
from ..retrieval.datasets import EbrainsDataset
|
|
33
32
|
TypeDataset = EbrainsDataset
|
|
@@ -53,7 +52,7 @@ _README_TMPL = """
|
|
|
53
52
|
Downloaded from siibra toolsuite.
|
|
54
53
|
siibra-python version: {version}
|
|
55
54
|
|
|
56
|
-
All
|
|
55
|
+
All related resources (e.g. doi, web resources) are categorized under publications.
|
|
57
56
|
|
|
58
57
|
Name
|
|
59
58
|
----
|
|
@@ -130,23 +129,22 @@ class Feature:
|
|
|
130
129
|
# allows subclasses to implement lazy loading of an anchor
|
|
131
130
|
return self._anchor_cached
|
|
132
131
|
|
|
133
|
-
def __init_subclass__(cls, configuration_folder=None, category=None,
|
|
132
|
+
def __init_subclass__(cls, configuration_folder=None, category=None, **kwargs):
|
|
134
133
|
|
|
135
134
|
# Feature.SUBCLASSES serves as an index where feature class inheritance is cached. When users
|
|
136
135
|
# queries a branch on the hierarchy, all children will also be queried. There are usecases where
|
|
137
136
|
# such behavior is not desired (e.g. ProxyFeature, which wraps livequery features id to capture the
|
|
138
137
|
# query context).
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if do_not_index is False:
|
|
138
|
+
if "ProxyFeature" in cls.__name__:
|
|
139
|
+
return
|
|
142
140
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
141
|
+
# extend the subclass lists
|
|
142
|
+
# Iterate over all mro, not just immediate base classes
|
|
143
|
+
for BaseCls in cls.__mro__:
|
|
144
|
+
# some base classes may not be sub class of feature, ignore these
|
|
145
|
+
if not issubclass(BaseCls, Feature):
|
|
146
|
+
continue
|
|
147
|
+
cls._SUBCLASSES[BaseCls].append(cls)
|
|
150
148
|
|
|
151
149
|
cls._live_queries = []
|
|
152
150
|
cls._preconfigured_instances = None
|
|
@@ -156,6 +154,9 @@ class Feature:
|
|
|
156
154
|
cls._CATEGORIZED[category].add(cls.__name__, cls)
|
|
157
155
|
return super().__init_subclass__(**kwargs)
|
|
158
156
|
|
|
157
|
+
def __repr__(self) -> str:
|
|
158
|
+
return f"<{self.__class__.__name__}(id='{self.id}', name='{self.name}')>"
|
|
159
|
+
|
|
159
160
|
@classmethod
|
|
160
161
|
def _get_subclasses(cls):
|
|
161
162
|
return {Cls.__name__: Cls for Cls in cls._SUBCLASSES}
|
|
@@ -199,9 +200,9 @@ class Feature:
|
|
|
199
200
|
@property
|
|
200
201
|
def authors(self):
|
|
201
202
|
return [
|
|
202
|
-
|
|
203
|
+
contributor['name']
|
|
203
204
|
for ds in self.datasets
|
|
204
|
-
for
|
|
205
|
+
for contributor in ds.contributors
|
|
205
206
|
]
|
|
206
207
|
|
|
207
208
|
@property
|
|
@@ -256,7 +257,7 @@ class Feature:
|
|
|
256
257
|
concept: Union[structure.BrainStructure, space.Space],
|
|
257
258
|
) -> bool:
|
|
258
259
|
"""
|
|
259
|
-
Match the features anatomical anchor
|
|
260
|
+
Match the features anatomical anchor against the given query concept.
|
|
260
261
|
Record the most recently matched concept for inspection by the caller.
|
|
261
262
|
"""
|
|
262
263
|
# TODO: storing the last matched concept. It is not ideal, might cause problems in multithreading
|
|
@@ -509,7 +510,7 @@ class Feature:
|
|
|
509
510
|
This will
|
|
510
511
|
- call Feature.match(concept) for any registered preconfigured features
|
|
511
512
|
- run any registered live queries
|
|
512
|
-
The preconfigured and live query instances are merged and
|
|
513
|
+
The preconfigured and live query instances are merged and returned as a list.
|
|
513
514
|
|
|
514
515
|
If multiple feature types are given, recurse for each of them.
|
|
515
516
|
|
|
@@ -519,7 +520,7 @@ class Feature:
|
|
|
519
520
|
concept: AtlasConcept
|
|
520
521
|
An anatomical concept, typically a brain region or parcellation.
|
|
521
522
|
feature_type: subclass of Feature, str
|
|
522
|
-
|
|
523
|
+
specifies the type of features ("modality")
|
|
523
524
|
"""
|
|
524
525
|
if isinstance(feature_type, list):
|
|
525
526
|
# a list of feature types is given, collect match results on those
|
|
@@ -604,7 +605,7 @@ class Feature:
|
|
|
604
605
|
if inst.id == feature_id
|
|
605
606
|
]
|
|
606
607
|
if len(candidates) == 0:
|
|
607
|
-
raise NotFoundException(f"No feature instance
|
|
608
|
+
raise NotFoundException(f"No feature instance with {feature_id} found.")
|
|
608
609
|
if len(candidates) == 1:
|
|
609
610
|
return candidates[0]
|
|
610
611
|
else:
|
|
@@ -625,7 +626,9 @@ class Feature:
|
|
|
625
626
|
|
|
626
627
|
See docstring of serialize_query_context for further context.
|
|
627
628
|
"""
|
|
628
|
-
|
|
629
|
+
|
|
630
|
+
# if you change the name of this class, change the string in Feature.__init_subclass__
|
|
631
|
+
class ProxyFeature(feature.__class__):
|
|
629
632
|
|
|
630
633
|
# override __class__ property
|
|
631
634
|
# some instances of features accesses inst.__class__
|
|
@@ -719,7 +722,7 @@ class Compoundable(ABC):
|
|
|
719
722
|
"""
|
|
720
723
|
Compute the merge data and create a merged instance from a set of
|
|
721
724
|
elements of this class. This will be used by CompoundFeature to
|
|
722
|
-
create the
|
|
725
|
+
create the aggregated data and plot it. For example, to compute an
|
|
723
726
|
average connectivity matrix from a set of subfeatures, we create a
|
|
724
727
|
RegionalConnectivty feature.
|
|
725
728
|
"""
|
|
@@ -728,7 +731,7 @@ class Compoundable(ABC):
|
|
|
728
731
|
|
|
729
732
|
class CompoundFeature(Feature):
|
|
730
733
|
"""
|
|
731
|
-
A compound aggregating
|
|
734
|
+
A compound aggregating multiple features of the same type, forming its
|
|
732
735
|
elements. The anatomical anchors and data of the features is merged.
|
|
733
736
|
Features need to subclass "Compoundable" to allow aggregation
|
|
734
737
|
into a compound feature.
|
|
@@ -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,6 +22,8 @@ from .volume_of_interest import (
|
|
|
22
22
|
XPCTVolumeOfInterest,
|
|
23
23
|
LSFMVolumeOfInterest,
|
|
24
24
|
DTIVolumeOfInterest
|
|
25
|
-
# SegmentedVolumeOfInterest
|
|
26
25
|
)
|
|
27
|
-
from .sections import
|
|
26
|
+
from .sections import (
|
|
27
|
+
CellbodyStainedSection,
|
|
28
|
+
BigBrain1MicronPatch
|
|
29
|
+
)
|
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");
|
|
@@ -14,15 +14,13 @@
|
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
"""Base type of features in volume format and related anatomical anchor."""
|
|
16
16
|
|
|
17
|
+
from typing import List, TYPE_CHECKING
|
|
17
18
|
from zipfile import ZipFile
|
|
18
|
-
from .. import feature
|
|
19
19
|
|
|
20
|
+
from .. import feature
|
|
20
21
|
from .. import anchor as _anchor
|
|
21
|
-
|
|
22
22
|
from ...volumes import volume as _volume
|
|
23
23
|
|
|
24
|
-
from typing import List, TYPE_CHECKING
|
|
25
|
-
|
|
26
24
|
if TYPE_CHECKING:
|
|
27
25
|
from ...locations.boundingbox import BoundingBox
|
|
28
26
|
from ...volumes.providers import provider
|
|
@@ -44,7 +42,7 @@ class ImageAnchor(_anchor.AnatomicalAnchor):
|
|
|
44
42
|
if self._location_cached is None:
|
|
45
43
|
self._location_cached = self.volume.get_boundingbox(
|
|
46
44
|
clip=False
|
|
47
|
-
) # use unclipped to
|
|
45
|
+
) # use unclipped to preserve existing behaviour
|
|
48
46
|
return self._location_cached
|
|
49
47
|
|
|
50
48
|
@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");
|
|
@@ -14,13 +14,92 @@
|
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
"""Multimodal data features in 2D section."""
|
|
16
16
|
|
|
17
|
+
from typing import TYPE_CHECKING
|
|
18
|
+
|
|
17
19
|
from . import image
|
|
18
20
|
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from ...locations import AxisAlignedPatch, Contour
|
|
23
|
+
from ...features.anchor import AnatomicalAnchor
|
|
24
|
+
|
|
19
25
|
|
|
20
26
|
class CellbodyStainedSection(
|
|
21
27
|
image.Image,
|
|
22
|
-
configuration_folder=
|
|
23
|
-
category="cellular"
|
|
28
|
+
configuration_folder="features/images/sections/cellbody",
|
|
29
|
+
category="cellular",
|
|
24
30
|
):
|
|
25
31
|
def __init__(self, **kwargs):
|
|
26
32
|
image.Image.__init__(self, **kwargs, modality="cell body staining")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class BigBrain1MicronPatch(image.Image, category="cellular"):
|
|
36
|
+
|
|
37
|
+
_DESCRIPTION = """Sample approximately orthogonal cortical image patches
|
|
38
|
+
from BigBrain 1 micron sections, guided by an image volume
|
|
39
|
+
in a supported reference space providing. The image
|
|
40
|
+
volume is used as a weighted mask to extract patches
|
|
41
|
+
along the cortical midsurface with nonzero weights in the
|
|
42
|
+
input image.
|
|
43
|
+
An optional lower_threshold can be used to narrow down
|
|
44
|
+
the search. The weight is stored with the resulting features."""
|
|
45
|
+
|
|
46
|
+
def __init__(
|
|
47
|
+
self,
|
|
48
|
+
patch: "AxisAlignedPatch",
|
|
49
|
+
profile: "Contour",
|
|
50
|
+
section: CellbodyStainedSection,
|
|
51
|
+
vertex: int,
|
|
52
|
+
relevance: float,
|
|
53
|
+
anchor: "AnatomicalAnchor",
|
|
54
|
+
):
|
|
55
|
+
self._patch = patch
|
|
56
|
+
self._profile = profile
|
|
57
|
+
self._section = section
|
|
58
|
+
self.vertex = vertex
|
|
59
|
+
self.relevance = relevance
|
|
60
|
+
image.Image.__init__(
|
|
61
|
+
self,
|
|
62
|
+
name=f"Cortical patch in {section.name}",
|
|
63
|
+
modality=section.modality,
|
|
64
|
+
space_spec=section._space_spec,
|
|
65
|
+
providers=list(section._providers.values()),
|
|
66
|
+
region=None,
|
|
67
|
+
datasets=section.datasets,
|
|
68
|
+
bbox=patch.boundingbox,
|
|
69
|
+
id=None,
|
|
70
|
+
)
|
|
71
|
+
self._anchor_cached = anchor
|
|
72
|
+
self._description_cached = self._DESCRIPTION
|
|
73
|
+
|
|
74
|
+
def __repr__(self):
|
|
75
|
+
return (
|
|
76
|
+
f"<{self.__class__.__name__}(space_spec={self._space_spec}, "
|
|
77
|
+
f"name='{self.name}', "
|
|
78
|
+
f"section='{self._section.get_boundingbox().minpoint.bigbrain_section()}', "
|
|
79
|
+
f"vertex='{self.vertex}', providers={self._providers})>"
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def section(self) -> CellbodyStainedSection:
|
|
84
|
+
return self._section
|
|
85
|
+
|
|
86
|
+
def get_boundingbox(self, **fetch_kwargs):
|
|
87
|
+
"""Enforce that the bounding box spans the full section thickness."""
|
|
88
|
+
bbox_section = self._section.get_boundingbox(**fetch_kwargs)
|
|
89
|
+
bbox = self._patch.boundingbox
|
|
90
|
+
bbox.minpoint[1] = bbox_section.minpoint[1]
|
|
91
|
+
bbox.maxpoint[1] = bbox_section.maxpoint[1]
|
|
92
|
+
return bbox
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def profile(self) -> "Contour":
|
|
96
|
+
return self._profile
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def bigbrain_section(self):
|
|
100
|
+
return self.get_boundingbox().minpoint.bigbrain_section()
|
|
101
|
+
|
|
102
|
+
def fetch(self, flip: bool = False, resolution_mm: float = -1, **kwargs):
|
|
103
|
+
assert len(kwargs) == 0
|
|
104
|
+
p = self._patch.flip() if flip else self._patch
|
|
105
|
+
return p.extract_volume(self._section, resolution_mm=resolution_mm).fetch()
|
|
@@ -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");
|
|
@@ -78,11 +78,3 @@ class LSFMVolumeOfInterest(
|
|
|
78
78
|
):
|
|
79
79
|
def __init__(self, modality, **kwargs):
|
|
80
80
|
image.Image.__init__(self, **kwargs, modality=modality)
|
|
81
|
-
|
|
82
|
-
# class SegmentedVolumeOfInterest(
|
|
83
|
-
# image.Image,
|
|
84
|
-
# configuration_folder="features/images/vois/segmentation",
|
|
85
|
-
# category="segmentation"
|
|
86
|
-
# ):
|
|
87
|
-
# def __init__(self, **kwargs):
|
|
88
|
-
# image.Image.__init__(self, **kwargs, modality="segmentation")
|
|
@@ -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");
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"""Multimodal data features in tabular formats."""
|
|
16
16
|
|
|
17
17
|
from .bigbrain_intensity_profile import BigBrainIntensityProfile
|
|
18
|
-
from .cell_density_profile import CellDensityProfile
|
|
18
|
+
from .cell_density_profile import CellDensityProfile, cell_reader, layer_reader
|
|
19
19
|
from .gene_expression import GeneExpressions
|
|
20
20
|
from .layerwise_bigbrain_intensities import LayerwiseBigBrainIntensities
|
|
21
21
|
from .layerwise_cell_density import LayerwiseCellDensity
|
|
@@ -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");
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
+
from typing import List, TYPE_CHECKING
|
|
17
|
+
|
|
16
18
|
from . import cortical_profile
|
|
17
19
|
|
|
18
|
-
from typing import List, TYPE_CHECKING
|
|
19
20
|
if TYPE_CHECKING:
|
|
20
21
|
from ...features.anchor import AnatomicalAnchor
|
|
21
22
|
|
|
@@ -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");
|
|
@@ -13,19 +13,18 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
-
from
|
|
17
|
-
|
|
18
|
-
from .. import anchor as _anchor
|
|
19
|
-
from ...commons import logger
|
|
20
|
-
from ...retrieval import requests
|
|
16
|
+
from io import BytesIO
|
|
17
|
+
from typing import Union, Tuple, Iterable
|
|
21
18
|
|
|
22
|
-
from skimage.draw import polygon
|
|
23
|
-
from skimage.transform import resize
|
|
24
19
|
import numpy as np
|
|
25
20
|
import pandas as pd
|
|
21
|
+
from skimage.draw import polygon
|
|
22
|
+
from skimage.transform import resize
|
|
26
23
|
|
|
27
|
-
from
|
|
28
|
-
from
|
|
24
|
+
from . import cortical_profile
|
|
25
|
+
from .. import anchor as _anchor
|
|
26
|
+
from ...commons import logger
|
|
27
|
+
from ...retrieval import requests
|
|
29
28
|
|
|
30
29
|
|
|
31
30
|
def cell_reader(bytes_buffer: bytes):
|
|
@@ -60,7 +59,7 @@ class PolyLine:
|
|
|
60
59
|
return sum(self.lengths)
|
|
61
60
|
|
|
62
61
|
def sample(self, d: Union[Iterable[float], np.ndarray, float]):
|
|
63
|
-
# if d is
|
|
62
|
+
# if d is iterable, we assume a list of sample positions
|
|
64
63
|
try:
|
|
65
64
|
iter(d)
|
|
66
65
|
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");
|
|
@@ -13,15 +13,15 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
-
from . import tabular
|
|
17
|
-
from ..feature import Compoundable
|
|
18
|
-
|
|
19
|
-
from .. import anchor as _anchor
|
|
20
|
-
|
|
21
|
-
import pandas as pd
|
|
22
16
|
from typing import Union, Dict, Tuple, List
|
|
17
|
+
|
|
23
18
|
from textwrap import wrap
|
|
24
19
|
import numpy as np
|
|
20
|
+
import pandas as pd
|
|
21
|
+
|
|
22
|
+
from . import tabular
|
|
23
|
+
from .. import anchor as _anchor
|
|
24
|
+
from ..feature import Compoundable
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
class CorticalProfile(tabular.Tabular, Compoundable):
|
|
@@ -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");
|
|
@@ -13,11 +13,6 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
-
from .. import anchor as _anchor
|
|
17
|
-
from . import tabular
|
|
18
|
-
from ...retrieval.datasets import GenericDataset
|
|
19
|
-
|
|
20
|
-
import pandas as pd
|
|
21
16
|
from textwrap import wrap
|
|
22
17
|
from typing import List
|
|
23
18
|
try:
|
|
@@ -25,6 +20,12 @@ try:
|
|
|
25
20
|
except ImportError:
|
|
26
21
|
from typing_extensions import TypedDict
|
|
27
22
|
|
|
23
|
+
import pandas as pd
|
|
24
|
+
|
|
25
|
+
from . import tabular
|
|
26
|
+
from .. import anchor as _anchor
|
|
27
|
+
from ...retrieval.datasets import GenericDataset
|
|
28
|
+
|
|
28
29
|
|
|
29
30
|
class GeneExpressions(
|
|
30
31
|
tabular.Tabular,
|
|
@@ -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");
|
|
@@ -13,13 +13,14 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
-
from
|
|
17
|
-
from . import tabular
|
|
16
|
+
from typing import TYPE_CHECKING
|
|
18
17
|
|
|
19
18
|
import pandas as pd
|
|
20
19
|
import numpy as np
|
|
21
20
|
|
|
22
|
-
from
|
|
21
|
+
from . import tabular
|
|
22
|
+
from . import cortical_profile
|
|
23
|
+
|
|
23
24
|
if TYPE_CHECKING:
|
|
24
25
|
from ...features.anchor import AnatomicalAnchor
|
|
25
26
|
|
|
@@ -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");
|
|
@@ -13,17 +13,15 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
+
import numpy as np
|
|
17
|
+
import pandas as pd
|
|
18
|
+
|
|
16
19
|
from . import cortical_profile
|
|
20
|
+
from . import tabular, cell_reader, layer_reader
|
|
17
21
|
from .. import anchor as _anchor
|
|
18
|
-
from . import tabular
|
|
19
|
-
from ..tabular.cell_density_profile import cell_reader, layer_reader
|
|
20
|
-
|
|
21
22
|
from ... import commons
|
|
22
23
|
from ...retrieval import requests
|
|
23
24
|
|
|
24
|
-
import pandas as pd
|
|
25
|
-
import numpy as np
|
|
26
|
-
|
|
27
25
|
|
|
28
26
|
class LayerwiseCellDensity(
|
|
29
27
|
tabular.Tabular,
|
|
@@ -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");
|
|
@@ -13,17 +13,18 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
-
from .. import anchor as _anchor
|
|
17
|
-
from . import tabular
|
|
18
|
-
|
|
19
|
-
from ... import commons, vocabularies
|
|
20
|
-
from ...retrieval import requests
|
|
21
|
-
|
|
22
|
-
import pandas as pd
|
|
23
|
-
import numpy as np
|
|
24
16
|
from textwrap import wrap
|
|
25
17
|
from typing import List
|
|
26
18
|
|
|
19
|
+
import numpy as np
|
|
20
|
+
import pandas as pd
|
|
21
|
+
|
|
22
|
+
from . import tabular
|
|
23
|
+
from .. import anchor as _anchor
|
|
24
|
+
from ...commons import logger
|
|
25
|
+
from ...vocabularies import RECEPTOR_SYMBOLS
|
|
26
|
+
from ...retrieval import requests
|
|
27
|
+
|
|
27
28
|
|
|
28
29
|
class ReceptorDensityFingerprint(
|
|
29
30
|
tabular.Tabular,
|
|
@@ -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
|
|
@@ -187,6 +190,31 @@ class ReceptorDensityFingerprint(
|
|
|
187
190
|
else:
|
|
188
191
|
raise NotImplementedError
|
|
189
192
|
|
|
190
|
-
def plot(
|
|
193
|
+
def plot(
|
|
194
|
+
self,
|
|
195
|
+
*args,
|
|
196
|
+
receptors: List[str] = None,
|
|
197
|
+
backend: str = "matplotlib",
|
|
198
|
+
**kwargs
|
|
199
|
+
):
|
|
200
|
+
"""
|
|
201
|
+
Create a bar plot of receptor density fingerprint.
|
|
202
|
+
|
|
203
|
+
Parameters
|
|
204
|
+
----------
|
|
205
|
+
receptors : List[str], optional
|
|
206
|
+
Plot a subset of receptors.
|
|
207
|
+
backend: str
|
|
208
|
+
"matplotlib", "plotly", or others supported by pandas DataFrame
|
|
209
|
+
plotting backend.
|
|
210
|
+
**kwargs
|
|
211
|
+
takes Matplotlib.pyplot keyword arguments
|
|
212
|
+
"""
|
|
191
213
|
kwargs['xlabel'] = ""
|
|
192
|
-
|
|
214
|
+
kwargs["backend"] = backend
|
|
215
|
+
og_data = self.data
|
|
216
|
+
if receptors is not None:
|
|
217
|
+
self._data_cached = og_data.loc[receptors]
|
|
218
|
+
fig = super().plot(*args, **kwargs)
|
|
219
|
+
self._data_cached = og_data
|
|
220
|
+
return fig
|
|
@@ -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");
|
|
@@ -13,9 +13,8 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
-
from .. import anchor as _anchor
|
|
17
16
|
from . import cortical_profile
|
|
18
|
-
|
|
17
|
+
from .. import anchor as _anchor
|
|
19
18
|
from ... import vocabularies
|
|
20
19
|
from ...commons import create_key
|
|
21
20
|
from ...retrieval import requests
|