diff --git a/Python_script/MeasurementPlot.py b/Python_script/MeasurementPlot.py index 7f54028d7f8d1947980ac07573a9c49e0fbe14cd..bd7e0b46d2c88f858e89f0e210cb078040a947c4 100644 --- a/Python_script/MeasurementPlot.py +++ b/Python_script/MeasurementPlot.py @@ -2,9 +2,10 @@ import pandas as pd import matplotlib.pyplot as plt import numpy as np import time -from multiprocessing import Queue +import multiprocessing as mp import queue import sys +import process_sync # Different exceptions can be thrown while plotting, depending on the backend. # We catch them all locally and raise our own exception instead @@ -145,7 +146,7 @@ class MeasurementPlot: plt.rcParams.update({'font.size': 16}) - self.data_queue = Queue(10) + self.data_queue = mp.Queue(10) def stop(self): self.data_queue.put((None, None, True)) @@ -162,12 +163,18 @@ class MeasurementPlot: def drawing_loop(self): while True: print('drawing loop getting') - data_frame, pdf_name, stop_thread = self.data_queue.get() - print('drawing loop got. stop is ' +str(stop_thread)) - if stop_thread: + data_frame, pdf_name, stop_drawing = self.data_queue.get() + print('drawing loop got. stop is ' +str(stop_drawing)) + if stop_drawing: return print('drawing loop drawing') - self.draw_in_this_thread(data_frame, pdf_name='') + try: + if not process_sync.stop_measurement.is_set(): + self.draw_in_this_thread(data_frame, pdf_name='') + except Exception as e: + print('caught exception when drawing: '+str(e)) + # Don't exit here. Always drain the data queue so the program can terminate correctly + process_sync.stop_measurement.set() def draw_in_this_thread(self, data_frame, pdf_name=''): timestamps = data_frame.TIMESTAMP diff --git a/Python_script/prototype.py b/Python_script/prototype.py index a16c1de7ffb78ebbf07d2b8f8435bce5a7a163ca..7fc36bfea9401f85eac9a61f79ab9e334b82631e 100755 --- a/Python_script/prototype.py +++ b/Python_script/prototype.py @@ -17,6 +17,7 @@ from multiprocessing import Process import external_sensors import PostPlot import os +import process_sync # Only use these when calculating the equilibrium indicator. Don't use in the algorithm. TEMPERATURE_STABLE = 0x1 @@ -158,9 +159,10 @@ class Measurements: except KeyboardInterrupt: pass - except MeasurementPlot.PlottingError: - # Remove the remaining measurements from the list. - # One measurement was partly done and should be plotted, so we leave 'val' in the list + + # Remove the remaining measurements from the list. + # One measurement was partly done and should be plotted, so we leave 'val' in the list + if process_sync.stop_measurement.is_set(): del sweep_values[sweep_values.index(val)+1:] plt.close() @@ -174,15 +176,14 @@ class Measurements: This is a "chamber measurement point". It consists out of multiple measurements sets. The data for all measurement sets of this chamber point are taken for this measurement. """ + process_sync.stop_measurement.clear() measurement_process = Process(target=self.perform_single_measurement_impl, args=(output, target_temp, target_hum, soaking_time, n_stable_reads)) measurement_process.start() #turn interactive plotting (back) on (is deactivated by starting the process) plt.ion() - try: - self.measurement_plot.drawing_loop() - finally: - measurement_process.join() + self.measurement_plot.drawing_loop() + measurement_process.join() def perform_single_measurement_impl(self, output, target_temp, target_hum, soaking_time, n_stable_reads): with open(output, mode='w', newline='') as csv_file: @@ -214,6 +215,10 @@ class Measurements: dut_signal_queues = [[], []] while True: + if process_sync.stop_measurement.is_set(): + do_another_measurement = False + break + # Only read the climate chamber data once. The equilibrium indicator is only calculated on the # primary data set. data = self.read_data(self.dut.get_measurement_set_names()[0]) @@ -273,6 +278,11 @@ class Measurements: all_measurements_stable = True for i in range(0, n_stable_reads): + if process_sync.stop_measurement.is_set(): + all_measurements_stable = False #not enough stable reads yet + do_another_measurement = False + break + # create the main data set for the first measurement set data = self.read_data(self.dut.get_measurement_set_names()[0]) self.temperature_stable = self.calculate_temperature_stability(target_temp, float(data.temp))