Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/siibra-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,30 @@ jobs:
fi
pytest -rx e2e

ctrl-sxplr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: "Install siibra"
run: pip install -e .
- name: "Install ctrl-sxplr dep"
run: |
pip install -r siibra/explorer/requirements.txt
python -m playwright install chromium
- name: "Run test"
run: |
python siibra/explorer/sample_playwrite.py --video
- uses: actions/upload-artifact@v4
with:
name: video-artefact
path: |
video
retention-days: 3

check-importable:
runs-on: ubuntu-22.04
env:
Expand Down
56 changes: 56 additions & 0 deletions siibra/explorer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# (experimental) Explorer extension

Control siibra-explorer with python

```python
from siibra.explorer.plugin import Explorer
explorer = Explorer()
explorer.start()

# Open the link specified in the console
# And click "OK" to open the companion plugin

explorer.navigate(position=(1e7,1e7,1e7)) # in nm

explorer.overlay(url="nifti://https://data-proxy.ebrains.eu/api/v1/public/buckets/d-d69b70e2-3002-4eaf-9c61-9c56f019bbc8/probabilistic_maps_pmaps_175areas/Area-hOc1/Area-hOc1_pmap_l_N10_nlin2ICBM152asym2009c_4.2_public_258e8c1d846f92be76922b20287344ae.nii.gz") # TODO a bit buggy, and does not yet work

from siibra.locations import PointSet
import siibra

ptst = PointSet([
[1,2,3],
[2,3,4]
], space=siibra.spaces['mni152'])

explorer.annotate(points=ptst) # maximize perspective view for best effect

```

## Automated tests

