Skip to content

Commit

Permalink
Merge pull request #900 from annie-xd-wang/fix-multiposition-table-error
Browse files Browse the repository at this point in the history
  • Loading branch information
AdvancedImagingUTSW authored May 24, 2024
2 parents 4fac2fb + 586c903 commit 5a912c1
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 18 deletions.
1 change: 0 additions & 1 deletion docs/source/user_guide/setup_microscope.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ Setting Up A Microscope
:maxdepth: 2

software_configuration
hardware/hardware_home
multiple_cameras
2 changes: 1 addition & 1 deletion src/navigate/controller/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -1213,7 +1213,7 @@ def update_event(self):
elif event == "multiposition":
# Update the multi-position tab without appending to the list
update_table(
table=self.view.settings.multiposition_tab.multipoint_list.get_table(),
table=self.multiposition_tab_controller.table,
pos=value,
)
self.channels_tab_controller.is_multiposition_val.set(True)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@ def set_mode(self, mode):
mode = list(reverse_dict.keys())[0]
self.mode = mode
self.view.pull_down.set(reverse_dict[mode])
self.parent_controller.configuration["experiment"]["MicroscopeState"][
"image_mode"
] = mode
self.show_verbose_info("Image mode is set to", mode)

def get_mode(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -455,8 +455,8 @@ def mark_position(self):
stage_flip_flags = (
self.parent_controller.configuration_controller.stage_flip_flags
)
stage_position["x"] += offset_x * (-1 if stage_flip_flags["x"] else 1)
stage_position["y"] -= offset_y * (-1 if stage_flip_flags["y"] else 1)
stage_position["x"] = float(stage_position["x"]) + offset_x * (-1 if stage_flip_flags["x"] else 1)
stage_position["y"] = float(stage_position["y"]) - offset_y * (-1 if stage_flip_flags["y"] else 1)

# Place the stage position in the multi-position table.
self.parent_controller.execute("mark_position", stage_position)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def get_positions(self):
temp = list(self.table.model.df.iloc[i])
if (
len(
list(filter(lambda v: type(v) == float and not math.isnan(v), temp))
list(filter(lambda v: type(v) in (float, int) and not math.isnan(v), temp))
)
== 5
):
Expand Down Expand Up @@ -211,12 +211,10 @@ def load_positions(self):
)
logger.info("The csv file isn't right, it should contain [X, Y, Z, R, F]")
return
model = TableModel(dataframe=df)
self.table.updateModel(model)
try:
self.table.redraw()
except KeyError:
pass
self.table.model.df = df
self.table.update_rowcolors()
self.table.redraw()
self.table.tableChanged()
self.show_verbose_info("loaded csv file", filename)

