def make_entry(self, frame, var, label, row, column, minval, maxval, increment): Label(frame, text=label).grid(row=row, column=column, sticky="EW") e = Spinbox(frame, width=10, textvariable=var, from_=minval, to=maxval, increment=increment) e.grid(row=row, column=column + 1, sticky="EW", padx=5, pady=2.5)
def make_slider(self, frame, var, label, row, minval, maxval, command=None): Label(frame, text=label, width=20).grid(row=row, column=0, sticky="W") e = Spinbox(frame, width=10, textvariable=var, from_=minval, to=maxval, increment=0.1) e.grid(row=row, column=1, sticky="EW", padx=5) slider = Scale(frame, variable=var, from_=minval, to=maxval, command=command) slider.grid(row=row, column=2, columnspan=2, sticky="EW")
class VideoStreamFrame(Frame): """docstring for VideoStreamFrame""" def __init__(self, parent, stream, app=None): super().__init__() self.stream = stream self.app = app self.panel = None self.frame_delay = 50 self.frametime = 0.05 self.brightness = 1.0 self.display_range = self.display_range_default = self.stream.cam.dynamic_range # Maximum number from image readout self.auto_contrast = True self.resize_image = False self.last = time.perf_counter() self.nframes = 1 self.update_frequency = 0.25 self.last_interval = self.frametime self._atexit_funcs = [] ####################### self.parent = parent self.init_vars() self.buttonbox(self.parent) self.header(self.parent) self.makepanel(self.parent) self.parent.wm_title("Video stream") self.parent.wm_protocol("WM_DELETE_WINDOW", self.close) self.parent.bind('<Escape>', self.close) self.start_stream() def init_vars(self): self.var_fps = DoubleVar() self.var_interval = DoubleVar() # self.var_overhead = DoubleVar() self.var_frametime = DoubleVar() self.var_frametime.set(self.frametime) self.var_frametime.trace_add("write", self.update_frametime) self.var_brightness = DoubleVar(value=self.brightness) self.var_brightness.trace_add("write", self.update_brightness) self.var_display_range = DoubleVar(value=self.display_range_default) self.var_display_range.trace_add("write", self.update_display_range) self.var_resize_image = BooleanVar(value=self.resize_image) self.var_resize_image.trace_add("write", self.update_resize_image) self.var_auto_contrast = BooleanVar(value=self.auto_contrast) self.var_auto_contrast.trace_add("write", self.update_auto_contrast) def buttonbox(self, master): btn = Button(master, text="Save image", command=self.saveImage) btn.pack(side="bottom", fill="both", padx=10, pady=10) def header(self, master): ewidth = 8 lwidth = 12 frame = Frame(master) self.cb_resize = Checkbutton(frame, text="Increase size", variable=self.var_resize_image) self.cb_resize.grid(row=1, column=4) self.cb_contrast = Checkbutton(frame, text="Auto contrast", variable=self.var_auto_contrast) self.cb_contrast.grid(row=1, column=5) self.e_fps = Entry(frame, width=lwidth, textvariable=self.var_fps, state=DISABLED) self.e_interval = Entry(frame, width=lwidth, textvariable=self.var_interval, state=DISABLED) # self.e_overhead = Entry(frame, bd=0, width=ewidth, textvariable=self.var_overhead, state=DISABLED) Label(frame, width=lwidth, text="fps:").grid(row=1, column=0) self.e_fps.grid(row=1, column=1, sticky='we') Label(frame, width=lwidth, text="interval (ms):").grid(row=1, column=2) self.e_interval.grid(row=1, column=3, sticky='we') # Label(frame, width=lwidth, text="overhead (ms):").grid(row=1, column=4) # self.e_overhead.grid(row=1, column=5) frame.pack() frame = Frame(master) self.e_frametime = Spinbox(frame, width=ewidth, textvariable=self.var_frametime, from_=0.0, to=1.0, increment=0.01) Label(frame, width=lwidth, text="exposure (s)").grid(row=1, column=0) self.e_frametime.grid(row=1, column=1) self.e_brightness = Spinbox(frame, width=ewidth, textvariable=self.var_brightness, from_=0.0, to=10.0, increment=0.1) Label(frame, width=lwidth, text="Brightness").grid(row=1, column=2) self.e_brightness.grid(row=1, column=3) Label(frame, width=lwidth, text="DisplayRange").grid(row=1, column=4) self.e_display_range = Spinbox(frame, width=ewidth, textvariable=self.var_display_range, from_=1, to=self.display_range_default, increment=1000) self.e_display_range.grid(row=1, column=5) frame.pack() def makepanel(self, master, resolution=(512, 512)): if self.panel is None: image = Image.fromarray(np.zeros(resolution)) image = ImageTk.PhotoImage(image) self.panel = Label(image=image) self.panel.image = image self.panel.pack(side="left", padx=10, pady=10) def setup_stream(self): pass def update_resize_image(self, name, index, mode): # print name, index, mode try: self.resize_image = self.var_resize_image.get() except: pass def update_auto_contrast(self, name, index, mode): # print name, index, mode try: self.auto_contrast = self.var_auto_contrast.get() except: pass def update_frametime(self, name, index, mode): # print name, index, mode try: self.frametime = self.var_frametime.get() except: pass else: self.stream.update_frametime(self.frametime) def update_brightness(self, name, index, mode): # print name, index, mode try: self.brightness = self.var_brightness.get() except: pass def update_display_range(self, name, index, mode): try: val = self.var_display_range.get() self.display_range = max(1, val) except: pass def saveImage(self): """Dump the current frame to a file""" outfile = datetime.datetime.now().strftime( "%Y%m%d-%H%M%S.%f") + ".tiff" if self.app: module_io = self.app.get_module("io") drc = module_io.get_experiment_directory() drc.mkdir(exist_ok=True, parents=True) outfile = drc / outfile try: flatfield, h = read_tiff(module_io.get_flatfield()) frame = apply_flatfield_correction(self.frame, flatfield) except: frame = self.frame h = {} else: frame = self.frame h = {} write_tiff(outfile, frame, header=h) print(" >> Wrote file:", outfile) def close(self): self.stream.close() self.parent.quit() # for func in self._atexit_funcs: # func() def start_stream(self): self.stream.update_frametime(self.frametime) self.parent.after(500, self.on_frame) def on_frame(self, event=None): self.stream.lock.acquire(True) self.frame = frame = self.stream.frame self.stream.lock.release() # the display range in ImageTk is from 0 to 256 if self.auto_contrast: frame = frame * (256.0 / (1 + np.percentile(frame[::4, ::4], 99.5)) ) # use 128x128 array for faster calculation image = Image.fromarray(frame) elif self.display_range != self.display_range_default: image = np.clip(frame, 0, self.display_range) image = (256.0 / self.display_range) * image image = Image.fromarray(image) else: image = Image.fromarray(frame) if self.brightness != 1: image = ImageEnhance.Brightness(image.convert("L")).enhance( self.brightness) # Can also use ImageEnhance.Sharpness or ImageEnhance.Contrast if needed if self.resize_image: image = image.resize((950, 950)) image = ImageTk.PhotoImage(image=image) self.panel.configure(image=image) # keep a reference to avoid premature garbage collection self.panel.image = image self.update_frametimes() # self.parent.update_idletasks() self.parent.after(self.frame_delay, self.on_frame) def update_frametimes(self): self.current = time.perf_counter() delta = self.current - self.last if delta > self.update_frequency: interval = delta / self.nframes interval = (interval * 0.5) + (self.last_interval * 0.5) fps = 1.0 / interval # overhead = interval - self.stream.frametime self.var_fps.set(round(fps, 2)) self.var_interval.set(round(interval * 1000, 2)) # self.var_overhead.set(round(overhead*1000, 2)) self.last = self.current self.nframes = 1 self.last_interval = interval else: self.nframes += 1
def __init__(self, parent): LabelFrame.__init__(self, parent, text="Stage Control") self.parent = parent self.init_vars() frame = Frame(self) b_stage_stop = Button(frame, text="Stop stage", command=self.stage_stop) b_stage_stop.grid(row=0, column=2, sticky="W") cb_nowait = Checkbutton(frame, text="Wait for stage", variable=self.var_stage_wait) cb_nowait.grid(row=0, column=3) 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) 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) 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=5, column=0, sticky="W") e_negative_angle = Spinbox(frame, width=10, textvariable=self.var_negative_angle, from_=-90, to=90, increment=5) 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.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.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.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) self.b_stop_wobble.grid(row=4, column=3, sticky="W") e_stage_x = Entry(frame, width=10, textvariable=self.var_stage_x) e_stage_x.grid(row=5, column=1, sticky="EW") e_stage_y = Entry(frame, width=10, textvariable=self.var_stage_y) e_stage_y.grid(row=5, column=2, sticky="EW") b_negative_angle = Button(frame, text="Set", command=self.set_negative_angle) b_negative_angle.grid(row=1, column=2, sticky="W") b_neutral_angle = Button(frame, text="Set", command=self.set_neutral_angle) b_neutral_angle.grid(row=2, column=2, sticky="W") b_positive_angle = Button(frame, text="Set", command=self.set_positive_angle) b_positive_angle.grid(row=3, column=2, sticky="W") b_stage = Button(frame, text="Set", command=self.set_stage) b_stage.grid(row=5, column=3, sticky="W") b_stage_get = Button(frame, text="Get", command=self.get_stage) b_stage_get.grid(row=5, column=4, sticky="W") # frame.grid_columnconfigure(1, weight=1) frame.pack(side="top", fill="x", padx=10, pady=10) frame = Frame(self) Label(frame, text="Brightness", width=20).grid(row=11, column=0, sticky="W") e_brightness = Entry(frame, width=10, textvariable=self.var_brightness) e_brightness.grid(row=11, column=1, sticky="W") b_brightness = Button(frame, text="Set", command=self.set_brightness) b_brightness.grid(row=11, column=2, sticky="W") b_brightness_get = Button(frame, text="Get", command=self.get_brightness) b_brightness_get.grid(row=11, column=3, sticky="W") slider = Scale(frame, variable=self.var_brightness, from_=0, to=2**16 - 1, orient=HORIZONTAL, command=self.set_brightness) slider.grid(row=12, column=0, columnspan=3, sticky="EW") frame.pack(side="top", fill="x", padx=10, pady=10) frame = Frame(self) Label(frame, text="DiffFocus", width=20).grid(row=11, column=0, sticky="W") e_difffocus = Entry(frame, width=10, textvariable=self.var_difffocus) e_difffocus.grid(row=11, 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_get = Button(frame, text="Get", command=self.get_difffocus) b_difffocus_get.grid(row=11, column=3, sticky="W") slider = Scale(frame, variable=self.var_difffocus, from_=0, to=2**16 - 1, orient=HORIZONTAL, command=self.set_difffocus) slider.grid(row=12, column=0, columnspan=3, sticky="EW") frame.pack(side="top", fill="x", padx=10, pady=10) from instamatic import TEMController self.ctrl = TEMController.get_instance()
class ExperimentalcRED_FEI(LabelFrame): """docstring for ExperimentalcRED on FEI""" def __init__(self, parent): LabelFrame.__init__(self, parent, text="cRED_FEI") self.parent = parent sbwidth = 10 self.init_vars() frame = Frame(self) Label(frame, text="Exposure time (s):").grid(row=4, column=0, sticky="W") self.e_exposure_time = Spinbox(frame, textvariable=self.var_exposure_time, width=sbwidth, from_=0.1, to=9999, increment=0.1) self.e_exposure_time.grid(row=4, column=1, sticky="W", padx=10) Label(frame, text="Target angle (deg):").grid(row=5, column=0, sticky="W") self.e_endangle = Spinbox(frame, textvariable=self.var_endangle, width=sbwidth, from_=0.1, to=9999, increment=0.5) self.e_endangle.grid(row=5, column=1, sticky="W", padx=10) Label(frame, text="Rotation speed (0 - 1):").grid(row=6, column=0, sticky="W") self.e_rotspeed = Spinbox(frame, textvariable=self.var_rotspeed, width=sbwidth, from_=-10.0, to=10.0, increment=0.2) self.e_rotspeed.grid(row=6, column=1, sticky="W", padx=10) frame.pack(side="top", fill="x", padx=10, pady=10) frame = Frame(self) Label(frame, text="Output formats:").grid(row=5, columnspan=2, sticky="EW") Checkbutton(frame, text="PETS (.tiff)", variable=self.var_save_tiff, state=DISABLED).grid(row=5, column=2, sticky="EW") Checkbutton(frame, text="REDp (.mrc)", variable=self.var_save_red, state=DISABLED).grid(row=5, column=3, sticky="EW") frame.grid_columnconfigure(0, weight=1) frame.grid_columnconfigure(1, weight=1) frame.grid_columnconfigure(2, weight=1) frame.grid_columnconfigure(3, weight=1) frame.pack(side="top", fill="x", padx=10, pady=10) frame = Frame(self) self.StartButton = Button(frame, text="Start Rotation", command=self.start_collection) self.StartButton.grid(row=1, column=0, sticky="EW") self.FinalizeButton = Button(frame, text="Stop Rotation", command=self.stop_collection, state=DISABLED) self.FinalizeButton.grid(row=1, column=2, sticky="EW") frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=1) frame.columnconfigure(2, weight=1) frame.pack(side="bottom", fill="x", padx=10, pady=10) def init_vars(self): self.var_exposure_time = DoubleVar(value=0.5) self.var_endangle = DoubleVar(value=60.0) self.var_rotspeed = DoubleVar(value=1.0) self.var_save_tiff = BooleanVar(value=True) self.var_save_red = BooleanVar(value=True) def set_trigger(self, trigger=None, q=None): self.triggerEvent = trigger self.q = q def start_collection(self): self.StartButton.config(state=DISABLED) self.FinalizeButton.config(state=NORMAL) self.e_exposure_time.config(state=DISABLED) self.e_rotspeed.config(state=DISABLED) self.q.put(("credfei", { "task": "stageposition.set_with_speed", "a": self.var_endangle.get(), "speed": self.var_rotspeed.get() })) self.triggerEvent.set() def stop_collection(self): self.StartButton.config(state=NORMAL) self.FinalizeButton.config(state=DISABLED) self.e_exposure_time.config(state=NORMAL) self.e_rotspeed.config(state=NORMAL) params = self.get_params(task="None") self.q.put(("credfei", params)) self.triggerEvent.set() def get_params(self, task=None): params = { "exposure_time": self.var_exposure_time.get(), "endangle": self.var_endangle.get(), "rotspeed": self.var_rotspeed.get(), "task": task } return params
class ExperimentalcRED_FEI(LabelFrame): """Simple panel to assist cRED data collection (mainly rotation control) on a FEI microscope.""" def __init__(self, parent): LabelFrame.__init__(self, parent, text='cRED_FEI') self.parent = parent sbwidth = 10 self.init_vars() frame = Frame(self) Label(frame, text='Exposure time (s):').grid(row=4, column=0, sticky='W') self.e_exposure_time = Spinbox(frame, textvariable=self.var_exposure_time, width=sbwidth, from_=0.1, to=9999, increment=0.1) self.e_exposure_time.grid(row=4, column=1, sticky='W', padx=10) Label(frame, text='Target angle (deg):').grid(row=5, column=0, sticky='W') self.e_endangle = Spinbox(frame, textvariable=self.var_endangle, width=sbwidth, from_=0.1, to=9999, increment=0.5) self.e_endangle.grid(row=5, column=1, sticky='W', padx=10) Label(frame, text='Rotation speed (0 - 1):').grid(row=6, column=0, sticky='W') self.e_rotspeed = Spinbox(frame, textvariable=self.var_rotspeed, width=sbwidth, from_=-10.0, to=10.0, increment=0.2) self.e_rotspeed.grid(row=6, column=1, sticky='W', padx=10) frame.pack(side='top', fill='x', padx=10, pady=10) frame = Frame(self) Label(frame, text='Output formats:').grid(row=5, columnspan=2, sticky='EW') Checkbutton(frame, text='PETS (.tiff)', variable=self.var_save_tiff, state=DISABLED).grid(row=5, column=2, sticky='EW') Checkbutton(frame, text='REDp (.mrc)', variable=self.var_save_red, state=DISABLED).grid(row=5, column=3, sticky='EW') frame.grid_columnconfigure(0, weight=1) frame.grid_columnconfigure(1, weight=1) frame.grid_columnconfigure(2, weight=1) frame.grid_columnconfigure(3, weight=1) frame.pack(side='top', fill='x', padx=10, pady=10) frame = Frame(self) self.StartButton = Button(frame, text='Start Rotation', command=self.start_collection) self.StartButton.grid(row=1, column=0, sticky='EW') self.FinalizeButton = Button(frame, text='Stop Rotation', command=self.stop_collection, state=DISABLED) self.FinalizeButton.grid(row=1, column=2, sticky='EW') frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=1) frame.columnconfigure(2, weight=1) frame.pack(side='bottom', fill='x', padx=10, pady=10) def init_vars(self): self.var_exposure_time = DoubleVar(value=0.5) self.var_endangle = DoubleVar(value=60.0) self.var_rotspeed = DoubleVar(value=1.0) self.var_save_tiff = BooleanVar(value=True) self.var_save_red = BooleanVar(value=True) def set_trigger(self, trigger=None, q=None): self.triggerEvent = trigger self.q = q def start_collection(self): self.StartButton.config(state=DISABLED) self.FinalizeButton.config(state=NORMAL) self.e_exposure_time.config(state=DISABLED) self.e_rotspeed.config(state=DISABLED) self.q.put(('credfei', { 'task': 'stage.set_with_speed', 'a': self.var_endangle.get(), 'speed': self.var_rotspeed.get() })) self.triggerEvent.set() def stop_collection(self): self.StartButton.config(state=NORMAL) self.FinalizeButton.config(state=DISABLED) self.e_exposure_time.config(state=NORMAL) self.e_rotspeed.config(state=NORMAL) params = self.get_params(task='None') self.q.put(('credfei', params)) self.triggerEvent.set() def get_params(self, task=None): params = { 'exposure_time': self.var_exposure_time.get(), 'endangle': self.var_endangle.get(), 'rotspeed': self.var_rotspeed.get(), 'task': task } return params
class IOFrame(LabelFrame): """Simple interface to set the working directory and experiment name/numbering, and access the configs/work directory.""" def __init__(self, parent): LabelFrame.__init__(self, parent, text='Input/Output') self.parent = parent self.workdrc = Path(config.settings.work_directory) self.init_vars() frame = Frame(self) self.directory = Entry(frame, width=50, textvariable=self.var_directory) self.directory.grid(row=2, column=1, sticky='EW') self.BrowseButton = Button(frame, text='Browse..', command=self.browse_directory) self.BrowseButton.grid(row=2, column=2, sticky='EW') self.sample_name = Entry(frame, width=50, textvariable=self.var_sample_name) self.sample_name.grid(row=3, column=1, sticky='EW') self.flatfield = Entry(frame, width=50, textvariable=self.var_flatfield) self.flatfield.grid(row=4, column=1, sticky='EW') self.BrowseFFButton = Button(frame, text='Browse..', command=self.browse_flatfield) self.BrowseFFButton.grid(row=4, column=2, sticky='EW') Label(frame, text='Directory:').grid(row=2, column=0, sticky='W') Label(frame, text='Sample name:').grid(row=3, column=0, sticky='W') Label(frame, text='Flatfield:').grid(row=4, column=0, sticky='W') self.incrementer = Spinbox(frame, width=10, from_=0, to=999, increment=1, textvariable=self.var_experiment_number) self.incrementer.grid(row=3, column=2) frame.grid_columnconfigure(1, weight=1) frame.pack(side='top', fill='x', padx=10) frame = Frame(self) self.OpenDatadirButton = Button(frame, text='Open work directory', command=self.open_data_directory) self.OpenDatadirButton.grid(row=1, column=0, sticky='EW') self.OpenConfigdirButton = Button(frame, text='Open settings directory', command=self.open_config_directory) self.OpenConfigdirButton.grid(row=1, column=1, sticky='EW') self.DeleteButton = Button(frame, text='Delete last experiment', command=self.delete_last) self.DeleteButton.grid(row=1, column=2, sticky='EW') frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=1) frame.columnconfigure(2, weight=1) frame.pack(side='bottom', fill='both', padx=10, pady=10) self.update_experiment_number() def init_vars(self): workdrc = self.workdrc ff = config.settings.flatfield if not ff: self.var_flatfield = StringVar(value='') else: self.var_flatfield = StringVar(value=Path(ff).absolute()) self.var_directory = StringVar(value=workdrc.absolute()) self.var_sample_name = StringVar(value='experiment') self.var_experiment_number = IntVar(value=1) def get_working_directory(self): drc = self.var_directory.get() return Path(drc) def update_experiment_number(self): drc = Path(self.var_directory.get()) name = self.var_sample_name.get() number = self.var_experiment_number.get() path = drc / f'{name}_{number}' while path.exists(): number += 1 path = drc / f'{name}_{number}' self.var_experiment_number.set(number) return number def get_new_experiment_directory(self): self.update_experiment_number() return self.get_experiment_directory() def get_experiment_directory(self): drc = Path(self.var_directory.get()) name = self.var_sample_name.get() number = self.var_experiment_number.get() path = drc / f'{name}_{number}' return path def browse_directory(self): drc = tkinter.filedialog.askdirectory(parent=self.parent, title='Select working directory') if not drc: return drc = Path(drc).absolute() self.var_directory.set(drc) print(self.get_experiment_directory()) self.update_experiment_number() # TODO: set to 1 on experiment update return drc def browse_flatfield(self): ff = tkinter.filedialog.askopenfilename( parent=self.parent, initialdir=self.var_directory.get(), title='Select flatfield') if not ff: return ff = Path(ff).absolute() self.var_flatfield.set(ff) return ff def get_flatfield(self): ff = self.var_flatfield.get() if ff == '': ff = None return ff def delete_last(self): drc = self.get_experiment_directory() date = datetime.datetime.now().strftime('%H%M%S') newdrc = drc.parent / f'delete_me-{date}' if drc.exists(): drc.rename(newdrc) print(f'Marked {drc} for deletion') else: print(f'{drc} does not exist') def open_data_directory(self): drc = self.get_working_directory() try: os.startfile(drc) except FileNotFoundError: os.startfile(drc.parent) def open_config_directory(self): drc = config.locations['base'] os.startfile(drc)
class VideoStreamFrame(LabelFrame): """GUI panel to continuously display the last frame streamed from the camera.""" def __init__(self, parent, stream, app=None): LabelFrame.__init__(self, parent, text='Stream') self.parent = parent self.stream = stream self.app = app self.panel = None self.frame_delay = 50 self.frametime = 0.05 self.brightness = 1.0 self.display_range = self.display_range_default = self.stream.cam.dynamic_range # Maximum number from image readout self.auto_contrast = True self.resize_image = False self.last = time.perf_counter() self.nframes = 1 self.update_frequency = 0.25 self.last_interval = self.frametime self._atexit_funcs = [] ####################### self.parent = parent self.init_vars() self.buttonbox(self) self.header(self) self.makepanel(self) try: self.parent.wm_title('Video stream') self.parent.wm_protocol('WM_DELETE_WINDOW', self.close) except AttributeError: pass self.parent.bind('<Escape>', self.close) self.start_stream() def init_vars(self): self.var_fps = DoubleVar() self.var_interval = DoubleVar() # self.var_overhead = DoubleVar() self.var_frametime = DoubleVar() self.var_frametime.set(self.frametime) self.var_frametime.trace_add('write', self.update_frametime) self.var_brightness = DoubleVar(value=self.brightness) self.var_brightness.trace_add('write', self.update_brightness) self.var_display_range = DoubleVar(value=self.display_range_default) self.var_display_range.trace_add('write', self.update_display_range) self.var_resize_image = BooleanVar(value=self.resize_image) self.var_resize_image.trace_add('write', self.update_resize_image) self.var_auto_contrast = BooleanVar(value=self.auto_contrast) self.var_auto_contrast.trace_add('write', self.update_auto_contrast) def buttonbox(self, master): btn = Button(master, text='Save image', command=self.saveImage) btn.pack(side='bottom', fill='both', padx=10, pady=10) def header(self, master): ewidth = 8 lwidth = 12 frame = Frame(master) self.cb_resize = Checkbutton(frame, text='Increase size', variable=self.var_resize_image) self.cb_resize.grid(row=1, column=4) self.cb_contrast = Checkbutton(frame, text='Auto contrast', variable=self.var_auto_contrast) self.cb_contrast.grid(row=1, column=5) self.e_fps = Entry(frame, width=lwidth, textvariable=self.var_fps, state=DISABLED) self.e_interval = Entry(frame, width=lwidth, textvariable=self.var_interval, state=DISABLED) # self.e_overhead = Entry(frame, bd=0, width=ewidth, textvariable=self.var_overhead, state=DISABLED) Label(frame, width=lwidth, text='fps:').grid(row=1, column=0) self.e_fps.grid(row=1, column=1, sticky='we') Label(frame, width=lwidth, text='interval (ms):').grid(row=1, column=2) self.e_interval.grid(row=1, column=3, sticky='we') # Label(frame, width=lwidth, text="overhead (ms):").grid(row=1, column=4) # self.e_overhead.grid(row=1, column=5) frame.pack() frame = Frame(master) self.e_frametime = Spinbox(frame, width=ewidth, textvariable=self.var_frametime, from_=0.0, to=1.0, increment=0.01) Label(frame, width=lwidth, text='exposure (s)').grid(row=1, column=0) self.e_frametime.grid(row=1, column=1) self.e_brightness = Spinbox(frame, width=ewidth, textvariable=self.var_brightness, from_=0.0, to=10.0, increment=0.1) Label(frame, width=lwidth, text='Brightness').grid(row=1, column=2) self.e_brightness.grid(row=1, column=3) Label(frame, width=lwidth, text='DisplayRange').grid(row=1, column=4) self.e_display_range = Spinbox(frame, width=ewidth, textvariable=self.var_display_range, from_=1, to=self.display_range_default, increment=1000) self.e_display_range.grid(row=1, column=5) frame.pack() def makepanel(self, master, resolution=(512, 512)): if self.panel is None: image = Image.fromarray(np.zeros(resolution)) image = ImageTk.PhotoImage(image) self.panel = Label(master, image=image) self.panel.image = image self.panel.pack(side='left', padx=10, pady=10) def setup_stream(self): pass def update_resize_image(self, name, index, mode): # print name, index, mode try: self.resize_image = self.var_resize_image.get() except BaseException: pass def update_auto_contrast(self, name, index, mode): # print name, index, mode try: self.auto_contrast = self.var_auto_contrast.get() except BaseException: pass def update_frametime(self, name, index, mode): # print name, index, mode try: self.frametime = self.var_frametime.get() except BaseException: pass else: self.stream.update_frametime(self.frametime) def update_brightness(self, name, index, mode): # print name, index, mode try: self.brightness = self.var_brightness.get() except BaseException: pass def update_display_range(self, name, index, mode): try: val = self.var_display_range.get() self.display_range = max(1, val) except BaseException: pass def saveImage(self): """Dump the current frame to a file.""" self.q.put(('save_image', {'frame': self.frame})) self.triggerEvent.set() def set_trigger(self, trigger=None, q=None): self.triggerEvent = trigger self.q = q def close(self): self.stream.close() self.parent.quit() # for func in self._atexit_funcs: # func() def start_stream(self): self.stream.update_frametime(self.frametime) self.after(500, self.on_frame) def on_frame(self, event=None): self.stream.lock.acquire(True) self.frame = frame = self.stream.frame self.stream.lock.release() # the display range in ImageTk is from 0 to 256 if self.auto_contrast: frame = frame * (256.0 / (1 + np.percentile(frame[::4, ::4], 99.5)) ) # use 128x128 array for faster calculation image = Image.fromarray(frame) elif self.display_range != self.display_range_default: image = np.clip(frame, 0, self.display_range) image = (256.0 / self.display_range) * image image = Image.fromarray(image) else: image = Image.fromarray(frame) if self.brightness != 1: image = ImageEnhance.Brightness(image.convert('L')).enhance( self.brightness) # Can also use ImageEnhance.Sharpness or ImageEnhance.Contrast if needed if self.resize_image: image = image.resize((950, 950)) image = ImageTk.PhotoImage(image=image) self.panel.configure(image=image) # keep a reference to avoid premature garbage collection self.panel.image = image self.update_frametimes() # self.parent.update_idletasks() self.after(self.frame_delay, self.on_frame) def update_frametimes(self): self.current = time.perf_counter() delta = self.current - self.last if delta > self.update_frequency: interval = delta / self.nframes interval = (interval * 0.5) + (self.last_interval * 0.5) fps = 1.0 / interval # overhead = interval - self.stream.frametime self.var_fps.set(round(fps, 2)) self.var_interval.set(round(interval * 1000, 2)) # self.var_overhead.set(round(overhead*1000, 2)) self.last = self.current self.nframes = 1 self.last_interval = interval else: self.nframes += 1
def __init__(self, parent): LabelFrame.__init__(self, parent, text='Stage Control') self.parent = parent self.init_vars() frame = Frame(self) b_stage_stop = Button(frame, text='Stop stage', command=self.stage_stop) b_stage_stop.grid(row=0, column=2, sticky='W') cb_nowait = Checkbutton(frame, text='Wait for stage', variable=self.var_stage_wait) cb_nowait.grid(row=0, column=3) 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) 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) 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') e_negative_angle = Spinbox(frame, width=10, textvariable=self.var_negative_angle, from_=-90, to=90, increment=5) 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.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.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.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) self.b_stop_wobble.grid(row=4, column=3, sticky='W') e_stage_x = Entry(frame, width=10, textvariable=self.var_stage_x) 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.grid(row=6, column=2, sticky='EW') if config.settings.use_goniotool: Label(frame, text='Rot. Speed', width=20).grid(row=5, column=0, sticky='W') e_goniotool_tx = Spinbox(frame, width=10, textvariable=self.var_goniotool_tx, from_=1, to=12, increment=1) e_goniotool_tx.grid(row=5, column=1, sticky='EW') b_goniotool_set = Button(frame, text='Set', command=self.set_goniotool_tx) b_goniotool_set.grid(row=5, column=2, sticky='W') b_goniotool_default = Button(frame, text='Default', command=self.set_goniotool_tx_default) b_goniotool_default.grid(row=5, column=3, sticky='W') b_negative_angle = Button(frame, text='Set', command=self.set_negative_angle) b_negative_angle.grid(row=1, column=2, sticky='W') b_neutral_angle = Button(frame, text='Set', command=self.set_neutral_angle) b_neutral_angle.grid(row=2, column=2, sticky='W') b_positive_angle = Button(frame, text='Set', command=self.set_positive_angle) b_positive_angle.grid(row=3, column=2, sticky='W') b_stage = Button(frame, text='Set', command=self.set_stage) b_stage.grid(row=6, column=3, sticky='W') b_stage_get = Button(frame, text='Get', command=self.get_stage) 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') self.e_diff_defocus = Spinbox(frame, textvariable=self.var_diff_defocus, width=10, from_=-10000, to=10000, increment=100) self.e_diff_defocus.grid(row=13, column=1, sticky='EW') self.c_toggle_defocus = Checkbutton( frame, text='Toggle defocus', variable=self.var_toggle_diff_defocus, command=self.toggle_diff_defocus) self.c_toggle_defocus.grid(row=13, column=2, sticky='W', columnspan=2) self.b_reset_defocus = Button(frame, text='Reset', command=self.reset_diff_defocus, state=DISABLED) self.b_reset_defocus.grid(row=13, column=4, sticky='EW') # frame.grid_columnconfigure(1, weight=1) frame.pack(side='top', fill='x', padx=10, pady=10) frame = Frame(self) Label(frame, text='Brightness', width=20).grid(row=11, column=0, sticky='W') e_brightness = Entry(frame, width=10, textvariable=self.var_brightness) e_brightness.grid(row=11, column=1, sticky='W') b_brightness = Button(frame, text='Set', command=self.set_brightness) b_brightness.grid(row=11, column=2, sticky='W') b_brightness_get = Button(frame, text='Get', command=self.get_brightness) b_brightness_get.grid(row=11, column=3, sticky='W') slider = Scale(frame, variable=self.var_brightness, from_=0, to=2**16 - 1, orient=HORIZONTAL, command=self.set_brightness) slider.grid(row=12, column=0, columnspan=3, sticky='EW') frame.pack(side='top', fill='x', padx=10, pady=10) frame = Frame(self) Label(frame, text='DiffFocus', width=20).grid(row=11, column=0, sticky='W') e_difffocus = Entry(frame, width=10, textvariable=self.var_difffocus) e_difffocus.grid(row=11, 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_get = Button(frame, text='Get', command=self.get_difffocus) b_difffocus_get.grid(row=11, column=3, sticky='W') slider = Scale(frame, variable=self.var_difffocus, from_=0, to=2**16 - 1, orient=HORIZONTAL, command=self.set_difffocus) slider.grid(row=12, column=0, columnspan=3, sticky='EW') frame.pack(side='top', fill='x', padx=10, pady=10) from instamatic import TEMController self.ctrl = TEMController.get_instance()
def __init__(self, parent): LabelFrame.__init__(self, parent, text="Continuous rotation electron diffraction") self.parent = parent sbwidth = 10 self.init_vars() frame = Frame(self) Label(frame, text="Exposure time (s):").grid(row=1, column=0, sticky="W") exposure_time = Spinbox(frame, textvariable=self.var_exposure_time, width=sbwidth, from_=0.0, to=100.0, increment=0.01) exposure_time.grid(row=1, column=1, sticky="W", padx=10) Checkbutton(frame, text="Beam unblanker", variable=self.var_unblank_beam).grid(row=1, column=2, sticky="W") Separator(frame, orient=HORIZONTAL).grid(row=4, columnspan=3, sticky="ew", pady=10) Checkbutton(frame, text="Enable image interval", variable=self.var_enable_image_interval, command=self.toggle_interval_buttons).grid(row=5, column=2, sticky="W") self.c_toggle_defocus = Checkbutton( frame, text="Toggle defocus", variable=self.var_toggle_diff_defocus, command=self.toggle_diff_defocus, state=DISABLED) self.c_toggle_defocus.grid(row=6, column=2, sticky="W") Label(frame, text="Image interval:").grid(row=5, column=0, sticky="W") self.e_image_interval = Spinbox(frame, textvariable=self.var_image_interval, width=sbwidth, from_=1, to=9999, increment=1, state=DISABLED) self.e_image_interval.grid(row=5, column=1, sticky="W", padx=10) Label(frame, text="Diff defocus:").grid(row=6, column=0, sticky="W") self.e_diff_defocus = Spinbox(frame, textvariable=self.var_diff_defocus, width=sbwidth, from_=-10000, to=10000, increment=100, state=DISABLED) self.e_diff_defocus.grid(row=6, column=1, sticky="W", padx=10) Label(frame, text="Image exposure (s):").grid(row=7, column=0, sticky="W") self.e_image_exposure = Spinbox( frame, textvariable=self.var_exposure_time_image, width=sbwidth, from_=0.0, to=100.0, increment=0.01, state=DISABLED) self.e_image_exposure.grid(row=7, column=1, sticky="W", padx=10) self.RelaxButton = Button(frame, text="Relax beam", command=self.relax_beam, state=DISABLED) self.RelaxButton.grid(row=7, column=2, sticky="EW") if ENABLE_FOOTFREE_OPTION: Separator(frame, orient=HORIZONTAL).grid(row=8, columnspan=3, sticky="ew", pady=10) Label(frame, text="Rotate to:").grid(row=9, column=0, sticky="W") self.e_max_rotation = Spinbox( frame, textvariable=self.var_footfree_rotate_to, width=sbwidth, from_=0.0, to=70.0, increment=1.0, state=DISABLED) self.e_max_rotation.grid(row=9, column=1, sticky="W", padx=10) Checkbutton(frame, text="Footfree mode", variable=self.var_toggle_footfree, command=self.toggle_footfree).grid(row=9, column=2, sticky="W") self.lb_coll0 = Label(frame, text="") self.lb_coll1 = Label(frame, text="") self.lb_coll2 = Label(frame, text="") self.lb_coll0.grid(row=10, column=0, columnspan=3, sticky="EW") self.lb_coll1.grid(row=11, column=0, columnspan=3, sticky="EW") self.lb_coll2.grid(row=12, column=0, columnspan=3, sticky="EW") frame.grid_columnconfigure(1, weight=1) frame.pack(side="top", fill="x", expand=False, padx=10, pady=10) frame = Frame(self) Label(frame, text="Select output formats:").grid(row=5, columnspan=2, sticky="EW") Checkbutton(frame, text=".tiff", variable=self.var_save_tiff).grid(row=5, column=2, sticky="EW") Checkbutton(frame, text="XDS (.smv)", variable=self.var_save_xds).grid(row=5, column=3, sticky="EW") Checkbutton(frame, text="DIALS (.smv)", variable=self.var_save_dials).grid(row=6, column=2, sticky="EW") Checkbutton(frame, text="REDp (.mrc)", variable=self.var_save_red).grid(row=6, column=3, sticky="EW") frame.grid_columnconfigure(0, weight=1) frame.grid_columnconfigure(1, weight=1) frame.grid_columnconfigure(2, weight=1) frame.grid_columnconfigure(3, weight=1) frame.pack(side="top", fill="x", padx=10, pady=10) frame = Frame(self) self.CollectionButton = Button(frame, text="Start Collection", command=self.start_collection) self.CollectionButton.grid(row=1, column=0, sticky="EW") self.CollectionStopButton = Button(frame, text="Stop Collection", command=self.stop_collection, state=DISABLED) self.CollectionStopButton.grid(row=1, column=1, sticky="EW") frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=1) frame.pack(side="bottom", fill="x", padx=10, pady=10) self.stopEvent = threading.Event()
class ExperimentalRED(LabelFrame): """GUI panel to perform a simple RED experiment using discrete rotation steps.""" def __init__(self, parent): LabelFrame.__init__(self, parent, text='Rotation electron diffraction') self.parent = parent sbwidth = 10 self.init_vars() frame = Frame(self) Label(frame, text='Exposure time (s):').grid(row=4, column=0, sticky='W') self.e_exposure_time = Spinbox(frame, textvariable=self.var_exposure_time, width=sbwidth, from_=0.1, to=9999, increment=0.1) self.e_exposure_time.grid(row=4, column=1, sticky='W', padx=10) Label(frame, text='Tilt range (deg):').grid(row=5, column=0, sticky='W') self.e_tilt_range = Spinbox(frame, textvariable=self.var_tilt_range, width=sbwidth, from_=0.1, to=9999, increment=0.5) self.e_tilt_range.grid(row=5, column=1, sticky='W', padx=10) Label(frame, text='Step size (deg):').grid(row=6, column=0, sticky='W') self.e_stepsize = Spinbox(frame, textvariable=self.var_stepsize, width=sbwidth, from_=-10.0, to=10.0, increment=0.2) self.e_stepsize.grid(row=6, column=1, sticky='W', padx=10) frame.pack(side='top', fill='x', padx=10, pady=10) frame = Frame(self) Label(frame, text='Output formats:').grid(row=5, columnspan=2, sticky='EW') Checkbutton(frame, text='PETS (.tiff)', variable=self.var_save_tiff, state=DISABLED).grid(row=5, column=2, sticky='EW') Checkbutton(frame, text='REDp (.mrc)', variable=self.var_save_red, state=DISABLED).grid(row=5, column=3, sticky='EW') frame.grid_columnconfigure(0, weight=1) frame.grid_columnconfigure(1, weight=1) frame.grid_columnconfigure(2, weight=1) frame.grid_columnconfigure(3, weight=1) frame.pack(side='top', fill='x', padx=10, pady=10) frame = Frame(self) self.StartButton = Button(frame, text='Start Collection', command=self.start_collection) self.StartButton.grid(row=1, column=0, sticky='EW') self.ContinueButton = Button(frame, text='Continue', command=self.continue_collection, state=DISABLED) self.ContinueButton.grid(row=1, column=1, sticky='EW') self.FinalizeButton = Button(frame, text='Finalize', command=self.stop_collection, state=DISABLED) self.FinalizeButton.grid(row=1, column=2, sticky='EW') frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=1) frame.columnconfigure(2, weight=1) frame.pack(side='bottom', fill='x', padx=10, pady=10) def init_vars(self): self.var_exposure_time = DoubleVar(value=0.5) self.var_tilt_range = DoubleVar(value=5.0) self.var_stepsize = DoubleVar(value=1.0) self.var_save_tiff = BooleanVar(value=True) self.var_save_red = BooleanVar(value=True) def set_trigger(self, trigger=None, q=None): self.triggerEvent = trigger self.q = q def start_collection(self): self.StartButton.config(state=DISABLED) self.ContinueButton.config(state=NORMAL) self.FinalizeButton.config(state=NORMAL) self.e_exposure_time.config(state=DISABLED) self.e_stepsize.config(state=DISABLED) params = self.get_params(task='start') self.q.put(('red', params)) self.triggerEvent.set() def continue_collection(self): params = self.get_params(task='continue') self.q.put(('red', params)) self.triggerEvent.set() def stop_collection(self): self.StartButton.config(state=NORMAL) self.ContinueButton.config(state=DISABLED) self.FinalizeButton.config(state=DISABLED) self.e_exposure_time.config(state=NORMAL) self.e_stepsize.config(state=NORMAL) params = self.get_params(task='stop') self.q.put(('red', params)) self.triggerEvent.set() def get_params(self, task=None): params = { 'exposure_time': self.var_exposure_time.get(), 'tilt_range': self.var_tilt_range.get(), 'stepsize': self.var_stepsize.get(), 'task': task } return params
class ExperimentalTVIPS(LabelFrame): """docstring for ExperimentalRED""" def __init__(self, parent): LabelFrame.__init__(self, parent, text="Continuous rotation electron diffraction (TVIPS)") self.parent = parent sbwidth = 10 self.init_vars() frame = Frame(self) Label(frame, text="Target angle (degrees):").grid(row=4, column=0, sticky="W") self.e_target_angle = Spinbox(frame, textvariable=self.var_target_angle, width=sbwidth, from_=-80.0, to=80.0, increment=5.0, state=NORMAL) self.e_target_angle.grid(row=4, column=1, sticky="W", padx=10) self.InvertAngleButton = Button(frame, text="Invert", command=self.invert_angle) self.InvertAngleButton.grid(row=4, column=2, sticky="EW") self.c_toggle_manual_control = Checkbutton(frame, text="Manual rotation control", variable=self.var_toggle_manual_control, command=self.toggle_manual_control) self.c_toggle_manual_control.grid(row=4, column=3, sticky="W") # defocus button Label(frame, text="Diff defocus:").grid(row=6, column=0, sticky="W") self.e_diff_defocus = Spinbox(frame, textvariable=self.var_diff_defocus, width=sbwidth, from_=-10000, to=10000, increment=100) self.e_diff_defocus.grid(row=6, column=1, sticky="W", padx=10) Label(frame, text="Exposure (ms):").grid(row=7, column=0, sticky="W") self.e_exposure = Spinbox(frame, textvariable=self.var_exposure, width=sbwidth, from_=0, to=10000, increment=100) self.e_exposure.grid(row=7, column=1, sticky="W", padx=10) 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') self.o_mode.grid(row=8, column=1, sticky="W", padx=10) self.c_toggle_defocus = Checkbutton(frame, text="Toggle defocus", variable=self.var_toggle_diff_defocus, command=self.toggle_diff_defocus) self.c_toggle_defocus.grid(row=6, column=3, sticky="W") self.b_reset_defocus = Button(frame, text="Reset", command=self.reset_diff_defocus, state=DISABLED) self.b_reset_defocus.grid(row=6, column=2, sticky="EW") self.c_toggle_diffraction = Checkbutton(frame, text="Toggle DIFF", variable=self.var_toggle_diff_mode, command=self.toggle_diff_mode) self.c_toggle_diffraction.grid(row=7, column=3, sticky="W") self.c_toggle_screen = Checkbutton(frame, text="Toggle screen", variable=self.var_toggle_screen, command=self.toggle_screen) self.c_toggle_screen.grid(row=8, column=3, sticky="W") self.b_start_liveview = Button(frame, text="Start live view", command=self.start_liveview) self.b_start_liveview.grid(row=7, column=2, sticky="EW") self.b_stop_liveview = Button(frame, text="Stop live view", command=self.stop_liveview) self.b_stop_liveview.grid(row=8, column=2, sticky="EW") self.c_toggle_beamblank = Checkbutton(frame, text="Toggle beamblank", variable=self.var_toggle_beamblank, command=self.toggle_beamblank) self.c_toggle_beamblank.grid(row=10, column=3, sticky="W") frame.pack(side="top", fill="x", padx=10, pady=10) frame = Frame(self) self.e_instructions = Entry(frame, width=50, textvariable=self.var_instruction_file) self.e_instructions.grid(row=4, column=1, sticky="EW") self.BrowseTrackButton = Button(frame, text="Browse..", command=self.browse_instructions) self.BrowseTrackButton.grid(row=4, column=2, sticky="EW") Label(frame, text="Instruction file:").grid(row=4, column=0, sticky="W") frame.pack(side="top", fill="x", padx=10, pady=10) frame = Frame(self) self.SearchButton = Button(frame, text="Search", command=self.search) self.SearchButton.grid(row=1, column=0, sticky="EW") self.FocusButton = Button(frame, text="Focus", command=self.focus) self.FocusButton.grid(row=1, column=1, sticky="EW") self.GetImageButton = Button(frame, text="Get image", command=self.get_image) self.GetImageButton.grid(row=1, column=2, sticky="EW") frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=1) frame.columnconfigure(2, weight=1) frame.pack(fill="x", padx=10, pady=10) frame = Frame(self) self.SerialButton = Button(frame, text="Start serial acquisition", width=25, command=self.serial_collection) self.SerialButton.grid(row=1, column=0, sticky="EW") frame.pack(fill="x", padx=10, pady=10) frame = Frame(self) self.GetReadyButton = Button(frame, text="Get Ready", command=self.prime_collection) self.GetReadyButton.grid(row=1, column=0, sticky="EW") self.AcquireButton = Button(frame, text="Acquire", command=self.start_collection, state=DISABLED) self.AcquireButton.grid(row=1, column=1, sticky="EW") self.FinalizeButton = Button(frame, text="Finalize", command=self.stop_collection, state=DISABLED) self.FinalizeButton.grid(row=1, column=2, sticky="EW") frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=1) frame.columnconfigure(2, weight=1) frame.pack(side="bottom", fill="x", padx=10, pady=10) from instamatic import TEMController self.ctrl = TEMController.get_instance() def init_vars(self): self.var_target_angle = DoubleVar(value=40.0) self.var_exposure = IntVar(value=400) self.var_save_tiff = BooleanVar(value=True) self.var_save_red = BooleanVar(value=True) self.var_diff_defocus = IntVar(value=1500) self.var_toggle_diff_defocus = BooleanVar(value=False) self.var_toggle_beamblank = BooleanVar(value=False) self.var_toggle_diff_mode = BooleanVar(value=False) self.var_toggle_screen = BooleanVar(value=False) self.var_toggle_manual_control = BooleanVar(value=False) self.var_instruction_file = StringVar(value="") self.var_mode = StringVar(value="diff") def set_trigger(self, trigger=None, q=None): self.triggerEvent = trigger self.q = q def invert_angle(self): angle = self.var_target_angle.get() self.var_target_angle.set(-angle) def disable_ui(self): self.InvertAngleButton.config(state=DISABLED) self.GetReadyButton.config(state=DISABLED) self.AcquireButton.config(state=NORMAL) self.FinalizeButton.config(state=NORMAL) self.SerialButton.config(state=DISABLED) self.e_target_angle.config(state=DISABLED) self.SearchButton.config(state=DISABLED) self.FocusButton.config(state=DISABLED) self.GetImageButton.config(state=DISABLED) self.b_start_liveview.config(state=DISABLED) self.b_stop_liveview.config(state=DISABLED) def enable_ui(self): self.InvertAngleButton.config(state=NORMAL) self.GetReadyButton.config(state=NORMAL) self.AcquireButton.config(state=DISABLED) self.FinalizeButton.config(state=DISABLED) self.SerialButton.config(state=NORMAL) if not self.var_toggle_manual_control.get(): self.e_target_angle.config(state=NORMAL) self.SearchButton.config(state=NORMAL) self.FocusButton.config(state=NORMAL) self.GetImageButton.config(state=NORMAL) self.b_start_liveview.config(state=NORMAL) self.b_stop_liveview.config(state=NORMAL) def prime_collection(self): self.disable_ui() # self.e_target_angle.config(state=DISABLED) params = self.get_params(task="get_ready") self.q.put(("cred_tvips", params)) self.triggerEvent.set() def start_collection(self): self.AcquireButton.config(state=DISABLED) params = self.get_params(task="acquire") self.q.put(("cred_tvips", params)) self.triggerEvent.set() def stop_collection(self): self.enable_ui() params = self.get_params(task="stop") self.q.put(("cred_tvips", params)) self.triggerEvent.set() def serial_collection(self): self.disable_ui() params = self.get_params(task="serial") self.q.put(("cred_tvips", params)) self.triggerEvent.set() def browse_instructions(self): fn = filedialog.askopenfilename(parent=self.parent, initialdir=None, title="Select instruction file") if not fn: return fn = Path(fn).absolute() self.var_instruction_file.set(fn) return fn def get_params(self, task=None): params = { "target_angle": self.var_target_angle.get(), "instruction_file": self.var_instruction_file.get(), "exposure": self.var_exposure.get(), "mode": self.var_mode.get(), "manual_control": self.var_toggle_manual_control.get(), "task": task } return params def toggle_manual_control(self): toggle = self.var_toggle_manual_control.get() if toggle: self.e_target_angle.config(state=DISABLED) else: self.e_target_angle.config(state=NORMAL) def toggle_diff_mode(self): toggle = self.var_toggle_diff_mode.get() if toggle: self.ctrl.mode_diffraction() else: self.ctrl.mode_mag1() def toggle_beamblank(self): toggle = self.var_toggle_beamblank.get() if toggle: self.ctrl.beamblank_on() else: self.ctrl.beamblank_off() def toggle_screen(self): toggle = self.var_toggle_screen.get() if toggle: self.ctrl.screen_up() else: self.ctrl.screen_down() def start_liveview(self): self.ctrl.cam.start_liveview() def stop_liveview(self): self.ctrl.cam.stop_liveview() def toggle_diff_defocus(self): toggle = self.var_toggle_diff_defocus.get() if toggle: 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) def reset_diff_defocus(self): self.ctrl.difffocus.refocus() self.var_toggle_diff_defocus.set(False) def search(self): self.ctrl.run_script("search_mode.py") def focus(self): self.ctrl.run_script("focus_mode.py") def get_image(self): self.ctrl.cam.acquireImage()
class ExperimentalcRED(LabelFrame): """GUI panel for doing cRED experiments on a Timepix camera.""" def __init__(self, parent): LabelFrame.__init__(self, parent, text='Continuous rotation electron diffraction') self.parent = parent sbwidth = 10 self.init_vars() frame = Frame(self) Label(frame, text='Exposure time (s):').grid(row=1, column=0, sticky='W') exposure_time = Spinbox(frame, textvariable=self.var_exposure_time, width=sbwidth, from_=0.0, to=100.0, increment=0.01) exposure_time.grid(row=1, column=1, sticky='W', padx=10) Checkbutton(frame, text='Beam unblanker', variable=self.var_unblank_beam).grid(row=1, column=2, sticky='W') Separator(frame, orient=HORIZONTAL).grid(row=4, columnspan=3, sticky='ew', pady=10) Checkbutton(frame, text='Enable image interval', variable=self.var_enable_image_interval, command=self.toggle_interval_buttons).grid(row=5, column=2, sticky='W') self.c_toggle_defocus = Checkbutton( frame, text='Toggle defocus', variable=self.var_toggle_diff_defocus, command=self.toggle_diff_defocus, state=DISABLED) self.c_toggle_defocus.grid(row=6, column=2, sticky='W') Label(frame, text='Image interval:').grid(row=5, column=0, sticky='W') self.e_image_interval = Spinbox(frame, textvariable=self.var_image_interval, width=sbwidth, from_=1, to=9999, increment=1, state=DISABLED) self.e_image_interval.grid(row=5, column=1, sticky='W', padx=10) Label(frame, text='Diff defocus:').grid(row=6, column=0, sticky='W') self.e_diff_defocus = Spinbox(frame, textvariable=self.var_diff_defocus, width=sbwidth, from_=-10000, to=10000, increment=100, state=DISABLED) self.e_diff_defocus.grid(row=6, column=1, sticky='W', padx=10) Label(frame, text='Image exposure (s):').grid(row=7, column=0, sticky='W') self.e_image_exposure = Spinbox( frame, textvariable=self.var_exposure_time_image, width=sbwidth, from_=0.0, to=100.0, increment=0.01, state=DISABLED) self.e_image_exposure.grid(row=7, column=1, sticky='W', padx=10) self.RelaxButton = Button(frame, text='Relax beam', command=self.relax_beam, state=DISABLED) self.RelaxButton.grid(row=7, column=2, sticky='EW') if ENABLE_FOOTFREE_OPTION: Separator(frame, orient=HORIZONTAL).grid(row=8, columnspan=3, sticky='ew', pady=10) Label(frame, text='Rotate to:').grid(row=9, column=0, sticky='W') self.e_max_rotation = Spinbox( frame, textvariable=self.var_footfree_rotate_to, width=sbwidth, from_=0.0, to=70.0, increment=1.0, state=DISABLED) self.e_max_rotation.grid(row=9, column=1, sticky='W', padx=10) Checkbutton(frame, text='Footfree mode', variable=self.var_toggle_footfree, command=self.toggle_footfree).grid(row=9, column=2, sticky='W') self.lb_coll0 = Label(frame, text='') self.lb_coll1 = Label(frame, text='') self.lb_coll2 = Label(frame, text='') self.lb_coll0.grid(row=10, column=0, columnspan=3, sticky='EW') self.lb_coll1.grid(row=11, column=0, columnspan=3, sticky='EW') self.lb_coll2.grid(row=12, column=0, columnspan=3, sticky='EW') frame.grid_columnconfigure(1, weight=1) frame.pack(side='top', fill='x', expand=False, padx=10, pady=10) frame = Frame(self) Label(frame, text='Select output formats:').grid(row=5, columnspan=2, sticky='EW') Checkbutton(frame, text='.tiff', variable=self.var_save_tiff).grid(row=5, column=2, sticky='EW') Checkbutton(frame, text='XDS (.smv)', variable=self.var_save_xds).grid(row=5, column=3, sticky='EW') Checkbutton(frame, text='DIALS (.smv)', variable=self.var_save_dials).grid(row=6, column=2, sticky='EW') Checkbutton(frame, text='REDp (.mrc)', variable=self.var_save_red).grid(row=6, column=3, sticky='EW') frame.grid_columnconfigure(0, weight=1) frame.grid_columnconfigure(1, weight=1) frame.grid_columnconfigure(2, weight=1) frame.grid_columnconfigure(3, weight=1) frame.pack(side='top', fill='x', padx=10, pady=10) frame = Frame(self) self.CollectionButton = Button(frame, text='Start Collection', command=self.start_collection) self.CollectionButton.grid(row=1, column=0, sticky='EW') self.CollectionStopButton = Button(frame, text='Stop Collection', command=self.stop_collection, state=DISABLED) self.CollectionStopButton.grid(row=1, column=1, sticky='EW') frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=1) frame.pack(side='bottom', fill='x', padx=10, pady=10) self.stopEvent = threading.Event() def init_vars(self): self.var_exposure_time = DoubleVar(value=0.5) self.var_unblank_beam = BooleanVar(value=False) self.var_image_interval = IntVar(value=10) self.var_diff_defocus = IntVar(value=1500) self.var_enable_image_interval = BooleanVar(value=False) self.var_toggle_diff_defocus = BooleanVar(value=False) self.var_exposure_time_image = DoubleVar(value=0.01) self.var_footfree_rotate_to = DoubleVar(value=65.0) self.var_toggle_footfree = BooleanVar(value=False) self.mode = 'regular' self.var_save_tiff = BooleanVar(value=True) self.var_save_xds = BooleanVar(value=True) self.var_save_dials = BooleanVar(value=True) self.var_save_red = BooleanVar(value=True) def set_trigger(self, trigger=None, q=None): self.triggerEvent = trigger self.q = q def start_collection(self): # TODO: make a pop up window with the STOP button? if self.var_toggle_diff_defocus.get(): self.var_toggle_diff_defocus.set(False) self.toggle_diff_defocus() self.CollectionStopButton.config(state=NORMAL) self.CollectionButton.config(state=DISABLED) if self.mode == 'footfree': self.lb_coll1.config(text='Data collection has started.') self.lb_coll2.config( text='Click STOP COLLECTION to end the experiment.') else: self.lb_coll1.config( text='Now you can start to rotate the goniometer at any time.') self.lb_coll2.config( text= 'Click STOP COLLECTION BEFORE removing your foot from the pedal!' ) self.parent.bind_all('<space>', self.stop_collection) params = self.get_params() self.q.put(('cred', params)) self.triggerEvent.set() def stop_collection(self, event=None): self.stopEvent.set() self.parent.unbind_all('<space>') self.CollectionStopButton.config(state=DISABLED) self.CollectionButton.config(state=NORMAL) self.lb_coll1.config(text='') self.lb_coll2.config(text='') def get_params(self): params = { 'exposure_time': self.var_exposure_time.get(), 'exposure_time_image': self.var_exposure_time_image.get(), 'unblank_beam': self.var_unblank_beam.get(), 'enable_image_interval': self.var_enable_image_interval.get(), 'image_interval': self.var_image_interval.get(), 'diff_defocus': self.var_diff_defocus.get(), 'mode': self.mode, 'footfree_rotate_to': self.var_footfree_rotate_to.get(), 'write_tiff': self.var_save_tiff.get(), 'write_xds': self.var_save_xds.get(), 'write_dials': self.var_save_dials.get(), 'write_red': self.var_save_red.get(), 'stop_event': self.stopEvent } return params def toggle_interval_buttons(self): enable = self.var_enable_image_interval.get() if enable: self.e_image_interval.config(state=NORMAL) self.e_image_exposure.config(state=NORMAL) self.e_diff_defocus.config(state=NORMAL) self.c_toggle_defocus.config(state=NORMAL) self.RelaxButton.config(state=NORMAL) else: self.e_image_interval.config(state=DISABLED) self.e_image_exposure.config(state=DISABLED) self.e_diff_defocus.config(state=DISABLED) self.c_toggle_defocus.config(state=DISABLED) self.RelaxButton.config(state=DISABLED) def relax_beam(self): difffocus = self.var_diff_defocus.get() self.q.put(('relax_beam', {'value': difffocus})) self.triggerEvent.set() def toggle_footfree(self): enable = self.var_toggle_footfree.get() if enable: self.mode = 'footfree' self.e_max_rotation.config(state=NORMAL) else: self.mode == 'regular' self.e_max_rotation.config(state=DISABLED) def toggle_diff_defocus(self): toggle = self.var_toggle_diff_defocus.get() difffocus = self.var_diff_defocus.get() self.q.put(('toggle_difffocus', { 'value': difffocus, 'toggle': toggle })) self.triggerEvent.set()
class ExperimentalRED(LabelFrame): """docstring for ExperimentalRED""" def __init__(self, parent): LabelFrame.__init__(self, parent, text="Rotation electron diffraction") self.parent = parent sbwidth = 10 self.init_vars() frame = Frame(self) Label(frame, text="Exposure time (s):").grid(row=4, column=0, sticky="W") self.e_exposure_time = Spinbox(frame, textvariable=self.var_exposure_time, width=sbwidth, from_=0.1, to=9999, increment=0.1) self.e_exposure_time.grid(row=4, column=1, sticky="W", padx=10) Label(frame, text="Tilt range (deg):").grid(row=5, column=0, sticky="W") self.e_tilt_range = Spinbox(frame, textvariable=self.var_tilt_range, width=sbwidth, from_=0.1, to=9999, increment=0.5) self.e_tilt_range.grid(row=5, column=1, sticky="W", padx=10) Label(frame, text="Step size (deg):").grid(row=6, column=0, sticky="W") self.e_stepsize = Spinbox(frame, textvariable=self.var_stepsize, width=sbwidth, from_=-10.0, to=10.0, increment=0.2) self.e_stepsize.grid(row=6, column=1, sticky="W", padx=10) frame.pack(side="top", fill="x", padx=10, pady=10) frame = Frame(self) Label(frame, text="Output formats:").grid(row=5, columnspan=2, sticky="EW") Checkbutton(frame, text="PETS (.tiff)", variable=self.var_save_tiff, state=DISABLED).grid(row=5, column=2, sticky="EW") Checkbutton(frame, text="REDp (.mrc)", variable=self.var_save_red, state=DISABLED).grid(row=5, column=3, sticky="EW") frame.grid_columnconfigure(0, weight=1) frame.grid_columnconfigure(1, weight=1) frame.grid_columnconfigure(2, weight=1) frame.grid_columnconfigure(3, weight=1) frame.pack(side="top", fill="x", padx=10, pady=10) frame = Frame(self) self.StartButton = Button(frame, text="Start Collection", command=self.start_collection) self.StartButton.grid(row=1, column=0, sticky="EW") self.ContinueButton = Button(frame, text="Continue", command=self.continue_collection, state=DISABLED) self.ContinueButton.grid(row=1, column=1, sticky="EW") self.FinalizeButton = Button(frame, text="Finalize", command=self.stop_collection, state=DISABLED) self.FinalizeButton.grid(row=1, column=2, sticky="EW") frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=1) frame.columnconfigure(2, weight=1) frame.pack(side="bottom", fill="x", padx=10, pady=10) def init_vars(self): self.var_exposure_time = DoubleVar(value=0.5) self.var_tilt_range = DoubleVar(value=5.0) self.var_stepsize = DoubleVar(value=1.0) self.var_save_tiff = BooleanVar(value=True) self.var_save_red = BooleanVar(value=True) def set_trigger(self, trigger=None, q=None): self.triggerEvent = trigger self.q = q def start_collection(self): self.StartButton.config(state=DISABLED) self.ContinueButton.config(state=NORMAL) self.FinalizeButton.config(state=NORMAL) self.e_exposure_time.config(state=DISABLED) self.e_stepsize.config(state=DISABLED) params = self.get_params(task="start") self.q.put(("red", params)) self.triggerEvent.set() def continue_collection(self): params = self.get_params(task="continue") self.q.put(("red", params)) self.triggerEvent.set() def stop_collection(self): self.StartButton.config(state=NORMAL) self.ContinueButton.config(state=DISABLED) self.FinalizeButton.config(state=DISABLED) self.e_exposure_time.config(state=NORMAL) self.e_stepsize.config(state=NORMAL) params = self.get_params(task="stop") self.q.put(("red", params)) self.triggerEvent.set() def get_params(self, task=None): params = { "exposure_time": self.var_exposure_time.get(), "tilt_range": self.var_tilt_range.get(), "stepsize": self.var_stepsize.get(), "task": task } return params
class ExperimentalCtrl(LabelFrame): """This panel holds some frequently used functions to control the electron microscope.""" def __init__(self, parent): LabelFrame.__init__(self, parent, text='Stage Control') self.parent = parent self.init_vars() frame = Frame(self) b_stage_stop = Button(frame, text='Stop stage', command=self.stage_stop) b_stage_stop.grid(row=0, column=2, sticky='W') cb_nowait = Checkbutton(frame, text='Wait for stage', variable=self.var_stage_wait) cb_nowait.grid(row=0, column=3) 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) 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) 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') e_negative_angle = Spinbox(frame, width=10, textvariable=self.var_negative_angle, from_=-90, to=90, increment=5) 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.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.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.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) self.b_stop_wobble.grid(row=4, column=3, sticky='W') e_stage_x = Entry(frame, width=10, textvariable=self.var_stage_x) 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.grid(row=6, column=2, sticky='EW') if config.settings.use_goniotool: Label(frame, text='Rot. Speed', width=20).grid(row=5, column=0, sticky='W') e_goniotool_tx = Spinbox(frame, width=10, textvariable=self.var_goniotool_tx, from_=1, to=12, increment=1) e_goniotool_tx.grid(row=5, column=1, sticky='EW') b_goniotool_set = Button(frame, text='Set', command=self.set_goniotool_tx) b_goniotool_set.grid(row=5, column=2, sticky='W') b_goniotool_default = Button(frame, text='Default', command=self.set_goniotool_tx_default) b_goniotool_default.grid(row=5, column=3, sticky='W') b_negative_angle = Button(frame, text='Set', command=self.set_negative_angle) b_negative_angle.grid(row=1, column=2, sticky='W') b_neutral_angle = Button(frame, text='Set', command=self.set_neutral_angle) b_neutral_angle.grid(row=2, column=2, sticky='W') b_positive_angle = Button(frame, text='Set', command=self.set_positive_angle) b_positive_angle.grid(row=3, column=2, sticky='W') b_stage = Button(frame, text='Set', command=self.set_stage) b_stage.grid(row=6, column=3, sticky='W') b_stage_get = Button(frame, text='Get', command=self.get_stage) 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') self.e_diff_defocus = Spinbox(frame, textvariable=self.var_diff_defocus, width=10, from_=-10000, to=10000, increment=100) self.e_diff_defocus.grid(row=13, column=1, sticky='EW') self.c_toggle_defocus = Checkbutton( frame, text='Toggle defocus', variable=self.var_toggle_diff_defocus, command=self.toggle_diff_defocus) self.c_toggle_defocus.grid(row=13, column=2, sticky='W', columnspan=2) self.b_reset_defocus = Button(frame, text='Reset', command=self.reset_diff_defocus, state=DISABLED) self.b_reset_defocus.grid(row=13, column=4, sticky='EW') # frame.grid_columnconfigure(1, weight=1) frame.pack(side='top', fill='x', padx=10, pady=10) frame = Frame(self) Label(frame, text='Brightness', width=20).grid(row=11, column=0, sticky='W') e_brightness = Entry(frame, width=10, textvariable=self.var_brightness) e_brightness.grid(row=11, column=1, sticky='W') b_brightness = Button(frame, text='Set', command=self.set_brightness) b_brightness.grid(row=11, column=2, sticky='W') b_brightness_get = Button(frame, text='Get', command=self.get_brightness) b_brightness_get.grid(row=11, column=3, sticky='W') slider = Scale(frame, variable=self.var_brightness, from_=0, to=2**16 - 1, orient=HORIZONTAL, command=self.set_brightness) slider.grid(row=12, column=0, columnspan=3, sticky='EW') frame.pack(side='top', fill='x', padx=10, pady=10) frame = Frame(self) Label(frame, text='DiffFocus', width=20).grid(row=11, column=0, sticky='W') e_difffocus = Entry(frame, width=10, textvariable=self.var_difffocus) e_difffocus.grid(row=11, 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_get = Button(frame, text='Get', command=self.get_difffocus) b_difffocus_get.grid(row=11, column=3, sticky='W') slider = Scale(frame, variable=self.var_difffocus, from_=0, to=2**16 - 1, orient=HORIZONTAL, command=self.set_difffocus) slider.grid(row=12, column=0, columnspan=3, sticky='EW') frame.pack(side='top', fill='x', padx=10, pady=10) from instamatic import TEMController self.ctrl = TEMController.get_instance() def init_vars(self): self.var_negative_angle = DoubleVar(value=-40) self.var_neutral_angle = DoubleVar(value=0) self.var_positive_angle = DoubleVar(value=40) self.var_mode = StringVar(value='diff') self.var_alpha_wobbler = DoubleVar(value=5) self.var_stage_x = IntVar(value=0) self.var_stage_y = IntVar(value=0) self.var_goniotool_tx = IntVar(value=1) self.var_brightness = IntVar(value=65535) self.var_difffocus = IntVar(value=65535) self.var_diff_defocus = IntVar(value=1500) self.var_toggle_diff_defocus = BooleanVar(value=False) self.var_stage_wait = BooleanVar(value=True) def set_trigger(self, trigger=None, q=None): self.triggerEvent = trigger self.q = q def set_mode(self, event=None): self.ctrl.mode.set(self.var_mode.get()) def set_brightness(self, event=None): self.var_brightness.set(self.var_brightness.get()) self.q.put(('ctrl', { 'task': 'brightness.set', 'value': self.var_brightness.get() })) self.triggerEvent.set() def get_brightness(self, event=None): self.var_brightness.set(self.ctrl.brightness.get()) 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() })) self.triggerEvent.set() 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() })) self.triggerEvent.set() 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() 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() def set_goniotool_tx(self, event=None, value=None): if not value: value = self.var_goniotool_tx.get() self.ctrl.stage.set_rotation_speed(value) def set_goniotool_tx_default(self, event=None): value = 12 self.set_goniotool_tx(value=value) def set_stage(self): self.q.put(('ctrl', { 'task': 'stage.set', 'x': self.var_stage_x.get(), 'y': self.var_stage_y.get(), 'wait': self.var_stage_wait.get() })) self.triggerEvent.set() def get_stage(self, event=None): x, y, _, _, _ = self.ctrl.stage.get() self.var_stage_x.set(int(x)) self.var_stage_y.set(int(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 })) 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) def stage_stop(self): self.q.put(('ctrl', {'task': 'stage.stop'})) self.triggerEvent.set() def find_eucentric_height(self): self.q.put(('ctrl', {'task': 'find_eucentric_height'})) self.triggerEvent.set() def toggle_diff_defocus(self): toggle = self.var_toggle_diff_defocus.get() if toggle: 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.get_difffocus() def reset_diff_defocus(self): self.ctrl.difffocus.refocus() self.var_toggle_diff_defocus.set(False) self.get_difffocus()
class ExperimentalcRED(LabelFrame): """docstring for ExperimentalSED""" def __init__(self, parent): LabelFrame.__init__(self, parent, text="Continuous rotation electron diffraction") self.parent = parent sbwidth = 10 self.init_vars() frame = Frame(self) Label(frame, text="Exposure time (s):").grid(row=1, column=0, sticky="W") exposure_time = Spinbox(frame, textvariable=self.var_exposure_time, width=sbwidth, from_=0.0, to=100.0, increment=0.01) exposure_time.grid(row=1, column=1, sticky="W", padx=10) Checkbutton(frame, text="Beam unblanker", variable=self.var_unblank_beam).grid(row=1, column=2, sticky="W") Separator(frame, orient=HORIZONTAL).grid(row=4, columnspan=3, sticky="ew", pady=10) Checkbutton(frame, text="Enable image interval", variable=self.var_enable_image_interval, command=self.toggle_interval_buttons).grid(row=5, column=2, sticky="W") self.c_toggle_defocus = Checkbutton( frame, text="Toggle defocus", variable=self.var_toggle_diff_defocus, command=self.toggle_diff_defocus, state=DISABLED) self.c_toggle_defocus.grid(row=6, column=2, sticky="W") Label(frame, text="Image interval:").grid(row=5, column=0, sticky="W") self.e_image_interval = Spinbox(frame, textvariable=self.var_image_interval, width=sbwidth, from_=1, to=9999, increment=1, state=DISABLED) self.e_image_interval.grid(row=5, column=1, sticky="W", padx=10) Label(frame, text="Diff defocus:").grid(row=6, column=0, sticky="W") self.e_diff_defocus = Spinbox(frame, textvariable=self.var_diff_defocus, width=sbwidth, from_=-10000, to=10000, increment=100, state=DISABLED) self.e_diff_defocus.grid(row=6, column=1, sticky="W", padx=10) Label(frame, text="Image exposure (s):").grid(row=7, column=0, sticky="W") self.e_image_exposure = Spinbox( frame, textvariable=self.var_exposure_time_image, width=sbwidth, from_=0.0, to=100.0, increment=0.01, state=DISABLED) self.e_image_exposure.grid(row=7, column=1, sticky="W", padx=10) self.RelaxButton = Button(frame, text="Relax beam", command=self.relax_beam, state=DISABLED) self.RelaxButton.grid(row=7, column=2, sticky="EW") if ENABLE_FOOTFREE_OPTION: Separator(frame, orient=HORIZONTAL).grid(row=8, columnspan=3, sticky="ew", pady=10) Label(frame, text="Rotate to:").grid(row=9, column=0, sticky="W") self.e_max_rotation = Spinbox( frame, textvariable=self.var_footfree_rotate_to, width=sbwidth, from_=0.0, to=70.0, increment=1.0, state=DISABLED) self.e_max_rotation.grid(row=9, column=1, sticky="W", padx=10) Checkbutton(frame, text="Footfree mode", variable=self.var_toggle_footfree, command=self.toggle_footfree).grid(row=9, column=2, sticky="W") self.lb_coll0 = Label(frame, text="") self.lb_coll1 = Label(frame, text="") self.lb_coll2 = Label(frame, text="") self.lb_coll0.grid(row=10, column=0, columnspan=3, sticky="EW") self.lb_coll1.grid(row=11, column=0, columnspan=3, sticky="EW") self.lb_coll2.grid(row=12, column=0, columnspan=3, sticky="EW") frame.grid_columnconfigure(1, weight=1) frame.pack(side="top", fill="x", expand=False, padx=10, pady=10) frame = Frame(self) Label(frame, text="Select output formats:").grid(row=5, columnspan=2, sticky="EW") Checkbutton(frame, text=".tiff", variable=self.var_save_tiff).grid(row=5, column=2, sticky="EW") Checkbutton(frame, text="XDS (.smv)", variable=self.var_save_xds).grid(row=5, column=3, sticky="EW") Checkbutton(frame, text="DIALS (.smv)", variable=self.var_save_dials).grid(row=6, column=2, sticky="EW") Checkbutton(frame, text="REDp (.mrc)", variable=self.var_save_red).grid(row=6, column=3, sticky="EW") frame.grid_columnconfigure(0, weight=1) frame.grid_columnconfigure(1, weight=1) frame.grid_columnconfigure(2, weight=1) frame.grid_columnconfigure(3, weight=1) frame.pack(side="top", fill="x", padx=10, pady=10) frame = Frame(self) self.CollectionButton = Button(frame, text="Start Collection", command=self.start_collection) self.CollectionButton.grid(row=1, column=0, sticky="EW") self.CollectionStopButton = Button(frame, text="Stop Collection", command=self.stop_collection, state=DISABLED) self.CollectionStopButton.grid(row=1, column=1, sticky="EW") frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=1) frame.pack(side="bottom", fill="x", padx=10, pady=10) self.stopEvent = threading.Event() def init_vars(self): self.var_exposure_time = DoubleVar(value=0.5) self.var_unblank_beam = BooleanVar(value=False) self.var_image_interval = IntVar(value=10) self.var_diff_defocus = IntVar(value=1500) self.var_enable_image_interval = BooleanVar(value=False) self.var_toggle_diff_defocus = BooleanVar(value=False) self.var_exposure_time_image = DoubleVar(value=0.01) self.var_footfree_rotate_to = DoubleVar(value=65.0) self.var_toggle_footfree = BooleanVar(value=False) self.mode = "regular" self.var_save_tiff = BooleanVar(value=True) self.var_save_xds = BooleanVar(value=True) self.var_save_dials = BooleanVar(value=True) self.var_save_red = BooleanVar(value=True) def set_trigger(self, trigger=None, q=None): self.triggerEvent = trigger self.q = q def start_collection(self): # TODO: make a pop up window with the STOP button? if self.var_toggle_diff_defocus.get(): self.var_toggle_diff_defocus.set(False) self.toggle_diff_defocus() self.CollectionStopButton.config(state=NORMAL) self.CollectionButton.config(state=DISABLED) if self.mode == "footfree": self.lb_coll1.config(text="Data collection has started.") self.lb_coll2.config( text="Click STOP COLLECTION to end the experiment.") else: self.lb_coll1.config( text="Now you can start to rotate the goniometer at any time.") self.lb_coll2.config( text= "Click STOP COLLECTION BEFORE removing your foot from the pedal!" ) self.parent.bind_all("<space>", self.stop_collection) params = self.get_params() self.q.put(("cred", params)) self.triggerEvent.set() def stop_collection(self, event=None): self.stopEvent.set() self.parent.unbind_all("<space>") self.CollectionStopButton.config(state=DISABLED) self.CollectionButton.config(state=NORMAL) self.lb_coll1.config(text="") self.lb_coll2.config(text="") def get_params(self): params = { "exposure_time": self.var_exposure_time.get(), "exposure_time_image": self.var_exposure_time_image.get(), "unblank_beam": self.var_unblank_beam.get(), "enable_image_interval": self.var_enable_image_interval.get(), "image_interval": self.var_image_interval.get(), "diff_defocus": self.var_diff_defocus.get(), "mode": self.mode, "footfree_rotate_to": self.var_footfree_rotate_to.get(), "write_tiff": self.var_save_tiff.get(), "write_xds": self.var_save_xds.get(), "write_dials": self.var_save_dials.get(), "write_red": self.var_save_red.get(), "stop_event": self.stopEvent } return params def toggle_interval_buttons(self): enable = self.var_enable_image_interval.get() if enable: self.e_image_interval.config(state=NORMAL) self.e_image_exposure.config(state=NORMAL) self.e_diff_defocus.config(state=NORMAL) self.c_toggle_defocus.config(state=NORMAL) self.RelaxButton.config(state=NORMAL) else: self.e_image_interval.config(state=DISABLED) self.e_image_exposure.config(state=DISABLED) self.e_diff_defocus.config(state=DISABLED) self.c_toggle_defocus.config(state=DISABLED) self.RelaxButton.config(state=DISABLED) def relax_beam(self): difffocus = self.var_diff_defocus.get() self.q.put(("relax_beam", {"value": difffocus})) self.triggerEvent.set() def toggle_footfree(self): enable = self.var_toggle_footfree.get() if enable: self.mode = "footfree" self.e_max_rotation.config(state=NORMAL) else: self.mode == "regular" self.e_max_rotation.config(state=DISABLED) def toggle_diff_defocus(self): toggle = self.var_toggle_diff_defocus.get() difffocus = self.var_diff_defocus.get() self.q.put(("toggle_difffocus", { "value": difffocus, "toggle": toggle })) self.triggerEvent.set()
class IOFrame(LabelFrame): """docstring for ExperimentalSED""" def __init__(self, parent): LabelFrame.__init__(self, parent, text="Input/Output") self.parent = parent self.workdrc = Path(config.cfg.work_directory) self.init_vars() frame = Frame(self) self.directory = Entry(frame, width=50, textvariable=self.var_directory) self.directory.grid(row=2, column=1, sticky="EW") self.BrowseButton = Button(frame, text="Browse..", command=self.browse_directory) self.BrowseButton.grid(row=2, column=2, sticky="EW") self.sample_name = Entry(frame, width=50, textvariable=self.var_sample_name) self.sample_name.grid(row=3, column=1, sticky="EW") self.flatfield = Entry(frame, width=50, textvariable=self.var_flatfield) self.flatfield.grid(row=4, column=1, sticky="EW") self.BrowseFFButton = Button(frame, text="Browse..", command=self.browse_flatfield) self.BrowseFFButton.grid(row=4, column=2, sticky="EW") Label(frame, text="Directory:").grid(row=2, column=0, sticky="W") Label(frame, text="Sample name:").grid(row=3, column=0, sticky="W") Label(frame, text="Flatfield:").grid(row=4, column=0, sticky="W") self.incrementer = Spinbox(frame, width=10, from_=0, to=999, increment=1, textvariable=self.var_experiment_number) self.incrementer.grid(row=3, column=2) frame.grid_columnconfigure(1, weight=1) frame.pack(side="top", fill="x", padx=10) frame = Frame(self) self.OpenDatadirButton = Button(frame, text="Open work directory", command=self.open_data_directory) self.OpenDatadirButton.grid(row=1, column=0, sticky="EW") self.OpenConfigdirButton = Button(frame, text="Open settings directory", command=self.open_config_directory) self.OpenConfigdirButton.grid(row=1, column=1, sticky="EW") self.DeleteButton = Button(frame, text="Delete last experiment", command=self.delete_last) self.DeleteButton.grid(row=1, column=2, sticky="EW") frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=1) frame.columnconfigure(2, weight=1) frame.pack(side="bottom", fill="both", padx=10, pady=10) self.update_experiment_number() def init_vars(self): workdrc = self.workdrc ff = config.cfg.flatfield if not ff: self.var_flatfield = StringVar(value="") else: self.var_flatfield = StringVar(value=Path(ff).absolute()) self.var_directory = StringVar(value=workdrc.absolute()) self.var_sample_name = StringVar(value="experiment") self.var_experiment_number = IntVar(value=1) def get_working_directory(self): drc = self.var_directory.get() return Path(drc) def update_experiment_number(self): drc = Path(self.var_directory.get()) name = self.var_sample_name.get() number = self.var_experiment_number.get() path = drc / f"{name}_{number}" while path.exists(): number += 1 path = drc / f"{name}_{number}" self.var_experiment_number.set(number) return number def get_new_experiment_directory(self): number = self.update_experiment_number() return self.get_experiment_directory() def get_experiment_directory(self): drc = Path(self.var_directory.get()) name = self.var_sample_name.get() number = self.var_experiment_number.get() path = drc / f"{name}_{number}" return path def browse_directory(self): drc = tkinter.filedialog.askdirectory(parent=self.parent, title="Select working directory") if not drc: return drc = Path(drc).absolute() self.var_directory.set(drc) print(self.get_experiment_directory()) self.update_experiment_number() # TODO: set to 1 on experiment update return drc def browse_flatfield(self): ff = tkinter.filedialog.askopenfilename( parent=self.parent, initialdir=self.var_directory.get(), title="Select flatfield") if not ff: return ff = Path(ff).absolute() self.var_flatfield.set(ff) return ff def get_flatfield(self): ff = self.var_flatfield.get() if ff == "": ff = None return ff def delete_last(self): drc = self.get_experiment_directory() date = datetime.datetime.now().strftime("%H%M%S") newdrc = drc.parent / f"delete_me-{date}" if drc.exists(): drc.rename(newdrc) print(f"Marked {drc} for deletion") else: print(f"{drc} does not exist") def open_data_directory(self): drc = self.get_working_directory() try: os.startfile(drc) except FileNotFoundError: os.startfile(drc.parent) def open_config_directory(self): drc = config.base_drc os.startfile(drc)