Skip to content

Commit fb182fe

Browse files
Merge pull request #896 from annie-xd-wang/update-multiposition-table
Update multiposition table
2 parents e33ed34 + 68b4062 commit fb182fe

File tree

9 files changed

+77
-83
lines changed

9 files changed

+77
-83
lines changed

src/navigate/config/config.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -673,22 +673,17 @@ def verify_experiment_config(manager, configuration):
673673
position_ids = []
674674
multipositions = configuration["experiment"]["MultiPositions"]
675675
for i, position in enumerate(multipositions):
676-
for axis in ["x", "y", "z", "theta", "f"]:
677676
try:
678-
position[axis] = float(position[axis])
679-
except ValueError:
677+
for j in range(5):
678+
float(position[j])
679+
except (ValueError, KeyError):
680680
position_ids.append(i)
681-
break
681+
682682
for idx in position_ids[::-1]:
683683
del multipositions[idx]
684684
if len(multipositions) < 1:
685-
multipositions.append(None)
686-
update_config_dict(
687-
manager,
688-
multipositions,
689-
0,
690-
{"x": 10.0, "y": 10.0, "z": 10.0, "f": 10.0, "theta": 10.0},
691-
)
685+
multipositions.append([10.0, 10.0, 10.0, 10.0, 10.0])
686+
692687
microscope_setting_dict["multiposition_count"] = len(multipositions)
693688

694689

src/navigate/config/experiment.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,4 @@ MicroscopeState:
7070
conpro_cycling_mode: Per Stack
7171
waveform_template: Default
7272
MultiPositions:
73-
[{'x': 15000.0, 'y': 12000.0, 'z': 15500.0, 'theta': 0.0, 'f': 70000.0}, {'x': 35000.0, 'y': 42000.0, 'z': 15500.0, 'theta': 0.0, 'f': 70000.0}]
73+
[[15000.0,12000.0,15500.0,0.0,70000.0], [35000.0,42000.0,15500.0,0.0,70000.0]]

src/navigate/controller/controller.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -456,12 +456,7 @@ def update_experiment_setting(self):
456456

457457
# update multi-positions
458458
positions = self.multiposition_tab_controller.get_positions()
459-
update_config_dict(
460-
self.manager,
461-
self.configuration["experiment"],
462-
"MultiPositions",
463-
positions,
464-
)
459+
self.configuration["experiment"]["MultiPositions"] = positions
465460
self.configuration["experiment"]["MicroscopeState"][
466461
"multiposition_count"
467462
] = len(positions)

src/navigate/controller/sub_controllers/multi_position_controller.py

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -96,22 +96,22 @@ def set_positions(self, positions):
9696
9797
Parameters
9898
----------
99-
positions : dict
99+
positions : [[]]
100100
positions to be set
101101
102102
Example
103103
-------
104-
>>> positions = {
105-
>>> 0: {'x': 0, 'y': 0, 'z': 0, 'theta': 0, 'f': 0},
106-
>>> 1: {'x': 1, 'y': 1, 'z': 1, 'theta': 1, 'f': 1},
107-
>>> 2: {'x': 2, 'y': 2, 'z': 2, 'theta': 2, 'f': 2}}
104+
>>> positions = [
105+
>>> [0, 0, 0, 0, 0],
106+
>>> [1, 1, 1, 1, 1],
107+
>>> [2, 2, 2, 2, 2]]
108108
>>> set_positions(positions)
109109
"""
110110
axis_dict = {"x": "X", "y": "Y", "z": "Z", "theta": "R", "f": "F"}
111111
data = {}
112112

113-
for name in axis_dict:
114-
data[axis_dict[name]] = list(pos[name] for pos in positions)
113+
for i, name in enumerate(axis_dict.keys()):
114+
data[axis_dict[name]] = list(pos[i] for pos in positions)
115115
self.table.model.df = pd.DataFrame(data)
116116
self.table.redraw()
117117
self.show_verbose_info("loaded new positions")
@@ -121,14 +121,13 @@ def get_positions(self):
121121
122122
Returns
123123
-------
124-
dict
125-
positions in the format of {index: {axis: value}}
124+
list
125+
positions in the format of [[x, y, z, theta, f], ]
126126
127127
Example
128128
-------
129129
>>> get_positions()
130130
"""
131-
axis_dict = {"X": "x", "Y": "y", "Z": "z", "R": "theta", "F": "f"}
132131
positions = []
133132
rows = self.table.model.df.shape[0]
134133
for i in range(rows):
@@ -139,10 +138,7 @@ def get_positions(self):
139138
)
140139
== 5
141140
):
142-
temp = dict(self.table.model.df.iloc[i])
143-
positions.append({})
144-
for k in axis_dict:
145-
positions[i][axis_dict[k]] = temp[k]
141+
positions.append(temp)
146142
return positions
147143

