diff --git a/.github/workflows/test_and_deploy.yml b/.github/workflows/test_and_deploy.yml index d10c8fc8..8d4ffbba 100644 --- a/.github/workflows/test_and_deploy.yml +++ b/.github/workflows/test_and_deploy.yml @@ -48,6 +48,14 @@ jobs: python-version: "3.11" steps: + - name: Cache brainglobe directory + uses: actions/cache@v3 + with: + path: | # ensure we don't cache any interrupted atlas download and extraction, if e.g. we cancel the workflow manually + ~/.brainglobe + !~/.brainglobe/atlas.tar.gz + key: brainglobe + - name: Install hdf5 libs for Mac if: runner.os == 'macOS' run: brew install hdf5 diff --git a/.gitignore b/.gitignore index 509fb15e..f93c9e88 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,8 @@ brainrender/atlas_specific/gene_expression/__pycache__ brainrender/atlas_specific/gene_expression/__pycache__/* brainrender/atlas_specific/__pycache__ +example_brainrender_shot* + workspace.py workspace.ipynb brexport.html diff --git a/MANIFEST.in b/MANIFEST.in index 225ca7a9..274b2f69 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -7,6 +7,7 @@ prune tests prune examples prune imgs prune videos +prune resources graft brainrender diff --git a/README.md b/README.md index c355e4b3..bd964432 100644 --- a/README.md +++ b/README.md @@ -108,4 +108,4 @@ year = {2021} ## Contributing -Contributions to brainrender are more than welcome. Please see the [developers guide](https://brainglobe.info/community/developers/index.html). Note that some tests are only run locally, by specifying `--runslow --runlocal` in `pytest`. +Contributions to brainrender are more than welcome. Please see the [developers guide](https://brainglobe.info/community/developers/index.html). diff --git a/examples/__init__.py b/examples/__init__.py index 49eff8c7..4d6ae3e2 100644 --- a/examples/__init__.py +++ b/examples/__init__.py @@ -1,20 +1,24 @@ from examples import ( add_cells, + add_cylinder, add_labels, add_mesh_from_file, - add_cylinder, animation, brain_regions, brainglobe_atlases, cell_density, custom_camera, gene_expression, + line, neurons, + probe_tracks, ruler, + screenshot, settings, slice, # streamlines, user_volumetric_data, video, volumetric_data, + web_export, ) diff --git a/examples/add_mesh_from_file.py b/examples/add_mesh_from_file.py index 8e5f3ba2..854e5305 100644 --- a/examples/add_mesh_from_file.py +++ b/examples/add_mesh_from_file.py @@ -1,11 +1,12 @@ from pathlib import Path -from importlib.resources import files from myterial import orange from rich import print from brainrender import Scene +obj_file = Path(__file__).parent.parent / "resources" / "CC_134_1_ch1inj.obj" + print(f"[{orange}]Running example: {Path(__file__).name}") # Create a brainrender scene @@ -15,10 +16,7 @@ scene.add_brain_region("SCm", alpha=0.2) # Add from file -scene.add( - files("brainrender").joinpath("resources/CC_134_1_ch1inj.obj"), - color="tomato", -) +scene.add(obj_file, color="tomato") # Render! scene.render() diff --git a/examples/brainglobe_atlases.py b/examples/brainglobe_atlases.py index 20c89a24..982fdc6c 100644 --- a/examples/brainglobe_atlases.py +++ b/examples/brainglobe_atlases.py @@ -9,6 +9,5 @@ # Create a brainrender scene using the zebrafish atlas scene = Scene(atlas_name="mpin_zfish_1um", title="zebrafish") - # Render! scene.render() diff --git a/examples/neurons.py b/examples/neurons.py index 61efb848..05049b87 100644 --- a/examples/neurons.py +++ b/examples/neurons.py @@ -8,13 +8,15 @@ from brainrender import Scene from brainrender.actors import Neuron, make_neurons +neuron_file = Path(__file__).parent.parent / "resources" / "neuron1.swc" + print(f"[{orange}]Running example: {Path(__file__).name}") # Create a brainrender scene scene = Scene(title="neurons") # Add a neuron from file -scene.add(Neuron(files("brainrender").joinpath("resources/neuron1.swc"))) +scene.add(Neuron(neuron_file)) # Download neurons data with morphapi mlapi = MouseLightAPI() diff --git a/examples/notebook_workflow.ipynb b/examples/notebook_workflow.ipynb index 0020aa8f..aede0131 100644 --- a/examples/notebook_workflow.ipynb +++ b/examples/notebook_workflow.ipynb @@ -35,7 +35,6 @@ "cell_type": "code", "execution_count": 1, "metadata": {}, - "outputs": [], "source": [ "import vedo\n", "vedo.settings.default_backend= 'vtk'\n", @@ -46,7 +45,8 @@ "popup_scene.add_brain_region('VISp')\n", "\n", "popup_scene.render() # press 'Esc' to close" - ] + ], + "outputs": [] }, { "cell_type": "markdown", @@ -73,7 +73,6 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [], "source": [ "# Set the backend\n", "import vedo\n", @@ -94,7 +93,8 @@ "from vedo import Plotter # <- this will be used to render an embedded scene \n", "plt = Plotter()\n", "plt.show(*scene.renderables) # same as vedo.show(*scene.renderables)" - ] + ], + "outputs": [] } ], "metadata": { diff --git a/examples/probe_tracks.py b/examples/probe_tracks.py index bb341660..1383d1dc 100644 --- a/examples/probe_tracks.py +++ b/examples/probe_tracks.py @@ -8,7 +8,7 @@ from brainrender import Scene from brainrender.actors import Points -data_path = Path(__file__).parent.parent / "brainrender" / "resources" +resource_path = Path(__file__).parent.parent / "resources" scene = Scene(title="Silicon Probe Visualization") @@ -21,7 +21,7 @@ # part of the probe. scene.add( Points( - np.load(data_path / "probe_1_striatum.npy"), + np.load(resource_path / "probe_1_striatum.npy"), name="probe_1", colors="darkred", radius=50, @@ -29,7 +29,7 @@ ) scene.add( Points( - np.load(data_path / "probe_2_RSP.npy"), + np.load(resource_path / "probe_2_RSP.npy"), name="probe_2", colors="darkred", radius=50, diff --git a/examples/user_volumetric_data.py b/examples/user_volumetric_data.py index c52d101b..ca0c2a7d 100644 --- a/examples/user_volumetric_data.py +++ b/examples/user_volumetric_data.py @@ -28,23 +28,21 @@ print(f"[{orange}]Running example: {Path(__file__).name}") +download_path = Path.home() / ".brainglobe" / "brainrender" / "example-data" +filename = "T_AVG_s356tTg.tif" +scene = Scene(atlas_name="mpin_zfish_1um") -retrieved_paths = pooch.retrieve( +# for some reason the list of returned by pooch does not seem to be +# in the same order every time +_ = pooch.retrieve( url="https://api.mapzebrain.org/media/Lines/brn3cGFP/average_data/T_AVG_s356tTg.zip", known_hash="54b59146ba08b4d7eea64456bcd67741db4b5395235290044545263f61453a61", - path=Path.home() - / ".brainglobe" - / "brainrender" - / "example-data", # zip will be downloaded here + path=download_path, progressbar=True, - processor=pooch.Unzip( - extract_dir="" - # path to unzipped dir, - # *relative* to the path set in 'path' - ), + processor=pooch.Unzip(extract_dir="."), ) -datafile = Path(retrieved_paths[0]) # [0] is zip file +datafile = download_path / filename # 1. load the data diff --git a/examples/volumetric_data.py b/examples/volumetric_data.py index 509ccd78..604e7120 100644 --- a/examples/volumetric_data.py +++ b/examples/volumetric_data.py @@ -11,18 +11,19 @@ from brainrender.actors import Volume from pathlib import Path -from importlib.resources import files from myterial import orange from rich import print settings.SHOW_AXES = False +volume_file = Path(__file__).parent.parent / "resources" / "volume.npy" + print(f"[{orange}]Running example: {Path(__file__).name}") scene = Scene(inset=False) -data = np.load(files("brainrender").joinpath("resources/volume.npy")) +data = np.load(volume_file) print(data.shape) # make a volume actor and add diff --git a/brainrender/resources/CC_134_1_ch1inj.obj b/resources/CC_134_1_ch1inj.obj similarity index 100% rename from brainrender/resources/CC_134_1_ch1inj.obj rename to resources/CC_134_1_ch1inj.obj diff --git a/brainrender/resources/CC_134_2_ch1inj.obj b/resources/CC_134_2_ch1inj.obj similarity index 100% rename from brainrender/resources/CC_134_2_ch1inj.obj rename to resources/CC_134_2_ch1inj.obj diff --git a/brainrender/resources/neuron1.swc b/resources/neuron1.swc similarity index 100% rename from brainrender/resources/neuron1.swc rename to resources/neuron1.swc diff --git a/brainrender/resources/probe_1_striatum.npy b/resources/probe_1_striatum.npy similarity index 100% rename from brainrender/resources/probe_1_striatum.npy rename to resources/probe_1_striatum.npy diff --git a/brainrender/resources/probe_2_RSP.npy b/resources/probe_2_RSP.npy similarity index 100% rename from brainrender/resources/probe_2_RSP.npy rename to resources/probe_2_RSP.npy diff --git a/brainrender/resources/random_cells.h5 b/resources/random_cells.h5 similarity index 100% rename from brainrender/resources/random_cells.h5 rename to resources/random_cells.h5 diff --git a/brainrender/resources/random_cells.npy b/resources/random_cells.npy similarity index 100% rename from brainrender/resources/random_cells.npy rename to resources/random_cells.npy diff --git a/brainrender/resources/volume.npy b/resources/volume.npy similarity index 100% rename from brainrender/resources/volume.npy rename to resources/volume.npy diff --git a/tests/conftest.py b/tests/conftest.py deleted file mode 100644 index f064cf12..00000000 --- a/tests/conftest.py +++ /dev/null @@ -1,14 +0,0 @@ -import pytest - - -def pytest_addoption(parser): - parser.addoption("--runslow", action="store_true", help="run slow tests") - parser.addoption("--runlocal", action="store_true", help="run local tests") - - -def pytest_runtest_setup(item): - if "slow" in item.keywords and not item.config.getvalue("runslow"): - pytest.skip("need --runslow option to run") - - if "local" in item.keywords and not item.config.getvalue("runlocal"): - pytest.skip("need --runlocal option to run") diff --git a/tests/test_aba_gene.py b/tests/test_aba_gene.py index aa2dd1da..49a83b6b 100644 --- a/tests/test_aba_gene.py +++ b/tests/test_aba_gene.py @@ -12,7 +12,6 @@ # return geapi - # @pytest.mark.xfail # def test_gene_expression_api(geapi): diff --git a/tests/test_examples.py b/tests/test_examples.py index 03cfd1a8..3d73c046 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -1,28 +1,5 @@ -import pytest - -from brainrender import settings - -settings.INTERACTIVE = False - - -@pytest.mark.slow -@pytest.mark.local def test_examples(): - import examples - - examples.add_cells - examples.add_mesh_from_file - examples.animation - examples.brain_regions - examples.brainglobe_atlases - examples.cell_density - examples.custom_camera - examples.gene_expression - examples.neurons - examples.ruler - examples.settings - examples.slice - # examples.streamlines - examples.user_volumetric_data - examples.video - examples.volumetric_data + """ + Run every script in the examples directory + """ + import examples # noqa diff --git a/tests/test_integration.py b/tests/test_integration.py index fcf7c00a..36a30328 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -1,4 +1,3 @@ -from importlib.resources import files from pathlib import Path import numpy as np @@ -19,6 +18,8 @@ ) from brainrender.atlas_specific import GeneExpressionAPI +resources_dir = Path(__file__).parent.parent / "resources" + def get_n_points_in_region(region, N): """ @@ -109,7 +110,7 @@ def test_add_labels(scene): def test_add_mesh_from_file(scene): - data_path = files("brainrender").joinpath("resources/CC_134_1_ch1inj.obj") + data_path = resources_dir / "CC_134_1_ch1inj.obj" scene.add_brain_region("SCm", alpha=0.2) file_mesh = scene.add(data_path, color="tomato") @@ -236,7 +237,7 @@ def test_gene_expression(scene): def test_neurons(scene, pytestconfig): - data_path = files("brainrender").joinpath("resources/neuron1.swc") + data_path = resources_dir / "neuron1.swc" neuron = Neuron(data_path) scene.add(neuron) @@ -300,26 +301,24 @@ def test_slice(scene): assert np.all(ca1_clone.bounds() != ca1.bounds()) -@pytest.mark.slow -@pytest.mark.local def test_user_volumetric_data(): + download_path = ( + Path.home() / ".brainglobe" / "brainrender" / "example-data" + ) + filename = "T_AVG_s356tTg.tif" scene = Scene(atlas_name="mpin_zfish_1um") - retrieved_paths = pooch.retrieve( + + # for some reason the list of returned by pooch does not seem to be + # in the same order every time + _ = pooch.retrieve( url="https://api.mapzebrain.org/media/Lines/brn3cGFP/average_data/T_AVG_s356tTg.zip", known_hash="54b59146ba08b4d7eea64456bcd67741db4b5395235290044545263f61453a61", - path=Path.home() - / ".brainglobe" - / "brainrender" - / "example-data", # zip will be downloaded here + path=download_path, progressbar=True, - processor=pooch.Unzip( - extract_dir="" - # path to unzipped dir, - # *relative* to the path set in 'path' - ), + processor=pooch.Unzip(extract_dir="."), ) - datafile = Path(retrieved_paths[0]) + datafile = download_path / filename data = load_any(datafile) source_space = AnatomicalSpace("ira") target_space = scene.atlas.space @@ -368,7 +367,7 @@ def test_video(scene, pytestconfig): def test_volumetric_data(scene): - data_path = files("brainrender").joinpath("resources/volume.npy") + data_path = resources_dir / "volume.npy" data = np.load(data_path) actor = Volume( data, diff --git a/tests/test_neuron.py b/tests/test_neuron.py index 26867fd8..702f9b2d 100644 --- a/tests/test_neuron.py +++ b/tests/test_neuron.py @@ -1,4 +1,4 @@ -from importlib.resources import files +from pathlib import Path import pytest from vedo import Sphere @@ -7,12 +7,12 @@ from brainrender.actor import Actor from brainrender.actors import Neuron, make_neurons +resources_dir = Path(__file__).parent.parent / "resources" + def test_neuron(): s = Scene(title="BR") - neuron = s.add( - Neuron(files("brainrender").joinpath("resources/neuron1.swc")) - ) + neuron = s.add(Neuron(resources_dir / "neuron1.swc")) s.add(Neuron(Actor(neuron.mesh))) s.add(Neuron(neuron.mesh)) Neuron(Sphere()) @@ -21,13 +21,13 @@ def test_neuron(): Neuron(1) with pytest.raises(FileExistsError): - Neuron(files("brainrender").joinpath("resources/neuronsfsfs.swc")) + Neuron(resources_dir / "neuronsfsfs.swc") with pytest.raises(NotImplementedError): - Neuron(files("brainrender").joinpath("resources/random_cells.h5")) + Neuron(resources_dir / "random_cells.h5") del s def test_make_neurons(): - data_path = files("brainrender").joinpath("resources/neuron1.swc") + data_path = resources_dir / "neuron1.swc" make_neurons(data_path, data_path) diff --git a/tests/test_points.py b/tests/test_points.py index 2341204c..995c4aa8 100644 --- a/tests/test_points.py +++ b/tests/test_points.py @@ -1,5 +1,5 @@ import random -from importlib.resources import files +from pathlib import Path import numpy as np import pytest @@ -8,6 +8,8 @@ from brainrender.actor import Actor from brainrender.actors import Point, Points, PointsDensity +resources_dir = Path(__file__).parent.parent / "resources" + def get_n_random_points_in_region(region, N): """ @@ -26,7 +28,7 @@ def get_n_random_points_in_region(region, N): def test_points_working(): s = Scene(title="BR") - data_path = files("brainrender").joinpath("resources/random_cells.npy") + data_path = resources_dir / "random_cells.npy" act = Points(np.load(data_path)) act2 = Points(data_path, colors="k") act3 = Points(data_path, name="test") @@ -59,11 +61,11 @@ def test_points_density(): def test_points_error(): with pytest.raises(FileExistsError): Points( - files("brainrender").joinpath("resources/testsfsdfs.npy"), + resources_dir / "testsfsdfs.npy", colors="k", ) with pytest.raises(NotImplementedError): Points( - files("brainrender").joinpath("resources/random_cells.h5"), + resources_dir / "random_cells.h5", colors="k", ) diff --git a/tests/test_streamlines.py b/tests/test_streamlines.py index 1a409c6b..aab1a614 100644 --- a/tests/test_streamlines.py +++ b/tests/test_streamlines.py @@ -1,38 +1,33 @@ -import pandas as pd -import pytest - -from brainrender import Scene -from brainrender.actors.streamlines import ( - Streamlines, - make_streamlines, -) -from brainrender.atlas_specific import get_streamlines_for_region - - -@pytest.mark.local -def test_download(): - streams = get_streamlines_for_region("TH", force_download=False) - assert len(streams) == 54 - assert isinstance(streams[0], pd.DataFrame) - - -@pytest.mark.local -@pytest.mark.slow -def test_download_slow(): - streams = get_streamlines_for_region("TH", force_download=True) - assert len(streams) == 54 - assert isinstance(streams[0], pd.DataFrame) - - -@pytest.mark.local -def test_streamlines(): - s = Scene(title="BR") - streams = get_streamlines_for_region("TH", force_download=False) - s.add(Streamlines(streams[0])) - s.add(*make_streamlines(*streams[1:3])) - - with pytest.raises(TypeError): - Streamlines([1, 2, 3]) - - # s.render(interactive=False) - del s +# import pandas as pd +# import pytest +# +# from brainrender import Scene +# from brainrender.actors.streamlines import ( +# Streamlines, +# make_streamlines, +# ) +# from brainrender.atlas_specific import get_streamlines_for_region +# +# +# def test_download(): +# streams = get_streamlines_for_region("TH", force_download=False) +# assert len(streams) == 54 +# assert isinstance(streams[0], pd.DataFrame) +# +# +# def test_download_slow(): +# streams = get_streamlines_for_region("TH", force_download=True) +# assert len(streams) == 54 +# assert isinstance(streams[0], pd.DataFrame) +# +# +# def test_streamlines(): +# s = Scene(title="BR") +# streams = get_streamlines_for_region("TH", force_download=False) +# s.add(Streamlines(streams[0])) +# s.add(*make_streamlines(*streams[1:3])) +# +# with pytest.raises(TypeError): +# Streamlines([1, 2, 3]) +# +# del s diff --git a/tests/test_volume.py b/tests/test_volume.py index 57bb1ac6..c3e61829 100644 --- a/tests/test_volume.py +++ b/tests/test_volume.py @@ -1,15 +1,17 @@ -from importlib.resources import files +from pathlib import Path import numpy as np from brainrender import Scene from brainrender.actors import Volume +resources_dir = Path(__file__).parent.parent / "resources" + def test_volume(): s = Scene(inset=False, root=True) - data = np.load(files("brainrender").joinpath("resources/volume.npy")) + data = np.load(resources_dir / "volume.npy") s.add(Volume(data, voxel_size=200, as_surface=False, c="Reds")) s.add(Volume(data, voxel_size=200, as_surface=True, c="Reds")) del s