Skip to content

Commit 61a3bdb

Browse files
Baharisviljarjf
andauthored
Tighten code and add magnification control to the hand panel (#142)
* Speed up kinematic simulations * Fix typos in Magnification error messages * Tighten handpanel, use config modes, spinbox stage xy * Remove repetition and excessive lines * Make spacing consistent * Change alpha-wobbler 2-button toggle into a checkbutton for consistency * Simulated beamshift = 0 not strictly necessary for this PR * Set columnspan=2 of wobble toggle to avoid unnecessary stretch * Apply changes suggested during review Co-authored-by: Viljar Femoen <viljar.femoen@hotmail.no> * In control panel's 'Stage (XYZ)', add Z control (ugly but very useful) --------- Co-authored-by: Viljar Femoen <viljar.femoen@hotmail.no>
1 parent 9e2e04a commit 61a3bdb

File tree

2 files changed

+88
-112
lines changed

2 files changed

+88
-112
lines changed

src/instamatic/gui/ctrl_frame.py

Lines changed: 86 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ def __init__(self, parent):
2222

2323
frame = Frame(self)
2424

25+
stage_reset_btn = Button(frame, text='Reset stage', command=self.reset_stage)
26+
stage_reset_btn.grid(row=0, column=1, sticky='W')
27+
2528
b_stage_stop = Button(frame, text='Stop stage', command=self.stage_stop)
2629
b_stage_stop.grid(row=0, column=2, sticky='W')
2730

@@ -31,60 +34,49 @@ def __init__(self, parent):
3134
b_find_eucentric_height = Button(
3235
frame, text='Find eucentric height', command=self.find_eucentric_height
3336
)
34-
b_find_eucentric_height.grid(row=0, column=0, sticky='EW', columnspan=2)
37+
b_find_eucentric_height.grid(row=0, column=0, sticky='EW')
3538

3639
Label(frame, text='Mode:').grid(row=8, column=0, sticky='W')
37-
self.o_mode = OptionMenu(
38-
frame,
39-
self.var_mode,
40-
'diff',
41-
'diff',
42-
'mag1',
43-
'mag2',
44-
'lowmag',
45-
'samag',
46-
command=self.set_mode,
47-
)
48-
self.o_mode.grid(row=8, column=1, sticky='W', padx=10)
40+
modes = list(config.microscope.ranges.keys())
41+
self.o_mode = OptionMenu(frame, self.var_mode, modes[0], *modes, command=self.set_mode)
42+
self.o_mode.grid(row=8, column=1, sticky='EW')
4943

5044
frame.pack(side='top', fill='x', padx=10, pady=10)
5145

5246
frame = Frame(self)
53-
5447
Label(frame, text='Angle (-)', width=20).grid(row=1, column=0, sticky='W')
5548
Label(frame, text='Angle (0)', width=20).grid(row=2, column=0, sticky='W')
5649
Label(frame, text='Angle (+)', width=20).grid(row=3, column=0, sticky='W')
5750
Label(frame, text='Alpha wobbler (±)', width=20).grid(row=4, column=0, sticky='W')
58-
Label(frame, text='Stage(XY)', width=20).grid(row=6, column=0, sticky='W')
51+
Label(frame, text='Stage (XYZ)', width=20).grid(row=6, column=0, sticky='W')
5952

60-
e_negative_angle = Spinbox(
61-
frame, width=10, textvariable=self.var_negative_angle, from_=-90, to=90, increment=5
62-
)
53+
angle = {'width': 10, 'from_': -90, 'to': 90, 'increment': 5}
54+
angle_i1 = {**angle, 'increment': 1}
55+
stage = {'width': 10, 'from_': -1e6, 'to': 1e6, 'increment': 100}
56+
57+
e_negative_angle = Spinbox(frame, textvariable=self.var_negative_angle, **angle)
6358
e_negative_angle.grid(row=1, column=1, sticky='EW')
64-
e_neutral_angle = Spinbox(
65-
frame, width=10, textvariable=self.var_neutral_angle, from_=-90, to=90, increment=5
66-
)
59+
e_neutral_angle = Spinbox(frame, textvariable=self.var_neutral_angle, **angle)
6760
e_neutral_angle.grid(row=2, column=1, sticky='EW')
68-
e_positive_angle = Spinbox(
69-
frame, width=10, textvariable=self.var_positive_angle, from_=-90, to=90, increment=5
70-
)
61+
e_positive_angle = Spinbox(frame, textvariable=self.var_positive_angle, **angle)
7162
e_positive_angle.grid(row=3, column=1, sticky='EW')
72-
73-
e_alpha_wobbler = Spinbox(
74-
frame, width=10, textvariable=self.var_alpha_wobbler, from_=-90, to=90, increment=1
75-
)
63+
e_alpha_wobbler = Spinbox(frame, textvariable=self.var_alpha_wobbler, **angle_i1)
7664
e_alpha_wobbler.grid(row=4, column=1, sticky='EW')
77-
self.b_start_wobble = Button(frame, text='Start', command=self.start_alpha_wobbler)
78-
self.b_start_wobble.grid(row=4, column=2, sticky='W')
79-
self.b_stop_wobble = Button(
80-
frame, text='Stop', command=self.stop_alpha_wobbler, state=DISABLED
65+
66+
b_wobble = Checkbutton(
67+
frame,
68+
text='Toggle wobble',
69+
variable=self.var_alpha_wobbler_on,
70+
command=self.toggle_alpha_wobbler,
8171
)
82-
self.b_stop_wobble.grid(row=4, column=3, sticky='W')
72+
b_wobble.grid(row=4, column=2, sticky='W', columnspan=2)
8373

84-
e_stage_x = Entry(frame, width=10, textvariable=self.var_stage_x)
74+
e_stage_x = Spinbox(frame, textvariable=self.var_stage_x, **stage)
8575
e_stage_x.grid(row=6, column=1, sticky='EW')
86-
e_stage_y = Entry(frame, width=10, textvariable=self.var_stage_y)
76+
e_stage_y = Spinbox(frame, textvariable=self.var_stage_y, **stage)
8777
e_stage_y.grid(row=6, column=2, sticky='EW')
78+
e_stage_z = Spinbox(frame, textvariable=self.var_stage_z, **stage)
79+
e_stage_z.grid(row=6, column=3, sticky='EW')
8880

8981
if config.settings.use_goniotool:
9082
Label(frame, text='Rot. Speed', width=20).grid(row=5, column=0, sticky='W')
@@ -107,12 +99,12 @@ def __init__(self, parent):
10799
b_positive_angle.grid(row=3, column=2, sticky='W')
108100

109101
b_stage = Button(frame, text='Set', command=self.set_stage)
110-
b_stage.grid(row=6, column=3, sticky='W')
102+
b_stage.grid(row=6, column=4, sticky='W')
111103
b_stage_get = Button(frame, text='Get', command=self.get_stage)
112-
b_stage_get.grid(row=6, column=4, sticky='W')
104+
b_stage_get.grid(row=6, column=5, sticky='W')
113105

114106
# defocus button
115-
Label(frame, text='Diff defocus:', width=20).grid(row=13, column=0, sticky='W')
107+
Label(frame, text='Diff defocus', width=20).grid(row=13, column=0, sticky='W')
116108
self.e_diff_defocus = Spinbox(
117109
frame,
118110
textvariable=self.var_diff_defocus,
@@ -126,7 +118,7 @@ def __init__(self, parent):
126118
self.c_toggle_defocus = Checkbutton(
127119
frame,
128120
text='Toggle defocus',
129-
variable=self.var_toggle_diff_defocus,
121+
variable=self.var_diff_defocus_on,
130122
command=self.toggle_diff_defocus,
131123
)
132124
self.c_toggle_defocus.grid(row=13, column=2, sticky='W', columnspan=2)
@@ -161,19 +153,22 @@ def __init__(self, parent):
161153
)
162154
slider.grid(row=12, column=0, columnspan=3, sticky='EW')
163155

164-
frame.pack(side='top', fill='x', padx=10, pady=10)
165-
166-
frame = Frame(self)
156+
# Magnification
157+
Label(frame, text='Magnification', width=20).grid(row=14, column=0, sticky='W')
158+
mag_inc_btn = Button(frame, text='+', command=self.increase_mag)
159+
mag_inc_btn.grid(row=14, column=1)
160+
mag_dec_btn = Button(frame, text='-', command=self.decrease_mag)
161+
mag_dec_btn.grid(row=14, column=2)
167162

168-
Label(frame, text='DiffFocus', width=20).grid(row=11, column=0, sticky='W')
163+
Label(frame, text='DiffFocus', width=20).grid(row=21, column=0, sticky='W')
169164
e_difffocus = Entry(frame, width=10, textvariable=self.var_difffocus)
170-
e_difffocus.grid(row=11, column=1, sticky='W')
165+
e_difffocus.grid(row=21, column=1, sticky='W')
171166

172167
b_difffocus = Button(frame, text='Set', command=self.set_difffocus)
173-
b_difffocus.grid(row=11, column=2, sticky='W')
168+
b_difffocus.grid(row=21, column=2, sticky='WE')
174169

175170
b_difffocus_get = Button(frame, text='Get', command=self.get_difffocus)
176-
b_difffocus_get.grid(row=11, column=3, sticky='W')
171+
b_difffocus_get.grid(row=21, column=3, sticky='W')
177172

178173
slider = Scale(
179174
frame,
@@ -183,7 +178,7 @@ def __init__(self, parent):
183178
orient=HORIZONTAL,
184179
command=self.set_difffocus,
185180
)
186-
slider.grid(row=12, column=0, columnspan=3, sticky='EW')
181+
slider.grid(row=22, column=0, columnspan=3, sticky='EW')
187182

188183
frame.pack(side='top', fill='x', padx=10, pady=10)
189184

@@ -199,17 +194,19 @@ def init_vars(self):
199194
self.var_mode = StringVar(value='diff')
200195

201196
self.var_alpha_wobbler = DoubleVar(value=5)
197+
self.var_alpha_wobbler_on = BooleanVar(value=False)
202198

203199
self.var_stage_x = IntVar(value=0)
204200
self.var_stage_y = IntVar(value=0)
201+
self.var_stage_z = IntVar(value=0)
205202

206203
self.var_goniotool_tx = IntVar(value=1)
207204

208205
self.var_brightness = IntVar(value=65535)
209206
self.var_difffocus = IntVar(value=65535)
210207

211208
self.var_diff_defocus = IntVar(value=1500)
212-
self.var_toggle_diff_defocus = BooleanVar(value=False)
209+
self.var_diff_defocus_on = BooleanVar(value=False)
213210

214211
self.var_stage_wait = BooleanVar(value=True)
215212

@@ -228,6 +225,17 @@ def set_brightness(self, event=None):
228225
def get_brightness(self, event=None):
229226
self.var_brightness.set(self.ctrl.brightness.get())
230227

228+
def increase_mag(self):
229+
self.ctrl.magnification.increase()
230+
print(f'Set magnification: {self.ctrl.magnification.get()}')
231+
232+
def decrease_mag(self):
233+
self.ctrl.magnification.decrease()
234+
print(f'Set magnification: {self.ctrl.magnification.get()}')
235+
236+
def reset_stage(self):
237+
self.ctrl.stage.neutral()
238+
231239
def set_difffocus(self, event=None):
232240
self.var_difffocus.set(self.var_difffocus.get())
233241
self.q.put(('ctrl', {'task': 'difffocus.set', 'value': self.var_difffocus.get()}))
@@ -236,44 +244,19 @@ def set_difffocus(self, event=None):
236244
def get_difffocus(self, event=None):
237245
self.var_difffocus.set(self.ctrl.difffocus.get())
238246

239-
def set_negative_angle(self):
240-
self.q.put(
241-
(
242-
'ctrl',
243-
{
244-
'task': 'stage.set',
245-
'a': self.var_negative_angle.get(),
246-
'wait': self.var_stage_wait.get(),
247-
},
248-
)
249-
)
247+
def _set_angle(self, var: Variable) -> None:
248+
kwargs = {'task': 'stage.set', 'a': var.get(), 'wait': self.var_stage_wait.get()}
249+
self.q.put(('ctrl', kwargs))
250250
self.triggerEvent.set()
251251

252+
def set_negative_angle(self):
253+
return self._set_angle(self.var_negative_angle)
254+
252255
def set_neutral_angle(self):
253-
self.q.put(
254-
(
255-
'ctrl',
256-
{
257-
'task': 'stage.set',
258-
'a': self.var_neutral_angle.get(),
259-
'wait': self.var_stage_wait.get(),
260-
},
261-
)
262-
)
263-
self.triggerEvent.set()
256+
return self._set_angle(self.var_neutral_angle)
264257

265258
def set_positive_angle(self):
266-
self.q.put(
267-
(
268-
'ctrl',
269-
{
270-
'task': 'stage.set',
271-
'a': self.var_positive_angle.get(),
272-
'wait': self.var_stage_wait.get(),
273-
},
274-
)
275-
)
276-
self.triggerEvent.set()
259+
return self._set_angle(self.var_positive_angle)
277260

278261
def set_goniotool_tx(self, event=None, value=None):
279262
if not value:
@@ -292,40 +275,35 @@ def set_stage(self):
292275
'task': 'stage.set',
293276
'x': self.var_stage_x.get(),
294277
'y': self.var_stage_y.get(),
278+
'z': self.var_stage_z.get(),
295279
'wait': self.var_stage_wait.get(),
296280
},
297281
)
298282
)
299283
self.triggerEvent.set()
300284

