feat: init
This commit is contained in:
193
test/model/devices/camera/test_camera_synthetic.py
Normal file
193
test/model/devices/camera/test_camera_synthetic.py
Normal file
@@ -0,0 +1,193 @@
|
||||
# Copyright (c) 2021-2025 The University of Texas Southwestern Medical Center.
|
||||
# All rights reserved.
|
||||
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted for academic and research use only (subject to the
|
||||
# limitations in the disclaimer below) provided that the following conditions are met:
|
||||
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
|
||||
# * Neither the name of the copyright holders nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from this
|
||||
# software without specific prior written permission.
|
||||
|
||||
# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
|
||||
# THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
# Third Party Imports
|
||||
import pytest
|
||||
import numpy as np
|
||||
|
||||
from navigate.model.devices.camera.synthetic import (
|
||||
SyntheticCamera,
|
||||
SyntheticCameraController,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
def synthetic_camera(dummy_model):
|
||||
dummy_model = dummy_model
|
||||
scc = SyntheticCameraController()
|
||||
microscope_name = dummy_model.configuration["experiment"]["MicroscopeState"][
|
||||
"microscope_name"
|
||||
]
|
||||
synthetic_camera = SyntheticCamera(microscope_name, scc, dummy_model.configuration)
|
||||
return synthetic_camera
|
||||
|
||||
|
||||
class TestSyntheticCamera:
|
||||
"""Unit Test for Camera Synthetic Class"""
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _prepare_camera(self, synthetic_camera):
|
||||
self.synthetic_camera = synthetic_camera
|
||||
|
||||
def test_synthetic_camera_attributes(self):
|
||||
desired_attributes = [
|
||||
"x_pixels",
|
||||
"y_pixels",
|
||||
"is_acquiring",
|
||||
"_mean_background_count",
|
||||
"_noise_sigma",
|
||||
"camera_controller",
|
||||
"current_frame_idx",
|
||||
"data_buffer",
|
||||
"num_of_frame",
|
||||
"pre_frame_idx",
|
||||
]
|
||||
for da in desired_attributes:
|
||||
assert hasattr(self.synthetic_camera, da)
|
||||
|
||||
def test_synthetic_camera_wheel_attributes_type(self):
|
||||
desired_attributes = {
|
||||
"x_pixels": int,
|
||||
"y_pixels": int,
|
||||
"is_acquiring": bool,
|
||||
"_mean_background_count": int,
|
||||
"_noise_sigma": np.float64,
|
||||
# 'current_frame_idx': None,
|
||||
# 'data_buffer': None,
|
||||
# 'num_of_frame': None,
|
||||
# 'pre_frame_idx': None,
|
||||
}
|
||||
|
||||
for key in desired_attributes:
|
||||
attribute = getattr(self.synthetic_camera, key)
|
||||
print(key, type(attribute), desired_attributes[key])
|
||||
assert type(attribute) == desired_attributes[key]
|
||||
|
||||
def test_synthetic_camera_methods(self):
|
||||
methods = [
|
||||
"report_settings",
|
||||
"close_camera",
|
||||
"set_sensor_mode",
|
||||
"set_exposure_time",
|
||||
"set_line_interval",
|
||||
"set_binning",
|
||||
"initialize_image_series",
|
||||
"close_image_series",
|
||||
"generate_new_frame",
|
||||
"get_new_frame",
|
||||
"set_ROI",
|
||||
]
|
||||
|
||||
for m in methods:
|
||||
assert hasattr(self.synthetic_camera, m) and callable(
|
||||
getattr(self.synthetic_camera, m)
|
||||
)
|
||||
|
||||
def test_synthetic_camera_wheel_method_calls(self):
|
||||
self.synthetic_camera.report_settings()
|
||||
self.synthetic_camera.close_camera()
|
||||
self.synthetic_camera.set_sensor_mode(mode="test")
|
||||
self.synthetic_camera.set_exposure_time(exposure_time=0.2)
|
||||
self.synthetic_camera.set_line_interval(line_interval_time=1)
|
||||
self.synthetic_camera.set_binning(binning_string="2x2")
|
||||
self.synthetic_camera.initialize_image_series()
|
||||
self.synthetic_camera.close_image_series()
|
||||
self.synthetic_camera.get_new_frame()
|
||||
self.synthetic_camera.set_ROI()
|
||||
|
||||
def test_synthetic_camera_exposure(self):
|
||||
exposure_time = 200
|
||||
self.synthetic_camera.set_exposure_time(exposure_time=exposure_time / 1000)
|
||||
assert (exposure_time / 1000) == self.synthetic_camera.camera_exposure_time
|
||||
|
||||
def test_synthetic_camera_binning(self):
|
||||
x_pixels = self.synthetic_camera.x_pixels
|
||||
self.synthetic_camera.set_binning(binning_string="2x2")
|
||||
assert self.synthetic_camera.x_binning == 2
|
||||
assert self.synthetic_camera.y_binning == 2
|
||||
assert type(self.synthetic_camera.x_binning) == int
|
||||
assert type(self.synthetic_camera.y_binning) == int
|
||||
assert self.synthetic_camera.x_pixels == x_pixels / 2
|
||||
|
||||
def test_synthetic_camera_initialize_image_series(self):
|
||||
self.synthetic_camera.initialize_image_series()
|
||||
assert self.synthetic_camera.num_of_frame == 100
|
||||
assert self.synthetic_camera.data_buffer is None
|
||||
assert self.synthetic_camera.current_frame_idx == 0
|
||||
assert self.synthetic_camera.pre_frame_idx == 0
|
||||
assert self.synthetic_camera.is_acquiring is True
|
||||
|
||||
def test_synthetic_camera_close_image_series(self):
|
||||
self.synthetic_camera.close_image_series()
|
||||
assert self.synthetic_camera.pre_frame_idx == 0
|
||||
assert self.synthetic_camera.current_frame_idx == 0
|
||||
assert self.synthetic_camera.is_acquiring is False
|
||||
|
||||
def test_synthetic_camera_acquire_images(self):
|
||||
import random
|
||||
from navigate.model.concurrency.concurrency_tools import SharedNDArray
|
||||
|
||||
number_of_frames = 100
|
||||
data_buffer = [
|
||||
SharedNDArray(shape=(2048, 2048), dtype="uint16")
|
||||
for i in range(number_of_frames)
|
||||
]
|
||||
|
||||
self.synthetic_camera.initialize_image_series(data_buffer, number_of_frames)
|
||||
|
||||
assert self.synthetic_camera.is_acquiring is True, "should be acquring"
|
||||
|
||||
frame_idx = 0
|
||||
|
||||
for i in range(10):
|
||||
frame_num = random.randint(1, 30)
|
||||
for j in range(frame_num):
|
||||
self.synthetic_camera.generate_new_frame()
|
||||
frames = self.synthetic_camera.get_new_frame()
|
||||
|
||||
assert len(frames) == frame_num, "frame number isn't right!"
|
||||
assert frames[0] == frame_idx, "frame idx isn't right!"
|
||||
|
||||
frame_idx = (frame_idx + frame_num) % number_of_frames
|
||||
|
||||
self.synthetic_camera.close_image_series()
|
||||
assert (
|
||||
self.synthetic_camera.is_acquiring is False
|
||||
), "is_acquiring should be False"
|
||||
|
||||
def test_synthetic_camera_set_roi(self):
|
||||
self.synthetic_camera.set_ROI()
|
||||
assert self.synthetic_camera.x_pixels == 2048
|
||||
assert self.synthetic_camera.y_pixels == 2048
|
||||
self.synthetic_camera.set_ROI(roi_height=500, roi_width=700)
|
||||
assert self.synthetic_camera.x_pixels == 700
|
||||
assert self.synthetic_camera.y_pixels == 500
|
||||
Reference in New Issue
Block a user