siibra 0.5a2__py3-none-any.whl → 1.0.0a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of siibra might be problematic. Click here for more details.

Files changed (83) hide show
  1. siibra/VERSION +1 -1
  2. siibra/__init__.py +20 -12
  3. siibra/commons.py +145 -90
  4. siibra/configuration/__init__.py +1 -1
  5. siibra/configuration/configuration.py +22 -17
  6. siibra/configuration/factory.py +177 -128
  7. siibra/core/__init__.py +1 -8
  8. siibra/core/{relation_qualification.py → assignment.py} +17 -14
  9. siibra/core/atlas.py +66 -35
  10. siibra/core/concept.py +81 -39
  11. siibra/core/parcellation.py +83 -67
  12. siibra/core/region.py +569 -263
  13. siibra/core/space.py +7 -39
  14. siibra/core/structure.py +111 -0
  15. siibra/exceptions.py +63 -0
  16. siibra/experimental/__init__.py +19 -0
  17. siibra/experimental/contour.py +61 -0
  18. siibra/experimental/cortical_profile_sampler.py +57 -0
  19. siibra/experimental/patch.py +98 -0
  20. siibra/experimental/plane3d.py +256 -0
  21. siibra/explorer/__init__.py +16 -0
  22. siibra/explorer/url.py +112 -52
  23. siibra/explorer/util.py +31 -9
  24. siibra/features/__init__.py +73 -8
  25. siibra/features/anchor.py +75 -196
  26. siibra/features/connectivity/__init__.py +1 -1
  27. siibra/features/connectivity/functional_connectivity.py +2 -2
  28. siibra/features/connectivity/regional_connectivity.py +99 -10
  29. siibra/features/connectivity/streamline_counts.py +1 -1
  30. siibra/features/connectivity/streamline_lengths.py +1 -1
  31. siibra/features/connectivity/tracing_connectivity.py +1 -1
  32. siibra/features/dataset/__init__.py +1 -1
  33. siibra/features/dataset/ebrains.py +3 -3
  34. siibra/features/feature.py +219 -110
  35. siibra/features/image/__init__.py +1 -1
  36. siibra/features/image/image.py +21 -13
  37. siibra/features/image/sections.py +1 -1
  38. siibra/features/image/volume_of_interest.py +1 -1
  39. siibra/features/tabular/__init__.py +1 -1
  40. siibra/features/tabular/bigbrain_intensity_profile.py +24 -13
  41. siibra/features/tabular/cell_density_profile.py +111 -69
  42. siibra/features/tabular/cortical_profile.py +82 -16
  43. siibra/features/tabular/gene_expression.py +117 -6
  44. siibra/features/tabular/layerwise_bigbrain_intensities.py +7 -9
  45. siibra/features/tabular/layerwise_cell_density.py +9 -24
  46. siibra/features/tabular/receptor_density_fingerprint.py +11 -6
  47. siibra/features/tabular/receptor_density_profile.py +12 -15
  48. siibra/features/tabular/regional_timeseries_activity.py +74 -18
  49. siibra/features/tabular/tabular.py +17 -8
  50. siibra/livequeries/__init__.py +1 -7
  51. siibra/livequeries/allen.py +139 -77
  52. siibra/livequeries/bigbrain.py +104 -128
  53. siibra/livequeries/ebrains.py +7 -4
  54. siibra/livequeries/query.py +1 -2
  55. siibra/locations/__init__.py +32 -25
  56. siibra/locations/boundingbox.py +153 -127
  57. siibra/locations/location.py +45 -80
  58. siibra/locations/point.py +97 -83
  59. siibra/locations/pointcloud.py +349 -0
  60. siibra/retrieval/__init__.py +1 -1
  61. siibra/retrieval/cache.py +107 -13
  62. siibra/retrieval/datasets.py +9 -14
  63. siibra/retrieval/exceptions/__init__.py +2 -1
  64. siibra/retrieval/repositories.py +147 -53
  65. siibra/retrieval/requests.py +64 -29
  66. siibra/vocabularies/__init__.py +2 -2
  67. siibra/volumes/__init__.py +7 -9
  68. siibra/volumes/parcellationmap.py +396 -253
  69. siibra/volumes/providers/__init__.py +20 -0
  70. siibra/volumes/providers/freesurfer.py +113 -0
  71. siibra/volumes/{gifti.py → providers/gifti.py} +29 -18
  72. siibra/volumes/{neuroglancer.py → providers/neuroglancer.py} +204 -92
  73. siibra/volumes/{nifti.py → providers/nifti.py} +64 -44
  74. siibra/volumes/providers/provider.py +107 -0
  75. siibra/volumes/sparsemap.py +159 -260
  76. siibra/volumes/volume.py +720 -152
  77. {siibra-0.5a2.dist-info → siibra-1.0.0a1.dist-info}/METADATA +25 -28
  78. siibra-1.0.0a1.dist-info/RECORD +84 -0
  79. {siibra-0.5a2.dist-info → siibra-1.0.0a1.dist-info}/WHEEL +1 -1
  80. siibra/locations/pointset.py +0 -198
  81. siibra-0.5a2.dist-info/RECORD +0 -74
  82. {siibra-0.5a2.dist-info → siibra-1.0.0a1.dist-info}/LICENSE +0 -0
  83. {siibra-0.5a2.dist-info → siibra-1.0.0a1.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
1
- # Copyright 2018-2021
1
+ # Copyright 2018-2024
2
2
  # Institute of Neuroscience and Medicine (INM-1), Forschungszentrum Jülich GmbH
3
3
 
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,18 +20,19 @@ from ..features.tabular import (
20
20
  receptor_density_fingerprint,
21
21
  cell_density_profile,
22
22
  layerwise_cell_density,
23
- regional_timeseries_activity
23
+ regional_timeseries_activity,
24
24
  )
25
25
  from ..features.image import sections, volume_of_interest
26
26
  from ..core import atlas, parcellation, space, region
27
- from ..locations import point, pointset
27
+ from ..locations import point, pointcloud, boundingbox
28
28
  from ..retrieval import datasets, repositories
29
- from ..volumes import gifti, volume, nifti, neuroglancer, sparsemap, parcellationmap
29
+ from ..volumes import volume, sparsemap, parcellationmap
30
+ from ..volumes.providers.provider import VolumeProvider
30
31
 
31
32
  from os import path
32
33
  import json
33
34
  import numpy as np
34
- from typing import List, Type, Dict, Callable
35
+ from typing import List, Dict, Callable
35
36
  import pandas as pd
36
37
  from io import BytesIO
37
38
  from functools import wraps
@@ -47,7 +48,9 @@ def build_type(type_str: str):
47
48
  @wraps(fn)
48
49
  def inner(*args, **kwargs):
49
50
  return fn(*args, **kwargs)
51
+
50
52
  return inner
53
+
51
54
  return outer
52
55
 
53
56
 
@@ -64,7 +67,9 @@ class Factory:
64
67
  )
