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
siibra/core/region.py CHANGED
@@ -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,9 +14,18 @@
14
14
  # limitations under the License.
15
15
  """Representation of a brain region."""
16
16
 
17
- from . import concept, structure, space as _space, parcellation as _parcellation
18
- from .assignment import Qualification, AnatomicalAssignment
17
+ import re
18
+ from typing import List, Union, Iterable, Dict, Callable, Tuple, Set
19
+ from difflib import SequenceMatcher
20
+ import json
21
+ from functools import wraps, reduce
22
+ from concurrent.futures import ThreadPoolExecutor
23
+ from functools import lru_cache
24
+
25
+ import anytree
26
+ from ebrains_drive import BucketApiClient
19
27
 
28
+ from . import concept, structure, space as _space, parcellation as _parcellation, assignment
20
29
  from ..retrieval.cache import cache_user_fn
21
30
  from ..locations import location, pointcloud, boundingbox as _boundingbox
22
31
  from ..volumes import parcellationmap, volume
@@ -29,16 +38,6 @@ from ..commons import (
29
38
  )
30
39
  from ..exceptions import NoMapAvailableError, SpaceWarpingFailedError
31
40
 
32
- import re
33
- import anytree
34
- from typing import List, Union, Iterable, Dict, Callable, Tuple
35
- from difflib import SequenceMatcher
36
- from ebrains_drive import BucketApiClient
37
- import json
38
- from functools import wraps, reduce
39
- from concurrent.futures import ThreadPoolExecutor
40
- from functools import lru_cache
41
-
42
41
 
43
42
  REGEX_TYPE = type(re.compile("test"))
44
43
 
@@ -53,8 +52,8 @@ class Region(anytree.NodeMixin, concept.AtlasConcept, structure.BrainStructure):
53
52
  _regex_re = re.compile(r'^\/(?P<expression>.+)\/(?P<flags>[a-zA-Z]*)$')
54
53
  _accepted_flags = "aiLmsux"
55
54
 
56
- _GETMAP_CACHE = {}
57
- _GETMAP_CACHE_MAX_ENTRIES = 1
55
+ _GETMASK_CACHE = {}
56
+ _GETMASK_CACHE_MAX_ENTRIES = 1
58
57
 
59
58
  def __init__(
60
59
  self,
@@ -111,30 +110,30 @@ class Region(anytree.NodeMixin, concept.AtlasConcept, structure.BrainStructure):
111
110
  )
112
111
 
113
112
  # anytree node will take care to use this appropriately
114
- self.parent = parent
115
- self.children = children
113
+ self.parent: "Region" = parent
114
+ self.children: List["Region"] = children
116
115
  # convert hex to int tuple if rgb is given
117
116
  self.rgb = (
118
117
  None if rgb is None
119
118
  else tuple(int(rgb[p:p + 2], 16) for p in [1, 3, 5])
120
119
  )
121
- self._supported_spaces = None # computed on 1st call of self.supported_spaces
120
+ self._supported_spaces: Set[_space.Space] = None # computed on 1st call of self.supported_spaces
122
121
  self._str_aliases = None
123
122
  self.find = lru_cache(maxsize=3)(self.find)
124
123
 
125
124
  def get_related_regions(self) -> Iterable["RegionRelationAssessments"]:
