Skip to content

Commit

Permalink
Merge pull request #1030 from annie-xd-wang/speed-up-loading-multi-po…
Browse files Browse the repository at this point in the history
…sitions

Speed up loading multi-positions
  • Loading branch information
AdvancedImagingUTSW authored Nov 12, 2024
2 parents bdee78c + 7c2b613 commit b7412e9
Show file tree
Hide file tree
Showing 28 changed files with 240 additions and 129 deletions.
2 changes: 1 addition & 1 deletion docs/source/contributing/feature_container.rst
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ To create a customized feature list, follow these steps:
{"name": PrepareNextChannel},
{
"name": LoopByCount,
"args": ("experiment.MicroscopeState.selected_channels",),
"args": ("channels",),
},
)
]
Expand Down
2 changes: 1 addition & 1 deletion docs/source/user_guide/acquiring_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ a :doc:`feature list <features>`, shown in its
{"name": PrepareNextChannel},
{
"name": LoopByCount,
"args": ("experiment.MicroscopeState.selected_channels",),
"args": ("channels",),
},
)
]
Expand Down
2 changes: 1 addition & 1 deletion docs/source/user_guide/features/example_feature_lists.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ prior to moving to the next position in the multi-position table.
{"name": CalculateFocusRange,},
{"name": ZStackAcquisition,"args": (True,True,"z-stack",),},
{"name": WaitToContinue,},
{"name": LoopByCount,"args": ("experiment.MicroscopeState.multiposition_count",),},
{"name": LoopByCount,"args": ("positions",),},
),
]
Expand Down
43 changes: 16 additions & 27 deletions src/navigate/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ def get_configuration_paths():
"rest_api_config.yml",
"waveform_templates.yml",
"gui_configuration.yml",
"multi_positions.yml"
]

base_directory = Path(__file__).resolve().parent
Expand Down Expand Up @@ -520,8 +521,6 @@ def verify_experiment_config(manager, configuration):
"timepoint_interval": 0,
"experiment_duration": 1.03,
"is_multiposition": False,
"multiposition_count": 1,
"selected_channels": 0,
"stack_z_origin": 0,
"stack_focus_origin": 0,
"start_focus": 0.0,
Expand Down Expand Up @@ -654,31 +653,6 @@ def verify_experiment_config(manager, configuration):
if channel_value[k] < 0:
channel_value[k] = temp[k]

microscope_setting_dict["selected_channels"] = selected_channel_num

# MultiPositions
if (
"MultiPositions" not in configuration["experiment"]
or type(configuration["experiment"]["MultiPositions"]) is not ListProxy
):
update_config_dict(manager, configuration["experiment"], "MultiPositions", [])
position_ids = []
multipositions = configuration["experiment"]["MultiPositions"]
for i, position in enumerate(multipositions):
try:
for j in range(5):
float(position[j])
except (ValueError, KeyError):
position_ids.append(i)

for idx in position_ids[::-1]:
del multipositions[idx]
if len(multipositions) < 1:
multipositions.append([10.0, 10.0, 10.0, 10.0, 10.0])

microscope_setting_dict["multiposition_count"] = len(multipositions)