148144
def handle_double_click(self, event):

src/navigate/model/features/common_features.py

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,7 @@ def signal_func(self):
595595
)
596596
if self.current_idx >= self.position_count:
597597
return False
598-
pos_dict = self.multiposition_table[self.current_idx]
598+
pos_dict = dict(zip(["x", "y", "z", "theta", "f"], self.multiposition_table[self.current_idx]))
599599
# pause data thread if necessary
600600
if self.current_idx == 0:
601601
temp = self.model.get_stage_position()
@@ -606,7 +606,7 @@ def signal_func(self):
606606
)
607607
)
608608
else:
609-
pre_stage_pos = self.multiposition_table[self.current_idx - 1]
609+
pre_stage_pos = dict(zip(["x", "y", "z", "theta", "f"], self.multiposition_table[self.current_idx - 1]))
610610
delta_x = abs(pos_dict["x"] - pre_stage_pos["x"])
611611
delta_y = abs(pos_dict["y"] - pre_stage_pos["y"])
612612
delta_z = abs(pos_dict["z"] - pre_stage_pos["z"])
@@ -872,31 +872,32 @@ def pre_signal_func(self):
872872
#: float: The f position of the channel being acquired in the z-stack
873873
self.restore_f = pos_dict["f_pos"]
874874

875+
# position: x, y, z, theta, f
875876
if bool(microscope_state["is_multiposition"]):
876877
self.positions = self.model.configuration["experiment"]["MultiPositions"]
877878
else:
878879
self.positions = [
879-
{
880-
"x": float(pos_dict["x_pos"]),
881-
"y": float(pos_dict["y_pos"]),
882-
"z": float(
880+
[
881+
float(pos_dict["x_pos"]),
882+
float(pos_dict["y_pos"]),
883+
float(
883884
microscope_state.get(
884885
"stack_z_origin",
885886
pos_dict["z_pos"],
886887
)
887888
if not self.get_origin
888889
else pos_dict["z_pos"]
889890
),
890-
"theta": float(pos_dict["theta_pos"]),
891-
"f": float(
891+
float(pos_dict["theta_pos"]),
892+
float(
892893
microscope_state.get(
893894
"stack_focus_origin",
894895
pos_dict["f_pos"],
895896
)
896897
if not self.get_origin
897898
else pos_dict["f_pos"]
898899
),
899-
}
900+
]
900901
]
901902

902903
# Setup next channel down here, to ensure defocus isn't merged into
@@ -910,6 +911,7 @@ def pre_signal_func(self):
910911
f"{self.start_z_position}"
911912
)
912913
self.current_position_idx = 0
914+
self.current_position = dict(zip(["x", "y", "z", "theta", "f"], self.positions[0]))
913915
self.z_position_moved_time = 0
914916
self.need_to_move_new_position = True
915917
self.need_to_move_z_position = True
@@ -941,16 +943,20 @@ def signal_func(self):
941943
if self.model.stop_acquisition:
942944
return False
943945
data_thread_is_paused = False
946+
944947
# move stage X, Y, Theta
945948
if self.need_to_move_new_position:
946949
self.need_to_move_new_position = False
947950

951+
self.pre_position = self.current_position
952+
self.current_position = dict(zip(["x", "y", "z", "theta", "f"], self.positions[self.current_position_idx]))
953+
948954
# calculate first z, f position
949955
self.current_z_position = (
950-
self.start_z_position + self.positions[self.current_position_idx]["z"]
956+
self.start_z_position + self.current_position["z"]
951957
)
952958
self.current_focus_position = (
953-
self.start_focus + self.positions[self.current_position_idx]["f"]
959+
self.start_focus + self.current_position["f"]
954960
)
955961
if self.defocus is not None:
956962
self.current_focus_position += self.defocus[
@@ -963,29 +969,29 @@ def signal_func(self):
963969
map(
964970
lambda ax: (
965971
f"{ax}_abs",
966-
self.positions[self.current_position_idx][ax],
972+
self.current_position[ax],
967973
),
968974
["x", "y", "theta"],
969975
)
970976
)
971977

972978
if self.current_position_idx > 0:
973979
delta_x = (
974-
self.positions[self.current_position_idx]["x"]
975-
- self.positions[self.current_position_idx - 1]["x"]
980+
self.current_position["x"]
981+
- self.pre_position["x"]
976982
)
977983
delta_y = (
978-
self.positions[self.current_position_idx]["y"]
979-
- self.positions[self.current_position_idx - 1]["y"]
984+
self.current_position["y"]
985+
- self.pre_position["y"]
980986
)
981987
delta_z = (
982-
self.positions[self.current_position_idx]["z"]
983-
- self.positions[self.current_position_idx - 1]["z"]
988+
self.current_position["z"]
989+
- self.pre_position["z"]
984990
+ self.z_stack_distance
985991
)
986992
delta_f = (
987-
self.positions[self.current_position_idx]["f"]
988-
- self.positions[self.current_position_idx - 1]["f"]
993+
self.current_position["f"]
994+
- self.pre_position["f"]
989995
+ self.f_stack_distance
990996
)
991997
else:
@@ -1076,10 +1082,10 @@ def signal_end(self):
10761082
self.z_position_moved_time = 0
10771083
# calculate first z, f position
10781084
self.current_z_position = (
1079-
self.start_z_position + self.positions[self.current_position_idx]["z"]
1085+
self.start_z_position + self.current_position["z"]
10801086
)
10811087
self.current_focus_position = (
1082-
self.start_focus + self.positions[self.current_position_idx]["f"]
1088+
self.start_focus + self.current_position["f"]
10831089
)
10841090
if (
10851091
self.z_stack_distance > self.stage_distance_threshold

test/config/test_config.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ def setUp(self):
362362
}
363363

364364
multipositions_sample = [
365-
{"x": 10.0, "y": 10.0, "z": 10.0, "f": 10.0, "theta": 10.0}
365+
[10.0, 10.0, 10.0, 10.0, 10.0]
366366
]
367367

368368
self.experiment_sample = {
@@ -425,7 +425,7 @@ def test_load_empty_experiment_file(self):
425425

426426
# MultiPositions
427427
for i, position in enumerate(self.experiment_sample["MultiPositions"]):
428-
self.assert_equal_dict(position, experiement_config["MultiPositions"][i])
428+
assert position == experiement_config["MultiPositions"][i]
429429

430430
def test_load_experiment_file_with_missing_parameters(self):
431431
experiment = load_yaml_file(os.path.join(self.config_path, "experiment.yml"))

test/config/test_experiment.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -207,17 +207,11 @@ def test_microscope_state(self):
207207
), f"{key_key} is not of type {expected_values[key_key]}"
208208

209209
def test_multiposition(self):
210-
expected_values = {
211-
"x": float,
212-
"y": float,
213-
"z": float,
214-
"theta": float,
215-
"f": float,
216-
}
210+
expected_values = [float, float, float, float, float]
217211
positions = self.data["MultiPositions"]
212+
print("*** positions:", positions)
218213
for position in positions:
219-
for key in position.keys():
220-
self.assertIn(key, expected_values)
214+
for i in range(len(expected_values)):
221215
assert isinstance(
222-
position[key], expected_values[key]
223-
), f"{key} is not of type {expected_values[key]}"
216+
position[i], expected_values[i]
217+
), f"{i} is not of type {expected_values[i]}"

