Skip to content

Commit 358908a

Browse files
authored
Merge pull request #50 from philipstarkey/feature/resample-performance
Improved performance of resample thread
2 parents 1d0ea1a + 219e4e4 commit 358908a

File tree

1 file changed

+44
-29
lines changed

1 file changed

+44
-29
lines changed

runviewer/__main__.py

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import ast
3434
import pprint
3535
import signal
36+
import concurrent.futures
3637

3738
splash.update_text('importing labscript suite modules')
3839
from labscript_utils.setup_logging import setup_logging
@@ -1226,40 +1227,54 @@ def __resample3(self, x_in, y_in, x_out, stop_time):
12261227
return y_out
12271228

12281229
def _resample_thread(self):
1229-
logger = logging.getLogger('runviewer.resample_thread')
1230-
while True:
1231-
if self._resample:
1232-
self._resample = False
1233-
# print 'resampling'
1234-
ticked_shots = inmain(self.get_selected_shots_and_colours)
1235-
for shot, (colour, shutters_checked) in ticked_shots.items():
1236-
for channel in shot.traces:
1237-
if self.channel_checked_and_enabled(channel):
1238-
try:
1239-
xmin, xmax, dx = self._get_resample_params(channel, shot)
1240-
1241-
# We go a bit outside the visible range so that scrolling
1242-
# doesn't immediately go off the edge of the data, and the
1243-
# next resampling might have time to fill in more data before
1244-
# the user sees any empty space.
1245-
if self.scale_time:
1246-
xnew, ynew = self.resample(shot.scaled_times(channel), shot.traces[channel][1], xmin, xmax, shot.stop_time, dx)
1247-
else:
1248-
xnew, ynew = self.resample(shot.traces[channel][0], shot.traces[channel][1], xmin, xmax, shot.stop_time, dx)
1249-
inmain(self.plot_items[channel][shot].setData, xnew, ynew, pen=pg.mkPen(QColor(colour), width=2), stepMode=True)
1250-
except Exception:
1251-
#self._resample = True
1252-
pass
1253-
else:
1254-
logger.info('ignoring channel %s' % channel)
1255-
time.sleep(0.5)
1230+
# logger = logging.getLogger('runviewer.resample_thread')
1231+
with concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count()) as executer:
1232+
while True:
1233+
if self._resample:
1234+
self._resample = False
1235+
channel_data = self.__get_all_resample_params()
1236+
1237+
results = []
1238+
for args in channel_data:
1239+
results.append(executer.submit(self.__pool_resample, *args))
1240+
1241+
# wait for all inmain_later calls from threadpool to finish before we trigger a new resample
1242+
for future in results:
1243+
result = future.result()
1244+
if isinstance(result, Queue):
1245+
result.get()
1246+
1247+
time.sleep(0.1)
1248+
1249+
@inmain_decorator(wait_for_return=True)
1250+
def __get_all_resample_params(self):
1251+
return [(channel, shot, colour, *self._get_resample_params(channel, shot))
1252+
for shot, (colour, shutters_checked) in self.get_selected_shots_and_colours().items()
1253+
for channel in shot.traces
1254+
if self.channel_checked_and_enabled(channel)
1255+
]
1256+
1257+
def __pool_resample(self, channel, shot, colour, xmin, xmax, dx):
1258+
try:
1259+
# We go a bit outside the visible range so that scrolling
1260+
# doesn't immediately go off the edge of the data, and the
1261+
# next resampling might have time to fill in more data before
1262+
# the user sees any empty space.
1263+
if self.scale_time:
1264+
xnew, ynew = self.resample(shot.scaled_times(channel), shot.traces[channel][1], xmin, xmax, shot.stop_time, dx)
1265+
else:
1266+
xnew, ynew = self.resample(shot.traces[channel][0], shot.traces[channel][1], xmin, xmax, shot.stop_time, dx)
1267+
return inmain_later(self.plot_items[channel][shot].setData, xnew, ynew, pen=pg.mkPen(QColor(colour), width=2), stepMode=True)
1268+
except Exception:
1269+
#self._resample = True
1270+
pass
12561271

12571272
@inmain_decorator(wait_for_return=True)
12581273
def channel_checked_and_enabled(self, channel):
1259-
logger.info('is channel %s enabled' % channel)
1274+
# logger.info('is channel %s enabled' % channel)
12601275
index = self.channel_model.index(0, CHANNEL_MODEL__CHANNEL_INDEX)
12611276
indexes = self.channel_model.match(index, Qt.DisplayRole, channel, 1, Qt.MatchExactly)
1262-
logger.info('number of matches %d' % len(indexes))
1277+
# logger.info('number of matches %d' % len(indexes))
12631278
if len(indexes) == 1:
12641279
check_item = self.channel_model.itemFromIndex(indexes[0])
12651280
if check_item.checkState() == Qt.Checked and check_item.isEnabled():

0 commit comments

Comments
 (0)