def verify_waveform_constants(manager, configuration):
"""Verifies and updates the waveform constants in the configuration dictionary.
Expand Down Expand Up @@ -1119,3 +1093,18 @@ def verify_configuration(manager, configuration):
"gui",
{"channels": {"count": channel_count}},
)

def verify_positions_config(positions):
if positions is None or type(positions) not in (list, ListProxy):
return []
# MultiPositions
position_num = len(positions)
for i in range(position_num-1, -1, -1):
position = positions[i]
try:
for j in range(5):
float(position[j])
except (ValueError, KeyError, IndexError):
del positions[i]

return positions
2 changes: 0 additions & 2 deletions src/navigate/config/experiment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ MicroscopeState:
timepoint_interval: 0
experiment_duration: 600.0899999999995
is_multiposition: False
multiposition_count: 2
selected_channels: 3
channels: {'channel_1': {'is_selected': True, 'laser': '488nm', 'laser_index': 0, 'filter': 'GFP - FF01-515/30-32', 'filter_position': 1, 'camera_exposure_time': 200.0, 'laser_power': '20', 'interval_time': '1', 'defocus': 100.0}, 'channel_2': {'is_selected': True, 'laser': '562nm', 'laser_index': 1, 'filter': 'RFP - FF01-595/31-32', 'filter_position': 2, 'camera_exposure_time': 200.0, 'laser_power': '20', 'interval_time': '1', 'defocus': 200.0}, 'channel_3': {'is_selected': True, 'laser': '642nm', 'laser_index': 2, 'filter': 'Far-Red - BLP01-647R/31-32', 'filter_position': 3, 'camera_exposure_time': 200.0, 'laser_power': '20', 'interval_time': '1', 'defocus': 0.0}}
stack_z_origin: 0.0
stack_focus_origin: 0.0
Expand Down
1 change: 1 addition & 0 deletions src/navigate/config/multi_positions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[[0, 0, 0, 0, 0]]
33 changes: 27 additions & 6 deletions src/navigate/controller/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,16 @@
update_config_dict,
verify_experiment_config,
verify_waveform_constants,
verify_positions_config,
verify_configuration,
get_navigate_path,
)
from navigate.tools.file_functions import create_save_path, save_yaml_file, get_ram_info
from navigate.tools.file_functions import (
create_save_path,
load_yaml_file,
save_yaml_file,
get_ram_info,
)
from navigate.tools.common_dict_tools import update_stage_dict
from navigate.tools.multipos_table_tools import update_table
from navigate.tools.common_functions import combine_funcs
Expand All @@ -108,6 +114,7 @@ def __init__(
rest_api_path,
waveform_templates_path,
gui_configuration_path,
multi_positions_path,
args,
):
"""Initialize the Navigate Controller.
Expand Down Expand Up @@ -198,6 +205,10 @@ def __init__(
verify_experiment_config(self.manager, self.configuration)
verify_waveform_constants(self.manager, self.configuration)

positions = load_yaml_file(multi_positions_path)
positions = verify_positions_config(positions)
self.configuration["multi_positions"] = positions

total_ram, available_ram = get_ram_info()
logger.info(
f"Total RAM: {total_ram / 1024**3:.2f} GB. "
Expand Down Expand Up @@ -460,7 +471,7 @@ def populate_experiment_setting(self, file_name=None, in_initialize=False):
self.acquire_bar_controller.populate_experiment_values()
# self.stage_controller.populate_experiment_values()
self.multiposition_tab_controller.set_positions(
self.configuration["experiment"]["MultiPositions"]
self.configuration["multi_positions"]
)
self.channels_tab_controller.populate_experiment_values()
self.camera_setting_controller.populate_experiment_values()
Expand Down Expand Up @@ -510,10 +521,7 @@ def update_experiment_setting(self):

# update multi-positions
positions = self.multiposition_tab_controller.get_positions()
self.configuration["experiment"]["MultiPositions"] = positions
self.configuration["experiment"]["MicroscopeState"][
"multiposition_count"
] = len(positions)
self.configuration["multi_positions"] = positions

if (
self.configuration["experiment"]["MicroscopeState"]["is_multiposition"]
Expand Down Expand Up @@ -848,6 +856,13 @@ def execute(self, command, *args):
filename="waveform_constants.yml",
)

# Save multi_positions.yml file
save_yaml_file(
file_directory=file_directory,
content_dict=self.configuration["multi_positions"],
filename="multi_positions.yml",
)

self.camera_setting_controller.solvent = self.configuration["experiment"][
"Saving"
]["solvent"]
Expand Down Expand Up @@ -952,6 +967,12 @@ def execute(self, command, *args):
content_dict=self.configuration["experiment"],
filename="experiment.yml",
)
save_yaml_file(
file_directory=file_directory,
content_dict=self.configuration["multi_positions"],
filename="multi_positions.yml",
)

if hasattr(self, "waveform_popup_controller"):
self.waveform_popup_controller.save_waveform_constants()

Expand Down
2 changes: 1 addition & 1 deletion src/navigate/controller/sub_controllers/acquire_bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def progress_bar(
number_of_positions = 1
else:
number_of_positions = len(
self.parent_controller.configuration["experiment"]["MultiPositions"]
self.parent_controller.configuration["multi_positions"]
)

if mode == "single":
Expand Down
5 changes: 2 additions & 3 deletions src/navigate/controller/sub_controllers/camera_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,8 +526,8 @@ def initialize_non_live_display(self, microscope_state, camera_parameters):
self.slice_index = 0
self.image_mode = microscope_state["image_mode"]
self.stack_cycling_mode = microscope_state["stack_cycling_mode"]
self.number_of_channels = int(microscope_state["selected_channels"])
self.get_selected_channels(microscope_state)
self.number_of_channels = len(self.selected_channels)
self.number_of_slices = int(microscope_state["number_z_steps"])
self.total_images_per_volume = self.number_of_channels * self.number_of_slices
self.original_image_width = int(camera_parameters["img_x_pixels"])
Expand Down Expand Up @@ -1169,8 +1169,7 @@ def slider_update(self, *_):

slider_index = self.view.slider.get()
channel_index = self.view.live_frame.channel.get()
channel_index = channel_index[-1]
channel_index = int(channel_index) - 1
channel_index = self.selected_channels.index(channel_index)
image = self.spooled_images.load_image(
channel=channel_index, slice_index=slider_index
)
Expand Down
7 changes: 0 additions & 7 deletions src/navigate/controller/sub_controllers/channels_tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@

# Standard Library Imports
import logging
from functools import reduce
import datetime

# Third Party Imports
Expand Down Expand Up @@ -773,12 +772,6 @@ def execute(self, command, *args):
Returns parent_controller.execute(command) if command = 'get_stage_position'
"""
if command == "recalculate_timepoint":
# update selected channels num
self.microscope_state_dict["selected_channels"] = reduce(
lambda count, channel: count + (channel["is_selected"] is True),
self.microscope_state_dict["channels"].values(),
0,
)
self.update_timepoint_setting()
# update framerate info in camera setting tab
exposure_time = max(
Expand Down
7 changes: 6 additions & 1 deletion src/navigate/controller/sub_controllers/multiposition.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,12 @@ def set_positions(self, positions):
"""
axis_dict = {"x": "X", "y": "Y", "z": "Z", "theta": "R", "f": "F"}
data = {}

if len(positions) == 0:
# add current stage position to the table
stage_position = self.parent_controller.configuration["experiment"][
"StageParameters"
]
positions = [[stage_position[axis] for axis in axis_dict.keys()]]
for i, name in enumerate(axis_dict.keys()):
data[axis_dict[name]] = list(pos[i] for pos in positions)
self.table.model.df = pd.DataFrame(data)
Expand Down
2 changes: 2 additions & 0 deletions src/navigate/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ def main():
logging_path,
configurator,
gui_configuration_path,
multi_positions_path,
) = evaluate_parser_input_arguments(args)

log_setup("logging.yml", logging_path)
Expand All @@ -119,6 +120,7 @@ def main():
rest_api_path,
waveform_templates_path,
gui_configuration_path,
multi_positions_path,
args,
)

Expand Down
Loading

0 comments on commit b7412e9

Please sign in to comment.