65
68
  if "openminds/DatasetVersion" in spec.get("ebrains", {}):
66
69
  result.append(
67
- datasets.EbrainsV3DatasetVersion(id=spec["ebrains"]["openminds/DatasetVersion"])
70
+ datasets.EbrainsV3DatasetVersion(
71
+ id=spec["ebrains"]["openminds/DatasetVersion"]
72
+ )
68
73
  )
69
74
  if "openminds/Dataset" in spec.get("ebrains", {}):
70
75
  result.append(
@@ -77,28 +82,41 @@ class Factory:
77
82
  contributors=pub["authors"],
78
83
  url=pub["url"],
79
84
  description=pub["description"],
80
- license=pub.get("license")
85
+ license=pub.get("license"),
81
86
  )
82
- for pub in spec["publications"] if pub.get('name')
87
+ for pub in spec["publications"]
88
+ if pub.get("name")
83
89
  )
84
90
  return result
85
91
 
86
92
  @classmethod
87
- def extract_volumes(cls, spec, space_id: str = None, name: str = None):
93
+ def extract_volumes(
94
+ cls, spec, space_id: str = None, names: List[str] = None, name_prefix: str = ""
95
+ ):
88
96
  volume_specs = spec.get("volumes", [])
89
- for vspec in volume_specs:
97
+ if names:
98
+ if len(names) != len(volume_specs) and len(names) == 1:
99
+ variants = [vol["variant"] for vol in volume_specs]
100
+ names = [f"{name_prefix}{names[0]} {var} variant" for var in variants]
101
+ else:
102
+ names = [f"{name_prefix} - volume {i}" for i in range(len(volume_specs))]
103
+ for i, vspec in enumerate(volume_specs):
90
104
  if space_id:
