Skip to content

Commit

Permalink
Gui testing take two (#119)
Browse files Browse the repository at this point in the history
* first draft

* Added first version of GUI testing - browse tabs

* Added first version of GUI testing - browse tabs

* Fixing setup.py

* arrayqueues dep fix

* disabled GUI testing

* Testing only python 3.8

* fixed tests

* Not testing on windows because of vispy/OpenGL problems with pytest-qt

* Update main.yml

* Update main.yml

* Full exp test running now

* comments added

* removed unnecessary print, minor refactoring in streaming_save.py while debugging
  • Loading branch information
vigji authored Feb 18, 2021
1 parent 25f98ee commit 697a3d5
Show file tree
Hide file tree
Showing 12 changed files with 119 additions and 119 deletions.
9 changes: 2 additions & 7 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,8 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: [3.7, 3.8.6]
exclude:
- os: macos-latest
python-version: 3.7
- os: windows-latest
python-version: 3.7
os: [macos-latest]
python-version: [3.8.6]
steps:
- uses: actions/checkout@v2
- name: Set up Python
Expand Down
56 changes: 0 additions & 56 deletions .travis.yml

This file was deleted.

28 changes: 0 additions & 28 deletions noxfile.py

This file was deleted.

4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
arrayqueues==1.2.0b0
flammkuchen==0.9
arrayqueues==1.3.1
split_dataset
lightparam>=0.4, <0.5
pyqt5>=5.15
pyzmq
Expand Down
9 changes: 9 additions & 0 deletions requirements_dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
pytest-cov
pytest-qt
pytest
gitpython
coverage
pre-commit
black
flake8
isort
4 changes: 2 additions & 2 deletions sashimi/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@
},
"camera": {
"id": 0,
"name": "hamamatsu",
"name": "mock",
"max_sensor_resolution": [2048, 2048],
"default_exposure": 60,
"default_binning": 1,
},
"light_source": {"name": "cobolt", "port": "COM4", "intensity_units": "mA"},
"light_source": {"name": "mock", "port": "COM4", "intensity_units": "mock"},
"external_communication": {"name": "stytra", "address": "tcp://O1-589:5555"},
"notifier": "none",
"notifier_options": {},
Expand Down
2 changes: 1 addition & 1 deletion sashimi/hardware/cameras/hamamatsu/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ def get_camera_properties(self):
"dcamprop_getname",
)

if properties == {'': 0}:
if properties == {"": 0}:
raise ConnectionError("The Hamamatsu camera seems to be off!")

return properties
30 changes: 18 additions & 12 deletions sashimi/processes/streaming_save.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from sashimi.config import read_config
from sashimi.processes.logging import LoggingProcess
from sashimi.events import LoggedEvent, SashimiEvents
from sashimi.utilities import get_last_parameters

conf = read_config()

Expand Down Expand Up @@ -130,7 +131,8 @@ def fill_dataset(self, volume):
if self.current_data is None:
self.calculate_optimal_size(volume)
self.current_data = np.empty(
(self.save_parameters.chunk_size, *volume.shape), dtype=self.dtype,
(self.save_parameters.chunk_size, *volume.shape),
dtype=self.dtype,
)