test/model/features/test_common_features.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ def _prepare_test(self, dummy_model_to_test_features):
5454
position_list = self.model.configuration["experiment"]["MultiPositions"]
5555
if len(position_list) < 5:
5656
for i in range(5):
57-
pos = {}
58-
for axis in ["x", "y", "z", "theta", "f"]:
59-
pos[axis] = random.randint(1, 10000)
57+
pos = [0] * 5
58+
for i in range(5):
59+
pos[i] = random.randint(1, 10000)
6060
position_list.append(pos)
6161

6262
def get_next_record(self, record_prefix, idx):
@@ -97,13 +97,13 @@ def z_stack_verification(self):
9797
else:
9898
pos_dict = self.model.configuration["experiment"]["StageParameters"]
9999
positions = [
100-
{
101-
"x": pos_dict["x"],
102-
"y": pos_dict["y"],
103-
"z": self.config.get("stack_z_origin", pos_dict["z"]),
104-
"theta": pos_dict["theta"],
105-
"f": self.config.get("stack_focus_origin", pos_dict["f"]),
106-
}
100+
[
101+
pos_dict["x"],
102+
pos_dict["y"],
103+
self.config.get("stack_z_origin", pos_dict["z"]),
104+
pos_dict["theta"],
105+
self.config.get("stack_focus_origin", pos_dict["f"]),
106+
]
107107
]
108108

