Skip to content
182 changes: 76 additions & 106 deletions src/instamatic/gui/ctrl_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ def __init__(self, parent):

frame = Frame(self)

stage_reset_btn = Button(frame, text='Reset stage', command=self.reset_stage)
stage_reset_btn.grid(row=0, column=1, sticky='W')

b_stage_stop = Button(frame, text='Stop stage', command=self.stage_stop)
b_stage_stop.grid(row=0, column=2, sticky='W')

Expand All @@ -31,59 +34,47 @@ def __init__(self, parent):
b_find_eucentric_height = Button(
frame, text='Find eucentric height', command=self.find_eucentric_height
)
b_find_eucentric_height.grid(row=0, column=0, sticky='EW', columnspan=2)
b_find_eucentric_height.grid(row=0, column=0, sticky='EW')

Label(frame, text='Mode:').grid(row=8, column=0, sticky='W')
self.o_mode = OptionMenu(
frame,
self.var_mode,
'diff',
'diff',
'mag1',
'mag2',
'lowmag',
'samag',
command=self.set_mode,
)
self.o_mode.grid(row=8, column=1, sticky='W', padx=10)
ranges = config.microscope.ranges
modes = list(ranges.keys())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Python always iterates over the dict keys, so it's not necessary to call keys.

Suggested change
ranges = config.microscope.ranges
modes = list(ranges.keys())
modes = list(config.microscope.ranges)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The panels gets only as much love as time I can spare now, unfortunately.
Also, as import this verse 2 proclaimeth, Explicit is better than implicit

self.o_mode = OptionMenu(frame, self.var_mode, modes[0], *modes, command=self.set_mode)
self.o_mode.grid(row=8, column=1, sticky='EW')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I noticed when playing around with simulations is that the initial value for the dropdown is not the actual initial value on the microscope (at least using the simulation microscope). I also just noticed that the names of the different modes are inconsistent between FEI and JEOL microscopes, but your implementation here accounts for that.

self.ctrl is only populated in the end of the constructor, so I don't think we can get the initial mode without moving self.ctrl to the start of the constructor.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@viljarjf Yea, the values were hardcoded here so I suggest pulling them from config. I am not sure why self.ctrl is at the end, I checked and it works at the beginning at least on the simulator. This prevents nice larger changes. @stefsmeets do you remember?


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

frame = Frame(self)

Label(frame, text='Angle (-)', width=20).grid(row=1, column=0, sticky='W')
Label(frame, text='Angle (0)', width=20).grid(row=2, column=0, sticky='W')
Label(frame, text='Angle (+)', width=20).grid(row=3, column=0, sticky='W')
Label(frame, text='Alpha wobbler (±)', width=20).grid(row=4, column=0, sticky='W')
Label(frame, text='Stage(XY)', width=20).grid(row=6, column=0, sticky='W')
Label(frame, text='Stage (XY)', width=20).grid(row=6, column=0, sticky='W')

e_negative_angle = Spinbox(
frame, width=10, textvariable=self.var_negative_angle, from_=-90, to=90, increment=5
)
angle = {'width': 10, 'from_': -90, 'to': 90, 'increment': 5}
angle_i1 = {**angle, 'increment': 1}
stage = {'width': 10, 'from_': -1e6, 'to': 1e6, 'increment': 100}

e_negative_angle = Spinbox(frame, textvariable=self.var_negative_angle, **angle)
e_negative_angle.grid(row=1, column=1, sticky='EW')
e_neutral_angle = Spinbox(
frame, width=10, textvariable=self.var_neutral_angle, from_=-90, to=90, increment=5
)
e_neutral_angle = Spinbox(frame, textvariable=self.var_neutral_angle, **angle)
e_neutral_angle.grid(row=2, column=1, sticky='EW')
e_positive_angle = Spinbox(
frame, width=10, textvariable=self.var_positive_angle, from_=-90, to=90, increment=5
)
e_positive_angle = Spinbox(frame, textvariable=self.var_positive_angle, **angle)
e_positive_angle.grid(row=3, column=1, sticky='EW')

