class MeasureFrame(LabelFrame): def __init__(self, master, tracker, text="Measuring", *args, **kwargs): LabelFrame.__init__(self, master, text=text, *args, **kwargs) self.tracker = tracker self.config_frame = NamedEntryFrame(self, (OBS_INTERVAL, NUM_SAMPLES, NUM_OBSS), parsers={OBS_INTERVAL: float, NUM_SAMPLES: int, NUM_OBSS: int}) self.config_frame.grid() self.save_frame = LabelFrame(self, text="Saving") self.dest_selector = FileSelectionFrame(self.save_frame, ask_mode="save") self.dest_selector.grid(row=0, column=0, columnspan=2) self.save_button = Button(self.save_frame, text="Save", command=bg_caller(self.save)) self.save_button.grid(row=1, column=0) self.appending_var = BooleanVar() self.append_checkbutton = Checkbutton(self.save_frame, text="Append", variable=self.appending_var) self.append_checkbutton.grid(row=1, column=1) self.save_frame.grid() def measure(self, only_accurate=True): try: interval = self.config_frame.get(OBS_INTERVAL) samples = self.config_frame.get(NUM_SAMPLES) num_obss = self.config_frame.get(NUM_OBSS) except ValueError: logger.error("Could not parse input fields.") data = self.tracker.measure(observation_interval=interval, samples_per_observation=samples, number_of_observations=num_obss) if only_accurate: accurate_data = [point for point in data if point.status == point.DATA_ACCURATE] num_invalid = len(data) - len(accurate_data) if num_invalid > 0: logger.warning("Hiding {} inaccurate data points." .format(num_invalid)) return accurate_data else: return data def save(self, only_accurate=True): dest = self.dest_selector.path_var.get() if not dest: logger.error("Must select a destination file.") return data = self.measure(only_accurate=only_accurate) w = csv.writer(open(dest, 'a' if self.appending_var.get() else 'w')) for point in data: w.writerow((point.time, point.position.r, point.position.theta, point.position.phi)) logger.info("Saved measurements into {!r}".format(dest))
class MovementFrame(LabelFrame): """Has controls for aiming the laser tracker.""" def __init__(self, master, text="Movement", **options): LabelFrame.__init__(self, master, text=text, **options) self.tracker = master.tracker self.coordinate_frame = NamedEntryFrame(self, ("Radius", "Theta", "Phi"), parsers={"Radius": float, "Theta": float, "Phi": float}) self.coordinate_frame.grid(row=0, column=0, rowspan=3) self.search_button = Button(self, text="Search", command=bg_caller(self.search)) self.search_button.grid(row=0, column=1) self.move_button = Button(self, text="Move", command=bg_caller(self.move_tracker)) self.move_button.grid(row=1, column=1) self.move_absolute_button = Button(self, text="Move (absolute)", command=bg_caller(self.move_absolute)) self.move_absolute_button.grid(row=2, column=1) def move_tracker(self): try: coords = self.coordinate_frame.get_all() except ValueError as e: logger.error("Parsing error: {}".format(e.message)) return r, theta, phi = coords["Radius"], coords["Theta"], coords["Phi"] self.tracker.move(r, theta, phi) logger.info("Moved tracker by {}".format((r, theta, phi))) def move_absolute(self): try: coords = self.coordinate_frame.get_all() except ValueError as e: logger.error("Parsing error: {}".format(e.message)) return r, theta, phi = coords["Radius"], coords["Theta"], coords["Phi"] self.tracker.move_absolute(r, theta, phi) logger.info("Moved tracker to {}".format((r, theta, phi))) def search(self): try: r = self.coordinate_frame.get("Radius") except ValueError: logger.error("Couldn't parse radius field.") return self.tracker.search(r) logger.info("Searched with radius {}".format(r))
class MovementFrame(LabelFrame): """Provides motion-related controls for an ActuatorBoard.""" def __init__(self, master, text="Movement", **options): LabelFrame.__init__(self, master, text=text, **options) self.listbox = master.listbox self.board = master.board self.micron_frame = NamedEntryFrame(self, ("Microns",), parsers={"Microns": float}) self.micron_frame.grid(row=0, column=0, columnspan=2) self.move_button = Button(self, text="Move", command=bg_caller(self.move_actuators)) self.move_button.grid(row=1, column=0) self.move_absolute_button = Button(self, text="Move absolute", command=bg_caller(self.move_absolute)) self.move_absolute_button.grid(row=1, column=1) def move_actuators(self): try: microns = self.micron_frame.get("Microns") except ValueError: logger.error("Unable to parse micron field.") return for port in self.listbox.get_selected_items(): self.board.move(microns=microns, port=port) logger.info("Moved actuator {} by {} microns.".format(port, microns)) def move_absolute(self): try: microns = self.micron_frame.get("Microns") except ValueError: logger.error("Unable to parse micron field.") return for port in self.listbox.get_selected_items(): self.board.move_absolute(microns=microns, port=port) logger.info("Moved actuator {} by {} microns (absolute)." .format(port, microns)) def _unsafe_parse_microns(self): return def get_microns(self): try: return float(self.micron_field.get()) except ValueError: logger.error("Unable to parse micron field.") return None