Skip to content
Snippets Groups Projects

Multi-thread TPS plot

Merged Kien Le requested to merge featured-threading_TPS_plot into master
1 unresolved thread
2 files
+ 59
17
Compare changes
  • Side-by-side
  • Inline
Files
2
# Display time-power-squared values for waveform data
from math import sqrt
from typing import Optional
from typing import Optional, List
import numpy as np
@@ -61,7 +61,13 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget):
"""
self.tps_t = 0
self.tps_processor: Optional[TimePowerSquaredProcessor] = None
self.tps_processors: List[TimePowerSquaredProcessor] = []
self.channels = []
self.processed_channels = []
# The post-processing step does not take too much time so there is no
# need to limit the number of threads that can run at once.
self.thread_pool = QtCore.QThreadPool()
self.finished_lock = QtCore.QMutex()
super().__init__(*args, **kwarg)
@@ -78,6 +84,11 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget):
:param waveform_data: dict - read waveform data of selected data set,
refer to DataTypeModel.__init__.waveform_data[key]['read_data']
"""
self.processed_channels = []
self.channels = []
self.tps_processors = []
display_tracking_info(self.tracking_box, 'Plotting TPS data...')
self.processing_log = [] # [(message, type)]
self.gap_bar = None
self.min_x = max(data_time[0], start_tm)
@@ -111,8 +122,37 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget):
self.each_day5_min_list = get_each_day_5_min_list(self.min_x,
self.max_x)
for chan_id in self.plotting_data1:
ax = self.get_plot_data(self.plotting_data1[chan_id], chan_id)
self.axes.append(ax)
c_data = self.plotting_data1[chan_id]
if 'tps_data' not in c_data:
# get new minX, maxX according to exact start time of days
self.channels.append(chan_id)
channel_processor = TimePowerSquaredProcessor(
chan_id, c_data, self.min_x, self.max_x,
self.each_day5_min_list
)
channel_processor.signals.finished.connect(self.channel_done)
self.tps_processors.append(channel_processor)
# Because the widget determine if processing is done by comparing the
# lists of scheduled and finished channels, if a channel runs fast
# enough that it finishes before any other channel can be scheduled,
# it will be the only channel executed. To prevent this, we tell the
# threadpool to only start running the processors once all channels
# have been scheduled.
for processor in self.tps_processors:
self.thread_pool.start(processor)
@QtCore.Slot()
def channel_done(self, chan_id):
self.finished_lock.lock()
ax = self.plot_channel(self.plotting_data1[chan_id], chan_id)
self.axes.append(ax)
self.processed_channels.append(chan_id)
if len(self.processed_channels) == len(self.channels):
self.done()
self.finished_lock.unlock()
def done(self):
self.set_legend()
# Set view size fit with the given data
if self.main_widget.geometry().height() < self.plotting_bot_pixel:
@@ -120,7 +160,7 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget):
self.set_lim_markers()
self.draw()
def get_plot_data(self, c_data, chan_id):
def plot_channel(self, c_data, chan_id):
"""
TPS is plotted in lines of small rectangular, so called bars.
Each line is a day so - y value is the order of days
@@ -132,10 +172,8 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget):
based on mapping between tps value of the five minutes against
the selected color range.
This function trim data to minx, max_x and calculate time-power-square
for each 5 minute into c_data['tps_data'] then draw each 5 minute
with the color corresponding to value.
Create ruler, zoom_marker1, zoom_marker2 for the channel.
This function draws each 5 minute with the color corresponding to
value and create ruler, zoom_marker1, and zoom_marker2 for the channel.
:param c_data: dict - data of the channel which includes down-sampled
data in keys 'times' and 'data'. Refer to
@@ -143,12 +181,7 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget):
:param chan_id: str - name of channel
:return ax: matplotlib.axes.Axes - axes of the channel
"""
if 'tps_data' not in c_data:
# get new minX, maxX according to exact start time of days
self.tps_processor = TimePowerSquaredProcessor(
c_data, self.min_x, self.max_x, self.each_day5_min_list
)
self.tps_processor.run()
total_days = c_data['tps_data'].shape[0]
plot_h = self.plotting_axes.get_height(
1.5 * total_days, bw_plots_distance=0.003)
@@ -302,7 +335,7 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget):
xdata = 287
ydata = round(event.mouseevent.ydata) # y value on the plot
# refer to description in get_plot_data to understand x,y vs
# refer to description in plot_channel to understand x,y vs
# day_index, five_min_index
day_index = - ydata
five_min_index = xdata
Loading