301285
def get_stage(self, event=None):
302-
x, y, _, _, _ = self.ctrl.stage.get()
286+
x, y, z, _, _ = self.ctrl.stage.get()
303287
self.var_stage_x.set(round(x))
304288
self.var_stage_y.set(round(y))
305-
306-
def start_alpha_wobbler(self):
307-
self.wobble_stop_event = threading.Event()
308-
309-
self.b_stop_wobble.config(state=NORMAL)
310-
self.b_start_wobble.config(state=DISABLED)
311-
312-
self.q.put(
313-
(
314-
'ctrl',
315-
{
316-
'task': 'stage.alpha_wobbler',
317-
'delta': self.var_alpha_wobbler.get(),
318-
'event': self.wobble_stop_event,
319-
},
289+
self.var_stage_z.set(round(z))
290+
291+
def toggle_alpha_wobbler(self):
292+
if self.var_alpha_wobbler_on.get():
293+
self.wobble_stop_event = threading.Event()
294+
self.q.put(
295+
(
296+
'ctrl',
297+
{
298+
'task': 'stage.alpha_wobbler',
299+
'delta': self.var_alpha_wobbler.get(),
300+
'event': self.wobble_stop_event,
301+
},
302+
)
320303
)
321-
)
322-
self.triggerEvent.set()
323-
324-
def stop_alpha_wobbler(self):
325-
self.wobble_stop_event.set()
326-
327-
self.b_stop_wobble.config(state=DISABLED)
328-
self.b_start_wobble.config(state=NORMAL)
304+
self.triggerEvent.set()
305+
else: # wobbler off
306+
self.wobble_stop_event.set()
329307

330308
def stage_stop(self):
331309
self.q.put(('ctrl', {'task': 'stage.stop'}))
@@ -336,21 +314,19 @@ def find_eucentric_height(self):
336314
self.triggerEvent.set()
337315

338316
def toggle_diff_defocus(self):
339-
toggle = self.var_toggle_diff_defocus.get()
340-
341-
if toggle:
317+
if self.var_diff_defocus_on.get():
342318
offset = self.var_diff_defocus.get()
343319
self.ctrl.difffocus.defocus(offset=offset)
344320
self.b_reset_defocus.config(state=NORMAL)
345321
else:
346322
self.ctrl.difffocus.refocus()
347-
self.var_toggle_diff_defocus.set(False)
323+
self.var_diff_defocus_on.set(False)
348324

349325
self.get_difffocus()
350326

351327
def reset_diff_defocus(self):
352328
self.ctrl.difffocus.refocus()
353-
self.var_toggle_diff_defocus.set(False)
329+
self.var_diff_defocus_on.set(False)
354330
self.get_difffocus()
355331

356332

src/instamatic/microscope/components/lenses.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,13 @@ def increase(self) -> None:
135135
try:
136136
self.index += 1
137137
except ValueError:
138-
print(f'Error: Cannot change magnficication index (current={self.value}).')
138+
print(f'Error: Cannot change magnification index (current={self.value}).')
139139

140140
def decrease(self) -> None:
141141
try:
142142
self.index -= 1
143143
except ValueError:
144-
print(f'Error: Cannot change magnficication index (current={self.value}).')
144+
print(f'Error: Cannot change magnification index (current={self.value}).')
145145

146146
def get_ranges(self) -> dict:
147147
"""Runs through all modes and fetches all the magnification settings

0 commit comments

Comments
 (0)