109109
z_step = self.config["step_size"]
@@ -141,14 +141,15 @@ def z_stack_verification(self):
141141

142142
# x, y, theta
143143
pos_moved = self.model.signal_records[idx][1][0]
144-
for axis in ["x", "y", "theta"]:
145-
assert pos[axis] == pos_moved[axis + "_abs"], (
146-
f"should move to {axis}: {pos[axis]}, "
144+
for i, axis in [(0,"x"), (1,"y"), (3,"theta")]:
145+
assert pos[i] == pos_moved[axis + "_abs"], (
146+
f"should move to {axis}: {pos[i]}, "
147147
f"but moved to {pos_moved[axis + '_abs']}"
148148
)
149149

150-
z_pos = pos["z"] + self.config["start_position"]
151-
f_pos = pos["f"] + self.config["start_focus"]
150+
# (x, y, z, theta, f)
151+
z_pos = pos[2] + self.config["start_position"]
152+
f_pos = pos[4] + self.config["start_focus"]
152153

153154
if mode == "per_z":
154155
f_pos += selected_channels[0]["defocus"]

test/model/test_model.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,14 @@ def test_multiposition_acquisition(model):
219219
model.__test_manager, # noqa
220220
model.configuration["experiment"],
221221
"MultiPositions",
222-
[{"x": 10.0, "y": 10.0, "z": 10.0, "theta": 10.0, "f": 10.0}],
222+
[[10.0, 10.0, 10.0, 10.0, 10.0]],
223+
)
224+
model.configuration["experiment"]["MicroscopeState"]["image_mode"] = "z-stack"
225+
model.configuration["experiment"]["MicroscopeState"]["number_z_steps"] = 10
226+
227+
model.configuration["experiment"]["MicroscopeState"]["step_size"] = 5.0
228+
model.configuration["experiment"]["MicroscopeState"]["end_position"] = (
229+
model.configuration["experiment"]["MicroscopeState"]["start_position"] + 15.0
223230
)
224231
model.run_command("acquire")
225232

0 commit comments

Comments
 (0)