self.current_data[self.i_in_chunk, :, :, :] = volume
Expand Down Expand Up @@ -165,7 +167,10 @@ def finalize_dataset(self):
) as f:
json.dump(
{
"shape_full": (self.n_volumes, *self.current_data.shape[1:],),
"shape_full": (
self.n_volumes,
*self.current_data.shape[1:],
),
"shape_block": (
self.save_parameters.chunk_size,
*self.current_data.shape[1:],
Expand Down Expand Up @@ -201,16 +206,17 @@ def calculate_optimal_size(self, volume):
)

def receive_save_parameters(self):
try:
self.save_parameters = self.saving_parameter_queue.get(timeout=0.001)
except Empty:
pass
try:
new_duration = self.duration_queue.get(timeout=0.001)
print(new_duration)
"""Receive parameters on the stack shape from the `State` obj and new duration
from either the `EsternalTrigger` or the `State` if triggering is disabled.
"""
# Get parameters:
parameters = get_last_parameters(self.saving_parameter_queue)
if parameters is not None:
self.save_parameters = parameters

# Get duration and update number of volumes:
new_duration = get_last_parameters(self.duration_queue)
if new_duration is not None:
self.n_volumes = int(
np.ceil(self.save_parameters.volumerate * new_duration)
)
print(self.n_volumes)
except Empty:
pass
29 changes: 20 additions & 9 deletions sashimi/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class TriggerSettings(ParametrizedQt):
def __init__(self):
super().__init__(self)
self.name = "trigger_settings"
self.experiment_duration = Param(2_000, (1, 10_000), unit="s")
self.experiment_duration = Param(5, (1, 50_000), unit="s")
self.is_triggered = Param(True, [True, False], gui=False)


Expand All @@ -71,7 +71,8 @@ def __init__(self):
super().__init__()
self.name = "general/scanning_state"
self.scanning_state = Param(
"Paused", ["Paused", "Calibration", "Planar", "Volume"],
"Paused",
["Paused", "Calibration", "Planar", "Volume"],
)


Expand Down Expand Up @@ -183,7 +184,11 @@ def __init__(self):

def add_calibration_point(self):
self.calibrations_points.append(
(self.z_settings.piezo, self.z_settings.lateral, self.z_settings.frontal,)
(
self.z_settings.piezo,
self.z_settings.lateral,
self.z_settings.frontal,
)
)
self.calculate_calibration()

Expand Down Expand Up @@ -219,7 +224,8 @@ def calculate_calibration(self):


def get_voxel_size(
scanning_settings: ZRecordingSettings, camera_settings: CameraSettings,
scanning_settings: ZRecordingSettings,
camera_settings: CameraSettings,
):
scan_length = (
scanning_settings.piezo_scan_range[1] - scanning_settings.piezo_scan_range[0]
Expand Down Expand Up @@ -522,7 +528,9 @@ def send_scansave_settings(self):

elif self.global_state == GlobalState.PLANAR_PREVIEW:
params = convert_single_plane_params(
self.planar_setting, self.single_plane_settings, self.calibration,
self.planar_setting,
self.single_plane_settings,
self.calibration,
)

elif self.global_state == GlobalState.VOLUME_PREVIEW:
Expand Down Expand Up @@ -644,10 +652,13 @@ def get_waveform(self):
return None

def calculate_pulse_times(self):
return np.arange(
self.volume_setting.n_skip_start,
self.volume_setting.n_planes - self.volume_setting.n_skip_end,
) / (self.volume_setting.frequency * self.volume_setting.n_planes)
return (
np.arange(
self.volume_setting.n_skip_start,
self.volume_setting.n_planes - self.volume_setting.n_skip_end,
)
/ (self.volume_setting.frequency * self.volume_setting.n_planes)
)

def set_trigger_mode(self, mode: bool):
if mode:
Expand Down
13 changes: 11 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,32 @@
with open("requirements.txt") as f:
requirements = f.read().splitlines()

with open("requirements_dev.txt") as f:
requirements_dev = f.read().splitlines()

with open("README.md") as f:
long_description = f.read()

setup(
name="sashimi",
version="0.2.0",
author="Vilim Stih @portugueslab",
author_email="[email protected]",
packages=find_packages(),
install_requires=requirements,
python_requires=">=3.7",
extras_require=dict(dev=requirements_dev),
python_requires=">=3.8",
classifiers=[
"Development Status :: 2 - Pre-Alpha",
"Intended Audience :: Science/Research",
"Natural Language :: English",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
],
keywords="imaging microscopy lightsheet",
description="A user-friendly software for efficient control of digital scanned light sheet microscopes (DSLMs).",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/portugueslab/sashimi",
entry_points={
"console_scripts": [
"sashimi=sashimi.main:main",
Expand Down
12 changes: 12 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import pytest
from pathlib import Path
import tempfile
import shutil


@pytest.fixture()
def temp_path():
"""Temporary path cleaned after the tests run."""
path = Path(tempfile.mkdtemp())
yield path
shutil.rmtree(path)
42 changes: 42 additions & 0 deletions tests/test_gui.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from sashimi.gui.main_gui import MainWindow
from sashimi.state import State, TriggerSettings
import qdarkstyle
from PyQt5.QtCore import Qt
from split_dataset import SplitDataset


class MockEvt:
def accept(self):
pass


def test_main(qtbot, temp_path):
st = State()
style = qdarkstyle.load_stylesheet_pyqt5()
main_window = MainWindow(st, style)
main_window.show()
qtbot.wait(300)

# go to calibration and volumetric mode:
main_window.wid_status.setCurrentIndex(1)
qtbot.wait(300)
main_window.wid_status.setCurrentIndex(3)

# Manually update new directory (to avoid nasty pop up window for filesystem):
st.save_settings.save_dir = str(temp_path)
main_window.wid_save_options.set_locationbutton()
st.send_scansave_settings()

# Wait to send and receive parameters:
qtbot.wait(10000)

qtbot.mouseClick(main_window.toolbar.experiment_toggle_btn, Qt.LeftButton, delay=1)

# wait end of the experiment:
qtbot.wait(TriggerSettings().experiment_duration + 5000)

# try opening the result:
SplitDataset(temp_path / "original")

main_window.closeEvent(MockEvt())
qtbot.wait(1000)

0 comments on commit 697a3d5

Please sign in to comment.