126
125
  """
127
- Get assements on relations of this region to others defined on EBRAINS.
126
+ Get assessments on relations of this region to others defined on EBRAINS.
128
127
 
129
128
  Yields
130
129
  ------
131
- Qualification
130
+ assignment.Qualification
132
131
 
133
132
  Example
134
133
  -------
135
134
  >>> region = siibra.get_region("monkey", "PG")
136
- >>> for assesment in region.get_related_regions():
137
- >>> print(assesment)
135
+ >>> for assessment in region.get_related_regions():
136
+ >>> print(assessment)
138
137
  'PG' is homologous to 'Area PGa (IPL)'
139
138
  'PG' is homologous to 'Area PGa (IPL) left'
140
139
  'PG' is homologous to 'Area PGa (IPL) right'
@@ -441,12 +440,21 @@ class Region(anytree.NodeMixin, concept.AtlasConcept, structure.BrainStructure):
441
440
  maptype = MapType[maptype.upper()]
442
441
 
443
442
  threshold_info = "" if maptype == MapType.LABELLED else f"(threshold: {threshold}) "
443
+ # check cache
444
+ getmask_hash = hash(f"{self.id} - {space} - {maptype}{threshold_info}")
445
+ if getmask_hash in self._GETMASK_CACHE:
446
+ return self._GETMASK_CACHE[getmask_hash]
447
+
444
448
  name = f"Mask {threshold_info}of '{self.name} ({self.parcellation})' in "
445
449
  try:
446
450
  regional_map = self.get_regional_map(space=space, maptype=maptype)
447
451
  if maptype == MapType.LABELLED:
448
452
  assert threshold == 0.0, f"threshold can only be set for {MapType.STATISTICAL} maps."
449
- result = regional_map
453
+ result = volume.FilteredVolume(
454
+ parent_volume=regional_map,
455
+ label=regional_map.label,
456
+ fragment=regional_map.fragment
457
+ )
450
458
  result._boundingbox = None
451
459
  if maptype == MapType.STATISTICAL:
452
460
  result = volume.FilteredVolume(
@@ -456,21 +464,30 @@ class Region(anytree.NodeMixin, concept.AtlasConcept, structure.BrainStructure):
456
464
  if threshold == 0.0:
457
465
  result._boundingbox = regional_map._boundingbox
458
466
  name += f"'{result.space}'"
459
- except NoMapAvailableError:
467
+ except NoMapAvailableError as e:
460
468
  # This region is not mapped directly in any map in the registry.
461
469
  # Try building a map from the child regions
462
- if (len(self.children) > 0) and all(c.mapped_in_space(space) for c in self.children):
463
- logger.info(f"{self.name} is not mapped in {space}. Merging the masks of its {len(self.children)} child regions.")
464
- child_volumes = [
465
- child.get_regional_mask(space=space, maptype=maptype, threshold=threshold)
466
- for child in self.children
470
+ if (len(self.children) > 0) and self.mapped_in_space(space, recurse=True):
471
+ mapped_descendants: List[Region] = [
472
+ d for d in self.descendants if d.mapped_in_space(space, recurse=False)
473
+ ]
474
+ logger.info(f"{self.name} is not mapped in {space}. Merging the masks of its {len(mapped_descendants)} map descendants.")
475
+ descendant_volumes = [
476
+ descendant.get_regional_mask(space=space, maptype=maptype, threshold=threshold)
477
+ for descendant in mapped_descendants
467
478
  ]
468
479
  result = volume.FilteredVolume(
469
- volume.merge(child_volumes),
480
+ volume.merge(descendant_volumes),
470
481
  label=1
471
482
  )
472
- name += f"'{result.space}' (built by merging the mask {threshold_info} of its decendants)"
483
+ name += f"'{result.space}' (built by merging the mask {threshold_info} of its descendants)"
484
+ else:
485
+ raise e
473
486
  result._name = name
487
+
488
+ while len(self._GETMASK_CACHE) > self._GETMASK_CACHE_MAX_ENTRIES:
489
+ self._GETMASK_CACHE.pop(next(iter(self._GETMASK_CACHE)))
490
+ self._GETMASK_CACHE[getmask_hash] = result
474
491
  return result
475
492
 
476
493
  def get_regional_map(
@@ -479,7 +496,7 @@ class Region(anytree.NodeMixin, concept.AtlasConcept, structure.BrainStructure):
479
496
  maptype: MapType = MapType.LABELLED,
480
497
  ) -> Union[volume.FilteredVolume, volume.Volume, volume.Subvolume]:
481
498
  """
482
- Get a volume reprsenting this region in the given space and MapType.
499
+ Get a volume representing this region in the given space and MapType.
483
500
 
484
501
  Note
485
502
  ----
@@ -515,34 +532,31 @@ class Region(anytree.NodeMixin, concept.AtlasConcept, structure.BrainStructure):
515
532
  and self.name in m.regions
516
533
  ):
517
534
  return m.get_volume(region=self)
