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.

Files changed (82) hide show
  1. siibra/VERSION +1 -1
  2. siibra/__init__.py +11 -20
  3. siibra/commons.py +17 -14
  4. siibra/configuration/__init__.py +1 -1
  5. siibra/configuration/configuration.py +6 -6
  6. siibra/configuration/factory.py +10 -9
  7. siibra/core/__init__.py +2 -2
  8. siibra/core/assignment.py +2 -1
  9. siibra/core/atlas.py +4 -4
  10. siibra/core/concept.py +7 -5
  11. siibra/core/parcellation.py +10 -10
  12. siibra/core/region.py +82 -73
  13. siibra/core/space.py +5 -7
  14. siibra/core/structure.py +4 -4
  15. siibra/exceptions.py +6 -2
  16. siibra/explorer/__init__.py +1 -1
  17. siibra/explorer/url.py +2 -2
  18. siibra/explorer/util.py +1 -1
  19. siibra/features/__init__.py +1 -1
  20. siibra/features/anchor.py +4 -6
  21. siibra/features/connectivity/__init__.py +1 -1
  22. siibra/features/connectivity/functional_connectivity.py +1 -1
  23. siibra/features/connectivity/regional_connectivity.py +12 -15
  24. siibra/features/connectivity/streamline_counts.py +1 -1
  25. siibra/features/connectivity/streamline_lengths.py +1 -1
  26. siibra/features/connectivity/tracing_connectivity.py +1 -1
  27. siibra/features/dataset/__init__.py +1 -1
  28. siibra/features/dataset/ebrains.py +2 -2
  29. siibra/features/feature.py +31 -28
  30. siibra/features/image/__init__.py +5 -3
  31. siibra/features/image/image.py +4 -6
  32. siibra/features/image/sections.py +82 -3
  33. siibra/features/image/volume_of_interest.py +1 -9
  34. siibra/features/tabular/__init__.py +2 -2
  35. siibra/features/tabular/bigbrain_intensity_profile.py +3 -2
  36. siibra/features/tabular/cell_density_profile.py +10 -11
  37. siibra/features/tabular/cortical_profile.py +9 -9
  38. siibra/features/tabular/gene_expression.py +7 -6
  39. siibra/features/tabular/layerwise_bigbrain_intensities.py +5 -4
  40. siibra/features/tabular/layerwise_cell_density.py +5 -7
  41. siibra/features/tabular/receptor_density_fingerprint.py +47 -19
  42. siibra/features/tabular/receptor_density_profile.py +2 -3
  43. siibra/features/tabular/regional_timeseries_activity.py +9 -9
  44. siibra/features/tabular/tabular.py +10 -9
  45. siibra/livequeries/__init__.py +1 -1
  46. siibra/livequeries/allen.py +23 -25
  47. siibra/livequeries/bigbrain.py +252 -55
  48. siibra/livequeries/ebrains.py +14 -11
  49. siibra/livequeries/query.py +5 -5
  50. siibra/locations/__init__.py +19 -10
  51. siibra/locations/boundingbox.py +10 -13
  52. siibra/{experimental/plane3d.py → locations/experimental.py} +117 -17
  53. siibra/locations/location.py +11 -13
  54. siibra/locations/point.py +10 -19
  55. siibra/locations/pointcloud.py +59 -23
  56. siibra/retrieval/__init__.py +1 -1
  57. siibra/retrieval/cache.py +2 -1
  58. siibra/retrieval/datasets.py +23 -17
  59. siibra/retrieval/exceptions/__init__.py +1 -1
  60. siibra/retrieval/repositories.py +14 -15
  61. siibra/retrieval/requests.py +32 -30
  62. siibra/vocabularies/__init__.py +2 -3
  63. siibra/volumes/__init__.py +5 -4
  64. siibra/volumes/parcellationmap.py +55 -20
  65. siibra/volumes/providers/__init__.py +1 -1
  66. siibra/volumes/providers/freesurfer.py +7 -7
  67. siibra/volumes/providers/gifti.py +5 -5
  68. siibra/volumes/providers/neuroglancer.py +25 -28
  69. siibra/volumes/providers/nifti.py +7 -7
  70. siibra/volumes/providers/provider.py +4 -3
  71. siibra/volumes/sparsemap.py +8 -7
  72. siibra/volumes/volume.py +33 -40
  73. {siibra-1.0.1a0.dist-info → siibra-1.0.1a2.dist-info}/METADATA +21 -8
  74. siibra-1.0.1a2.dist-info/RECORD +80 -0
  75. {siibra-1.0.1a0.dist-info → siibra-1.0.1a2.dist-info}/WHEEL +1 -1
  76. siibra/experimental/__init__.py +0 -19
  77. siibra/experimental/contour.py +0 -61
  78. siibra/experimental/cortical_profile_sampler.py +0 -57
  79. siibra/experimental/patch.py +0 -98
  80. siibra-1.0.1a0.dist-info/RECORD +0 -84
  81. {siibra-1.0.1a0.dist-info → siibra-1.0.1a2.dist-info}/LICENSE +0 -0
  82. {siibra-1.0.1a0.dist-info → siibra-1.0.1a2.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
1
- # Copyright 2018-2024
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 releated resources (e.g. doi, web resources) are categorized under publications.
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, do_not_index=False, **kwargs):
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
- # do_not_index flag allow the default index behavior to be toggled off.
140
-
141
- if do_not_index is False:
138
+ if "ProxyFeature" in cls.__name__:
139
+ return
142
140
 
143
- # extend the subclass lists
144
- # Iterate over all mro, not just immediate base classes
145
- for BaseCls in cls.__mro__:
146
- # some base classes may not be sub class of feature, ignore these
147
- if not issubclass(BaseCls, Feature):
148
- continue
149
- cls._SUBCLASSES[BaseCls].append(cls)
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
- contributer['name']
203
+ contributor['name']
203
204
  for ds in self.datasets
204
- for contributer in ds.contributors
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 agains the given query concept.
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 returend as a list.
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
- specififies the type of features ("modality")
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 wth {feature_id} found.")
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
- class ProxyFeature(feature.__class__, do_not_index=True):
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 aggegated data and plot it. For example, to compute an
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 mutliple features of the same type, forming its
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-2024
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 CellbodyStainedSection
26
+ from .sections import (
27
+ CellbodyStainedSection,
28
+ BigBrain1MicronPatch
29
+ )
@@ -1,4 +1,4 @@
1
- # Copyright 2018-2024
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 preseve exisiting behaviour
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-2024
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='features/images/sections/cellbody',
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-2024
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-2024
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-2024
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-2024
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 . import cortical_profile
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 io import BytesIO
28
- from typing import Union, Tuple, Iterable
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 interable, we assume a list of sample positions
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-2024
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 initialiation.
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 measurments,
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-2024
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-2024
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 . import cortical_profile
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 typing import TYPE_CHECKING
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-2024
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-2024
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 measurments for different receptors measured in tissue samples from different subjects "
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
- vocabularies.RECEPTOR_SYMBOLS[t]['neurotransmitter']['label'],
79
- vocabularies.RECEPTOR_SYMBOLS[t]['neurotransmitter']['name'],
80
- ) if t in vocabularies.RECEPTOR_SYMBOLS else
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
- commons.logger.error("Could not parse fingerprint from this dictionary")
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
- commons.logger.error("matplotlib not available. Plotting of fingerprints disabled.")
129
- return None
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(self, *args, **kwargs):
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
- return super().plot(*args, **kwargs)
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-2024
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