91
- if 'space' in vspec:
92
- logger.warning(f"Replacing space spec {vspec['space']} in volume spec with {space_id}")
93
- vspec['space'] = {"@id": space_id}
94
- if name and vspec.get('name') is None: # only use provided name if the volume has no specific name
95
- vspec['name'] = name
105
+ if "space" in vspec:
106
+ assert (
107
+ vspec["space"]["@id"] == space_id
108
+ ), "Space spec {vspec['space']} in volume field must be the same with space field in the configuration."
109
+ vspec["space"] = {"@id": space_id}
110
+ if (
111
+ names and vspec.get("name") is None
112
+ ): # only use provided name if the volume has no specific name
113
+ vspec["name"] = names[i]
96
114
  return list(map(cls.build_volume, volume_specs))
97
115
 
98
116
  @classmethod
99
117
  def extract_decoder(cls, spec):
100
118
  decoder_spec = spec.get("decoder", {})
101
- if decoder_spec["@type"].endswith('csv'):
119
+ if decoder_spec["@type"].endswith("csv"):
102
120
  kwargs = {k: v for k, v in decoder_spec.items() if k != "@type"}
103
121
  return lambda b: pd.read_csv(BytesIO(b), **kwargs)
104
122
  else:
@@ -106,52 +124,52 @@ class Factory:
106
124
 
107
125
  @classmethod
108
126
  def extract_anchor(cls, spec):
109
- if spec.get('region'):
110
- region = spec['region']
111
- elif spec.get('parcellation', {}).get('@id'):
127
+ if spec.get("region"):
128
+ region = spec["region"]
129
+ elif spec.get("parcellation", {}).get("@id"):
112
130
  # a parcellation is a special region,
113
131
  # and can be used if no region is found
114
- region = spec['parcellation']['@id']
115
- elif spec.get('parcellation', {}).get('name'):
116
- region = spec['parcellation']['name']
132
+ region = spec["parcellation"]["@id"]
133
+ elif spec.get("parcellation", {}).get("name"):
134
+ region = spec["parcellation"]["name"]
117
135
  else:
118
136
  region = None
119
137
 
120
- if 'location' in spec:
121
- location = cls.from_json(spec['location'])
138
+ if "location" in spec:
139
+ location = cls.from_json(spec["location"])
122
140
  else:
123
141
  location = None
124
142
 
125
143
  if (region is None) and (location is None):
126
144
  print(spec)
127
- raise RuntimeError("Spec provides neither region or location - no anchor can be extracted.")
145
+ raise RuntimeError(
146
+ "Spec provides neither region or location - no anchor can be extracted."
147
+ )
128
148
 
129
- if 'species' in spec:
130
- species = Species.decode(spec['species'])
131
- elif ('ebrains' in spec):
132
- species = Species.decode(spec['ebrains'])
149
+ if "species" in spec:
150
+ species = Species.decode(spec["species"])
151
+ elif "ebrains" in spec:
152
+ species = Species.decode(spec["ebrains"])
133
153
  else:
134
154
  raise ValueError(f"No species information found in spec {spec}")
135
155
 
136
156
  return anchor.AnatomicalAnchor(
137
- region=region,
138
- location=location,
139
- species=species
157
+ region=region, location=location, species=species
140
158
  )
141
159
 
142
160
  @classmethod
143
161
  def extract_connector(cls, spec):
144
- repospec = spec.get('repository', {})
162
+ repospec = spec.get("repository", {})
145
163
  spectype = repospec["@type"]
146
164
  if spectype == "siibra/repository/zippedfile/v1.0.0":
147
- return repositories.ZipfileConnector(repospec['url'])
165
+ return repositories.ZipfileConnector(repospec["url"])
148
166
  if spectype == "siibra/repository/localfolder/v1.0.0":
149
- return repositories.LocalFileRepository(repospec['folder'])
167
+ return repositories.LocalFileRepository(repospec["folder"])
150
168
  if spectype == "siibra/repository/gitlab/v1.0.0":