518
- else:
519
- raise NoMapAvailableError(
520
- f"{self.name} is not mapped in {space} as a {str(maptype)} map."
521
- " Please try getting the children or getting the mask."
522
- )
535
+ raise NoMapAvailableError(
536
+ f"{self.name} is not mapped in {space} as a {str(maptype)} map."
537
+ " Please try getting the children or getting the mask."
538
+ )
523
539
 
524
- def mapped_in_space(self, space, recurse: bool = True) -> bool:
540
+ def mapped_in_space(self, space, recurse: bool = False) -> bool:
525
541
  """
526
- Verifies wether this region is defined by an explicit map in the given space.
542
+ Verifies whether this region is defined by an explicit map in the given space.
527
543
 
528
544
  Parameters
529
545
  ----------
530
546
  space: Space or str
531
547
  reference space
532
- recurse: bool, default: True
533
- If True, check if all child regions are mapped instead
548
+ recurse: bool, default: False
549
+ If True, check if itself or all child regions are mapped instead recursively.
534
550
  Returns
535
551
  -------
536
552
  bool
537
553
  """
538
554
  from ..volumes.parcellationmap import Map
539
555
  for m in Map.registry():
540
- # Use and operant for efficiency (short circuiting logic)
541
- # Put the most inexpensive logic first
542
556
  if (
543
- self.name in m.regions
544
- and m.space.matches(space)
557
+ m.space.matches(space)
545
558
  and m.parcellation.matches(self.parcellation)
559
+ and self.name in m.regions
546
560
  ):
547
561
  return True
548
562
  if recurse and not self.is_leaf:
@@ -553,21 +567,16 @@ class Region(anytree.NodeMixin, concept.AtlasConcept, structure.BrainStructure):
553
567
  @property
554
568
  def supported_spaces(self) -> List[_space.Space]:
555
569
  """
556
- The set of spaces for which a mask could be extracted.
557
- Overwrites the corresponding method of AtlasConcept.
570
+ The list of spaces for which a mask could be extracted from an existing
571
+ map or combination of masks of its children.
558
572
  """
559
573
  if self._supported_spaces is None:
560
- self._supported_spaces = sorted(
561
- {s for s in _space.Space.registry() if self.mapped_in_space(s)}
562
- )
574
+ self._supported_spaces = sorted({
575
+ s for s in _space.Space.registry()
576
+ if self.mapped_in_space(s, recurse=True)
577
+ })
563
578
  return self._supported_spaces
564
579
 
565
- def supports_space(self, space: _space.Space):
566
- """
567
- Return true if this region supports the given space, else False.
568
- """
569
- return any(s.matches(space) for s in self.supported_spaces)
570
-
571
580
  @property
572
581
  def spaces(self):