def export_positions(self):
Expand Down
5 changes: 4 additions & 1 deletion src/navigate/controller/sub_controllers/stage_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ def get_position(self):
position = {}
try:
for axis in ["x", "y", "z", "theta", "f"]:
position[axis] = self.widget_vals[axis].get()
position[axis] = float(self.widget_vals[axis].get())
if self.stage_limits is True:
if (
position[axis] < self.position_min[axis]
Expand Down Expand Up @@ -554,6 +554,9 @@ def position_callback(self, axis, *args, **kwargs):

def handler(*args):
"""Callback functions bind to position variables."""
# check if focus on another window
if not self.view.focus_get():
return
if self.event_id[axis]:
self.view.after_cancel(self.event_id[axis])
# if position is not a number, then do not move stage
Expand Down
3 changes: 1 addition & 2 deletions src/navigate/model/devices/stages/stage_pi.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,6 @@ def move_absolute(self, move_dictionary, wait_until_done=False):

if wait_until_done is True:
return self.wait_on_target(axes=list(pos_dict.keys()))

return True

def stop(self):
Expand All @@ -274,7 +273,7 @@ def wait_on_target(self, axes=None):
"""
try:
self.pi_tools.waitontarget(
self.pi_device, axes=axes, timeout=1.75, polldelay=0.01
self.pi_device, axes=axes, timeout=10.75, polldelay=0.01
)
except GCSError as e:
print("Wait on target failed")
Expand Down
2 changes: 2 additions & 0 deletions src/navigate/model/microscope.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,8 @@ def move_stage_offset(self, former_microscope=None):
# print(self.stages)
pos_dict = self.get_stage_position()
for stage, axes in self.stages_list:

# x_abs: current x_pos + current_x_offset - former_x_offset
pos = {
axis
+ "_abs": (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@ def test_get_set_mode(self, mode):
self.acquire_bar_controller.set_mode(mode)
test = self.acquire_bar_controller.get_mode()
assert test == mode, "Mode not set correctly"
# assert imaging mode is updated in the experiment
assert self.acquire_bar_controller.parent_controller.configuration[
"experiment"]["MicroscopeState"]["image_mode"] == mode

def test_set_save(self):
"""Tests the set_save method of the AcquireBarController class
Expand Down Expand Up @@ -298,7 +301,7 @@ def test_update_microscope_mode(self, user_mode, expected_mode):
the AcquireBarController class is not correct
"""
# Assuming mode starts on live
assert self.acquire_bar_controller.mode == "live"
self.acquire_bar_controller.mode = "live"

# Setting to mode specified by user
self.acquire_bar_controller.view.pull_down.set(user_mode)
Expand All @@ -310,6 +313,8 @@ def test_update_microscope_mode(self, user_mode, expected_mode):

# Checking that new mode gets set by function
assert self.acquire_bar_controller.mode == expected_mode
assert self.acquire_bar_controller.parent_controller.configuration[
"experiment"]["MicroscopeState"]["image_mode"] == expected_mode

# Resetting to live
self.acquire_bar_controller.view.pull_down.set("Continuous Scan")
Expand Down
94 changes: 91 additions & 3 deletions test/controller/test_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ def controller(tk_root):
)
# To make sure the testcases won't hang on because of the model.event_queue
# The changes here won't affect other testcases,
# because the testcases from other files use DummyController and DummyModel instead of this controller fixture
# because the testcases from other files use DummyController
# and DummyModel instead of this controller fixture
controller.model = MagicMock()
controller.model.get_offset_variance_maps.return_value = (None, None)

Expand All @@ -69,18 +70,98 @@ def test_update_buffer(controller):
assert controller.img_width == camera_parameters["img_x_pixels"]
assert controller.img_height == camera_parameters["img_y_pixels"]

# Make sure that the get_data_buffer method is not called.
assert controller.model.get_data_buffer.called is False

# Change the buffer size
controller.configuration["experiment"]["CameraParameters"]["img_x_pixels"] = 100
controller.configuration["experiment"]["CameraParameters"]["img_y_pixels"] = 100
controller.update_buffer()

# Make sure that the get_data_buffer method is called.
assert controller.model.get_data_buffer.called is True

# Confirm that the buffer size has been updated.
assert controller.img_width == 100
assert controller.img_height == 100


def test_change_microscope(controller):
# Get the microscopes from the configuration file
microscopes = controller.configuration["configuration"]["microscopes"]

# Iterate through the microscopes and change the microscope
for microscope_name in microscopes.keys():

# Patch the configuration_controller
controller.configuration_controller.change_microscope = MagicMock()

# Default zoom is '0.63x'
zoom = microscopes[microscope_name]["zoom"]["position"].keys()[0]
controller.configuration["experiment"]["MicroscopeState"]["zoom"] = zoom

# Change the microscope without passing the zoom
controller.change_microscope(microscope_name)
assert (
controller.configuration["experiment"]["MicroscopeState"]["microscope_name"]
== microscope_name
)

# Confirm that the zoom has not changed.
assert controller.configuration["experiment"]["MicroscopeState"]["zoom"] == zoom

# Call it and pass the zoom
zoom = microscopes[microscope_name]["zoom"]["position"].keys()[-1]
controller.change_microscope(microscope_name, zoom)
assert controller.configuration["experiment"]["MicroscopeState"]["zoom"] == zoom

# Make sure that the configuration_controller has been called.
assert controller.configuration_controller.change_microscope.called is True

# Have configuration controller return False
controller.configuration_controller.change_microscope.return_value = False

# Patch the stage controller, channels_tab_controller...
controller.stage_controller.initialize = MagicMock()
controller.channels_tab_controller.initialize = MagicMock()
camera_setting_controller = controller.camera_setting_controller
camera_setting_controller.update_camera_device_related_setting = MagicMock()
camera_setting_controller.calculate_physical_dimensions = MagicMock()
controller.camera_view_controller.update_snr = MagicMock()

# Call change microscope, assert patched methods are not called
controller.change_microscope(microscope_name)
assert controller.stage_controller.initialize.called is False
assert controller.channels_tab_controller.initialize.called is False
assert (
camera_setting_controller.update_camera_device_related_setting.called
is False
)
assert camera_setting_controller.calculate_physical_dimensions.called is False
assert controller.camera_view_controller.update_snr.called is False

# Have configuration controller return True
controller.configuration_controller.change_microscope.return_value = True

# Call change microscope, assert patched methods are called
controller.change_microscope(microscope_name)
assert controller.stage_controller.initialize.called is True
assert controller.channels_tab_controller.initialize.called is True
assert (
camera_setting_controller.update_camera_device_related_setting.called
is True
)
assert camera_setting_controller.calculate_physical_dimensions.called is True
assert controller.camera_view_controller.update_snr.called is True

# Test waveform popup controller.
controller.waveform_popup_controller = MagicMock()
controller.change_microscope(microscope_name)
assert (
controller.waveform_popup_controller.populate_experiment_values.called
is True
)


def test_populate_experiment_setting(controller):
controller.populate_experiment_setting(in_initialize=False)
Expand All @@ -98,14 +179,21 @@ def test_execute(controller):


@pytest.mark.parametrize(
"acquisition_mode, sensor_mode, readout_direction, template_name, expected_template_name",
"acquisition_mode, sensor_mode, readout_direction, template_name, "
"expected_template_name",
[
("live", "Normal", "", "Bidirectional", "Default"),
("z-stack", "Normal", "", "Bidirectional", "Default"),
("customized", "Normal", "", "Bidirectional", "Bidirectional"),
("live", "Light-Sheet", "Top-To-Bottom", "Bidirectional", "Default"),
("live", "Light-Sheet", "Bidirectional", "Bidirectional", "Bidirectional"),
("customized", "Light-Sheet", "Bidirectional", "Bidirectional", "Bidirectional",),
(
"customized",
"Light-Sheet",
"Bidirectional",
"Bidirectional",
"Bidirectional",
),
("z-stack", "Light-Sheet", "Bidirectional", "Default", "Bidirectional"),
("z-stack", "Light-Sheet", "Top-To-Bottom", "Default", "Default"),
],
Expand Down

0 comments on commit 5a912c1

Please sign in to comment.