151
169
  return repositories.GitlabConnector(
152
- server=repospec['server'],
153
- project=repospec['project'],
154
- reftag=repospec['branch']
170
+ server=repospec["server"],
171
+ project=repospec["project"],
172
+ reftag=repospec["branch"],
155
173
  )
156
174
 
157
175
  logger.warning(
@@ -166,7 +184,8 @@ class Factory:
166
184
  a = atlas.Atlas(
167
185
  spec["@id"],
168
186
  spec["name"],
169
- species=Species.decode(spec.get('species')),
187
+ species=Species.decode(spec.get("species")),
188
+ prerelease=spec.get("prerelease", False),
170
189
  )
171
190
  for space_id in spec["spaces"]:
172
191
  a._register_space(space_id)
@@ -180,13 +199,16 @@ class Factory:
180
199
  return space.Space(
181
200
  identifier=spec["@id"],
182
201
  name=spec["name"],
183
- species=Species.decode(spec.get('species')),
184
- volumes=cls.extract_volumes(spec, space_id=spec.get("@id"), name=spec.get("name")),
202
+ species=Species.decode(spec.get("species")),
203
+ volumes=cls.extract_volumes(
204
+ spec, space_id=spec.get("@id"), names=[spec.get("name")]
205
+ ),
185
206
  shortname=spec.get("shortName", ""),
186
207
  description=spec.get("description"),
187
208
  modality=spec.get("modality"),
188
209
  publications=spec.get("publications", []),
189
210
  datasets=cls.extract_datasets(spec),
211
+ prerelease=spec.get("prerelease", False),
190
212
  )
191
213
 
192
214
  @classmethod
@@ -200,6 +222,7 @@ class Factory:
200
222
  datasets=cls.extract_datasets(spec),
201
223
  rgb=spec.get("rgb", None),
202
224
  spec=spec,
225
+ prerelease=spec.get("prerelease", False),
203
226
  )
204
227
 
205
228
  @classmethod
@@ -215,17 +238,18 @@ class Factory:
215
238
  p = parcellation.Parcellation(
216
239
  identifier=spec["@id"],
217
240
  name=spec["name"],
218
- species=Species.decode(spec.get('species')),
241
+ species=Species.decode(spec.get("species")),
219
242
  regions=regions,
220
243
  shortname=spec.get("shortName", ""),
221
244
  description=spec.get("description", ""),
222
- modality=spec.get('modality', ""),
245
+ modality=spec.get("modality", ""),
223
246
  publications=spec.get("publications", []),
224
247
  datasets=cls.extract_datasets(spec),
248
+ prerelease=spec.get("prerelease", False),
225
249
  )
226
250
 
227
251
  # add version object, if any is specified
228
- versionspec = spec.get('@version', None)
252
+ versionspec = spec.get("@version", None)
229
253
  if versionspec is not None:
230
254
  version = parcellation.ParcellationVersion(
231
255
  name=versionspec.get("name", None),
@@ -233,44 +257,44 @@ class Factory:
233
257
  collection=versionspec.get("collectionName", None),
234
258
  prev_id=versionspec.get("@prev", None),
235
259
  next_id=versionspec.get("@next", None),
236
- deprecated=versionspec.get("deprecated", False)
260
+ deprecated=versionspec.get("deprecated", False),
237
261
  )
238
262
  p.version = version
239
263
 
240
264
  return p
241
265
 
242
266
  @classmethod
243
- @build_type("siibra/volume/v0.0.1")
244
- def build_volume(cls, spec):
245
- providers: List[volume.VolumeProvider] = []
246
- provider_types: List[Type[volume.VolumeProvider]] = [
247
- neuroglancer.NeuroglancerProvider,
248
- neuroglancer.NeuroglancerMesh,
249
- neuroglancer.NeuroglancerSurfaceMesh,
250
- nifti.NiftiProvider,
251
- nifti.ZipContainedNiftiProvider,
252
- gifti.GiftiMesh,
253
- gifti.GiftiSurfaceLabeling
254
- ]
255
-
256
- for srctype, provider_spec in spec.get("providers", {}).items():
257
- for ProviderType in provider_types:
267
+ def build_volumeproviders(cls, provider_specs: Dict) -> List["VolumeProvider"]:
268
+ providers: List[VolumeProvider] = []
269
+ for srctype, provider_spec in provider_specs.items():
270
+ for ProviderType in VolumeProvider._SUBCLASSES:
258
271
  if srctype == ProviderType.srctype:
259
272
  providers.append(ProviderType(provider_spec))
260
273
  break
261
274
  else:
262
275
  if srctype not in cls._warnings_issued:
263
- logger.warning(f"No provider defined for volume Source type {srctype}")
276
+ logger.warning(
277
+ f"No provider defined for volume Source type {srctype}"
278
+ )
264
279
  cls._warnings_issued.append(srctype)
280
+ assert all([isinstance(p, VolumeProvider) for p in providers])
281
+ return providers
265
282
 
266
- assert all([isinstance(provider, volume.VolumeProvider) for provider in providers])
283
+ @classmethod
284
+ @build_type("siibra/volume/v0.0.1")
285
+ def build_volume(cls, spec):
267
286
  result = volume.Volume(
268
287
  space_spec=spec.get("space", {}),
269
- providers=providers,
270
- name=spec.get("name", {}),
288
+ providers=cls.build_volumeproviders(spec.get("providers")),
289
+ name=spec.get("name", ""),
271
290
  variant=spec.get("variant"),
272
291
  datasets=cls.extract_datasets(spec),
292
+ bbox=cls.build_boundingbox(spec),
273
293
  )
294
+ if result._boundingbox is not None:
295
+ assert (
296
+ result._boundingbox._space_spec == result._space_spec
297
+ ), "BoundingBox of a volume cannot be in a different space than the volume's space."
274
298
 
275
299
  return result
276
300
 
@@ -278,19 +302,18 @@ class Factory:
278
302
  @build_type("siibra/map/v0.0.1")
279
303
  def build_map(cls, spec):
280
304
  # maps have no configured identifier - we require the spec filename to build one
281
- assert "filename" in spec
282
- basename = path.splitext(path.basename(spec['filename']))[0]
283
- name = basename.replace('-', ' ').replace('_', ' ')
284
- identifier = f"{spec['@type'].replace('/','-')}_{basename}"
285
- volumes = cls.extract_volumes(spec)
305
+ identifier = spec.get("@id")
306
+ volumes = cls.extract_volumes(
307
+ spec, space_id=spec["space"].get("@id"), name_prefix=identifier
308
+ )
286
309
 
287
- if spec.get("sparsemap", {}).get("is_sparsemap"):
310
+ if spec.get("represented_as_sparsemap", False):
288
311
  Maptype = sparsemap.SparseMap
289
312
  else:
290
313
  Maptype = parcellationmap.Map
291
314
  return Maptype(
292
- identifier=spec.get("@id", identifier),
293
- name=spec.get("name", name),
315
+ identifier=identifier,
316
+ name=spec.get("name"),
294
317
  space_spec=spec.get("space", {}),
295
318
  parcellation_spec=spec.get("parcellation", {}),
296
319
  indices=spec.get("indices", {}),
@@ -299,7 +322,8 @@ class Factory:
299
322
  description=spec.get("description"),
300
323
  modality=spec.get("modality"),
301
324
  publications=spec.get("publications", []),
302
- datasets=cls.extract_datasets(spec)
325
+ datasets=cls.extract_datasets(spec),
326
+ prerelease=spec.get("prerelease", False),
303
327
  )
304
328
 
305
329
  @classmethod
@@ -316,11 +340,11 @@ class Factory:
316
340
  @build_type("https://openminds.ebrains.eu/sands/CoordinatePoint")
317
341
  @build_type("siibra/location/point/v0.1")
318
342
  def build_point(cls, spec):
319
- if spec.get('@type') == "https://openminds.ebrains.eu/sands/CoordinatePoint":
343
+ if spec.get("@type") == "https://openminds.ebrains.eu/sands/CoordinatePoint":
320
344
  space_id = spec["coordinateSpace"]["@id"]
321
345
  coord = list(np.float16(c["value"]) for c in spec["coordinates"])
322
346
  assert all(c["unit"]["@id"] == "id.link/mm" for c in spec["coordinates"])