573
582
  return InstanceTable(
@@ -585,7 +594,7 @@ class Region(anytree.NodeMixin, concept.AtlasConcept, structure.BrainStructure):
585
594
  except NoMapAvailableError:
586
595
  return False
587
596
 
588
- def assign(self, other: structure.BrainStructure) -> AnatomicalAssignment:
597
+ def assign(self, other: structure.BrainStructure) -> assignment.AnatomicalAssignment:
589
598
  """
590
599
  Compute assignment of a location to this region.
591
600
 
@@ -599,8 +608,8 @@ class Region(anytree.NodeMixin, concept.AtlasConcept, structure.BrainStructure):
599
608
 
600
609
  Returns
601
610
  -------
602
- AnatomicalAssignment or None
603
- None if there is no Qualification found.
611
+ assignment.AnatomicalAssignment or None
612
+ None if there is no assignment.Qualification found.
604
613
  """
605
614
  if (self, other) in self._ASSIGNMENT_CACHE:
606
615
  return self._ASSIGNMENT_CACHE[self, other]
@@ -610,7 +619,7 @@ class Region(anytree.NodeMixin, concept.AtlasConcept, structure.BrainStructure):
610
619
  return self._ASSIGNMENT_CACHE[other, self].invert()
611
620
 
612
621
  if isinstance(other, (location.Location, volume.Volume)):
613
- if self.mapped_in_space(other.space):
622
+ if self.mapped_in_space(other.space, recurse=True):
614
623
  regionmap = self.get_regional_mask(other.space)
615
624
  self._ASSIGNMENT_CACHE[self, other] = regionmap.assign(other)
616
625
  return self._ASSIGNMENT_CACHE[self, other]
@@ -649,17 +658,17 @@ class Region(anytree.NodeMixin, concept.AtlasConcept, structure.BrainStructure):
649
658
  else: # other is a Region
650
659
  assert isinstance(other, Region)
651
660
  if self == other:
652
- qualification = Qualification.EXACT
661
+ qualification = assignment.Qualification.EXACT
653
662
  elif self.__contains__(other):
654
- qualification = Qualification.CONTAINS
663
+ qualification = assignment.Qualification.CONTAINS
655
664
  elif other.__contains__(self):
656
- qualification = Qualification.CONTAINED
665
+ qualification = assignment.Qualification.CONTAINED
657
666
  else:
658
667
  qualification = None
659
668
  if qualification is None:
660
669
  self._ASSIGNMENT_CACHE[self, other] = None
661
670
  else:
662
- self._ASSIGNMENT_CACHE[self, other] = AnatomicalAssignment(self, other, qualification)
671
+ self._ASSIGNMENT_CACHE[self, other] = assignment.AnatomicalAssignment(self, other, qualification)
663
672
  return self._ASSIGNMENT_CACHE[self, other]
664
673
 
665
674
  def tree2str(self):
@@ -842,7 +851,7 @@ class Region(anytree.NodeMixin, concept.AtlasConcept, structure.BrainStructure):
842
851
  def intersection(self, other: "location.Location") -> "location.Location":
843
852
  """Use this region for filtering a location object."""
844
853
 
845
- if self.supports_space(other.space):
854
+ if self.mapped_in_space(other.space, recurse=True):
846
855
  try:
847
856
  volume = self.get_regional_mask(other.space)
848
857
  if volume is not None:
@@ -908,7 +917,7 @@ def get_peid_from_region(region: Region) -> str:
908
917
 
909
918
  def get_related_regions(region: Region) -> Iterable["RegionRelationAssessments"]:
910
919
  """
911
- Get assements on relations of a region to others defined on EBRAINS.
920
+ Get assessments on relations of a region to others defined on EBRAINS.
912
921
 
913
922
  Parameters
914
923
  ----------
@@ -916,13 +925,13 @@ def get_related_regions(region: Region) -> Iterable["RegionRelationAssessments"]
916
925
 
917
926
  Yields
918
927
  ------
919
- Qualification
928
+ assignment.Qualification
920
929
 
921
930
  Example
922
931
  -------
923
932
  >>> region = siibra.get_region("monkey", "PG")
924
- >>> for assesment in siibra.core.region.get_related_regions(region):
925
- >>> print(assesment)
933
+ >>> for assessment in siibra.core.region.get_related_regions(region):
934
+ >>> print(assessment)
926
935
  'PG' is homologous to 'Area PGa (IPL)'
927
936
  'PG' is homologous to 'Area PGa (IPL) left'
928
937
  'PG' is homologous to 'Area PGa (IPL) right'
@@ -958,7 +967,7 @@ def _register_region_reference_type(ebrain_type: str):
958
967
  return outer
959
968
 
960
969
 
961
- class RegionRelationAssessments(AnatomicalAssignment[Region]):
970
+ class RegionRelationAssessments(assignment.AnatomicalAssignment[Region]):
962
971
  """
963
972
  A collection of methods on finding related regions and the quantification
964
973
  of the relationship.
@@ -1100,7 +1109,7 @@ class RegionRelationAssessments(AnatomicalAssignment[Region]):
1100
1109
  yield cls(
1101
1110
  query_structure=src,
1102
1111
  assigned_structure=found_target,
1103
- qualification=Qualification.parse_relation_assessment(overlap)
1112
+ qualification=assignment.Qualification.parse_relation_assessment(overlap)
1104
1113
  )
1105
1114
 
1106
1115
  if "https://openminds.ebrains.eu/sands/ParcellationEntity" in target.get("type"):
@@ -1114,7 +1123,7 @@ class RegionRelationAssessments(AnatomicalAssignment[Region]):
1114
1123
  yield cls(
1115
1124
  query_structure=src,
1116
1125
  assigned_structure=reg,
1117
- qualification=Qualification.parse_relation_assessment(overlap)
1126
+ qualification=assignment.Qualification.parse_relation_assessment(overlap)
1118
1127
  )
1119
1128
 
1120
1129
  @classmethod
@@ -1168,7 +1177,7 @@ class RegionRelationAssessments(AnatomicalAssignment[Region]):
1168
1177
  yield cls(
1169
1178
  query_structure=src,
1170
1179
  assigned_structure=region,
1171
- qualification=Qualification.OTHER_VERSION
1180
+ qualification=assignment.Qualification.OTHER_VERSION
1172
1181
  )
1173
1182
 
1174
1183
  # homologuous
siibra/core/space.py CHANGED
@@ -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,18 +14,16 @@
14
14
  # limitations under the License.
15
15
  """A particular brain reference space."""
16
16
 
17
+ from typing import List, TYPE_CHECKING, Union
17
18
 
18
- from .concept import AtlasConcept
19
-
19
+ from . import concept
20
20
  from ..commons import logger, Species
21
21
 
22
- from typing import List, TYPE_CHECKING, Union
23
-
24
22
  if TYPE_CHECKING:
25
23
  from ..volumes import volume
26
24
 
27
25
 
28
- class Space(AtlasConcept, configuration_folder="spaces"):
26
+ class Space(concept.AtlasConcept, configuration_folder="spaces"):
29
27
 
30
28
  def __init__(
31
29
  self,
@@ -66,7 +64,7 @@ class Space(AtlasConcept, configuration_folder="spaces"):
66
64
  Key: EBRAINS KG schema, value: EBRAINS KG @id
67
65
  """
68
66
 
69
- AtlasConcept.__init__(
67
+ concept.AtlasConcept.__init__(
70
68
  self,
71
69
  identifier=identifier,
72
70
  name=name,
siibra/core/structure.py CHANGED
@@ -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");
@@ -21,11 +21,11 @@ a brain region is a structure which is at the same time an AtlasConcept. A
21
21
  bounding box in MNI space is a structure, but not an AtlasConcept.
22
22
  """
23
23
 
24
- from . import assignment, region as _region
25
-
26
24
  from abc import ABC, abstractmethod
27
25
  from typing import Tuple, Dict
28
26
 
27
+ from . import assignment, region as _region
28
+
29
29
 
30
30
  class BrainStructure(ABC):
31
31
  """Abstract base class for types who can act as a location filter."""
@@ -76,7 +76,7 @@ class BrainStructure(ABC):
76
76
  # Two cases:
77
77
  # 1) self is location, other is location -> look at spatial intersection/relationship, do it here
78
78
  # 2) self is location, other is region -> get region map, then call again. do it here
79
- # If self is region -> Region overwrite this method, adressed there
79
+ # If self is region -> Region overwrite this method, addressed there
80
80
 
81
81
  assert not isinstance(self, _region.Region) # method is overwritten by Region!
82
82
  if (self, other) in self._ASSIGNMENT_CACHE:
siibra/exceptions.py CHANGED
@@ -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");
@@ -55,9 +55,13 @@ class NoneCoordinateSuppliedError(ValueError):
55
55
  pass
56
56
 
57
57
 
58
- class NoMapMatchingValues(ValueError):
58
+ class MapNotFound(ValueError):
59
59
  pass
60
60
 
61
61
 
62
62
  class EmptyPointCloudError(ValueError):
63
63
  pass
64
+
65
+
66
+ class NoPredifinedColormapException(ValueError):
67
+ pass
@@ -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");
siibra/explorer/url.py CHANGED
@@ -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");
@@ -211,7 +211,7 @@ def get_hash(full_string: str):
211
211
  for char in full_string:
212
212
  # overflowing is expected and in fact the whole reason why convert number to int32
213
213
 
214
- # in windows, int32((0 - min_int32) << 5), rather than overflow to wraper around, raises OverflowError
214
+ # in windows, int32((0 - min_int32) << 5), rather than overflow to wrapper around, raises OverflowError
215
215
  shifted_5 = int32(
216
216
  (return_val - min_int32) if return_val > max_int32 else return_val << 5
217
217
  )
siibra/explorer/util.py CHANGED
@@ -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");
@@ -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");
siibra/features/anchor.py CHANGED
@@ -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,8 +14,9 @@
14
14
  # limitations under the License.
15
15
  """Handles the relation between study targets and BrainStructures."""
16
16
 
17
- from ..commons import Species, logger
17
+ from typing import Union, List, Dict, Iterable
18
18
 
19
+ from ..commons import Species, logger
19
20
  from ..core.structure import BrainStructure
20
21
  from ..core.assignment import AnatomicalAssignment, Qualification
21
22
  from ..locations.location import Location
@@ -23,11 +24,8 @@ from ..core.parcellation import Parcellation, find_regions
23
24
  from ..core.region import Region
24
25
  from ..core.space import Space
25
26
  from ..exceptions import SpaceWarpingFailedError
26
-
27
27
  from ..vocabularies import REGION_ALIASES
28
28
 
29
- from typing import Union, List, Dict, Iterable
30
-
31
29
 
32
30
  class AnatomicalAnchor:
33
31
  """
@@ -88,7 +86,7 @@ class AnatomicalAnchor:
88
86
 
89
87
  @property
90
88
  def space(self) -> Space:
91
- # may be overriden by derived classes, e.g. in features.VolumeOfInterest
89
+ # may be overridden by derived classes, e.g. in features.VolumeOfInterest
92
90
  return None if self.location is None else self.location.space
93
91
 
94
92
  @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");
@@ -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");
@@ -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,11 +14,18 @@
14
14
  # limitations under the License.
15
15
 
16
16
  from zipfile import ZipFile
17
- from ..feature import Feature, Compoundable
18
- from ..tabular.tabular import Tabular
17
+ from typing import Callable, Union, List, Tuple, Iterator
18
+ try:
19
+ from typing import Literal
20
+ except ImportError: # support python 3.7
21
+ from typing_extensions import Literal
19
22
 
20
- from .. import anchor as _anchor
23
+ import numpy as np
24
+ import pandas as pd
21
25
 
26
+ from .. import anchor as _anchor
27
+ from ..feature import Feature, Compoundable
28
+ from ..tabular.tabular import Tabular
22
29
  from ...commons import logger, QUIET, siibra_tqdm
23
30
  from ...core import region as _region
24
31
  from ...locations import pointcloud
@@ -26,16 +33,6 @@ from ...retrieval.repositories import RepositoryConnector
26
33
  from ...retrieval.requests import HttpRequest
27
34
 
28
35
 
29
- import pandas as pd
30
- import numpy as np
31
- from typing import Callable, Union, List, Tuple, Iterator
32
-
33
- try:
34
- from typing import Literal
35
- except ImportError: # support python 3.7
36
- from typing_extensions import Literal
37
-
38
-
39
36
  class RegionalConnectivity(Feature, Compoundable):
40
37
  """
41
38
  Parcellation-averaged connectivity, providing one or more matrices of a
@@ -275,7 +272,7 @@ class RegionalConnectivity(Feature, Compoundable):
275
272
 
276
273
  regions = [r for r in matrix.index if matches(r, region)]
277
274
  if len(regions) == 0:
278
- raise ValueError(f"Invalid region specificiation: {region}")
275
+ raise ValueError(f"Invalid region specification: {region}")
279
276
  elif len(regions) > 1:
280
277
  raise ValueError(f"Region specification {region} matched more than one profile: {regions}")
281
278
  else:
@@ -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");
@@ -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");
@@ -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");
@@ -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");
@@ -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,9 +15,9 @@
15
15
  """Non-preconfigured data features hosted at EBRAINS."""
16
16
 
17
17
  from zipfile import ZipFile
18
+
18
19
  from .. import anchor as _anchor
19
20
  from .. import feature
20
-
21
21
  from ...retrieval import datasets
22
22
 
23
23