feat: init
This commit is contained in:
426
test/config/test_configuration.py
Normal file
426
test/config/test_configuration.py
Normal file
@@ -0,0 +1,426 @@
|
||||
# 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.
|
||||
#
|
||||
|
||||
# Standard Imports
|
||||
import unittest
|
||||
import yaml
|
||||
import os
|
||||
|
||||
# Third Party Imports
|
||||
|
||||
# Local Imports
|
||||
|
||||
|
||||
class TestConfiguration(unittest.TestCase):
|
||||
def setUp(self):
|
||||
current_path = os.path.abspath(os.path.dirname(__file__))
|
||||
root_path = os.path.dirname(os.path.dirname(current_path))
|
||||
yaml_path = os.path.join(
|
||||
root_path, "src", "navigate", "config", "configuration.yaml"
|
||||
)
|
||||
|
||||
with open(yaml_path) as file:
|
||||
self.data = yaml.safe_load(file)
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
# # hardware head section has been removed
|
||||
# def test_hardware_section(self):
|
||||
# expected_hardware = ["daq", "camera", "filter_wheel", "stage", "zoom"]
|
||||
|
||||
# hardware_types = self.data["hardware"].keys()
|
||||
# for hardware_type in hardware_types:
|
||||
# self.assertIn(hardware_type, expected_hardware)
|
||||
# if isinstance(self.data["hardware"][hardware_type], dict):
|
||||
# hardware_keys = self.data["hardware"][hardware_type].keys()
|
||||
# for key in hardware_keys:
|
||||
# self.assertIn("type", self.data["hardware"][hardware_type])
|
||||
# elif isinstance(self.data["hardware"][hardware_type], list):
|
||||
# for i in range(len(self.data["hardware"][hardware_type])):
|
||||
# self.assertIn("type", self.data["hardware"][hardware_type][i])
|
||||
|
||||
def test_gui_section(self):
|
||||
expected_keys = ["channels"]
|
||||
expected_channel_keys = [
|
||||
"count",
|
||||
# "laser_power",
|
||||
# "exposure_time",
|
||||
# "interval_time",
|
||||
]
|
||||
expected_stack_keys = ["step_size", "start_pos", "end_pos"]
|
||||
min_max_step_keys = ["min", "max", "step"]
|
||||
|
||||
gui_keys = self.data["gui"].keys()
|
||||
for key in gui_keys:
|
||||
self.assertIn(key, expected_keys)
|
||||
|
||||
# Channels Entry
|
||||
if key == "channels":
|
||||
channel_keys = self.data["gui"][key].keys()
|
||||
for channel_key in channel_keys:
|
||||
self.assertIn(channel_key, expected_channel_keys)
|
||||
if channel_key != "count":
|
||||
channel_key_keys = self.data["gui"][key][channel_key].keys()
|
||||
for channel_key_key in channel_key_keys:
|
||||
self.assertIn(channel_key_key, min_max_step_keys)
|
||||
|
||||
# Stack Acquisition Entry
|
||||
elif key == "stack_acquisition":
|
||||
stack_keys = self.data["gui"][key].keys()
|
||||
for stack_key in stack_keys:
|
||||
self.assertIn(stack_key, expected_stack_keys)
|
||||
stack_key_keys = self.data["gui"][key][stack_key].keys()
|
||||
for stack_key_key in stack_key_keys:
|
||||
self.assertIn(stack_key_key, min_max_step_keys)
|
||||
|
||||
# Timepoint Entry
|
||||
elif key == "timepoint":
|
||||
timepoint_keys = self.data["gui"][key].keys()
|
||||
for timepoint_key in timepoint_keys:
|
||||
timepoint_key_keys = self.data["gui"][key][timepoint_key].keys()
|
||||
for timepoint_key_key in timepoint_key_keys:
|
||||
self.assertIn(timepoint_key_key, min_max_step_keys)
|
||||
|
||||
else:
|
||||
raise ValueError("Unexpected key in gui section")
|
||||
|
||||
def test_microscope_section(self):
|
||||
expected_hardware = [
|
||||
"daq",
|
||||
"camera",
|
||||
"remote_focus",
|
||||
"galvo",
|
||||
"shutter",
|
||||
"laser",
|
||||
"filter_wheel",
|
||||
"stage",
|
||||
"zoom",
|
||||
]
|
||||
|
||||
microscopes = self.data["microscopes"].keys()
|
||||
for microscope in microscopes:
|
||||
hardware = self.data["microscopes"][microscope].keys()
|
||||
for hardware_type in hardware:
|
||||
self.assertIn(hardware_type, expected_hardware)
|
||||
|
||||
if hardware_type == "daq":
|
||||
self.daq_section(microscope=microscope, hardware_type=hardware_type)
|
||||
|
||||
elif hardware_type == "camera":
|
||||
self.camera_section(
|
||||
microscope=microscope, hardware_type=hardware_type
|
||||
)
|
||||
|
||||
elif hardware_type == "remote_focus":
|
||||
self.remote_focus_section(
|
||||
microscope=microscope, hardware_type=hardware_type
|
||||
)
|
||||
|
||||
elif hardware_type == "galvo":
|
||||
self.galvo_section(
|
||||
microscope=microscope, hardware_type=hardware_type
|
||||
)
|
||||
|
||||
elif hardware_type == "filter_wheel":
|
||||
self.filter_wheel_section(
|
||||
microscope=microscope, hardware_type=hardware_type
|
||||
)
|
||||
elif hardware_type == "stage":
|
||||
self.stage_section(
|
||||
microscope=microscope, hardware_type=hardware_type
|
||||
)
|
||||
|
||||
elif hardware_type == "zoom":
|
||||
self.zoom_section(
|
||||
microscope=microscope, hardware_type=hardware_type
|
||||
)
|
||||
|
||||
elif hardware_type == "shutter":
|
||||
self.shutter_section(
|
||||
microscope=microscope, hardware_type=hardware_type
|
||||
)
|
||||
|
||||
elif hardware_type == "laser":
|
||||
self.laser_section(
|
||||
microscope=microscope, hardware_type=hardware_type
|
||||
)
|
||||
|
||||
else:
|
||||
raise ValueError("Unexpected hardware type")
|
||||
|
||||
def daq_section(self, microscope, hardware_type):
|
||||
expected_daq_keys = [
|
||||
"hardware",
|
||||
"sample_rate",
|
||||
"sweep_time",
|
||||
"master_trigger_out_line",
|
||||
"camera_trigger_out_line",
|
||||
"trigger_source",
|
||||
"laser_port_switcher",
|
||||
"laser_switch_state",
|
||||
]
|
||||
type_keys = ["type"]
|
||||
|
||||
daq_keys = self.data["microscopes"][microscope][hardware_type].keys()
|
||||
for key in daq_keys:
|
||||
if key == "hardware":
|
||||
for type_key in type_keys:
|
||||
self.assertIn(
|
||||
type_key,
|
||||
self.data["microscopes"][microscope][hardware_type][key],
|
||||
)
|
||||
else:
|
||||
self.assertIn(key, expected_daq_keys)
|
||||
|
||||
def camera_section(self, microscope, hardware_type):
|
||||
expected_keys = [
|
||||
"hardware",
|
||||
"defect_correct_mode",
|
||||
"delay",
|
||||
"settle_down",
|
||||
"flip_x",
|
||||
"flip_y",
|
||||
]
|
||||
type_keys = ["type", "serial_number", "camera_connection"]
|
||||
|
||||
camera_keys = self.data["microscopes"][microscope][hardware_type].keys()
|
||||
for key in camera_keys:
|
||||
if key == "hardware":
|
||||
for type_key in type_keys:
|
||||
self.assertIn(
|
||||
type_key,
|
||||
self.data["microscopes"][microscope][hardware_type][key],
|
||||
)
|
||||
else:
|
||||
self.assertIn(key, expected_keys)
|
||||
|
||||
def remote_focus_section(self, microscope, hardware_type):
|
||||
expected_keys = [
|
||||
"hardware",
|
||||
]
|
||||
type_keys = ["type", "channel", "min", "max", "port", "baudrate"]
|
||||
remote_focus_keys = self.data["microscopes"][microscope][hardware_type].keys()
|
||||
for key in remote_focus_keys:
|
||||
if key == "hardware":
|
||||
for type_key in type_keys:
|
||||
self.assertIn(
|
||||
type_key,
|
||||
self.data["microscopes"][microscope][hardware_type][key],
|
||||
)
|
||||
else:
|
||||
self.assertIn(key, expected_keys)
|
||||
|
||||
def galvo_section(self, microscope, hardware_type):
|
||||
expected_keys = [
|
||||
"hardware",
|
||||
"waveform",
|
||||
"phase",
|
||||
]
|
||||
type_keys = ["type", "channel", "min", "max"]
|
||||
|
||||
if isinstance(self.data["microscopes"][microscope][hardware_type], list):
|
||||
for i in range(len(self.data["microscopes"][microscope][hardware_type])):
|
||||
galvo_keys = self.data["microscopes"][microscope][hardware_type][
|
||||
i
|
||||
].keys()
|
||||
for key in galvo_keys:
|
||||
if key == "hardware":
|
||||
for type_key in type_keys:
|
||||
self.assertIn(
|
||||
type_key,
|
||||
self.data["microscopes"][microscope][hardware_type][i][
|
||||
key
|
||||
],
|
||||
)
|
||||
else:
|
||||
self.assertIn(key, expected_keys)
|
||||
else:
|
||||
raise ValueError("Galvo section is not a list")
|
||||
|
||||
def filter_wheel_section(self, microscope, hardware_type):
|
||||
expected_keys = [
|
||||
"hardware",
|
||||
"filter_wheel_delay",
|
||||
"available_filters",
|
||||
]
|
||||
type_keys = ["type", "wheel_number", "port", "baudrate"]
|
||||
|
||||
keys = self.data["microscopes"][microscope][hardware_type].keys()
|
||||
for key in keys:
|
||||
if key == "hardware":
|
||||
for type_key in type_keys:
|
||||
self.assertIn(
|
||||
type_key,
|
||||
self.data["microscopes"][microscope][hardware_type][key],
|
||||
)
|
||||
elif key == "available_filters":
|
||||
assert isinstance(
|
||||
self.data["microscopes"][microscope][hardware_type][key], dict
|
||||
)
|
||||
else:
|
||||
self.assertIn(key, expected_keys)
|
||||
|
||||
def stage_section(self, microscope, hardware_type):
|
||||
expected_keys = [
|
||||
"hardware",
|
||||
"x_max",
|
||||
"x_min",
|
||||
"y_max",
|
||||
"y_min",
|
||||
"z_max",
|
||||
"z_min",
|
||||
"f_max",
|
||||
"f_min",
|
||||
"theta_max",
|
||||
"theta_min",
|
||||
"x_offset",
|
||||
"y_offset",
|
||||
"z_offset",
|
||||
"theta_offset",
|
||||
"f_offset",
|
||||
"joystick_axes",
|
||||
"flip_x",
|
||||
"flip_y",
|
||||
"flip_z",
|
||||
"flip_f",
|
||||
]
|
||||
type_keys = [
|
||||
"type",
|
||||
"serial_number",
|
||||
"axes",
|
||||
"volts_per_micron",
|
||||
"axes_mapping",
|
||||
"max",
|
||||
"min",
|
||||
"controllername",
|
||||
"stages",
|
||||
"refmode",
|
||||
"port",
|
||||
"baudrate",
|
||||
"timeout",
|
||||
]
|
||||
|
||||
for key in self.data["microscopes"][microscope][hardware_type].keys():
|
||||
if key == "hardware":
|
||||
if isinstance(
|
||||
self.data["microscopes"][microscope][hardware_type][key], list
|
||||
):
|
||||
for i in range(
|
||||
len(self.data["microscopes"][microscope][hardware_type][key])
|
||||
):
|
||||
for type_key in type_keys:
|
||||
self.assertIn(
|
||||
type_key,
|
||||
self.data["microscopes"][microscope][hardware_type][
|
||||
key
|
||||
][i],
|
||||
)
|
||||
elif isinstance(
|
||||
self.data["microscopes"][microscope][hardware_type][key], dict
|
||||
):
|
||||
for type_key in type_keys:
|
||||
self.assertIn(
|
||||
type_key,
|
||||
self.data["microscopes"][microscope][hardware_type][key],
|
||||
)
|
||||
else:
|
||||
raise ValueError("Stage hardware is not a list or dict")
|
||||
else:
|
||||
self.assertIn(key, expected_keys)
|
||||
|
||||
def zoom_section(self, microscope, hardware_type):
|
||||
expected_keys = ["hardware", "position", "pixel_size", "stage_positions"]
|
||||
type_keys = ["type", "servo_id", "port", "baudrate"]
|
||||
|
||||
for key in self.data["microscopes"][microscope][hardware_type].keys():
|
||||
if key == "hardware":
|
||||
for type_key in type_keys:
|
||||
self.assertIn(
|
||||
type_key,
|
||||
self.data["microscopes"][microscope][hardware_type][key],
|
||||
)
|
||||
elif key == "position":
|
||||
assert isinstance(
|
||||
self.data["microscopes"][microscope][hardware_type][key], dict
|
||||
)
|
||||
elif key == "pixel_size":
|
||||
assert isinstance(
|
||||
self.data["microscopes"][microscope][hardware_type][key], dict
|
||||
)
|
||||
elif key == "stage_positions":
|
||||
assert isinstance(
|
||||
self.data["microscopes"][microscope][hardware_type][key], dict
|
||||
)
|
||||
else:
|
||||
self.assertIn(key, expected_keys)
|
||||
|
||||
def shutter_section(self, microscope, hardware_type):
|
||||
expected_keys = ["hardware"]
|
||||
type_keys = ["type", "channel", "min", "max"]
|
||||
|
||||
for key in self.data["microscopes"][microscope][hardware_type].keys():
|
||||
if key == "hardware":
|
||||
for type_key in type_keys:
|
||||
self.assertIn(
|
||||
type_key,
|
||||
self.data["microscopes"][microscope][hardware_type][key],
|
||||
)
|
||||
else:
|
||||
self.assertIn(key, expected_keys)
|
||||
|
||||
def laser_section(self, microscope, hardware_type):
|
||||
expected_keys = [
|
||||
"wavelength",
|
||||
"onoff",
|
||||
"power",
|
||||
"type",
|
||||
]
|
||||
|
||||
hardware_keys = ["type", "channel", "min", "max"]
|
||||
|
||||
if isinstance(self.data["microscopes"][microscope][hardware_type], list):
|
||||
for i in range(len(self.data["microscopes"][microscope][hardware_type])):
|
||||
laser_keys = self.data["microscopes"][microscope][hardware_type][
|
||||
i
|
||||
].keys()
|
||||
for key in laser_keys:
|
||||
if key == "onoff" or key == "power":
|
||||
onoff_keys = self.data["microscopes"][microscope][
|
||||
hardware_type
|
||||
][i][key]["hardware"].keys()
|
||||
for onoff_key in onoff_keys:
|
||||
self.assertIn(onoff_key, hardware_keys)
|
||||
else:
|
||||
self.assertIn(key, expected_keys)
|
||||
else:
|
||||
raise ValueError("Laser section is not a list")
|
||||
Reference in New Issue
Block a user