323
- elif spec.get('@type') == "siibra/location/point/v0.1":
347
+ elif spec.get("@type") == "siibra/location/point/v0.1":
324
348
  space_id = spec.get("space").get("@id")
325
349
  coord = spec.get("coordinate")
326
350
  else:
@@ -332,88 +356,112 @@ class Factory:
332
356
 
333
357
  @classmethod
334
358
  @build_type("tmp/poly")
335
- @build_type("siibra/location/pointset/v0.1")
336
- def build_pointset(cls, spec):
337
- if spec.get('@type') == 'tmp/poly':
359
+ @build_type("siibra/location/pointcloud/v0.1")
360
+ def build_pointcloud(cls, spec):
361
+ if spec.get("@type") == "tmp/poly":
338
362
  space_id = spec["coordinateSpace"]["@id"]
339
363
  coords = []
340
364
  for coord in spec["coordinates"]:
341
365
  assert all(c["unit"]["@id"] == "id.link/mm" for c in coord)
342
366
  coords.append(list(np.float16(c["value"]) for c in coord))
343
- elif spec.get('@type') == 'siibra/location/pointset/v0.1':
367
+ elif spec.get("@type") == "siibra/location/pointcloud/v0.1":
344
368
  space_id = spec.get("space").get("@id")
345
369
  coords = [tuple(c) for c in spec.get("coordinates")]
346
- return pointset.PointSet(coords, space=space_id)
370
+ return pointcloud.PointCloud(coords, space=space_id)
371
+
372
+ @classmethod
373
+ @build_type("siibra/location/boundingbox/v0.1")
374
+ def build_boundingbox(cls, spec):
375
+ bboxspec = spec.get("boundingbox", None)
376
+ if bboxspec is None:
377
+ return None
378
+ space_spec = bboxspec.get("space")
379
+ coords = [tuple(c) for c in bboxspec.get("coordinates")]
380
+ return boundingbox.BoundingBox(coords[0], coords[1], space=space_spec)
347
381
 
348
382
  @classmethod
349
383
  @build_type("siibra/feature/fingerprint/receptor/v0.1")
350
384
  def build_receptor_density_fingerprint(cls, spec):
351
385
  return receptor_density_fingerprint.ReceptorDensityFingerprint(
352
- tsvfile=spec['file'],
386
+ tsvfile=spec["file"],
353
387
  anchor=cls.extract_anchor(spec),
354
388
  datasets=cls.extract_datasets(spec),
389
+ id=spec.get("@id", None),
390
+ prerelease=spec.get("prerelease", False),
355
391
  )
356
392
 
357
393
  @classmethod
358
394
  @build_type("siibra/feature/fingerprint/celldensity/v0.1")
359
395
  def build_cell_density_fingerprint(cls, spec):
360
396
  return layerwise_cell_density.LayerwiseCellDensity(
361
- segmentfiles=spec['segmentfiles'],
362
- layerfiles=spec['layerfiles'],
397
+ segmentfiles=spec["segmentfiles"],
398
+ layerfiles=spec["layerfiles"],
363
399
  anchor=cls.extract_anchor(spec),
364
400
  datasets=cls.extract_datasets(spec),
401
+ id=spec.get("@id", None),
402
+ prerelease=spec.get("prerelease", False),
365
403
  )
366
404
 
367
405
  @classmethod
368
406
  @build_type("siibra/feature/profile/receptor/v0.1")
369
407
  def build_receptor_density_profile(cls, spec):
370
408
  return receptor_density_profile.ReceptorDensityProfile(
371
- receptor=spec['receptor'],
372
- tsvfile=spec['file'],
409
+ receptor=spec["receptor"],
410
+ tsvfile=spec["file"],
373
411
  anchor=cls.extract_anchor(spec),
374
412
  datasets=cls.extract_datasets(spec),
413
+ id=spec.get("@id", None),
414
+ prerelease=spec.get("prerelease", False),
375
415
  )
376
416
 
377
417
  @classmethod
378
418
  @build_type("siibra/feature/profile/celldensity/v0.1")
379
419
  def build_cell_density_profile(cls, spec):