use [playwrite](https://playwright.dev/python/) to automate user interactions.

n.b. this functionality will depend largely on network speed, and geographical closeness to the siibra data centers.

note: despite stdout, do not interact with

### Installation

```sh
pip install -r siibra/explorer/requirements.txt
playwright install chromium
```

### Example

see <sample_playwrite.py>

```sh
$ python siibra/explorer/sample_playwrite.py
<trimmed>
start Point in MNI Colin 27 [0.0,0.0,0.0]
navigated Point in MNI Colin 27 [10.0,10.0,10.0]
space_specced Point in MNI 152 ICBM 2009c Nonlinear Asymmetric [9.323640000000012,11.565300000000008,9.66219000000001]
returned Point in MNI Colin 27 [9.995550000000009,9.996489999999994,10.009999999999991]

```
118 changes: 118 additions & 0 deletions siibra/explorer/api/broadcast/allRegions/request/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# generated by datamodel-codegen:
# filename: sxplr.on.allRegions__fromSxplr__request.json
# timestamp: 2023-12-07T15:40:35+00:00

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, List, Optional, Union


@dataclass
class VocabModel:
field_vocab: str


@dataclass
class QuantitativeOverlapItem:
value: float
field_context: Optional[VocabModel] = field(
default_factory=lambda: {"@vocab": "https://openminds.ebrains.eu/vocab/"}
)
typeOfUncertainty: Optional[Any] = None
uncertainty: Optional[List[float]] = None
unit: Optional[Any] = None


@dataclass
class QuantitativeOverlapItem1:
maxValue: float
minValue: float
field_context: Optional[VocabModel] = field(
default_factory=lambda: {"@vocab": "https://openminds.ebrains.eu/vocab/"}
)
maxValueUnit: Optional[Any] = None
minValueUnit: Optional[Any] = None


@dataclass
class ApiModelsOpenmindsSANDSV3AtlasParcellationEntityVersionCoordinates:
value: float
field_context: Optional[VocabModel] = field(
default_factory=lambda: {"@vocab": "https://openminds.ebrains.eu/vocab/"}
)
typeOfUncertainty: Optional[Any] = None
uncertainty: Optional[List[float]] = None
unit: Optional[Any] = None


@dataclass
class RelationAssessmentItem:
inRelationTo: Any
qualitativeOverlap: Any
field_context: Optional[VocabModel] = field(
default_factory=lambda: {"@vocab": "https://openminds.ebrains.eu/vocab/"}
)
criteria: Optional[Any] = None


@dataclass
class RelationAssessmentItem1:
inRelationTo: Any
quantitativeOverlap: Union[QuantitativeOverlapItem, QuantitativeOverlapItem1]
field_context: Optional[VocabModel] = field(
default_factory=lambda: {"@vocab": "https://openminds.ebrains.eu/vocab/"}
)
criteria: Optional[Any] = None


@dataclass
class BestViewPoint:
coordinateSpace: Any
coordinates: List[
ApiModelsOpenmindsSANDSV3AtlasParcellationEntityVersionCoordinates
]
field_context: Optional[VocabModel] = field(
default_factory=lambda: {"@vocab": "https://openminds.ebrains.eu/vocab/"}
)


@dataclass
class HasAnnotation:
criteriaQualityType: Any
internalIdentifier: str
field_context: Optional[VocabModel] = field(
default_factory=lambda: {"@vocab": "https://openminds.ebrains.eu/vocab/"}
)
bestViewPoint: Optional[BestViewPoint] = None
criteria: Optional[Any] = None
displayColor: Optional[str] = None
inspiredBy: Optional[List] = None
laterality: Optional[List] = None
visualizedIn: Optional[Any] = None


@dataclass
class PTRegion:
field_type: str
field_id: str
versionIdentifier: str
field_context: Optional[VocabModel] = field(
default_factory=lambda: {"@vocab": "https://openminds.ebrains.eu/vocab/"}
)
hasAnnotation: Optional[HasAnnotation] = None
hasParent: Optional[List] = None
lookupLabel: Optional[str] = None
name: Optional[str] = None
ontologyIdentifier: Optional[List[str]] = None
relationAssessment: Optional[
Union[RelationAssessmentItem, RelationAssessmentItem1]
] = None
versionInnovation: Optional[str] = None


@dataclass
class Model:
jsonrpc: str = "2.0"
method: str = "sxplr.on.allRegions"
params: Optional[List[PTRegion]] = None
30 changes: 30 additions & 0 deletions siibra/explorer/api/broadcast/atlasSelected/request/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# generated by datamodel-codegen:
# filename: sxplr.on.atlasSelected__fromSxplr__request.json
# timestamp: 2023-12-07T15:40:36+00:00

from __future__ import annotations

from dataclasses import dataclass
from typing import List, Optional


@dataclass
class SiibraAtIdModel:
field_id: str


@dataclass
class PTAtlas:
field_type: str
field_id: str
name: str
spaces: List[SiibraAtIdModel]
parcellations: List[SiibraAtIdModel]
species: str


@dataclass
class Model:
jsonrpc: str = "2.0"
method: str = "sxplr.on.atlasSelected"
params: Optional[PTAtlas] = None
139 changes: 139 additions & 0 deletions siibra/explorer/api/broadcast/parcellationSelected/request/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# generated by datamodel-codegen:
# filename: sxplr.on.parcellationSelected__fromSxplr__request.json
# timestamp: 2023-12-07T15:40:36+00:00

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional


@dataclass
class EbrainsDsPerson:
field_type: str
field_id: str
schema_org_shortName: str
identifier: str
shortName: str
name: str


@dataclass
class EbrainsDsUrl:
field_type: str
url: str


@dataclass
class SiibraAtIdModel:
field_id: str


@dataclass
class VocabModel:
field_vocab: str


@dataclass
class EbrainsDatasetModel:
field_type: str
field_id: str
name: str
urls: List[EbrainsDsUrl]
contributors: List[EbrainsDsPerson]
custodians: List[EbrainsDsPerson]
description: Optional[str] = None
ebrains_page: Optional[str] = None


@dataclass
class SiibraParcellationVersionModel:
field_type: str
name: str
deprecated: Optional[bool] = None
prev: Optional[SiibraAtIdModel] = None
next: Optional[SiibraAtIdModel] = None


@dataclass
class Copyright:
holder: List
year: str
field_context: Optional[VocabModel] = field(
default_factory=lambda: {"@vocab": "https://openminds.ebrains.eu/vocab/"}
)


@dataclass
class HasTerminologyVersion:
hasEntityVersion: List
field_context: Optional[VocabModel] = field(
default_factory=lambda: {"@vocab": "https://openminds.ebrains.eu/vocab/"}
)
definedIn: Optional[List] = None
ontologyIdentifier: Optional[List[str]] = None


@dataclass
class OtherContribution:
contributionType: List
contributor: Any
field_context: Optional[VocabModel] = field(
default_factory=lambda: {"@vocab": "https://openminds.ebrains.eu/vocab/"}
)


@dataclass
class BrainAtlasVersionModel:
field_type: str
field_id: str
accessibility: Dict[str, Any]
coordinateSpace: Dict[str, Any]
fullDocumentation: Dict[str, Any]
hasTerminologyVersion: HasTerminologyVersion
license: Dict[str, Any]
releaseDate: str
shortName: str
versionIdentifier: str
versionInnovation: str
field_context: Optional[VocabModel] = field(
default_factory=lambda: {"@vocab": "https://openminds.ebrains.eu/vocab/"}
)
abbreviation: Optional[str] = None
atlasType: Optional[Dict[str, Any]] = None
author: Optional[List] = None
copyright: Optional[Copyright] = None
custodian: Optional[List] = None
description: Optional[str] = None
digitalIdentifier: Optional[Dict[str, Any]] = None
fullName: Optional[str] = None
funding: Optional[List] = None
homepage: Optional[Dict[str, Any]] = None
howToCite: Optional[str] = None
isAlternativeVersionOf: Optional[List] = None
isNewVersionOf: Optional[Dict[str, Any]] = None
keyword: Optional[List] = None
ontologyIdentifier: Optional[List[str]] = None
otherContribution: Optional[OtherContribution] = None
relatedPublication: Optional[List] = None
repository: Optional[Dict[str, Any]] = None
supportChannel: Optional[List[str]] = None


@dataclass
class PTParcellation:
field_type: str
field_id: str
name: str
datasets: List[EbrainsDatasetModel]
brainAtlasVersions: List[BrainAtlasVersionModel]
modality: Optional[str] = None
version: Optional[SiibraParcellationVersionModel] = None
shortname: Optional[str] = None


@dataclass
class Model:
jsonrpc: str = "2.0"
method: str = "sxplr.on.parcellationSelected"
params: Optional[PTParcellation] = None
Loading
Loading