forked from zietzm/Helmholtz_Test_Bench
Introduced red status indicator line, minor warning fixes
This commit is contained in:
+50
-7
@@ -9,6 +9,7 @@ import numpy as np
|
||||
from threading import *
|
||||
from tkinter import messagebox
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
||||
|
||||
from src.exceptions import DeviceBusy, DeviceAccessError
|
||||
from src.utility import ui_print
|
||||
@@ -79,6 +80,9 @@ class ExecCSVThread(Thread):
|
||||
messagebox.showwarning("Device Error!", "Required devices are not present, sequence aborted.")
|
||||
return
|
||||
|
||||
# Initialize plot
|
||||
figure, avx_lines = display_plot(parent)
|
||||
|
||||
i = 0 # index of the current array row
|
||||
while i < len(array):
|
||||
if self.stopped or g.exit_flag:
|
||||
@@ -88,9 +92,17 @@ class ExecCSVThread(Thread):
|
||||
return
|
||||
|
||||
# while array is not finished, devices are connected, user has not cancelled and application is running
|
||||
|
||||
t = time.time() - t_zero # get time relative to start of run
|
||||
target_t = array[i, 0] # Target execution time of data point
|
||||
|
||||
# Update figure
|
||||
try:
|
||||
for j in range(4):
|
||||
avx_lines[j].set_data([t, t], [0, 1])
|
||||
parent.plot_canvas.draw() # equivalent to matplotlib.show()
|
||||
except DeviceAccessError as e:
|
||||
ui_print("Failed to update figure: ", e)
|
||||
|
||||
if t >= target_t: # time for this row has come
|
||||
field_vec = array[i, 1:4] # extract desired field vector
|
||||
ui_print("[{:5.3f}s] B=[{:.1f}, {:.1f}, {:.1f}]\u03BCT for t={:.2f}s".format(t,
|
||||
@@ -106,7 +118,6 @@ class ExecCSVThread(Thread):
|
||||
logger = controller.pages[ui.ConfigureLogging] # get object of logging configurator
|
||||
if logger.event_logging: # data should be logged when test bench is commanded
|
||||
logger.log_datapoint() # log data
|
||||
|
||||
i = i + 1 # next row
|
||||
|
||||
elif t <= target_t - delay - 0.02: # is there enough time to sleep before the next row?
|
||||
@@ -117,7 +128,7 @@ class ExecCSVThread(Thread):
|
||||
|
||||
def read_csv_to_array(filepath): # convert a given csv file to a numpy array
|
||||
# csv format: time [s], xField [T], yField [T], zField [T] (german excel)
|
||||
# decimal or period commas. Do not use these characters as a thousands separator!
|
||||
# decimal or period commas. Do not use these characters as a thousand separator!
|
||||
with open(filepath, 'r') as csv_file:
|
||||
# Normalize separators
|
||||
csv_string = csv_file.read()
|
||||
@@ -153,6 +164,38 @@ def check_array_ok(array):
|
||||
messagebox.showwarning("Value Limits Warning!", warning_msg)
|
||||
|
||||
|
||||
def display_plot(parent): # create plot of fixed size (pixels) from array
|
||||
# calculate available height for plot (in pixels):
|
||||
height_others = 0 # initialize variable to calculate height of other widgets
|
||||
for element in parent.row_elements: # go through all rows in the widget except the plot frame
|
||||
height_others += element.winfo_height() # add up heights
|
||||
|
||||
# calculate available plot height:
|
||||
height = parent.parent.winfo_height() - height_others - 50 # height of parent frame - other widgets - margin
|
||||
width = min(parent.parent.winfo_width() - 100, 1100) # set width to available space but max. 1100
|
||||
|
||||
# Create plot
|
||||
figure = plot_field_sequence(parent.sequence_array, width, height) # create figure to be displayed
|
||||
# Clear previous plots first
|
||||
try:
|
||||
if parent.plot_canvas is not None:
|
||||
parent.plot_canvas.get_tk_widget().destroy()
|
||||
except Exception as e:
|
||||
ui_print("Something went wrong while plotting csv data!", e)
|
||||
messagebox.showerror("Error!", "Something went wrong while plotting csv data: \n%s" % e)
|
||||
pass
|
||||
|
||||
axes = figure.axes
|
||||
avx_lines = [axes[0].axvline(x=0, color="r"), axes[1].axvline(x=0, color="r"),
|
||||
axes[2].axvline(x=0, color="r"), axes[3].axvline(x=0, color="r")]
|
||||
# Show new plot
|
||||
parent.plot_canvas = FigureCanvasTkAgg(figure, parent.plot_frame) # create canvas to draw figure on
|
||||
parent.plot_canvas.draw() # equivalent to matplotlib.show()
|
||||
parent.plot_canvas.get_tk_widget().grid(row=0, column=0, sticky="nesw") # place canvas in the UI
|
||||
|
||||
return figure, avx_lines
|
||||
|
||||
|
||||
def plot_field_sequence(array, width, height): # create plot of fixed size (pixels) from array
|
||||
# ToDo (optional): polar plots, plots of angle...
|
||||
fig_dpi = 100 # set figure resolution (dots per inch)
|
||||
@@ -160,12 +203,12 @@ def plot_field_sequence(array, width, height): # create plot of fixed size (pix
|
||||
figure = plt.Figure(figsize=(width*px, height*px), dpi=fig_dpi) # create figure with correct size
|
||||
|
||||
# noinspection PyTypeChecker,SpellCheckingInspection
|
||||
axes = figure.subplots(4, sharex=True, sharey=False, gridspec_kw={'hspace': 0.4}) # create subplots with shared axes
|
||||
axes = figure.subplots(4, sharex=True, sharey=False, gridspec_kw={'hspace': 0.4}) # make subplots with shared axes
|
||||
|
||||
figure.suptitle("Magnetic Field Sequence") # set figure title
|
||||
|
||||
# modify data to show instantaneous jumps in field to reflect test bench operation
|
||||
new_array = np.array([[0, 0, 0, 0, 0]], dtype=float) # initialize modified array, zeros to show start from no fields
|
||||
new_array = np.array([[0, 0, 0, 0, 0]], dtype=float) # initialize modified array, zeros to show start from no field
|
||||
|
||||
last_values = [0, 0, 0, 0] # [x,y,z, rr] field values / rot rate from last data point (zero here)
|
||||
for row in array[:, 0:5]: # go through each row in the original array
|
||||
@@ -200,8 +243,8 @@ def plot_field_sequence(array, width, height): # create plot of fixed size (pix
|
||||
ylim_mag = ([min(axes[0].get_ylim()), max(axes[0].get_ylim()),
|
||||
min(axes[1].get_ylim()), max(axes[1].get_ylim()),
|
||||
min(axes[2].get_ylim()), max(axes[2].get_ylim())])
|
||||
for i in range(3): axes[0].set_ylim(min(ylim_mag),max(ylim_mag))
|
||||
|
||||
for i in range(3):
|
||||
axes[0].set_ylim(min(ylim_mag), max(ylim_mag))
|
||||
|
||||
# set shared axis labels:
|
||||
axes[2].set_xlabel("Time [s])")
|
||||
|
||||
Reference in New Issue
Block a user