380
420
  return cell_density_profile.CellDensityProfile(
381
- section=spec['section'],
382
- patch=spec['patch'],
383
- url=spec['file'],
421
+ section=spec["section"],
422
+ patch=spec["patch"],
423
+ url=spec["file"],
384
424
  anchor=cls.extract_anchor(spec),
385
425
  datasets=cls.extract_datasets(spec),
426
+ id=spec.get("@id", None),
427
+ prerelease=spec.get("prerelease", False),
386
428
  )
387
429
 
388
430
  @classmethod
389
431
  @build_type("siibra/feature/section/v0.1")
390
432
  def build_section(cls, spec):
391
- vol = cls.build_volume(spec)
392
433
  kwargs = {
393
- "name": spec.get('name', ""),
394
- "region": spec.get('region', None),
395
- "space_spec": vol._space_spec,
396
- "providers": vol._providers.values(),
434
+ "name": spec.get("name"),
435
+ "region": spec.get("region", None),
436
+ "space_spec": spec.get("space"),
437
+ "providers": cls.build_volumeproviders(spec.get("providers")),
397
438
  "datasets": cls.extract_datasets(spec),
439
+ "bbox": cls.build_boundingbox(spec),
440
+ "id": spec.get("@id", None),
441
+ "prerelease": spec.get("prerelease", False),
398
442
  }
399
- modality = spec.get('modality', "")
443
+ modality = spec.get("modality", "")
400
444
  if modality == "cell body staining":
401
445
  return sections.CellbodyStainedSection(**kwargs)
402
446
  else:
403
- raise ValueError(f"No method for building image section feature type {modality}.")
447
+ raise ValueError(
448
+ f"No method for building image section feature type {modality}."
449
+ )
404
450
 
405
451
  @classmethod
406
452
  @build_type("siibra/feature/voi/v0.1")
407
453
  def build_volume_of_interest(cls, spec):
408
- vol = cls.build_volume(spec)
409
454
  kwargs = {
410
- "name": spec.get('name', ""),
411
- "region": spec.get('region', None),
412
- "space_spec": vol._space_spec,
413
- "providers": vol._providers.values(),
455
+ "name": spec.get("name"),
456
+ "region": spec.get("region", None),
457
+ "space_spec": spec.get("space"),
458
+ "providers": cls.build_volumeproviders(spec.get("providers")),
414
459
  "datasets": cls.extract_datasets(spec),
460
+ "bbox": cls.build_boundingbox(spec),
461
+ "id": spec.get("@id", None),
462
+ "prerelease": spec.get("prerelease", False),
415
463
  }
416
- modality = spec.get('modality', "")
464
+ modality = spec.get("modality", "")
417
465
  if modality == "cell body staining":
418
466
  return volume_of_interest.CellBodyStainedVolumeOfInterest(**kwargs)
419
467
  elif modality == "blockface":
@@ -427,25 +475,21 @@ class Factory:
427
475
  modality="transmittance", **kwargs
428
476
  )
429
477
  elif modality == "XPCT":
430
- return volume_of_interest.XPCTVolumeOfInterest(
431
- modality="XPCT", **kwargs
432
- )
478
+ return volume_of_interest.XPCTVolumeOfInterest(modality="XPCT", **kwargs)
433
479
  elif modality == "DTI":
434
- return volume_of_interest.DTIVolumeOfInterest(
435
- modality=modality, **kwargs
436
- )
480
+ return volume_of_interest.DTIVolumeOfInterest(modality=modality, **kwargs)
437
481
  # elif modality == "segmentation":
438
482
  # return volume_of_interest.SegmentedVolumeOfInterest(**kwargs)
439
483
  elif "MRI" in modality:
440
- return volume_of_interest.MRIVolumeOfInterest(
441
- modality=modality, **kwargs
442
- )
484
+ return volume_of_interest.MRIVolumeOfInterest(modality=modality, **kwargs)
443
485
  elif modality == "LSFM":
444
486
  return volume_of_interest.LSFMVolumeOfInterest(
445
487
  modality="Light Sheet Fluorescence Microscopy", **kwargs
446
488
  )
447
489
  else:
448
- raise ValueError(f"No method for building image section feature type {modality}.")
490
+ raise ValueError(
491
+ f"No method for building image section feature type {modality}."
492
+ )
449
493
 
450
494
  @classmethod