e_alpha_wobbler = Spinbox(
frame, width=10, textvariable=self.var_alpha_wobbler, from_=-90, to=90, increment=1
)
e_alpha_wobbler = Spinbox(frame, textvariable=self.var_alpha_wobbler, **angle_i1)
e_alpha_wobbler.grid(row=4, column=1, sticky='EW')
self.b_start_wobble = Button(frame, text='Start', command=self.start_alpha_wobbler)
self.b_start_wobble.grid(row=4, column=2, sticky='W')
self.b_stop_wobble = Button(
frame, text='Stop', command=self.stop_alpha_wobbler, state=DISABLED

b_wobble = Checkbutton(
frame,
text='Toggle wobble',
variable=self.var_alpha_wobbler_on,
command=self.toggle_alpha_wobbler,
)
self.b_stop_wobble.grid(row=4, column=3, sticky='W')
b_wobble.grid(row=4, column=2, sticky='W', columnspan=2)

e_stage_x = Entry(frame, width=10, textvariable=self.var_stage_x)
e_stage_x = Spinbox(frame, textvariable=self.var_stage_x, **stage)
e_stage_x.grid(row=6, column=1, sticky='EW')
e_stage_y = Entry(frame, width=10, textvariable=self.var_stage_y)
e_stage_y = Spinbox(frame, textvariable=self.var_stage_y, **stage)
e_stage_y.grid(row=6, column=2, sticky='EW')

if config.settings.use_goniotool:
Expand Down Expand Up @@ -112,7 +103,7 @@ def __init__(self, parent):
b_stage_get.grid(row=6, column=4, sticky='W')

# defocus button
Label(frame, text='Diff defocus:', width=20).grid(row=13, column=0, sticky='W')
Label(frame, text='Diff defocus', width=20).grid(row=13, column=0, sticky='W')
self.e_diff_defocus = Spinbox(
frame,
textvariable=self.var_diff_defocus,
Expand All @@ -126,7 +117,7 @@ def __init__(self, parent):
self.c_toggle_defocus = Checkbutton(
frame,
text='Toggle defocus',
variable=self.var_toggle_diff_defocus,
variable=self.var_diff_defocus_on,
command=self.toggle_diff_defocus,
)
self.c_toggle_defocus.grid(row=13, column=2, sticky='W', columnspan=2)
Expand Down Expand Up @@ -161,19 +152,22 @@ def __init__(self, parent):
)
slider.grid(row=12, column=0, columnspan=3, sticky='EW')

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

frame = Frame(self)
# Magnification
Label(frame, text='Magnification', width=20).grid(row=14, column=0, sticky='W')
Comment on lines +156 to +157
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any merit to displaying the magnification value as well? Increasing and decreasing with buttons is the way to go I think, but at least for the sim microscope it is useful to see the actual magnification too

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@viljarjf I absolutely wanted to display this value and the traces of this idea are in the code (see explicit declaration of ranges = config.microscope.ranges dict with this info) but once I started implementing it I noticed this requires a lot of changes, so I backpedaled for now. Maybe I'll add a print at least.

mag_inc_btn = Button(frame, text='+', command=self.increase_mag)
mag_inc_btn.grid(row=14, column=1)
mag_dec_btn = Button(frame, text='-', command=self.decrease_mag)
mag_dec_btn.grid(row=14, column=2)

Label(frame, text='DiffFocus', width=20).grid(row=11, column=0, sticky='W')
Label(frame, text='DiffFocus', width=20).grid(row=21, column=0, sticky='W')
e_difffocus = Entry(frame, width=10, textvariable=self.var_difffocus)
e_difffocus.grid(row=11, column=1, sticky='W')
e_difffocus.grid(row=21, column=1, sticky='W')

b_difffocus = Button(frame, text='Set', command=self.set_difffocus)
b_difffocus.grid(row=11, column=2, sticky='W')
b_difffocus.grid(row=21, column=2, sticky='WE')

b_difffocus_get = Button(frame, text='Get', command=self.get_difffocus)
b_difffocus_get.grid(row=11, column=3, sticky='W')
b_difffocus_get.grid(row=21, column=3, sticky='W')

slider = Scale(
frame,
Expand All @@ -183,7 +177,7 @@ def __init__(self, parent):
orient=HORIZONTAL,
command=self.set_difffocus,
)
slider.grid(row=12, column=0, columnspan=3, sticky='EW')
slider.grid(row=22, column=0, columnspan=3, sticky='EW')

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

Expand All @@ -199,6 +193,7 @@ def init_vars(self):
self.var_mode = StringVar(value='diff')

self.var_alpha_wobbler = DoubleVar(value=5)
self.var_alpha_wobbler_on = BooleanVar(value=False)

self.var_stage_x = IntVar(value=0)
self.var_stage_y = IntVar(value=0)
Expand All @@ -209,7 +204,7 @@ def init_vars(self):
self.var_difffocus = IntVar(value=65535)

self.var_diff_defocus = IntVar(value=1500)
self.var_toggle_diff_defocus = BooleanVar(value=False)
self.var_diff_defocus_on = BooleanVar(value=False)

self.var_stage_wait = BooleanVar(value=True)

Expand All @@ -228,6 +223,15 @@ def set_brightness(self, event=None):
def get_brightness(self, event=None):
self.var_brightness.set(self.ctrl.brightness.get())

def increase_mag(self):
self.ctrl.magnification.increase()

def decrease_mag(self):
self.ctrl.magnification.decrease()

def reset_stage(self):
self.ctrl.stage.set(0, 0, 0, 0, 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ctrl.stage.neutral() also exists, but it does exactly the same


def set_difffocus(self, event=None):
self.var_difffocus.set(self.var_difffocus.get())
self.q.put(('ctrl', {'task': 'difffocus.set', 'value': self.var_difffocus.get()}))
Expand All @@ -236,44 +240,19 @@ def set_difffocus(self, event=None):
def get_difffocus(self, event=None):
self.var_difffocus.set(self.ctrl.difffocus.get())

def set_negative_angle(self):
self.q.put(
(
'ctrl',
{
'task': 'stage.set',
'a': self.var_negative_angle.get(),
'wait': self.var_stage_wait.get(),
},
)
)
def _set_angle(self, var: Variable) -> None:
kwargs = {'task': 'stage.set', 'a': var.get(), 'wait': self.var_stage_wait.get()}
self.q.put(('ctrl', kwargs))
self.triggerEvent.set()

def set_negative_angle(self):
return self._set_angle(self.var_negative_angle)

def set_neutral_angle(self):
self.q.put(
(
'ctrl',
{
'task': 'stage.set',
'a': self.var_neutral_angle.get(),
'wait': self.var_stage_wait.get(),
},
)
)
self.triggerEvent.set()
return self._set_angle(self.var_neutral_angle)

def set_positive_angle(self):
self.q.put(
(
'ctrl',
{
'task': 'stage.set',
'a': self.var_positive_angle.get(),
'wait': self.var_stage_wait.get(),
},
)
)
self.triggerEvent.set()
return self._set_angle(self.var_positive_angle)

def set_goniotool_tx(self, event=None, value=None):
if not value:
Expand Down Expand Up @@ -303,29 +282,22 @@ def get_stage(self, event=None):
self.var_stage_x.set(round(x))
self.var_stage_y.set(round(y))

def start_alpha_wobbler(self):
self.wobble_stop_event = threading.Event()

self.b_stop_wobble.config(state=NORMAL)
self.b_start_wobble.config(state=DISABLED)

self.q.put(
(
'ctrl',
{
'task': 'stage.alpha_wobbler',
'delta': self.var_alpha_wobbler.get(),
'event': self.wobble_stop_event,
},
def toggle_alpha_wobbler(self):
if self.var_alpha_wobbler_on.get():
self.wobble_stop_event = threading.Event()
self.q.put(
(
'ctrl',
{
'task': 'stage.alpha_wobbler',
'delta': self.var_alpha_wobbler.get(),
'event': self.wobble_stop_event,
},
)
)
)
self.triggerEvent.set()

def stop_alpha_wobbler(self):
self.wobble_stop_event.set()

self.b_stop_wobble.config(state=DISABLED)
self.b_start_wobble.config(state=NORMAL)
self.triggerEvent.set()
else: # wobbler off
self.wobble_stop_event.set()

def stage_stop(self):
self.q.put(('ctrl', {'task': 'stage.stop'}))
Expand All @@ -336,21 +308,19 @@ def find_eucentric_height(self):
self.triggerEvent.set()

def toggle_diff_defocus(self):
toggle = self.var_toggle_diff_defocus.get()

if toggle:
if self.var_diff_defocus_on.get():
offset = self.var_diff_defocus.get()
self.ctrl.difffocus.defocus(offset=offset)
self.b_reset_defocus.config(state=NORMAL)
else:
self.ctrl.difffocus.refocus()
self.var_toggle_diff_defocus.set(False)
self.var_diff_defocus_on.set(False)

self.get_difffocus()

def reset_diff_defocus(self):
self.ctrl.difffocus.refocus()
self.var_toggle_diff_defocus.set(False)
self.var_diff_defocus_on.set(False)
self.get_difffocus()


Expand Down
4 changes: 2 additions & 2 deletions src/instamatic/microscope/components/lenses.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,13 @@ def increase(self) -> None:
try:
self.index += 1
except ValueError:
print(f'Error: Cannot change magnficication index (current={self.value}).')
print(f'Error: Cannot change magnification index (current={self.value}).')

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

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