Commit 26ef709d authored by Lars Bittrich's avatar Lars Bittrich
Browse files

Bugfix to improve thread safety in opticalscan; it now uses queue and event instead of just pipes

parent c6633317
Loading
Loading
Loading
Loading
+22 −19
Original line number Diff line number Diff line
@@ -21,7 +21,8 @@ If not, see <https://www.gnu.org/licenses/>.

from PyQt5 import QtCore, QtWidgets
import numpy as np
from multiprocessing import Process, Pipe
from multiprocessing import Process, Queue, Event
import queue
from imagestitch import imageStacking
import os
import cv2
@@ -30,7 +31,7 @@ from time import sleep, time
import datetime
import sys

def scan(path, sol, zpositions, grid, controlclass, connection, ishdr=False):
def scan(path, sol, zpositions, grid, controlclass, dataqueue, stopevent, ishdr=False):
    if ishdr:
        merge_mertens = cv2.createMergeMertens()
    with open("scanlog.txt", "a") as fp:
@@ -63,16 +64,11 @@ def scan(path, sol, zpositions, grid, controlclass, connection, ishdr=False):
                    cv2imwrite_fix(os.path.join(path,name), res_mertens_8bit)                        
                else:
                    ramanctrl.saveImage(os.path.join(path,name))
                if connection.poll():
                    instruction = connection.recv()
                    if instruction=="stop":
                if stopevent.is_set():
                    ramanctrl.disconnect()
                    return
            connection.send(i)
            dataqueue.put(i)
        ramanctrl.disconnect()
        while not connection.poll():
            sleep(.1)
        connection.recv()
    
def loadAndPasteImage(srcnames, fullimage, fullzval, width, height, 
                      rotationvalue, p0, p1, p):
@@ -295,8 +291,10 @@ class OpticalScan(QtWidgets.QWidget):
                                QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)
            if reply == QtWidgets.QMessageBox.Yes:
                self.timer.stop()
                self.connection.send("stop")
                self.processstopevent.set()
                self.process.join()
                self.dataqueue.close()
                self.dataqueue.join_thread()
                self.view.unblockUI()
            else:
                return
@@ -464,10 +462,11 @@ class OpticalScan(QtWidgets.QWidget):
        if reply == QtWidgets.QMessageBox.Yes:
            self.prun.setEnabled(False)
            self.ramanctrl.disconnect()
            parent_conn, child_conn = Pipe()
            self.connection = parent_conn
            self.processstopevent = Event()
            self.dataqueue = Queue()
            self.process = Process(target=scan, args=(path, sol, self.dataset.zpositions, 
                                self.dataset.grid, self.ramanctrl.__class__, child_conn, self.hdrcheck.isChecked()))
                                self.dataset.grid, self.ramanctrl.__class__,
                                self.dataqueue, self.processstopevent, self.hdrcheck.isChecked()))
            self.process.start()
            self.starttime = time()
            self.progresstime.setEnabled(True)
@@ -490,8 +489,12 @@ class OpticalScan(QtWidgets.QWidget):
    
    @QtCore.pyqtSlot()      
    def checkOnScan(self):
        if self.connection.poll():
            i = self.connection.recv()
        try:
            i = self.dataqueue.get_nowait()
        except queue.Empty:
            i = -1
            
        if i>=0:
            Ngrid = len(self.dataset.grid)
            names = []
            for k in range(len(self.dataset.zpositions)):
@@ -509,11 +512,11 @@ class OpticalScan(QtWidgets.QWidget):
                self.progresstime.setText(self.timelabeltext + str(datetime.timedelta(seconds=round(time2go))))
            self.imageUpdate.emit()
            if i==Ngrid-1:
                self.connection.send("stop")
                cv2imwrite_fix(self.dataset.getImageName(), cv2.cvtColor(self.view.imgdata, cv2.COLOR_RGB2BGR))
                self.dataset.saveZvalImg()
                self.process.join()
                self.connection.close()
                self.dataqueue.close()
                self.dataqueue.join_thread()
                self.ramanctrl.connect()
                self.view.saveDataSet()
                self.view.unblockUI()