451
495
  @build_type("siibra/feature/connectivitymatrix/v0.3")
@@ -455,10 +499,14 @@ class Factory:
455
499
  try:
456
500
  conn_cls = getattr(connectivity, modality)
457
501
  except Exception:
458
- raise ValueError(f"No method for building connectivity matrix of type {modality}.")
502
+ raise ValueError(
503
+ f"No method for building connectivity matrix of type {modality}."
504
+ )
459
505
 
460
506
  decoder_func = cls.extract_decoder(spec)
461
- repo_connector = cls.extract_connector(spec) if spec.get('repository', None) else None
507
+ repo_connector = (
508
+ cls.extract_connector(spec) if spec.get("repository", None) else None
509
+ )
462
510
  if repo_connector is None:
463
511
  base_url = spec.get("base_url", "")
464
512
  kwargs = {
@@ -469,7 +517,8 @@ class Factory:
469
517
  "decode_func": decoder_func,
470
518
  "anchor": cls.extract_anchor(spec),
471
519
  "description": spec.get("description", ""),
472
- "datasets": cls.extract_datasets(spec)
520
+ "datasets": cls.extract_datasets(spec),
521
+ "prerelease": spec.get("prerelease", False),
473
522
  }
474
523
  paradigm = spec.get("paradigm")
475
524
  if paradigm:
@@ -478,12 +527,15 @@ class Factory:
478
527
  assert files_indexed_by in ["subject", "feature"]
479
528
  conn_by_file = []
480
529
  for fkey, filename in files.items():
481
- kwargs.update({
482
- "filename": filename,
483
- "subject": fkey if files_indexed_by == "subject" else "average",
484
- "feature": fkey if files_indexed_by == "feature" else None,
485
- "connector": repo_connector or base_url + filename
486
- })
530
+ kwargs.update(
531
+ {
532
+ "filename": filename,
533
+ "subject": fkey if files_indexed_by == "subject" else "average",
534
+ "feature": fkey if files_indexed_by == "feature" else None,
535
+ "connector": repo_connector or base_url + filename,
536
+ "id": spec.get("@id", None),
537
+ }
538
+ )
487
539
  conn_by_file.append(conn_cls(**kwargs))
488
540
  return conn_by_file
489
541
 
@@ -506,17 +558,17 @@ class Factory:
506
558
  "anchor": cls.extract_anchor(spec),
507
559
  "description": spec.get("description", ""),
508
560
  "datasets": cls.extract_datasets(spec),
509
- "timestep": spec.get("timestep")
561
+ "timestep": spec.get("timestep"),
562
+ "prerelease": spec.get("prerelease", False),
510
563
  }
511
564
  paradigm = spec.get("paradigm")
512
565
  if paradigm:
513
566
  kwargs["paradigm"] = paradigm
514
567
  timeseries_by_file = []
515
568
  for fkey, filename in files.items():
516
- kwargs.update({
517
- "filename": filename,
518
- "subject": fkey
519
- })
569
+ kwargs.update(
570
+ {"filename": filename, "subject": fkey, "id": spec.get("@id", None)}
571
+ )
520
572
  timeseries_by_file.append(timeseries_cls(**kwargs))
521
573
  return timeseries_by_file
522
574
 
@@ -525,11 +577,8 @@ class Factory:
525
577
 
526
578
  if isinstance(spec, str):
527
579
  if path.isfile(spec):
528
- fname = spec
529
580
  with open(spec, "r") as f:
530
581
  spec = json.load(f)
531
- assert "filename" not in spec
532
- spec['filename'] = fname
533
582
  else:
534
583
  spec = json.loads(spec)
535
584
 
siibra/core/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2018-2021
1
+ # Copyright 2018-2024
2
2
  # Institute of Neuroscience and Medicine (INM-1), Forschungszentrum Jülich GmbH
3
3
 
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,10 +14,3 @@
14
14
  # limitations under the License.
15
15
  """:ref:`Main siibra concepts<mainconcepts>`"""
16
16
  from . import atlas, parcellation, space
17
-
18
-
19
- def warm_cache():
20
- """Preload preconfigured siibra core concepts."""
21
- _ = atlas.Atlas.registry()
22
- _ = space.Space.registry()
23
- _ = parcellation.Parcellation.registry()