Skip to content

Commit

Permalink
BRAYNS-594 Add sonata tests. (#1226)
Browse files Browse the repository at this point in the history
  • Loading branch information
Adrien4193 committed Jan 17, 2024
1 parent 45e5073 commit 8819a42
Show file tree
Hide file tree
Showing 25 changed files with 121 additions and 58 deletions.
3 changes: 2 additions & 1 deletion .gitlab-ci.hpc-spack.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ brayns-python-testapi:
- source pythonvenv/bin/activate
- export BRAYNS_TEST_EXECUTABLE=${SPACK_BUILD_DIR}/bin/braynsService
- export BRAYNS_TEST_BBP_CIRCUIT=/gpfs/bbp.cscs.ch/project/proj3/TestData/install/share/BBPTestData/circuitBuilding_1000neurons/BlueConfig
- export BRAYNS_TEST_MORPHOLOGY=/gpfs/bbp.cscs.ch/project/proj3/TestData/install/share/BBPTestData/circuitBuilding_1000neurons/morphologies/C150501A-I3.h5
- export BRAYNS_TEST_SONATA_CIRCUIT=/gpfs/bbp.cscs.ch/project/proj3/cloned_circuits/GeneratedTest/simulation_config.json
- export BRAYNS_TEST_MORPHOLOGY=/gpfs/bbp.cscs.ch/project/proj3/cloned_circuits/test_morphology.h5
- export BRAYNS_TEST_DTI_FILE=/gpfs/bbp.cscs.ch/project/proj3/TestData/install/share/BBPTestData/DTI/dtitest.json
- export BRAYNS_TEST_NRRD_FOLDER=/gpfs/bbp.cscs.ch/project/proj3/TestData/install/share/BBPTestData/nrrd
- python -m unittest discover -s testapi -p test_*.py
Expand Down
4 changes: 4 additions & 0 deletions python/testapi/api_test_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ def env(self) -> dict[str, str]:
def bbp_circuit(self) -> str:
return os.environ["BRAYNS_TEST_BBP_CIRCUIT"]

@property
def sonata_circuit(self) -> str:
return os.environ["BRAYNS_TEST_SONATA_CIRCUIT"]

@property
def morphology_file(self) -> str:
return os.environ["BRAYNS_TEST_MORPHOLOGY"]
Expand Down
Binary file modified python/testapi/core/assets/color_model.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified python/testapi/core/assets/frame_0.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added python/testapi/core/assets/frame_1.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added python/testapi/core/assets/frame_2.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed python/testapi/core/assets/frame_99.png
Binary file not shown.
20 changes: 13 additions & 7 deletions python/testapi/core/test_color_ramp.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,37 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import brayns
from testapi.loading import load_circuit
from testapi.loading import load_sonata_circuit
from testapi.render import RenderSettings, render_and_validate
from testapi.simple_test_case import SimpleTestCase


class TestGetColorRamp(SimpleTestCase):
def test_get_color_ramp(self) -> None:
model = load_circuit(self, report=True)
model = load_sonata_circuit(self, report=True)
function = brayns.get_color_ramp(self.instance, model.id)
self.assertEqual(function.value_range, brayns.ValueRange(-80, -10))
self.assertEqual(len(function.colors), 128)
self.assertEqual(function.colors[0], brayns.Color4.black)
self.assertEqual(function.colors[-1], brayns.Color4.white)

def test_set_color_ramp(self) -> None:
model = load_circuit(self, report=True)
model = load_sonata_circuit(self, dendrites=True, report=True)
ramp = brayns.ColorRamp(
brayns.ValueRange(-100, 0),
colors=[brayns.Color4.red, brayns.Color4.green],
brayns.ValueRange(0, 3),
colors=[
brayns.Color4.red,
brayns.Color4.green,
brayns.Color4.blue,
],
)
brayns.set_color_ramp(self.instance, model.id, ramp)
test = brayns.get_color_ramp(self.instance, model.id)
self.assertEqual(test, ramp)
brayns.enable_simulation(self.instance, model.id, True)
settings = RenderSettings(frame=0)
render_and_validate(self, "frame_0", settings)
settings.frame = 99
render_and_validate(self, "frame_99", settings)
settings.frame = 1
render_and_validate(self, "frame_1", settings)
settings.frame = 2
render_and_validate(self, "frame_2", settings)
23 changes: 13 additions & 10 deletions python/testapi/core/test_coloring.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,21 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import brayns
from testapi.loading import add_sphere, load_circuit
from testapi.loading import add_sphere, load_sonata_circuit
from testapi.render import render_and_validate
from testapi.simple_test_case import SimpleTestCase


class TestColoring(SimpleTestCase):
def test_color_model(self) -> None:
model = load_circuit(self)
model = load_sonata_circuit(self, dendrites=True)
brayns.color_model(
self.instance,
model.id,
method=brayns.CircuitColorMethod.ID,
colors={
"0-500": brayns.Color4.red,
"501-1000": brayns.Color4.green,
"0-5": brayns.Color4.red,
"5-10": brayns.Color4.green,
},
)
render_and_validate(self, "color_model")
Expand All @@ -44,22 +44,25 @@ def test_set_model_color(self) -> None:
render_and_validate(self, "set_model_color")

def test_get_color_methods(self) -> None:
model = load_circuit(self)
model = load_sonata_circuit(self)
methods = brayns.get_color_methods(self.instance, model.id)
ref = {
brayns.ColorMethod.SOLID,
brayns.CircuitColorMethod.ID,
brayns.CircuitColorMethod.ETYPE,
brayns.CircuitColorMethod.ID,
brayns.CircuitColorMethod.LAYER,
brayns.CircuitColorMethod.MORPHOLOGY,
brayns.CircuitColorMethod.MORPHOLOGY_CLASS,
brayns.CircuitColorMethod.MTYPE,
brayns.CircuitColorMethod.REGION,
brayns.CircuitColorMethod.SUBREGION,
brayns.CircuitColorMethod.SYNAPSE_CLASS,
brayns.ColorMethod.SOLID,
}
self.assertEqual(len(methods), len(ref))
self.assertSetEqual(set(methods), ref)

def test_get_color_values(self) -> None:
model = load_circuit(self)
model = load_sonata_circuit(self)
method = brayns.CircuitColorMethod.LAYER
values = brayns.get_color_values(self.instance, model.id, method)
ref = [str(i) for i in range(6)]
self.assertEqual(values, ref)
self.assertEqual(values, ["CBXmo"])
12 changes: 6 additions & 6 deletions python/testapi/core/test_pick.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from typing import cast

import brayns
from testapi.loading import load_circuit
from testapi.loading import load_sonata_circuit
from testapi.render import prepare_image
from testapi.simple_test_case import SimpleTestCase

Expand All @@ -32,11 +32,11 @@ def test_hit(self) -> None:
test = brayns.pick(self.instance, brayns.Vector2(0.5, 0.5))
self.assertIsNotNone(test)
test = cast(brayns.PickResult, test)
self.assertAlmostEqual(test.position.x, 38.38946, delta=0.001)
self.assertAlmostEqual(test.position.y, 999.41394, delta=0.001)
self.assertAlmostEqual(test.position.z, 56.914795, delta=0.001)
self.assertAlmostEqual(test.position.x, 195.463, delta=0.01)
self.assertAlmostEqual(test.position.y, 176.531, delta=0.01)
self.assertAlmostEqual(test.position.z, 104.240, delta=0.01)
self.assertEqual(test.model_id, 0)
self.assertEqual(test.metadata, {"neuron_id": 559})
self.assertEqual(test.metadata, {"neuron_id": 5})

def test_missed(self) -> None:
self._prepare_scene()
Expand All @@ -48,5 +48,5 @@ def test_empty_scene(self) -> None:
self.assertIsNone(test)

def _prepare_scene(self) -> None:
load_circuit(self)
load_sonata_circuit(self, dendrites=True)
prepare_image(self.instance)
14 changes: 7 additions & 7 deletions python/testapi/core/test_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,22 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import brayns
from testapi.loading import load_circuit
from testapi.loading import load_sonata_circuit
from testapi.simple_test_case import SimpleTestCase


class TestSimulation(SimpleTestCase):
def test_get_simulation(self) -> None:
load_circuit(self, report=True)
load_sonata_circuit(self, report=True)
test = brayns.get_simulation(self.instance)
self.assertEqual(test.start_frame, 0)
self.assertEqual(test.end_frame, 99)
self.assertEqual(test.end_frame, 2)
self.assertEqual(test.current_frame, 0)
self.assertAlmostEqual(test.delta_time, 0.1)
self.assertAlmostEqual(test.delta_time, 1)
self.assertEqual(test.time_unit, brayns.TimeUnit.MILLISECOND)

def test_set_simulation_frame(self) -> None:
load_circuit(self, report=True)
brayns.set_simulation_frame(self.instance, 12)
load_sonata_circuit(self, report=True)
brayns.set_simulation_frame(self.instance, 2)
simulation = brayns.get_simulation(self.instance)
self.assertEqual(simulation.current_frame, 12)
self.assertEqual(simulation.current_frame, 2)
33 changes: 11 additions & 22 deletions python/testapi/loading.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,30 +39,19 @@ def add_clip_plane(context: SimpleTestCase) -> brayns.Model:
return brayns.add_clipping_geometries(context.instance, [plane])


def load_circuit(
def load_sonata_circuit(
context: SimpleTestCase, dendrites: bool = False, report: bool = False
) -> brayns.Model:
loader = brayns.BbpLoader(
cells=brayns.BbpCells.all(),
report=brayns.BbpReport.compartment("somas") if report else None,
morphology=brayns.Morphology(
radius_multiplier=10,
load_soma=True,
load_dendrites=dendrites,
),
loader = brayns.SonataLoader(
[
brayns.SonataNodePopulation(
name="cerebellum_neurons",
nodes=brayns.SonataNodes.all(),
report=brayns.SonataReport.compartment("test") if report else None,
morphology=brayns.Morphology(load_dendrites=dendrites),
)
]
)
models = loader.load_models(context.instance, context.bbp_circuit)
context.assertEqual(len(models), 1)
return models[0]


def load_neurons(context: SimpleTestCase, gids: list[int]) -> brayns.Model:
loader = brayns.BbpLoader(
cells=brayns.BbpCells.from_gids(gids),
morphology=brayns.Morphology(
load_dendrites=True,
),
)
models = loader.load_models(context.instance, context.bbp_circuit)
models = loader.load_models(context.instance, context.sonata_circuit)
context.assertEqual(len(models), 1)
return models[0]
Binary file modified python/testapi/plugins/assets/atlas_flatmap.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified python/testapi/plugins/assets/bbp_circuit.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified python/testapi/plugins/assets/constant_radius.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified python/testapi/plugins/assets/radius_multiplier.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified python/testapi/plugins/assets/resampling.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified python/testapi/plugins/assets/set_circuit_thickness.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified python/testapi/plugins/assets/smooth.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added python/testapi/plugins/assets/sonata_circuit.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified python/testapi/plugins/assets/spheres.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified python/testapi/plugins/assets/subsampling.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 18 additions & 4 deletions python/testapi/plugins/test_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,32 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import brayns
from testapi.loading import load_circuit, load_neurons
from testapi.loading import load_sonata_circuit
from testapi.render import render_and_validate
from testapi.simple_test_case import SimpleTestCase


class TestGetCircuitIds(SimpleTestCase):
def test_get_circuit_ids(self) -> None:
model = load_circuit(self)
model = load_sonata_circuit(self)
ids = brayns.get_circuit_ids(self.instance, model.id)
self.assertEqual(ids, list(range(1, 1001)))
self.assertEqual(ids, list(range(0, 10)))

def test_set_circuit_thickness(self) -> None:
model = load_neurons(self, [1])
model = self.load_neurons([1])
brayns.set_circuit_thickness(self.instance, model.id, 5)
render_and_validate(self, "set_circuit_thickness")

def load_neurons(self, ids: list[int]) -> brayns.Model:
loader = brayns.SonataLoader(
[
brayns.SonataNodePopulation(
name="cerebellum_neurons",
nodes=brayns.SonataNodes.from_ids(ids),
morphology=brayns.Morphology(load_dendrites=True),
)
]
)
models = loader.load_models(self.instance, self.sonata_circuit)
self.assertEqual(len(models), 1)
return models[0]
46 changes: 46 additions & 0 deletions python/testapi/plugins/test_sonata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Copyright (c) 2015-2023 EPFL/Blue Brain Project
# All rights reserved. Do not distribute without permission.
#
# Responsible Author: adrien.fleury@epfl.ch
#
# This file is part of Brayns <https://github.com/BlueBrain/Brayns>
#
# This library is free software; you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License version 3.0 as published
# by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this library; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import brayns
from testapi.render import RenderSettings, render_and_validate
from testapi.simple_test_case import SimpleTestCase


class TestSonata(SimpleTestCase):
def test_load_models(self) -> None:
loader = brayns.SonataLoader(
[
brayns.SonataNodePopulation(
name="cerebellum_neurons",
nodes=brayns.SonataNodes.from_density(0.5),
report=brayns.SonataReport.compartment("test"),
morphology=brayns.Morphology(load_dendrites=True, load_axon=True),
)
]
)
models = loader.load_models(self.instance, self.sonata_circuit)
self.assertEqual(len(models), 1)
ramp = brayns.ColorRamp(
value_range=brayns.ValueRange(0, 3),
colors=[brayns.Color4.red, brayns.Color4.blue],
)
brayns.set_color_ramp(self.instance, models[0].id, ramp)
settings = RenderSettings(frame=1)
render_and_validate(self, "sonata_circuit", settings)
2 changes: 1 addition & 1 deletion python/testapi/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

from .simple_test_case import SimpleTestCase

DEFAULT_THRESHOLD = 1.0
DEFAULT_THRESHOLD = 0.01


class ValidationFailed(RuntimeError):
Expand Down

0 comments on commit 8819a42

Please sign in to comment.