class UserLoginModule(QDialog, Ui_Dialog):
    def __init__(self, menu, parent=None):
        super(UserLoginModule, self).__init__(parent)
        self.setupUi(self)
        self.menu = menu
        self.label_tips.setVisible(False)
        self.CC = ClerksController()
        return_row = ('autoid', 'clerkid', 'clerkname')
        condition_key = ('clerkid', 'clerkname')
        treeheader_name = ["id", "编号", "姓名"]
        self.lineEdit_username.setup('Clerks', return_row, condition_key,
                                     treeheader_name, None, 250, 200)

    @pyqtSlot()
    def on_pushButton_accept_clicked(self):
        try:
            userid, username = self.lineEdit_username.text().split(' ')
        except:
            self.label_tips.setVisible(True)
            self.lineEdit_username.setFocus()
            return
        password = md5(
            self.lineEdit_password.text().encode('UTF-8')).hexdigest()
        condition = {
            'clerkid': userid,
            'clerkname': username,
            'password': password
        }
        res = self.CC.get_data(0, False, *VVALUES_TUPLE_CL, **condition)
        if len(res):
            user.user_id = userid
            user.user_name = username
            if res[0]['powers'] != '':
                try:
                    user.powers = json.loads(res[0]['powers'])
                except json.decoder.JSONDecodeError:
                    pass
            condition = {'clerkid': res[0]['autoid']}
            dept_res = self.CC.get_data(1, False,
                                        **condition).order_by('-defaultdept')
            if len(dept_res):
                user.dept_id = dept_res[0].deptid.deptid
                user.dept_name = dept_res[0].deptid.deptname

            self.menu.showMaximized()
            self.menu.set_module()
            self.setHidden(True)
        else:
            self.label_tips.setVisible(True)

    pyqtSlot(str)

    def on_lineEdit_username_textChanged(self, p_str):
        self.label_tips.setVisible(False)

    pyqtSlot(str)

    def on_lineEdit_password_textChanged(self, p_str):
        self.label_tips.setVisible(False)
Exemple #2
0
def create_slot(argType=None, name=None):

    if not name or name is None:
        if argType is None:
            return pyqtSlot()
        else:
            return pyqtSlot(argType)
    else:
        if argType is None:
            return pyqtSlot(name=name)
        else:
            return pyqtSlot(argType, name=name)
Exemple #3
0
def qtSlot(f: Callable[..., Any]) -> Callable[..., Any]:
    sig = inspect.signature(f)
    result_type = sig.return_annotation
    assert result_type != sig.empty, "Return annotation missing"
    parameters = []
    for par in sig.parameters.values():
        if par.name == "self":
            continue
        assert par.annotation != sig.empty, "Parameter annotation missing for %s" % (
            par.name)
        parameters.append(_toQtType(par.annotation))
    if result_type is not None:
        return pyqtSlot(*parameters, result=_toQtType(result_type))(f)
    return pyqtSlot(*parameters)(f)
Exemple #4
0
def slot(function: FuncT) -> FuncT:
    """Annotation based slot decorator using pyqtSlot.

    Syntactic sugar for pyqtSlot so the parameter types do not have to be repeated when
    there are type annotations.

    Example:
        @slot
        def function(self, x: int, y: int) -> None:
        ...
    """
    annotations = typing.get_type_hints(function)
    pyqtSlot(*_slot_args(function, annotations),
             **_slot_kwargs(annotations))(function)
    return function
Exemple #5
0
class VideoHandler:
    def __init__(self, filename):

        self.video_filename = filename
        try:
            self.video_handler = cv2.VideoCapture(self.video_filename)
        except:
            # there was an error reading the file, return
            # we need to add error codes so that the user can knows what happened
            return

        self.video_length = int(self.video_handler.get(cv2.CAP_PROP_FRAME_COUNT))
        self.video_fps = int(self.video_handler.get(cv2.CAP_PROP_FPS))
        self.playbackspeed = self.video_fps
        self.video_exist_landmarks = None
        self.video_landmarks_filename = None
        self.video_landmarks = None

    pyqtSlot(object)
    def emitimage(self, image):
        return image

    def playvideo(self):

        th = ThreadReadVideo(self.video_handler)
        th.videoframe.connect(self.emitimage)
        th.start()
Exemple #6
0
class App(QWidget):
    def __init__(self):
        super().__init__()
        self.title = "BLACKPINK Secret Word Song"
        self.left = 200
        self.top = 200
        self.width = 640
        self.height = 480
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.textbox1 = QLineEdit(self)
        self.textbox1.move(30, 30)
        self.textbox1.resize(280, 40)

        self.button = QPushButton('Click me', self)
        self.button.move(15, 85)
        self.button.clicked.connect(self.on_click)
        self.show()

    pyqtSlot()

    def on_click(self):
        textboxValue = self.textbox1.text()
        QMessageBox.question(self, 'Hello', 'Confirm: ' + textboxValue, QMessageBox.Ok,  QMessageBox.Cancel)
        self.textbox1.setText('')
Exemple #7
0
 def __init__(self, parent=None):
     super().__init__(parent)
     uic.loadUi('system/gui/chat_test.ui', self)
     self.listContacts.setSortingEnabled(True)
     self.selected_item_row = None
     self.selected_item_text = ""
     self.notifier = Notifier()
     self.receiver = ReceiverHandler()
     self.thread = QThread()
     self.auth = AuthReg()
     self.reg = AuthReg(auth=False)
     self.got_img = pyqtSlot(dict)
Exemple #8
0
 def _decorator(method):
     @functools.wraps(method)
     def new_method(self, *args, **kwargs):
         try:
             return method(self, *args, **kwargs)
         except:
             e = str(sys.exc_info()[0])
             log.network.exception("PAC evaluation error")
             # pylint: disable=protected-access
             return self._error_con.callAsConstructor([e])
             # pylint: enable=protected-access
     return pyqtSlot(*args, result=QJSValue)(new_method)
class OSCclient(QObject):
    """Connects to OSC server to send OSC messages to server
    input: ip of qlab machine, input port number
    default localhost, 53000 (QLab settings)"""
    def __init__(self, ip="127.0.0.1", port=53000):
        QObject.__init__(self)
        self.ip = ip
        self.port = port
        self.client = udp_client.UDPClient(ip, port)

    pyqtSlot(object)

    def emit(self, cuenum):
        msg_raw = f"/cue/{cuenum}/start"
        print(f'{msg_raw} sent')
        msg = osc_message_builder.OscMessageBuilder(msg_raw)
        msg = msg.build()
        self.client.send(msg)
Exemple #10
0
        class Reader(QObject):
            '''
            Synchronous data reader.
            '''

            received = pyqtSignal(bytes)
            done = pyqtSignal()

            def __init__(self, io):
                QObject.__init__(self)
                self.io = io
                self.proceedToExit = None

            pyqtSlot()

            def read(self):
                '''
                Infinitely wait for incoming data in an infinite loop. All the incoming data is passed outside with the
                signal.

                :return data: bytes, incoming data
                '''

                self.proceedToExit = False

                while not self.proceedToExit:
                    data = self.io.read()

                    QCoreApplication.processEvents(
                    )  # need to process events, and delivered signals

                    if not data:
                        continue

                    self.received.emit(data)

                self.io.close()
                self.done.emit()

            @pyqtSlot()
            def quit(self):
                self.proceedToExit = True
Exemple #11
0
    def decorator(func):
        if os.environ.get('READTHEDOCS') != 'True':
            func = pyqtSlot(*args, **kwargs)(func)

        signatures = []

        for srcline in inspect.getsourcelines(func)[0]:
            srcline = srcline.strip()

            mtc = SLOT_RE.match(srcline)
            if mtc:
                signatures.append(mtc.group(1))
            elif srcline.startswith('def '):
                break

        text = '\n\n'.join('This slot has signature ``%s%s``.' %
                           (func.__name__, sig) for sig in signatures)
        _addDoc(func, text)

        return func
Exemple #12
0
 def start(self):
     self.setIptables(self.APmode, option="A")
     self.procThreadDNS = QProcess(self)
     self.procThreadDNS.setProcessChannelMode(QProcess.MergedChannels)
     QObject.connect(
         self.procThreadDNS,
         pyqtSignal("readyReadStandardOutput()"),
         self,
         pyqtSlot("readProcessOutput()"),
     )
     self.procThreadDNS.start(
         "python",
         [
             "core/packets/dnsspoofNF.py",
             "-r",
             self.redirect,
             "-d",
             ",".join(self.domains),
         ],
     )
Exemple #13
0
	def decorator(func):
		if os.environ.get('READTHEDOCS') != 'True':
			func = pyqtSlot(*args, **kwargs)(func)

		signatures = []

		for srcline in inspect.getsourcelines(func)[0]:
			srcline = srcline.strip()

			mtc = SLOT_RE.match(srcline)
			if mtc:
				signatures.append('@Slot%s' % mtc.group(1))
			elif srcline.startswith('def '):
				break

		text = '\n\n'.join(signatures)

		if func.__doc__ is None:
			func.__doc__ = text
		else:
			func.__doc__ += '\n\n' + text

		return func
    def wrapper(func):
        if is_slot:
            func = pyqtSlot()(func)

        @wraps(func)
        def decorator(*args, **kwargs):
            qobj = args[0] if is_qt_method else None
            result, exception = None, None
            loop = QEventLoop()
            progress = ProgressWindow(parent=qobj, window_title=window_title, label_text=label_text)

            class Thread(QtCore.QThread):
                def run(self):
                    nonlocal result, exception
                    try:
                        result = func(*args, **kwargs)
                    except Exception as e:
                        exception = e

            task = Thread()
            task.finished.connect(progress.close)
            task.finished.connect(loop.exit)

            nonlocal disable
            disable = disable and qobj is not None

            with disabled(qobj, enable=disable, except_objs=[progress]):
                progress.show()
                task.start()
                loop.exec()
            
            if exception is not None:
                raise exception
                
            return result
            
        return decorator
Exemple #15
0
class ColorPalette(QFrame):
    """Represents the entire grid of color tiles in the color picker
    """
    def __init__(self):
        super().__init__()
        self.grid = QGridLayout()
        self.grid.setSpacing(0)
        self.grid.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self.grid)
        self.palette = [Color(n) for n in range(256)]
        self.setFrameShape(QFrame.Panel)
        self.setFrameShadow(QFrame.Sunken)
        self.setLineWidth(3)
        self.setFixedSize(400 + self.lineWidth() * 2,
                          400 + self.lineWidth() * 2)
        positions = [(row, col) for row in range(16) for col in range(16)]
        colors = [(red, green, blue) for blue in range(4) for red in range(8)
                  for green in range(8)]
        for position, color, swatch in zip(positions, colors, self.palette):
            color = QColor(*upsample(*color))
            swatch.fill(color)
            swatch.color_selected.connect(self.selectColor)
            self.grid.addWidget(swatch, *position)
        self.enabled = False

    pyqtSlot(int)

    def selectColor(self, index):
        """Selects a color in the color picker

        :param index:   Index of the selected color
        :type index:    int
        """
        for idx in range(self.grid.count()):
            if idx != index:
                self.grid.itemAt(idx).widget().deselect()
class ModulesManager(QObject):

    detectors_changed = pyqtSignal(list)
    actuators_changed = pyqtSignal(list)
    det_done_signal = pyqtSignal(OrderedDict)
    move_done_signal = pyqtSignal(OrderedDict)
    timeout_signal = pyqtSignal(bool)

    params = [
        {
            'title':
            'Actuators/Detectors Selection',
            'name':
            'modules',
            'type':
            'group',
            'children': [
                {
                    'title': 'detectors',
                    'name': 'detectors',
                    'type': 'itemselect'
                },
                {
                    'title': 'Actuators',
                    'name': 'actuators',
                    'type': 'itemselect'
                },
            ]
        },
        {
            'title': "Moves done?",
            'name': 'move_done',
            'type': 'led',
            'value': False
        },
        {
            'title': "Detections done?",
            'name': 'det_done',
            'type': 'led',
            'value': False
        },
        {
            'title':
            'Data dimensions',
            'name':
            'data_dimensions',
            'type':
            'group',
            'children': [
                {
                    'title': "Probe detector's data",
                    'name': 'probe_data',
                    'type': 'action'
                },
                {
                    'title': 'Data0D list:',
                    'name': 'det_data_list0D',
                    'type': 'itemselect'
                },
                {
                    'title': 'Data1D list:',
                    'name': 'det_data_list1D',
                    'type': 'itemselect'
                },
                {
                    'title': 'Data2D list:',
                    'name': 'det_data_list2D',
                    'type': 'itemselect'
                },
                {
                    'title': 'DataND list:',
                    'name': 'det_data_listND',
                    'type': 'itemselect'
                },
            ]
        },
        {
            'title':
            'Actuators positions',
            'name':
            'actuators_positions',
            'type':
            'group',
            'children': [
                {
                    'title': "Test actuators",
                    'name': 'test_actuator',
                    'type': 'action'
                },
                {
                    'title': 'Positions:',
                    'name': 'positions_list',
                    'type': 'itemselect'
                },
            ]
        },
    ]

    def __init__(self,
                 detectors=[],
                 actuators=[],
                 selected_detectors=[],
                 selected_actuators=[],
                 timeout=10000):
        super().__init__()

        for mod in selected_actuators:
            assert mod in actuators
        for mod in selected_detectors:
            assert mod in detectors

        self.timeout = timeout  #in ms

        self.det_done_datas = OrderedDict()
        self.det_done_flag = False
        self.move_done_positions = OrderedDict()
        self.move_done_flag = False

        self.settings = Parameter.create(name='Settings',
                                         type='group',
                                         children=self.params)
        self.settings_tree = ParameterTree()
        self.settings_tree.setMinimumWidth(300)
        self.settings_tree.setParameters(self.settings, showTop=False)

        self.settings.sigTreeStateChanged.connect(self.parameter_tree_changed)

        self.settings.child('data_dimensions',
                            'probe_data').sigActivated.connect(
                                self.get_det_data_list)
        self.settings.child('actuators_positions',
                            'test_actuator').sigActivated.connect(
                                self.test_move_actuators)

        self._detectors = []
        self._actuators = []

        self.grab_done_signals = []
        self.det_commands_signal = []

        self.set_actuators(actuators, selected_actuators)
        self.set_detectors(detectors, selected_detectors)

    @classmethod
    def get_names(cls, modules):
        if not hasattr(modules, '__iter__'):
            modules = [modules]
        return [mod.title for mod in modules]

    def get_mods_from_names(self, names, mod='det'):
        mods = []
        for name in names:
            d = self.get_mod_from_name(name, mod)
            if d is not None:
                mods.append(d)
        return mods

    def get_mod_from_name(self, name, mod='det'):
        if mod == 'det':
            modules = self._detectors
        else:
            modules = self._actuators

        if name in self.get_names(modules):
            return modules[self.get_names(modules).index(name)]
        else:
            logger.warning(f'No detector with this name: {name}')
            return None

    def set_actuators(self, actuators, selected_actuators):
        self._actuators = actuators
        self.settings.child('modules', 'actuators').setValue(
            dict(all_items=self.get_names(actuators),
                 selected=self.get_names(selected_actuators)))

    def set_detectors(self, detectors, selected_detectors):
        self._detectors = detectors
        self.settings.child('modules', 'detectors').setValue(
            dict(all_items=self.get_names(detectors),
                 selected=self.get_names(selected_detectors)))

    @property
    def detectors(self):
        return self.get_mods_from_names(self.selected_detectors_name)

    @property
    def actuators(self):
        return self.get_mods_from_names(self.selected_actuators_name,
                                        mod='act')

    @property
    def Ndetectors(self):
        return len(self.detectors)

    @property
    def Nactuators(self):
        return len(self.actuators)

    @property
    def detectors_name(self):
        return self.settings.child('modules', 'detectors').value()['all_items']

    @property
    def selected_detectors_name(self):
        return self.settings.child('modules', 'detectors').value()['selected']

    @property
    def actuators_name(self):
        return self.settings.child('modules', 'actuators').value()['all_items']

    @property
    def selected_actuators_name(self):
        return self.settings.child('modules', 'actuators').value()['selected']

    def parameter_tree_changed(self, param, changes):
        """
            Check for changes in the given (parameter,change,information) tuple list.
            In case of value changed, update the DAQscan_settings tree consequently.

            =============== ============================================ ==============================
            **Parameters**    **Type**                                     **Description**
            *param*           instance of pyqtgraph parameter              the parameter to be checked
            *changes*         (parameter,change,information) tuple list    the current changes state
            =============== ============================================ ==============================
        """
        for param, change, data in changes:
            path = self.settings.childPath(param)
            if change == 'childAdded':
                pass

            elif change == 'value':

                if param.name() == 'detectors':
                    self.detectors_changed.emit(data['selected'])

                elif param.name() == 'actuators':
                    self.actuators_changed.emit(data['selected'])

            elif change == 'parent':
                pass

    def get_det_data_list(self):
        self.connect_detectors()

        datas = self.grab_datas()

        data_list0D = []
        data_list1D = []
        data_list2D = []
        data_listND = []

        for k in datas.keys():
            if 'data0D' in datas[k].keys():
                data_list0D.extend(
                    [f'{k}/{name}' for name in datas[k]['data0D'].keys()])
            if 'data1D' in datas[k].keys():
                data_list1D.extend(
                    [f'{k}/{name}' for name in datas[k]['data1D'].keys()])
            if 'data2D' in datas[k].keys():
                data_list2D.extend(
                    [f'{k}/{name}' for name in datas[k]['data2D'].keys()])
            if 'dataND' in datas[k].keys():
                data_listND.extend(
                    [f'{k}/{name}' for name in datas[k]['dataND'].keys()])

        self.settings.child('data_dimensions', 'det_data_list0D').setValue(
            dict(all_items=data_list0D, selected=[]))
        self.settings.child('data_dimensions', 'det_data_list1D').setValue(
            dict(all_items=data_list1D, selected=[]))
        self.settings.child('data_dimensions', 'det_data_list2D').setValue(
            dict(all_items=data_list2D, selected=[]))
        self.settings.child('data_dimensions', 'det_data_listND').setValue(
            dict(all_items=data_listND, selected=[]))

        self.connect_detectors(False)

    def get_selected_probed_data(self, dim='0D'):
        return self.settings.child(
            'data_dimensions',
            f'det_data_list{dim.upper()}').value()['selected']

    def grab_datas(self, **kwargs):
        self.det_done_datas = OrderedDict()
        self.det_done_flag = False
        self.settings.child(('det_done')).setValue(self.det_done_flag)
        tzero = time.perf_counter()

        for sig in [mod.command_detector for mod in self.detectors]:
            sig.emit(utils.ThreadCommand("single", [1, kwargs]))

        while not self.det_done_flag:
            #wait for grab done signals to end

            QtWidgets.QApplication.processEvents()
            if time.perf_counter() - tzero > self.timeout:
                self.timeout_signal.emit(True)
                logger.error(
                    'Timeout Fired during waiting for data to be acquired')
                break

        self.det_done_signal.emit(self.det_done_datas)
        return self.det_done_datas

    def connect_actuators(self, connect=True, slot=None):
        if slot is None:
            slot = self.move_done
        if connect:
            for sig in [mod.move_done_signal for mod in self.actuators]:
                sig.connect(slot)
        else:
            try:
                for sig in [mod.move_done_signal for mod in self.actuators]:
                    sig.disconnect(slot)
            except Exception as e:
                logger.error(str(e))

    def connect_detectors(self, connect=True, slot=None):
        if slot is None:
            slot = self.det_done

        if connect:
            for sig in [mod.grab_done_signal for mod in self.detectors]:
                sig.connect(slot)
        else:
            try:
                for sig in [mod.grab_done_signal for mod in self.detectors]:
                    sig.disconnect(slot)
            except Exception as e:
                logger.error(str(e))

    def test_move_actuators(self):
        positions = dict()
        for act in self.get_names(self.actuators):
            pos, done = QtWidgets.QInputDialog.getDouble(
                None, f'Enter a target position for actuator {act}',
                'Position:')
            if not done:
                pos = 0.
            positions[act] = pos

        self.connect_actuators()

        positions = self.move_actuators(positions)

        self.settings.child('actuators_positions', 'positions_list').setValue(
            dict(all_items=[f'{k}: {positions[k]}' for k in positions],
                 selected=[]))

        self.connect_actuators(False)

    def move_actuators(self, positions):
        self.move_done_positions = OrderedDict()
        self.move_done_flag = False
        self.settings.child(('move_done')).setValue(self.move_done_flag)

        if not hasattr(positions, '__iter__'):
            positions = [positions]

        if len(positions) == self.Nactuators:
            if isinstance(positions, dict):
                for k in positions:
                    act = self.get_mod_from_name(k, 'act')
                    if act is not None:
                        act.command_stage.emit(
                            utils.ThreadCommand(command="move_Abs",
                                                attributes=[positions[k]]))
            else:
                for ind, act in enumerate(self.actuators):
                    act.command_stage.emit(
                        utils.ThreadCommand(command="move_Abs",
                                            attributes=[positions[ind]]))

        else:
            logger.error(
                'Invalid number of positions compared to selected actuators')
            return self.move_done_positions

        tzero = time.perf_counter()

        while not self.move_done_flag:
            QtWidgets.QApplication.processEvents()
            if time.perf_counter() - tzero > self.timeout:
                self.timeout_signal.emit(True)
                logger.error(
                    'Timeout Fired during waiting for data to be acquired')
                break

        self.move_done_signal.emit(self.move_done_positions)
        return self.move_done_positions

    def order_positions(self, positions_as_dict):
        actuators = self.selected_actuators_name
        pos = []
        for act in actuators:
            pos.append(positions_as_dict[act])
        return pos

    pyqtSlot(str, float)

    def move_done(self, name, position):
        """
        """
        try:
            if name not in list(self.move_done_positions.keys()):
                self.move_done_positions[name] = position

            if len(self.move_done_positions.items()) == len(self.actuators):
                self.move_done_flag = True
                self.settings.child(
                    ('move_done')).setValue(self.move_done_flag)
        except Exception as e:
            logger.exception(str(e))

    @pyqtSlot(OrderedDict)
    def det_done(self, data):
        try:
            if data['name'] not in list(self.det_done_datas.keys()):
                self.det_done_datas[data['name']] = data
            if len(self.det_done_datas.items()) == len(self.detectors):
                self.det_done_flag = True
                self.settings.child(('det_done')).setValue(self.det_done_flag)
        except Exception as e:
            logger.exception(str(e))
class StuffRepositoryModule(QWidget, Ui_Form):
    def __init__(self, parent=None):
        super(StuffRepositoryModule, self).__init__(parent)
        self.setupUi(self)

        if '41' not in user.powers:
            self.close()
        if user.powers['41'] == 0:
            self.close()
        self.power = '{:03b}'.format(user.powers['41'])

        self.WC = WarehouseController()
        self.CI = CheckItem()
        self.LC = LabrecordsController()
        self.SFC = StuffController()
        self.current_button = self.radioButton_batchno
        self.get_stuff_list()

    def get_stuff_list(self):
        if self.current_button == self.radioButton_batchno:
            values_tuple = VALUES_TUPLE_BATCHNO
            self.treeWidget_stuffbatchnolist.setVisible(True)
            self.treeWidget_stuffkindlist.setVisible(False)
            current_tree = self.treeWidget_stuffbatchnolist
            current_tree.hideColumn(0)
            current_tree.hideColumn(1)
        elif self.current_button == self.radioButton_kind:
            values_tuple = VALUES_TUPLE_KIND
            self.treeWidget_stuffbatchnolist.setVisible(False)
            self.treeWidget_stuffkindlist.setVisible(True)
            current_tree = self.treeWidget_stuffkindlist
        else:
            return

        current_tree.clear()
        index = self.tabWidget.currentIndex()
        key_dict = {'amount__gt': 0}
        if index != 0:
            key_dict['stufftype'] = index - 1
        stuff_list = self.WC.get_stuffrepository(False, *values_tuple,
                                                 **key_dict)
        if not len(stuff_list):
            return
        if current_tree == self.treeWidget_stuffbatchnolist:
            self.set_batchno_tree(current_tree, stuff_list)
            for i in range(2, 25):
                current_tree.resizeColumnToContents(i)
        elif current_tree == self.treeWidget_stuffkindlist:
            self.set_kind_tree(current_tree, stuff_list)
            for i in range(0, 3):
                current_tree.resizeColumnToContents(i)
        else:
            return

    def set_batchno_tree(self, current_tree, stuff_list):
        for item in stuff_list:
            qtreeitem = QTreeWidgetItem(current_tree)
            qtreeitem.setText(0, str(item['autoid']))
            qtreeitem.setText(1, str(item['lrid']))
            qtreeitem.setText(2, STATUS[item['status']])
            qtreeitem.setText(3, item['stuffid'] + ' ' + item['stuffname'])
            qtreeitem.setText(4, item['stuffkind'])
            qtreeitem.setText(5, STUFF_KIND[item['stufftype']])
            qtreeitem.setText(6, item['batchno'])
            qtreeitem.setText(7, item['mbatchno'])
            qtreeitem.setText(8, item['spec'])
            qtreeitem.setText(9, item['package'])
            qtreeitem.setText(10, str(item['piamount']))
            qtreeitem.setText(11, str(item['amount']))
            qtreeitem.setText(12, item['basicunit'])
            qtreeitem.setText(13, item['position'])
            qtreeitem.setText(14, str(item['makedate']))
            qtreeitem.setText(15, str(item['putindate']))
            qtreeitem.setText(16, str(item['expireddate']))
            qtreeitem.setText(17, str(item['nextcheckdate']))
            qtreeitem.setText(18, item['supid'] + ' ' + item['supname'])
            qtreeitem.setText(19, item['producer'])
            qtreeitem.setText(20, str(item['content']) + item['cunit'])
            qtreeitem.setText(21, str(item['water']) + '%')
            qtreeitem.setText(22, str(item['rdensity']))
            qtreeitem.setText(23, str(item['impurity']) + '%')
            qtreeitem.setText(
                24, item['warehousemanid'] + item['warehousemanname'])

    def set_kind_tree(self, current_tree, stuff_list):
        kind_list = stuff_list.annotate(amount=Sum('amount'),
                                        piamount=Sum('piamount'))
        for item in kind_list:
            qtreeitem = QTreeWidgetItem(current_tree)
            qtreeitem.setText(0, item['stuffkind'])
            qtreeitem.setText(1, str(item['piamount']))
            qtreeitem.setText(2, str(item['amount']))
            qtreeitem.setText(3, item['basicunit'])

    @pyqtSlot(int)
    def on_tabWidget_currentChanged(self, p_int):
        curent_tab = getattr(self, 'tab_' + str(p_int))
        curent_tab.setLayout(self.gridLayout_2)
        self.get_stuff_list()

    pyqtSlot(bool)

    def on_radioButton_batchno_toggled(self, p_bool):
        if p_bool:
            self.current_button = self.radioButton_batchno
            self.get_stuff_list()

    pyqtSlot(bool)

    def on_radioButton_kind_toggled(self, p_bool):
        if p_bool:
            self.current_button = self.radioButton_kind
            self.get_stuff_list()

    @pyqtSlot(QPoint)
    def on_treeWidget_stuffbatchnolist_customContextMenuRequested(self, pos):
        if self.power[1] == '0':
            return

        id = 0
        lrid = 0
        stuffid = ''
        batchno = ''
        sender_widget = self.sender()
        current_item = sender_widget.currentItem()
        if current_item is None:
            return

        id = int(current_item.text(0))
        lrid = int(current_item.text(1))
        stuffid, stuffname = current_item.text(3).split(' ')
        batchno = current_item.text(6)

        menu = QMenu()
        button1 = menu.addAction("修改记录")
        button2 = menu.addAction("查看检验报告")
        button3 = menu.addAction("新建库存复检申请单")

        global_pos = sender_widget.mapToGlobal(pos)
        action = menu.exec(global_pos)

        if action == button1:
            detail = ModifyStuffParmeter(id, self)
            detail.accepted.connect(self.get_stuff_list)
            detail.show()

        elif action == button2:
            detail = FindCheckReportModule(stuffid, batchno, self)
            detail.show()

        elif action == button3:
            key_dict = {'stuffid': stuffid, 'stuffname': stuffname}
            checkunit = ''
            res = self.SFC.get_stuffdict(True, *VALUES_TUPLE_SD, **key_dict)
            if len(res):
                checkunit = res[0]
            kwargs = {
                'labtype':
                1,
                'chkid':
                stuffid,
                'chkname':
                stuffname,
                'batchno':
                current_item.text(6),
                'mbatchno':
                current_item.text(7),
                'spec':
                current_item.text(8),
                'package':
                current_item.text(9),
                'producer':
                current_item.text(19),
                'supplyer':
                current_item.text(18) if current_item.text(18) in ('', ' ')
                else current_item.text(18).split(' ')[2],
                'ciid':
                int(current_item.text(0)),
                'createdate':
                user.now_date,
                'checkamount':
                decimal.Decimal(current_item.text(11)),
                'caunit':
                current_item.text(12),
                'sampleunit':
                checkunit,
                'samplesource':
                current_item.text(13)
            }
            labrecord = self.LC.update_labrecord(**kwargs)
            key_dict_checkitem = {'stuffid': stuffid, 'itemtype': 0}
            checkitems = self.CI.get_checkitems(False, *VALUES_TUPLE_CHECKITEM,
                                                **key_dict_checkitem)
            for item in checkitems:
                kwargs_checkitem = {
                    'lrid': labrecord.autoid,
                    'seqid': item['seqid'],
                    'itemname': item['itemname'],
                    'kind': item['kind'],
                    'referencevalue': item['referencevalue'],
                    'labvalue': item['referencevalue'],
                    'putintype': item['putintype'],
                    'startdate': user.now_date,
                    'enddate': user.now_date,
                    'checked': 2
                }
            self.LC.update_labitem(**kwargs_checkitem)
            detail = ApplycheckModule(autoid=labrecord.autoid, parent=self)
            detail.rejected.connect(
                lambda: self.delete_check_report(labrecord.autoid))
            detail.show()

    def delete_check_report(self, lrid):
        self.LC.delete_labrecord(lrid)
        self.LC.delete_labitem(lrid)

    @pyqtSlot(QTreeWidgetItem, int)
    def on_treeWidget_stuffbatchnolist_itemDoubleClicked(
            self, qtreeitem, p_int):
        if self.power[1] == '0':
            return

        id = int(qtreeitem.text(0))
        lrid = int(qtreeitem.text(1))
        detail = ModifyStuffParmeter(id, self)
        detail.accepted.connect(self.get_stuff_list)
        detail.show()
class DAQ_PID(QObject):
    """
    """
    log_signal = pyqtSignal(str)
    #look for eventual model files
    command_pid = pyqtSignal(ThreadCommand)
    command_stage = pyqtSignal(ThreadCommand)
    move_done_signal = pyqtSignal(str, float)

    models = []
    try:
        model_mod = importlib.import_module('pymodaq_pid_models')
        for ind_file, entry in enumerate(os.scandir(os.path.join(model_mod.__path__[0], 'models'))):
            if not entry.is_dir() and entry.name != '__init__.py':
                try:
                    file, ext = os.path.splitext(entry.name)
                    importlib.import_module('.'+file, model_mod.__name__+'.models')

                    models.append(file)
                except Exception as e:
                    print(e)
        if 'PIDModelMock' in models:
            mods = models
            mods.pop(models.index('PIDModelMock'))
            models = ['PIDModelMock']
            models.extend(mods)

    except Exception as e:
        print(e)

    if len(models) == 0:
        logger.warning('No valid installed models')


    def __init__(self,area, detector_modules = [], actuator_modules =[]):
        QLocale.setDefault(QLocale(QLocale.English, QLocale.UnitedStates))
        super(DAQ_PID,self).__init__()

        self.settings = Parameter.create(title='PID settings', name='pid_settings', type='group', children=params)
        self.title = 'PyMoDAQ PID'
        self.Initialized_state = False
        self.model_class = None
        self.detector_modules = detector_modules
        self.actuator_modules = actuator_modules
        self.dock_area = area
        self.overshoot = None
        self.check_moving = False
        self.preset_manager = PresetManager()
        self.setupUI()
        self.command_stage.connect(self.move_Abs) #to be compatible with actuator modules within daq scan

        self.enable_controls_pid(False)


        self.enable_controls_pid_run(False)



    def ini_PID(self):

        if self.ini_PID_action.isChecked():
            output_limits =[None,None]
            if self.settings.child('main_settings', 'pid_controls', 'output_limits', 'output_limit_min_enabled').value():
                output_limits[0] = self.settings.child('main_settings', 'pid_controls', 'output_limits', 'output_limit_min').value()
            if self.settings.child('main_settings', 'pid_controls', 'output_limits', 'output_limit_max_enabled').value():
                output_limits[1] = self.settings.child('main_settings', 'pid_controls', 'output_limits', 'output_limit_max').value()


            self.PIDThread = QThread()
            pid_runner = PIDRunner(self.model_class,
                            [mod.move_done_signal for mod in self.actuator_modules],
                            [mod.grab_done_signal for mod in self.detector_modules],
                           [mod.command_stage for mod in self.actuator_modules],
                           [mod.command_detector for mod in self.detector_modules],
                            dict(Kp=self.settings.child('main_settings', 'pid_controls', 'pid_constants', 'kp').value(),
                            Ki=self.settings.child('main_settings', 'pid_controls', 'pid_constants', 'ki').value(),
                            Kd=self.settings.child('main_settings', 'pid_controls', 'pid_constants', 'kd').value(),
                            setpoint=self.settings.child('main_settings', 'pid_controls', 'set_point').value(),
                            sample_time=self.settings.child('main_settings', 'pid_controls', 'sample_time').value()/1000,
                            output_limits=output_limits,
                            auto_mode=False),
                            filter=dict(enable=self.settings.child('main_settings', 'pid_controls', 'filter', 'filter_enable').value(),
                                         value=self.settings.child('main_settings', 'pid_controls', 'filter', 'filter_step').value()),
                            det_averaging=[mod.settings.child('main_settings', 'Naverage').value() for mod in self.detector_modules],
                                   )

            self.PIDThread.pid_runner = pid_runner
            pid_runner.pid_output_signal.connect(self.process_output)
            pid_runner.status_sig.connect(self.thread_status)
            self.command_pid.connect(pid_runner.queue_command)

            pid_runner.moveToThread(self.PIDThread)

            self.PIDThread.start()
            self.pid_led.set_as_true()
            self.enable_controls_pid_run(True)



        else:
            if hasattr(self,'PIDThread'):
                if self.PIDThread.isRunning():
                    try:
                        self.PIDThread.quit()
                    except:
                        pass
            self.pid_led.set_as_false()
            self.enable_controls_pid_run(False)

        self.Initialized_state = True

    pyqtSlot(dict)
    def process_output(self, datas):
        self.output_viewer.show_data([[dat] for dat in datas['output']])
        self.input_viewer.show_data([[dat] for dat in datas['input']])
        self.currpoint_sb.setValue(np.mean(datas['input']))

        if self.check_moving:
            if np.abs(np.mean(datas['input'])-self.settings.child('main_settings', 'pid_controls', 'set_point').value()) < \
                    self.settings.child('main_settings', 'epsilon').value():
                self.move_done_signal.emit(self.title, np.mean(datas['input']))
                self.check_moving = False
                print('Move from {:s} is done: {:f}'.format('PID', np.mean(datas['input'])))


    @pyqtSlot(ThreadCommand)
    def move_Abs(self, command=ThreadCommand()):
        """
        """
        if command.command == "move_Abs":
            self.check_moving = True
            self.setpoint_sb.setValue(command.attributes[0])
            QtWidgets.QApplication.processEvents()



    def enable_controls_pid(self,enable = False):
        self.ini_PID_action.setEnabled(enable)
        self.setpoint_sb.setOpts(enabled = enable)

    def enable_controls_pid_run(self,enable = False):
        self.run_action.setEnabled(enable)
        self.pause_action.setEnabled(enable)


    def setupUI(self):

        self.dock_pid = Dock('PID controller', self.dock_area)
        self.dock_area.addDock(self.dock_pid)

        #%% create logger dock
        self.logger_dock=Dock("Logger")
        self.logger_list=QtWidgets.QListWidget()
        self.logger_list.setMinimumWidth(300)
        self.logger_dock.addWidget(self.logger_list)
        self.dock_area.addDock(self.logger_dock,'right')
        self.logger_dock.setVisible(True)





        widget = QtWidgets.QWidget()
        widget_toolbar = QtWidgets.QWidget()
        verlayout = QtWidgets.QVBoxLayout()
        widget.setLayout(verlayout)
        toolbar_layout = QtWidgets.QGridLayout()
        widget_toolbar.setLayout(toolbar_layout)


        iconquit = QtGui.QIcon()
        iconquit.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/close2.png"), QtGui.QIcon.Normal,
                          QtGui.QIcon.Off)
        self.quit_action = QtWidgets.QPushButton(iconquit, "Quit")
        self.quit_action.setToolTip('Quit the application')
        toolbar_layout.addWidget(self.quit_action,0,0,1,2)
        self.quit_action.clicked.connect(self.quit_fun)

        iconini = QtGui.QIcon()
        iconini.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/ini.png"), QtGui.QIcon.Normal,
                          QtGui.QIcon.Off)
        self.ini_model_action = QtWidgets.QPushButton(iconini, "Init Model")
        self.ini_model_action.setToolTip('Initialize the chosen model')
        toolbar_layout.addWidget(self.ini_model_action,2,0)
        self.ini_model_action.clicked.connect(self.ini_model)
        self.model_led = QLED()
        toolbar_layout.addWidget(self.model_led, 2,1)

        self.ini_PID_action = QtWidgets.QPushButton(iconini, "Init PID")
        self.ini_PID_action.setToolTip('Initialize the PID loop')
        toolbar_layout.addWidget(self.ini_PID_action,2,2)
        self.ini_PID_action.setCheckable(True)
        self.ini_PID_action.clicked.connect(self.ini_PID)
        self.pid_led = QLED()
        toolbar_layout.addWidget(self.pid_led, 2,3)

        self.iconrun = QtGui.QIcon()
        self.iconrun.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/run2.png"), QtGui.QIcon.Normal,
                           QtGui.QIcon.Off)
        self.icon_stop = QtGui.QIcon()
        self.icon_stop.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/stop.png"))
        self.run_action = QtWidgets.QPushButton(self.iconrun, "", None)
        self.run_action.setToolTip('Start PID loop')
        self.run_action.setCheckable(True)
        toolbar_layout.addWidget(self.run_action,0,2)
        self.run_action.clicked.connect(self.run_PID)


        iconpause = QtGui.QIcon()
        iconpause.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/pause.png"), QtGui.QIcon.Normal,
                           QtGui.QIcon.Off)
        self.pause_action = QtWidgets.QPushButton(iconpause, "", None)
        self.pause_action.setToolTip('Pause PID')
        self.pause_action.setCheckable(True)
        toolbar_layout.addWidget(self.pause_action,0,3)
        self.pause_action.setChecked(True)
        self.pause_action.clicked.connect(self.pause_PID)

        lab = QtWidgets.QLabel('Set Point:')
        toolbar_layout.addWidget(lab, 3,0,1,2)

        self.setpoint_sb = custom_tree.SpinBoxCustom()
        self.setpoint_sb.setMinimumHeight(40)
        font = self.setpoint_sb.font()
        font.setPointSizeF(20)
        self.setpoint_sb.setFont(font)
        self.setpoint_sb.setDecimals(6)
        toolbar_layout.addWidget(self.setpoint_sb,3,2,1,2)
        self.setpoint_sb.valueChanged.connect(self.settings.child('main_settings', 'pid_controls', 'set_point').setValue)

        lab1 = QtWidgets.QLabel('Current Point:')
        toolbar_layout.addWidget(lab1, 4,0,1,2)

        self.currpoint_sb = custom_tree.SpinBoxCustom()
        self.currpoint_sb.setMinimumHeight(40)
        self.currpoint_sb.setReadOnly(True)
        self.currpoint_sb.setDecimals(6)
        self.currpoint_sb.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
        font = self.currpoint_sb.font()
        font.setPointSizeF(20)
        self.currpoint_sb.setFont(font)
        toolbar_layout.addWidget(self.currpoint_sb,4,2,1,2)


        #create main parameter tree
        self.settings_tree = ParameterTree()
        self.settings_tree.setParameters(self.settings, showTop=False)

        verlayout.addWidget(widget_toolbar)
        verlayout.addWidget(self.settings_tree)


        self.dock_output = Dock('PID output')
        widget_output = QtWidgets.QWidget()
        self.output_viewer = Viewer0D(widget_output)
        self.dock_output.addWidget(widget_output)
        self.dock_area.addDock(self.dock_output, 'right')

        self.dock_input = Dock('PID input')
        widget_input = QtWidgets.QWidget()
        self.input_viewer = Viewer0D(widget_input)
        self.dock_input.addWidget(widget_input)
        self.dock_area.addDock(self.dock_input, 'bottom',self.dock_output)

        if len(self.models) != 0:
            self.get_set_model_params(self.models[0])


        #connecting from tree
        self.settings.sigTreeStateChanged.connect(self.parameter_tree_changed)#any changes on the settings will update accordingly the detector
        self.dock_pid.addWidget(widget)

    def get_set_model_params(self, model_file):
        self.settings.child('models', 'model_params').clearChildren()
        model = importlib.import_module('.' + model_file, self.model_mod.__name__+'.models')
        model_class = getattr(model, model_file)
        params = getattr(model_class, 'params')
        self.settings.child('models', 'model_params').addChildren(params)

    def run_PID(self):
        if self.run_action.isChecked():
            self.run_action.setIcon(self.icon_stop)
            self.command_pid.emit(ThreadCommand('start_PID', [self.model_class.curr_input]))
            QtWidgets.QApplication.processEvents()

            QtWidgets.QApplication.processEvents()

            self.command_pid.emit(ThreadCommand('run_PID', [self.model_class.curr_output]))
        else:
            self.run_action.setIcon(self.iconrun)
            self.command_pid.emit(ThreadCommand('stop_PID'))

            QtWidgets.QApplication.processEvents()

    def pause_PID(self):
        self.command_pid.emit(ThreadCommand('pause_PID', [self.pause_action.isChecked()]))

    def update_status(self,txt,log_type=None):
        """
            Show the txt message in the status bar with a delay of wait_time ms.

            =============== =========== =======================
            **Parameters**    **Type**    **Description**
            *txt*             string      The message to show
            *wait_time*       int         the delay of showing
            *log_type*        string      the type of the log
            =============== =========== =======================
        """
        try:
            if log_type is not None:
                self.log_signal.emit(txt)
                logging.info(txt)
        except Exception as e:
            pass

    @pyqtSlot(str)
    def add_log(self,txt):
        """
            Add the QListWisgetItem initialized with txt informations to the User Interface logger_list and to the save_parameters.logger array.

            =============== =========== ======================
            **Parameters**    **Type**   **Description**
            *txt*             string     the log info to add.
            =============== =========== ======================
        """
        try:
            now=datetime.datetime.now()
            new_item=QtWidgets.QListWidgetItem(now.strftime('%Y/%m/%d %H:%M:%S')+": "+txt)
            self.logger_list.addItem(new_item)
        except:
            pass

    def set_file_preset(self,model):
        """
            Set a file managers from the converted xml file given by the filename parameter.


            =============== =========== ===================================================
            **Parameters**    **Type**    **Description**
            *filename*        string      the name of the xml file to be converted/treated
            =============== =========== ===================================================

            Returns
            -------
            (Object list, Object list) tuple
                The updated (Move modules list, Detector modules list).

            See Also
            --------
            custom_tree.XML_file_to_parameter, set_param_from_param, stop_moves, update_status,DAQ_Move_main.daq_move, DAQ_viewer_main.daq_viewer
        """

        filename = os.path.join(get_set_pid_path(), model + '.xml')
        self.preset_file = filename
        self.preset_manager.set_file_preset(filename, show=False)
        self.move_docks = []
        self.det_docks_settings = []
        self.det_docks_viewer = []
        move_forms = []
        actuator_modules = []
        detector_modules = []
        move_types = []


        #################################################################
        ###### sort plugins by IDs and within the same IDs by Master and Slave status
        plugins=[{'type': 'move', 'value': child} for child in self.preset_manager.preset_params.child(('Moves')).children()]+[{'type': 'det', 'value': child} for child in self.preset_manager.preset_params.child(('Detectors')).children()]

        for plug in plugins:
            plug['ID']=plug['value'].child('params','main_settings','controller_ID').value()
            if plug["type"]=='det':
                plug['status']=plug['value'].child('params','detector_settings','controller_status').value()
            else:
                plug['status']=plug['value'].child('params','move_settings', 'multiaxes', 'multi_status').value()

        IDs=list(set([plug['ID'] for plug in plugins]))
        #%%
        plugins_sorted=[]
        for id in IDs:
            plug_Ids=[]
            for plug in plugins:
                if plug['ID']==id:
                    plug_Ids.append(plug)
            plug_Ids.sort(key=lambda status: status['status'])
            plugins_sorted.append(plug_Ids)
        #################################################################
        #######################

        ind_move=-1
        ind_det=-1
        for plug_IDs in plugins_sorted:
            for ind_plugin, plugin in enumerate(plug_IDs):


                plug_name=plugin['value'].child(('name')).value()
                plug_init=plugin['value'].child(('init')).value()
                plug_settings=plugin['value'].child(('params'))

                if plugin['type'] == 'move':
                    ind_move+=1
                    plug_type=plug_settings.child('main_settings','move_type').value()
                    self.move_docks.append(Dock(plug_name, size=(150,250)))
                    if ind_move==0:
                        self.dock_area.addDock(self.move_docks[-1], 'top',self.logger_dock)
                    else:
                        self.dock_area.addDock(self.move_docks[-1], 'above',self.move_docks[-2])
                    move_forms.append(QtWidgets.QWidget())
                    mov_mod_tmp=DAQ_Move(move_forms[-1],plug_name)

                    mov_mod_tmp.ui.Stage_type_combo.setCurrentText(plug_type)
                    mov_mod_tmp.ui.Quit_pb.setEnabled(False)
                    QtWidgets.QApplication.processEvents()

                    set_param_from_param(mov_mod_tmp.settings,plug_settings)
                    QtWidgets.QApplication.processEvents()

                    mov_mod_tmp.bounds_signal[bool].connect(self.stop_moves)
                    self.move_docks[-1].addWidget(move_forms[-1])
                    actuator_modules.append(mov_mod_tmp)

                    try:
                        if ind_plugin==0: #should be a master type plugin
                            if plugin['status']!="Master":
                                raise Exception('error in the master/slave type for plugin {}'.format(plug_name))
                            if plug_init:
                                actuator_modules[-1].ui.IniStage_pb.click()
                                QtWidgets.QApplication.processEvents()
                                if 'Mock' in plug_type:
                                    QThread.msleep(500)
                                else:
                                    QThread.msleep(4000)  # to let enough time for real hardware to init properly
                                QtWidgets.QApplication.processEvents()
                                master_controller=actuator_modules[-1].controller
                        else:
                            if plugin['status']!="Slave":
                                raise Exception('error in the master/slave type for plugin {}'.format(plug_name))
                            if plug_init:
                                actuator_modules[-1].controller=master_controller
                                actuator_modules[-1].ui.IniStage_pb.click()
                                QtWidgets.QApplication.processEvents()
                                if 'Mock' in plug_type:
                                    QThread.msleep(500)
                                else:
                                    QThread.msleep(4000)  # to let enough time for real hardware to init properly
                                QtWidgets.QApplication.processEvents()
                    except Exception as e:
                        self.update_status(getLineInfo()+ str(e),'log')


                else:
                    ind_det+=1
                    plug_type=plug_settings.child('main_settings','DAQ_type').value()
                    plug_subtype=plug_settings.child('main_settings','detector_type').value()

                    self.det_docks_settings.append(Dock(plug_name+" settings", size=(150,250)))
                    self.det_docks_viewer.append(Dock(plug_name+" viewer", size=(350,350)))

                    if ind_det==0:
                        self.logger_dock.area.addDock(self.det_docks_settings[-1], 'bottom', self.dock_input) #dock_area of the logger dock
                    else:
                        self.dock_area.addDock(self.det_docks_settings[-1], 'bottom',self.det_docks_settings[-2])
                    self.dock_area.addDock(self.det_docks_viewer[-1],'right',self.det_docks_settings[-1])

                    det_mod_tmp=DAQ_Viewer(self.dock_area,dock_settings=self.det_docks_settings[-1],
                                                        dock_viewer=self.det_docks_viewer[-1],title=plug_name,
                                           DAQ_type=plug_type, parent_scan=self)
                    detector_modules.append(det_mod_tmp)
                    detector_modules[-1].ui.Detector_type_combo.setCurrentText(plug_subtype)
                    detector_modules[-1].ui.Quit_pb.setEnabled(False)
                    set_param_from_param(det_mod_tmp.settings,plug_settings)
                    QtWidgets.QApplication.processEvents()


                    try:
                        if ind_plugin==0: #should be a master type plugin
                            if plugin['status']!="Master":
                                raise Exception('error in the master/slave type for plugin {}'.format(plug_name))
                            if plug_init:
                                detector_modules[-1].ui.IniDet_pb.click()
                                QtWidgets.QApplication.processEvents()
                                if 'Mock' in plug_subtype:
                                    QThread.msleep(500)
                                else:
                                    QThread.msleep(4000)  # to let enough time for real hardware to init properly
                                QtWidgets.QApplication.processEvents()
                                master_controller=detector_modules[-1].controller
                        else:
                            if plugin['status']!="Slave":
                                raise Exception('error in the master/slave type for plugin {}'.format(plug_name))
                            if plug_init:
                                detector_modules[-1].controller=master_controller
                                detector_modules[-1].ui.IniDet_pb.click()
                                QtWidgets.QApplication.processEvents()
                                if 'Mock' in plug_subtype:
                                    QThread.msleep(500)
                                else:
                                    QThread.msleep(4000)  # to let enough time for real hardware to init properly
                                QtWidgets.QApplication.processEvents()
                    except Exception as e:
                        self.update_status(getLineInfo()+ str(e),'log')

                    detector_modules[-1].settings.child('main_settings','overshoot').show()
                    detector_modules[-1].overshoot_signal[bool].connect(self.stop_moves)

        QtWidgets.QApplication.processEvents()

        return actuator_modules,detector_modules


    pyqtSlot(bool)
    def stop_moves(self,overshoot):
        """
            Foreach module of the move module object list, stop motion.

            See Also
            --------
            stop_scan,  DAQ_Move_main.daq_move.stop_Motion
        """
        self.overshoot = overshoot
        for mod in self.actuator_modules:
            mod.stop_Motion()

    def set_default_preset(self):
        actuators = self.model_class.actuators
        actuator_names = self.model_class.actuators_name

        detectors_type = self.model_class.detectors_type
        detectors = self.model_class.detectors
        detectors_name = self.model_class.detectors_name

        detector_modules = []
        for ind_det, det in enumerate(detectors):

            detector_modules.append(DAQ_Viewer(area, title=detectors_name[ind_det], DAQ_type=detectors_type[ind_det]))
            #self.detector_modules[-1].ui.IniDet_pb.click()
            QtWidgets.QApplication.processEvents()
            detector_modules[-1].ui.Detector_type_combo.setCurrentText(detectors[ind_det])
            detector_modules[-1].ui.Quit_pb.setEnabled(False)


        self.dock_area.addDock(self.dock_output, 'bottom')
        self.dock_area.moveDock(self.dock_input, 'bottom', self.dock_output)
        self.dock_area.addDock(self.dock_pid, 'left')

        dock_moves = []
        actuator_modules = []
        for ind_act, act in enumerate(actuators):
            form = QtWidgets.QWidget()
            dock_moves.append(Dock(actuator_names[ind_act]))
            area.addDock(dock_moves[-1], 'bottom', self.dock_pid)
            dock_moves[-1].addWidget(form)
            actuator_modules.append(DAQ_Move(form))
            QtWidgets.QApplication.processEvents()
            actuator_modules[-1].ui.Stage_type_combo.setCurrentText(actuators[ind_act])
            actuator_modules[-1].ui.Quit_pb.setEnabled(False)
            #self.actuator_modules[-1].ui.IniStage_pb.click()
            #QThread.msleep(1000)
            QtWidgets.QApplication.processEvents()

        return actuator_modules, detector_modules

    def ini_model(self):
        try:
            model_name = self.settings.child('models', 'model_class').value()
            model = importlib.import_module('.' +model_name, self.model_mod.__name__+'.models')
            self.model_class = getattr(model, model_name)(self)


            #try to get corresponding managers file
            filename = os.path.join(get_set_pid_path(), model_name + '.xml')
            if os.path.isfile(filename):
                self.actuator_modules,  self.detector_modules = self.set_file_preset(model_name)
            else:
                self.actuator_modules, self.detector_modules = self.set_default_preset()

            # # connecting to logger
            # for mov in self.actuator_modules:
            #     mov.log_signal[str].connect(self.add_log)
            # for det in self.detector_modules:
            #     det.log_signal[str].connect(self.add_log)
            # self.log_signal[str].connect(self.add_log)

            self.model_class.ini_model()

            self.enable_controls_pid(True)
            self.model_led.set_as_true()
            self.ini_model_action.setEnabled(False)



        except Exception as e:
            self.update_status(getLineInfo() + str(e), log_type='log')

    def quit_fun(self):
        """
        """
        try:
            try:
                self.PIDThread.exit()
            except Exception as e:
                print(e)

            for module in self.actuator_modules:
                try:
                    module.quit_fun()
                    QtWidgets.QApplication.processEvents()
                    QThread.msleep(1000)
                    QtWidgets.QApplication.processEvents()
                except Exception as e:
                    print(e)

            for module in self.detector_modules:
                try:
                    module.stop_all()
                    QtWidgets.QApplication.processEvents()
                    module.quit_fun()
                    QtWidgets.QApplication.processEvents()
                    QThread.msleep(1000)
                    QtWidgets.QApplication.processEvents()
                except Exception as e:
                    print(e)

            areas=self.dock_area.tempAreas[:]
            for area in areas:
                area.win.close()
                QtWidgets.QApplication.processEvents()
                QThread.msleep(1000)
                QtWidgets.QApplication.processEvents()

            self.dock_area.parent().close()

        except Exception as e:
            print(e)


    def parameter_tree_changed(self,param,changes):
        """
            Foreach value changed, update :
                * Viewer in case of **DAQ_type** parameter name
                * visibility of button in case of **show_averaging** parameter name
                * visibility of naverage in case of **live_averaging** parameter name
                * scale of axis **else** (in 2D pymodaq type)

            Once done emit the update settings signal to link the commit.

            =============== =================================== ================================================================
            **Parameters**    **Type**                           **Description**
            *param*           instance of ppyqtgraph parameter   the parameter to be checked
            *changes*         tuple list                         Contain the (param,changes,info) list listing the changes made
            =============== =================================== ================================================================

            See Also
            --------
            change_viewer, daq_utils.custom_parameter_tree.iter_children
        """

        for param, change, data in changes:
            path = self.settings.childPath(param)
            if change == 'childAdded':
                pass

            elif change == 'value':
                if param.name() == 'model_class':
                    self.get_set_model_params(param.value())

                elif param.name() == 'module_settings':
                    if param.value():
                        self.settings.sigTreeStateChanged.disconnect( self.parameter_tree_changed)
                        param.setValue(False)
                        self.settings.sigTreeStateChanged.connect( self.parameter_tree_changed)
                        self.preset_manager.set_PID_preset(self.settings.child('models','model_class').value())

                elif param.name() == 'refresh_plot_time' or param.name() == 'timeout':
                    self.command_pid.emit(ThreadCommand('update_timer', [param.name(),param.value()]))

                elif param.name() == 'set_point':
                    if self.pid_led.state:
                        self.command_pid.emit(ThreadCommand('update_options', dict(setpoint=param.value())))
                    else:
                        output = self.model_class.convert_output(param.value(),0, stab=False)
                        for ind_act, act in enumerate(self.actuator_modules):
                            act.move_Abs(output[ind_act])



                elif param.name() == 'sample_time':
                    self.command_pid.emit(ThreadCommand('update_options', dict(sample_time=param.value())))

                elif param.name() in custom_tree.iter_children(self.settings.child('main_settings', 'pid_controls', 'output_limits'), []):
                    output_limits = [None, None]
                    if self.settings.child('main_settings', 'pid_controls', 'output_limits', 'output_limit_min_enabled').value():
                        output_limits[0] = self.settings.child('main_settings', 'pid_controls', 'output_limits', 'output_limit_min').value()
                    if self.settings.child('main_settings', 'pid_controls', 'output_limits', 'output_limit_max_enabled').value():
                        output_limits[1] = self.settings.child('main_settings', 'pid_controls', 'output_limits', 'output_limit_max').value()

                    self.command_pid.emit(ThreadCommand('update_options', dict(output_limits=output_limits)))

                elif param.name() in custom_tree.iter_children(self.settings.child('main_settings', 'pid_controls', 'filter'), []):
                    self.command_pid.emit(ThreadCommand('update_filter',
                                    [dict(enable=self.settings.child('main_settings', 'pid_controls', 'filter', 'filter_enable').value(),
                                         value=self.settings.child('main_settings', 'pid_controls', 'filter', 'filter_step').value())]))

                elif param.name() in custom_tree.iter_children(self.settings.child('main_settings', 'pid_controls', 'pid_constants'), []):
                    Kp = self.settings.child('main_settings', 'pid_controls', 'pid_constants', 'kp').value()
                    Ki = self.settings.child('main_settings', 'pid_controls', 'pid_constants', 'ki').value()
                    Kd = self.settings.child('main_settings', 'pid_controls', 'pid_constants', 'kd').value()
                    self.command_pid.emit(ThreadCommand('update_options', dict(tunings= (Kp, Ki, Kd))))

                elif param.name() in custom_tree.iter_children(self.settings.child('models', 'model_params'),[]):
                    self.model_class.update_settings(param)

                elif param.name() == 'detector_modules':
                    self.model_class.update_detector_names()

            elif change == 'parent':
                pass

    @pyqtSlot(list)
    def thread_status(self,status): # general function to get datas/infos from all threads back to the main
        """
            | General function to get datas/infos from all threads back to the main.
            |

            Switch the status with :
                * *"Update status"* : Update the status bar with the status attribute txt message

        """
        if status[0]=="Update_Status":
            self.update_status(status[1],log_type=status[2])
Exemple #19
0
class ShowImage(QMainWindow):
    def __init__(self):
        super(ShowImage,self).__init__()
        loadUi('latihan.ui',self)
        self.image=None
        self.loadButton.clicked.connect(self.loadClicked)
        self.saveButton.clicked.connect(self.saveClicked)
        self.grayButton.clicked.connect(self.grayClicked)
        self.actionBrightness.triggered.connect(self.brightClicked)
        self.actionContrast.triggered.connect(self.contrastClicked)
        self.actionContrastScretch.triggered.connect(self.scretchClicked)
        self.actionNegative.triggered.connect(self.negativeClicked)
        self.actionBiner.triggered.connect(self.binerClicked)
        self.actiongrayHistogram.triggered.connect(self.grayHistogramClicked)
        self.actionRGBHistogram.triggered.connect(self.RGBHistogramClicked)
        self.actionEqualHistogram.triggered.connect(self.EqualHistogramClicked)
        self.actionTranslasi.triggered.connect(self.TranslasiClicked)
        self.actionmin45derajat.triggered.connect(self.minus45Derajat)
        self.actionrot45derajat.triggered.connect(self.rot45Derajat)
        self.actionmin90derajat.triggered.connect(self.minus90Derajat)
        self.actionrot90derajat.triggered.connect(self.rot90Derajat)
        self.actionmin180derajat.triggered.connect(self.minus180Derajat)
        self.actionrot180derajat.triggered.connect(self.rot180Derajat)
        self.actionZoomIn.triggered.connect(self.LinearInterpolationClicked)
        self.actionZoomOut.triggered.connect(self.CubicInterppolationClicked)
        self.actionSkewedImage.triggered.connect(self.skewedSizeClicked)
        self.actionCrop.triggered.connect(self.CropClicked)
        self.actionAritmatika.triggered.connect(self.AritmatikaClicked)
        self.actionBoolean.triggered.connect(self.BooleanClicked)
        self.actionFilter.triggered.connect(self.FilteringClicked)
        self.actionMean.triggered.connect(self.MeanClicked)
        self.actionGaussian.triggered.connect(self.GaussianClicked)
        self.actionSharpening.triggered.connect(self.SharpeningClicked)
        self.actionMedian.triggered.connect(self.MedianClicked)
        self.actionMax.triggered.connect(self.MaxClicked)
        self.actionSobel.triggered.connect(self.SobelClicked)
        self.actionPrewit.triggered.connect(self.PrewitClicked)
        self.actionRobert.triggered.connect(self.RobertClicked)
        self.actionLaplace.triggered.connect(self.LaplaceClicked)
        self.actionLaplaceOfGaussian.triggered.connect(self.LaplaceofGaussianClicked)
        self.actionCanny.triggered.connect(self.CannyClicked)
        self.actionDilasi.triggered.connect(self.Dilasi)
        self.actionErosi.triggered.connect(self.Erosi)
        self.actionOpening.triggered.connect(self.Opening)
        self.actionClosing.triggered.connect(self.Closing)
        self.actionSkeleton.triggered.connect(self.SkeletonClicked)
        self.actionBinary.triggered.connect(self.Binary)
        self.actionBinaryInvers.triggered.connect(self.BinaryInvers)
        self.actionTrunc.triggered.connect(self.Trunc)
        self.actionToZero.triggered.connect(self.ToZero)
        self.actionToZeroInvers.triggered.connect(self.ToZeroInvers)
        self.actionOtsu.triggered.connect(self.otsuClicked)

    @pyqtSlot()
    def grayClicked(self):
        H,W = self.image.shape[:2]
        gray=np.zeros((H,W),np.uint8)
        for i in range (H):
            for j in range (W):
                gray[i,j]=np.clip(0.07*self.image[i,j,0]+0.72*self.image[i,j,1]+0.21*self.image[i,j,2],0,255)
        self.image=gray
        self.displayImage(2)

    @pyqtSlot()
    def loadClicked(self):
        flname,filter=QFileDialog.getOpenFileName(self,'Open File','D:/Foto',"Image Files (*.jpg)")
        if flname:
            self.loadImage(flname)
        else:
            print('Invalid Image')

    @pyqtSlot()
    def saveClicked(self):
        flname, filter=QFileDialog.getSaveFileName(self,'Save File','D:/',"Image Files (*.jpg)")
        if flname:
            cv2.imwrite(flname, self.image)
        else:
            print('Error')

    def loadImage(self,flname):
        self.image=cv2.imread(flname)
        self.displayImage(1)

    def brightClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        brightness = 50
        h,w = img.shape[:2]
        for i in np.arange(h):
            for j in np.arange(w):
                a = img.item(i, j)
                b = a + brightness
                if b > 255:
                    b = 255
                elif b < 0:
                    b = 0
                else:
                    b = b
                img.itemset((i,j), b)
        self.image = img
        self.displayImage(2)

    def contrastClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        h = img.shape[0]
        w =  img.shape[1]
        contrast = 1.6
        for i in np.arange(h):
            for j in np.arange(w):
                a = img.item(i, j)
                b = math.ceil(a * contrast)
                if b > 255:
                    b = 255
                img.itemset((i, j), b)
        self.image = img
        self.displayImage(2)

    def scretchClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        max = 255
        min = 0
        h, w = img.shape[:2]
        for i in np.arange(h):
            for j in np.arange(w):
                a = img.item(i, j)
                if a > max:
                    max = a
                if a < min:
                    min = a
        for i in np.arange(h):
            for j in np.arange(w):
                a = img.item(i, j)
                b = float(a - min) / (max - min) * 255
                img.itemset((i, j), b)

        self.image = img
        self.displayImage(2)

    def negativeClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        h, w = img.shape[:2]
        max_intensity = 255
        for i in range(h):
            for j in range(w):
                a = img.item(i, j)
                b = max_intensity - a
                img.itemset((i, j), b)
        self.image = img
        self.displayImage(2)

    def binerClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        thres = 100
        h, w = img.shape[:2]
        for i in np.arange(h):
            for j in np.arange(w):
                a = img.item(i, j)
                if a > thres:
                    a = 255
                elif a < thres:
                    a = 0
                else:
                    a = a
                img.itemset((i, j), a)

        self.image = img
        self.displayImage(2)

    def grayHistogramClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        self.image = img
        self.displayImage(2)
        plt.hist(img.ravel(), 255, [0, 255])
        plt.show()

    def RGBHistogramClicked(self):
        color = ('b', 'g', 'r')
        for i, col in enumerate(color):
            histo = cv2.calcHist([self.image], [i], None, [256], [0, 256])
            plt.plot(histo, color=col)
            plt.xlim([0, 256])
        plt.show()

    def EqualHistogramClicked(self):
        hist, bins = np.histogram(self.image.flatten(), 256, [0, 256])
        cdf = hist.cumsum()
        cdf_normalized = cdf * hist.max() / cdf.max()
        cdf_m = np.ma.masked_equal(cdf, 0)
        cdf_m = (cdf_m - cdf_m.min()) * 255 / (cdf_m.max() - cdf_m.min())
        cdf = np.ma.filled(cdf_m, 0).astype('uint8')
        self.image = cdf[self.image]
        self.displayImage(2)

        plt.plot(cdf_normalized, color='b')
        plt.hist(self.image.flatten(), 256, [0, 256], color='r')
        plt.xlim([0, 256])
        plt.legend(('cdf', 'histogram'), loc='upper left')
        plt.show()

    def TranslasiClicked(self):
        h, w = self.image.shape[:2]
        quarter_h, quarter_w = h / 4, w / 4
        t = np.float32([[1, 0, quarter_w], [0, 1, quarter_h]])
        img = cv2.warpAffine(self.image, t, (w, h))
        self.image = img
        self.displayImage(2)



    def RotasiClicked(self,degree):
        h, w = self.image.shape[:2]
        rotationMatrix = cv2.getRotationMatrix2D((w / 2, h / 2), degree, .7)
        cos = np.abs(rotationMatrix[0, 0])
        sin = np.abs(rotationMatrix[0, 1])

        nW = int((h * sin) * (w * cos))
        nH = int((h * cos) * (w * sin))

        rotationMatrix[0, 2] += (nW / 2) - w / 2
        rotationMatrix[1, 2] += (nH / 2) - h / 2

        rot_image = cv2.warpAffine(self.image, rotationMatrix, (h, w))
        self.image = rot_image

    def minus45Derajat(self):
        self.RotasiClicked(-45)
        self.displayImage(2)

    def rot45Derajat(self):
        self.RotasiClicked(45)
        self.displayImage(2)

    def minus90Derajat(self):
        self.RotasiClicked(-90)
        self.displayImage(2)

    def rot90Derajat(self):
        self.RotasiClicked(90)
        self.displayImage(2)

    def minus180Derajat(self):
        self.RotasiClicked(-180)
        self.displayImage(2)

    def rot180Derajat(self):
        self.RotasiClicked(180)
        self.displayImage(2)

    @pyqtSlot()
    def LinearInterpolationClicked(self):
    # make size 3/4 original image size
        cv2.imshow('Original',self.image)
        resize_img=cv2.resize(self.image,None,fx=0.50, fy=0.50)
        self.image=resize_img
        cv2.imshow('',self.image)
        #self.displayImage(2)

    @pyqtSlot()
    def CubicInterppolationClicked(self):
    # double size of original image size/zooming(scaling up)
        cv2.imshow('Original', self.image)
        resize_img=cv2.resize(self.image,None,fx=2,fy=2,interpolation= cv2.INTER_CUBIC)
        self.image = resize_img
        cv2.imshow('',self.image)
        #self.displayImage(2)

    @pyqtSlot()
    def skewedSizeClicked(self):
    # resize image based on exacat dimension
        cv2.imshow('Original', self.image)
        resize_img = cv2.resize(self.image, (900, 400), interpolation=cv2.INTER_AREA)
        self.image = resize_img
        cv2.imshow('', self.image)
        # self.displayImage(2)

    def CropClicked(self):
        h, w = self.image.shape[:2]
        # get the strating point of pixel coord(top left)
        start_row, start_col = int(h * .1), int(w * .1)
        # get the ending point coord (botoom right)
        end_row, end_col = int(h * .5), int(w * .5)
        crop = self.image[start_row:end_row, start_col:end_col]
        cv2.imshow('Original', self.image)
        cv2.imshow('Cropped', crop)

    def AritmatikaClicked(self):
        img1 = cv2.imread('2.jpg', 0)
        img2 = cv2.imread('1.jpg', 0)
        add_img = img1 + img2
        subtract = img1 - img2
        subtract2 = img2 - img1
        mul = img1 * img2
        div = img1 / img2
        cv2.imshow('Image 1', img1)
        cv2.imshow('Image 2', img2)
        cv2.imshow('Add', add_img)
        cv2.imshow('Subtraction', subtract)
        cv2.imshow('Multiply', mul)
        cv2.imshow('Divide', div)

    def BooleanClicked(self):
        img1 = cv2.imread('1.jpg', 1)
        img2 = cv2.imread('2.jpg', 1)
        img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
        img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)
        op_and = cv2.bitwise_and(img1, img2)
        op_or = cv2.bitwise_or(img2, img2)
        op_xor = cv2.bitwise_xor(img1, img2)
        cv2.imshow('Image 1', img1)
        cv2.imshow('Image 2', img2)
        cv2.imshow('And', op_and)
        cv2.imshow('OR', op_or)
        cv2.imshow('XOR', op_xor)

    def FilteringClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        gauss = (1.0 / 57) * np.array(
            [[0, 1, 0],
             [1, 0, 1],
             [0, 1, 0]])

        img_out = conv(img, gauss)
        plt.imshow(img_out, cmap='gray', interpolation='bicubic')
        plt.xticks([], plt.yticks([]))
        plt.show()

    def MeanClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        gauss = (1.0 / 57) * np.array(
            [[1/9, 1/9, 1/9],
             [1/9, 1/9, 1/9],
             [1/9, 1/9, 1/9]])

        img_out = conv(img, gauss)
        plt.imshow(img_out, cmap='gray', interpolation='bicubic')
        plt.xticks([], plt.yticks([]))
        plt.show()

    def GaussianClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        gauss = (1.0 / 57) * np.array(
            [[0.0029, 0.0131, 0.0215, 0.0131, 0.0029],
             [0.0131, 0.0585, 0.0965, 0.0585, 0.0131],
             [0.0215, 0.0965, 0.1592, 0.0965, 0.0215],
             [0.0131, 0.0585, 0.0965, 0.0585, 0.0131],
             [0.0029, 0.0131, 0.0215, 0.0131, 0.0029]])

        img_out = conv(img, gauss)
        plt.imshow(img_out, cmap='gray', interpolation='bicubic')
        plt.xticks([], plt.yticks([]))
        plt.show()

    def SharpeningClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        gauss = (1.0 / 16) * np.array(
            [[1, -2, 1],
             [-2, 5, -2],
             [1, -2, 1]])

        img_out = conv(img, gauss)
        plt.imshow(img_out, cmap='gray', interpolation='bicubic')
        plt.xticks([], plt.yticks([]))
        plt.show()

    @pyqtSlot()
    def MedianClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        img_out = img.copy()
        h, w = self.image.shape[:2]
        for i in np.arange(3, h - 3):
            for j in np.arange(3, w - 3):
                neighbors = []
                for k in np.arange(-3, 4):
                    for l in np.arange(-3, 4):
                        a = img.item(i + k, j + l)
                        neighbors.append(a)

                neighbors.sort()
                median = neighbors[24]
                b = median

        plt.imshow(img_out, cmap='gray', interpolation='bicubic')
        plt.xticks([], plt.yticks([]))
        plt.show()

    pyqtSlot()

    @pyqtSlot()
    def MaxClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        img_out = img.copy()
        h, w = self.image.shape[:2]
        for i in np.arange(3, h - 3):
            for j in np.arange(3, w - 3):
                max = 0
                for k in np.arange(-3, 4):
                    for l in np.arange(-3, 4):
                        a = img.item(i + k, j + l)
                        if a > max:
                            max = a
                b = max
                img_out.itemset((i, j), b)

        plt.imshow(img_out, cmap='gray', interpolation='bicubic')
        plt.xticks([], plt.yticks([]))
        plt.show()

    pyqtSlot()

    @pyqtSlot()
    def SobelClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)

        Sx = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])

        Sy = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]])
        img_x = conv(img, Sx)
        img_y = conv(img, Sy)
        img_out = np.sqrt(img_x * img_x + img_y * img_y)
        img_out = (img_out / np.max(img_out)) * 255

        self.image = img

        self.displayImage(2)
        plt.imshow(img_out, cmap='gray', interpolation='bicubic')
        plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
        plt.show()

    def PrewitClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)

        Px = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]])
        Py = np.array([[-1, -1, -1], [0, 0, 0], [1, 1, 1]])

        img_x = conv(img, Px)
        img_y = conv(img, Py)

        img_out = np.sqrt((img_x * img_x) + (img_y * img_y))
        img_out = (img_out / np.max(img_out)) * 255

        self.image = img
        self.displayImage(2)

        plt.imshow(img_out, cmap='gray', interpolation='bicubic')


        plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
        plt.show()

    def RobertClicked(self):
        img = cv2.imread('1.jpg')
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        x = np.array([[1, 0], [0, -1]])
        y = np.array([[0, 1], [-1, 0]])
        sx = cv2.filter2D(gray, cv2.CV_64F, x)
        sy = cv2.filter2D(gray, cv2.CV_64F, y)

        hitung = cv2.sqrt((sx * sx) + (sy * sy))
        h, w = hitung.shape[:2]
        for i in np.arange(h):
            for j in np.arange(w):
                a = hitung.item(i, j)
                if a > 255:
                    a = 255
                elif a < 0:
                    a = 0
                else:
                    a = a

        plt.imshow(hitung, cmap='gray', interpolation='bicubic')
        plt.xticks([]), plt.yticks([])
        print(hitung)
        plt.show()

    def LaplaceClicked(self):
        img = cv2.imread('1.jpg')
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        x = np.array([[0, -1, 0], [-1, 4, -1], [0, -1, 0]])
        y = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]])
        sx = cv2.filter2D(gray, cv2.CV_64F, x)
        sy = cv2.filter2D(gray, cv2.CV_64F, y)

        hitung = cv2.sqrt((sx * sx) + (sy * sy))
        h, w = hitung.shape[:2]
        for i in np.arange(h):
            for j in np.arange(w):
                a = hitung.item(i, j)
                if a > 255:
                    a = 255
                elif a < 0:
                    a = 0
                else:
                    a = a

        plt.imshow(hitung, cmap='gray', interpolation='bicubic')
        plt.xticks([]), plt.yticks([])
        print(hitung)
        plt.show()

    def LaplaceofGaussianClicked(self):
        img = cv2.imread('1.jpg')
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        img_out = cv2.GaussianBlur(gray, (5,5),0)

        x = np.array([[0, -1, 0], [-1, 4, -1], [0, -1, 0]])
        y = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]])
        sx = cv2.filter2D(img_out, cv2.CV_64F, x)
        sy = cv2.filter2D(img_out, cv2.CV_64F, y)

        hitung = cv2.sqrt((sx * sx) + (sy * sy))
        h, w = hitung.shape[:2]
        for i in np.arange(h):
            for j in np.arange(w):
                a = hitung.item(i, j)
                if a > 255:
                    a = 255
                elif a < 0:
                    a = 0
                else:
                    a = a

        plt.imshow(hitung, cmap='gray', interpolation='bicubic')
        plt.xticks([]), plt.yticks([])
        print(hitung)
        plt.show()

    @pyqtSlot()
    def CannyClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        gaus = (1.0 / 9) * np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])

        img_gaus = conv(img, gaus)

        # ubah format gambar
        img_gaus = img_gaus.astype("uint8")
        cv2.imshow("gaus",img_gaus)
        #sobel
        Sx = np.array([[-1, 0, 1],
                       [-2, 0, 2],
                       [-1, 0, 1]])

        Sy = np.array([[-1, -2, -1],
                       [0, 0, 0],
                       [1, 2, 1]])

        img_x = conv(img_gaus, Sx)
        img_y = conv(img_gaus, Sy)

        H, W = img.shape[:2]
        img_out = np.zeros((H, W))
        for i in np.arange(H):
            for j in np.arange(W):
                x = img_x.item(i, j)
                y = img_y.item(i, j)
                hasil = np.abs(x) + np.abs(y)
                if (hasil > 255):
                    hasil = 255
                if (hasil < 0):
                    hasil = 0
                else:
                    hasil = hasil
                img_out.itemset((i, j), hasil)

        # hasil gradient
        img_out = img_out.astype("uint8")
        #arah tepi
        theta = np.arctan2(img_y, img_x)
        cv2.imshow("sobel",img_out)
        #non-max supresion
        Z = np.zeros((H, W), dtype=np.int32)
        angle = theta * 180. / np.pi
        angle[angle < 0] += 180

        for i in range(1, H - 1):
            for j in range(1, W - 1):
                try:
                    q = 255
                    r = 255

                    # angle 0
                    if (0 <= angle[i, j] < 22.5) or (157.5 <= angle[i, j] <= 180):
                        q = img_out[i, j + 1]
                        r = img_out[i, j - 1]
                    # angle 45
                    elif (22.5 <= angle[i, j] < 67.5):
                        q = img_out[i + 1, j - 1]
                        r = img_out[i - 1, j + 1]
                    # angle 90
                    elif (67.5 <= angle[i, j] < 112.5):
                        q = img_out[i + 1, j]
                        r = img_out[i - 1, j]
                    # angle 135
                    elif (112.5 <= angle[i, j] < 157.5):
                        q = img_out[i - 1, j - 1]
                        r = img_out[i + 1, j + 1]

                    if (img_out[i, j] >= q) and (img_out[i, j] >= r):
                        Z[i, j] = img_out[i, j]
                    else:
                        Z[i, j] = 0

                except IndexError as e:
                    pass

        img_N = Z.astype("uint8")

        cv2.imshow("NON", img_N)

        # hysteresis Thresholding menentukan tepi lemah dan kuat
        weak = 50
        strong = 100
        for i in np.arange(H):
            for j in np.arange(W):
                a = img_N.item(i, j)
                if (a > weak) : #weak
                    b = weak
                    if (a > strong): #strong
                        b = 255
                else:
                    b = 0

                img_N.itemset((i, j), b)

        img_H1 = img_N.astype("uint8")
        cv2.imshow("hysteresis part 1", img_H1)

        # hysteresis Thresholding eliminasi titik tepi lemah jika tidak terhubung dengan tetangga tepi kuat

        strong = 255
        for i in range(1, H - 1):
            for j in range(1, W - 1):
                if (img_H1[i, j] == weak):
                    try:
                        if ((img_H1[i + 1, j - 1] == strong) or
        (img_H1[i + 1, j] == strong) or
                                  (img_H1[i + 1, j + 1] == strong) or
        (img_H1[i, j - 1] == strong) or
                                  (img_H1[i, j + 1] == strong) or
        (img_H1[i - 1, j - 1] == strong) or
        (img_H1[i - 1, j] == strong) or (img_H1[i - 1, j + 1] == strong)):
                              img_H1[i, j] = strong
                        else:
                            img_H1[i, j] = 0
                    except IndexError as e:
                        pass

        img_H2 = img_H1.astype("uint8")
        cv2.imshow("Canny Edge Detection", img_H2)


    @pyqtSlot()
    def Dilasi(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        _,thresh = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
        strel = np.ones((5, 5), np.uint8)
        dilasi = cv2.dilate(thresh, strel, iterations=1)
        cv2.imshow("Dilasi", dilasi)

    def Erosi(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        _, thresh = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
        strel = np.ones((5, 5), np.uint8)
        erosi = cv2.erode(thresh, strel, iterations=1)
        cv2.imshow("Erosi", erosi)

    def Opening(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        _, thresh = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
        strel = np.ones((5, 5), np.uint8)
        Opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, strel, iterations=1)
        cv2.imshow("Opening", Opening)


    def Closing(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        _, thresh = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
        strel = np.ones((5, 5), np.uint8)
        Closing = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, strel, iterations=1)
        cv2.imshow("Closing", Closing)

    @pyqtSlot()
    def SkeletonClicked(self):
        img = cv2.cvtColor(self.image)

        size = np.size(img)
        skeleton = np.zeros(img.shape, np.uint8)

        ret, img = cv2.threshold(img, 127, 255, 0)
        strel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
        done = False

        while (not done):
            erosi = cv2.erode(img, strel)
            temp = cv2.dilate(erosi, strel)

            temp = cv2.subtract(img, temp)
            skeleton = cv2.bitwise_or(skeleton, temp)
            img = erosi.copy()

            zeros = size - cv2.countNonZero(img)
            if zeros == size:
                done = True

        cv2.imshow('Image Asli', img)
        cv2.imshow('Skeletonizing', skeleton)

    @pyqtSlot()
    def Binary(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        _, thresh = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
        cv2.imshow("Binary", thresh)

    def BinaryInvers(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        _, thresh = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
        cv2.imshow("Binary Invers", thresh)

    def Trunc(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        _, thresh = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)
        cv2.imshow("Trunc", thresh)

    def ToZero(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        _, thresh = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)
        cv2.imshow("To Zero", thresh)

    def ToZeroInvers(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        _, thresh = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV)
        cv2.imshow("To Zero Invers", thresh)

    @pyqtSlot()
    def otsuClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        retval2, otsu_thres = cv2.threshold(img, 125, 255,
                                            cv2.THRESH_BINARY + cv2.THRESH_OTSU)
        mean_c = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 115, 1)
        gaus = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 1)

        cv2.imshow("Retval", retval2)
        cv2.imshow("Otsu", otsu_thres)
        cv2.imshow("mean_c", mean_c)
        cv2.imshow("gaus", gaus)



    def displayImage(self, windows=1):
        qformat=QImage.Format_Indexed8

        if len(self.image.shape)==3:
            if(self.image.shape[2])==4:
                qformat=QImage.Format_RGBA8888
            else:
                qformat=QImage.Format_RGB888

        img=QImage(self.image,self.image.shape[1],self.image.shape[0],self.image.strides[0],qformat)

        #cv membaca image dalam format BGR, PyQt membaca dalam format RGB
        img=img.rgbSwapped()


        #menyimpan gambar hasil load di dalam imgLabel
        if windows==1:
            self.imgLabel.setPixmap(QPixmap.fromImage(img))
        #memposisikan gambar
            self.imgLabel.setAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter)
            self.imgLabel.setScaledContents(True)

        if windows==2:
            self.imgLabel2.setPixmap(QPixmap.fromImage(img))
        #memposisikan gambar
            self.imgLabel2.setAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter)
            self.imgLabel2.setScaledContents(True)
Exemple #20
0
class FieldSelector(QDialog, Ui_FieldSelector):
    """
	Class documentation goes here.
	"""

    textualId = -1
    columnId = -1

    def __init__(self, base, url, currenttextualization, inColumnName,
                 newLineTags, sentenceSplit):
        """
		Constructor
		"""
        QDialog.__init__(self)
        self.setupUi(self)
        self.base = base
        self.currenturl = url
        self.constraints = None
        #		self.content=""

        self.columnName = ''
        #		self.inColumnName=inColumnName
        self.textualName = ''
        self.sourceTextualName = currenttextualization
        self.selectableTags = [
            "div", "span", "p", "h1", "h2", "h3", "tr", "ul", "li"
        ]

        #print newLineTags
        #print "|".join(newLineTags )
        self.newLineRe = re.compile(newLineTags, re.M + re.I)
        self.sentenceSplit = sentenceSplit
        self.progressBar.hide()

        self.selectedColor = '#b0c4de'
        self.webView.mousePressEvent = self.mousePressed
        self.selectColumnName = None
        if inColumnName:
            if self.base.columnIsSourceColumn(currenttextualization,
                                              inColumnName):
                self.selectColumnName = inColumnName

        self.getWebViewPage(self.currenturl)
        self.listTextualizations()
        self.listTextColumns()

    def getWebViewPage(self, url):
        self.currentrowid, source = self.base.getSourceByURL(
            url, self.sourceTextualName, self.selectColumnName)
        self.url.setText(url)
        if self.currentrowid == 1: self.backButton.setEnabled(False)
        if source: self.showPage(source)

    def showPage(self, source):
        """
		inserts interactive js into a page before showing it in the webView
		the interactive js copies the element under the mouse into an invisible node 'grogro'
		"""
        soup = BeautifulSoup(source, "html.parser")

        js = """
	
		function cli(e, ele) {
			ele.style.borderStyle = 'solid';
			event.cancelBubble = true; 
			host=document.getElementById("grogro");
			oldnode=host.firstChild;
			newnode=ele.cloneNode(true)
			host.replaceChild(newnode, oldnode);
			return false
			}


			"""
        #insert js
        newTag = soup.new_tag('script')
        newString = soup.new_string(js)
        newTag.append(newString)
        #		print "____________", soup.head
        if soup.html == None: return

        #		print soup.html, soup.html==None
        if not soup.head: soup.html.append(soup.new_tag("head"))
        if not soup.body: soup.html.append(soup.new_tag("body"))
        soup.head.append(newTag)

        #insert invisible div in the end
        new_tag = soup.new_tag("div", id="grogro", style="visibility:hidden")
        new_tag.append("nothing")
        soup.body.append(new_tag)

        for tag in self.selectableTags:
            for d in soup.findAll(tag):
                d['onmouseover'] = "cli(event,this);"
                d['onmouseout'] = "this.style.borderStyle='none';"

        self.webView.setHtml(str(soup))

#	@pyqtSignature("bool")
#	def on_webView_loadFinished(self, p0):
#		"""
#		Slot documentation goes here.
#		"""
#		self.webViewIsLoading=False

#	@pyqtSignature("QMouseEvent")

    def mousePressed(self, me):
        """
		Slot documentation goes here.
		"""
        self.constraints = [None, None, None]
        doc = self.webView.page().mainFrame().documentElement()

        host = doc.findFirst("div[id='grogro']").firstChild()

        #show the tag name
        self.tagCheckBox.setText('tag : ' + host.tagName())
        self.tagCheckBox.setEnabled(True)
        self.constraints[0] = str(host.tagName())

        #show the id name
        if host.hasAttribute('id'):
            self.idCheckBox.setText('id : ' + host.attribute('id'))
            self.idCheckBox.setEnabled(True)
            self.constraints[1] = str(host.attribute('id'))
        else:
            self.idCheckBox.setText('id')
            self.idCheckBox.setEnabled(False)

        #show the class name
        if host.hasAttribute('class'):
            self.classCheckBox.setText('class : ' + host.attribute('class'))
            self.classCheckBox.setEnabled(True)
            self.constraints[2] = str(host.attribute('class'))
        else:
            self.classCheckBox.setText('class')
            self.classCheckBox.setEnabled(False)

        #self.sourceText.setPlainText(self.applyConstraints()[0])
        self.applyConstraints()
#		self.sourceText.setPlainText(BeautifulSoup(unicode(host.toOuterXml()) ).get_text())

#if self.constraints:
#self.textualComboBox.setEnabled(True)
#self.listTextualizations()

#else:
#self.textualComboBox.setEnabled(False)

#		self.buttonBox.setEnabled(True)

    def listTextualizations(self):
        """
		shows the textualizations existing in the base
		"""
        self.textualNames = []  #remember the names that exist in the database
        self.textualComboBox.clear()
        #self.textualComboBox.addItem("")
        for cf in self.base.getTextualizations():
            self.textualComboBox.addItem(cf)
            self.textualNames.append(cf)
        self.textualComboBox.setCurrentIndex(self.textualComboBox.count() - 1)
        self.textualName = str(self.textualComboBox.currentText())
        self.textualComboBox.setEnabled(False)

    def listTextColumns(self):
        """
		get the column name you want
		1.if use the textualizations existing in the database , then list the column name belongs to the textualizations
			we can choose the existing column name or creat new names we want
		2. if we creat a new textualizations , then  no list for the column ,and we can creat a new name 
		3. the name can only Start with 'A~Z' and 'a~z
		
		"""
        self.columnNames = []
        self.textcolComboBox.clear()
        if self.textualName in self.textualNames:
            (textualId, ) = next(
                self.base.select(
                    "select id from textualizations where name='" +
                    self.textualName + "';"))
            for id, in self.base.select(
                    "select columnid from textualcolumns where textualid=" +
                    str(textualId) + ";"):
                (columnName, ) = next(
                    self.base.select(
                        "select name from textcolumns where  id=" + str(id) +
                        ";"))
                self.columnNames.append(columnName)
            self.textcolComboBox.addItem("")
            for cf in self.columnNames:
                self.textcolComboBox.addItem(cf)
            self.columnName = str(self.textcolComboBox.currentText())
        else:
            self.textcolComboBox.clear()

    #@pyqtSignature("int")
    def on_textualComboBox_currentIndexChanged(self, index):
        """
		Slot documentation goes here.
		"""
        self.textualName = str(self.textualComboBox.currentText())
        self.listTextColumns()
        self.setExtractionEnabled()

    #@pyqtSignature("QString")
    @pyqtSlot(str)
    def on_textualComboBox_editTextChanged(self, p0):
        """
		Slot documentation goes here.
		"""
        self.textualName = str(self.textualComboBox.currentText())
        if len(self.textualName) == 0:
            self.textcolComboBox.clear()
            self.textcolComboBox.clearEditText()
            self.warnLabel.setText("")
        else:
            if self.textualName < 'A' or 'Z' < self.textualName[
                    0] < 'a' or self.textualName[0] >= 'z':
                self.warnLabel.setText(
                    "Illegal Name . Please Start with 'A~Z' and 'a~z'")
            else:
                self.warnLabel.setText("")
        self.listTextColumns()
        self.setExtractionEnabled()

    #@pyqtSignature("int")
    def on_textcolComboBox_currentIndexChanged(self, index):
        """
			Slot documentation goes here.
			"""
        self.columnName = str(self.textcolComboBox.currentText())
        self.setExtractionEnabled()

    #@pyqtSignature("QString")
    @pyqtSlot(str)
    def on_textcolComboBox_editTextChanged(self, p0):
        """
		Slot documentation goes here.
		"""
        self.columnName = str(self.textcolComboBox.currentText())
        if len(self.columnName) == 0:
            self.warnLabel.setText("")
        else:
            if self.columnName < 'A' or 'Z' < self.columnName[
                    0] < 'a' or self.columnName[0] > 'z':
                self.warnLabel.setText(
                    "Illegal Name . Please Start with a letter")
            elif self.columnName in self.columnNames:
                self.warnLabel.setText("Existing columns will be overwritten!")
            else:
                self.warnLabel.setText("")
        self.setExtractionEnabled()

    #@pyqtSignature("")
    def on_additionTagLineEdit_returnPressed(self):
        #		print "iiii"
        newselectabletag = str(self.additionTagLineEdit.text())
        if newselectabletag:
            self.selectableTags = list(
                set(self.selectableTags + [newselectabletag]))
        #print self.selectableTags

    def setExtractionEnabled(self):
        if self.columnName != '' and self.textualName != '' and (
                self.warnLabel.text() == "" or self.warnLabel.text()
                == "Existing columns will be overwritten!"):
            self.extractFrame.setEnabled(True)
            self.newcolumnButton.setEnabled(True)
            self.textExtraction.setEnabled(True)
        else:
            self.extractFrame.setEnabled(False)
            self.newcolumnButton.setEnabled(False)
            self.textExtraction.setEnabled(False)

    def applyConstraints(self):
        """
		marks the divs of the current html document corresponding to the selected constraints
		gives back the selection as text and as source
		"""

        #		print "marking constraints"

        doc = self.webView.page().mainFrame().documentElement()

        #		for ele in doc.findAll("div") + doc.findAll("p")+doc.findAll("span"):
        for tag in self.selectableTags:
            for ele in doc.findAll(tag):
                ele.setStyleProperty(
                    'background-color', '#ffffff'
                )  # TODO: make this customizable or the contrary of the font color to remain readable

        if self.tagCheckBox.isChecked():
            constring = self.constraints[0] or "*"
        else:
            constring = "*"
        if self.idCheckBox.isChecked() and self.constraints[1]:
            constr1 = '[' + "id=" + '"' + self.constraints[1] + '"' + ']'
            constring += constr1
        if self.classCheckBox.isChecked() and self.constraints[2]:
            constr2 = '[' + "class=" + '"' + self.constraints[2] + '"' + ']'
            constring += constr2
        #the format of the css selector is  span[hello="Cleveland"][goodbye="Columbus"] { color: blue; } !important

        elemsSource = ""
        #paint the node
        if constring != "*":
            for elem in doc.findAll(constring):

                elemsSource += str(elem.toOuterXml()) + " "
                #				self.content=unicode(elem.toOuterXml())+self.content
                elem.setStyleProperty('background-color', self.selectedColor)
                for tag in self.selectableTags:
                    for child in elem.findAll(tag):  # all children
                        child.setStyleProperty('background-color',
                                               self.selectedColor)
        pureText = self.html2text(elemsSource)
        self.sourceText.setPlainText(pureText)
        return pureText, elemsSource

    def computeStat(self, content=""):
        """
		called from on_newcolumnButton_clicked
		when calculating the nbWords just calculate the number of characters
		
		"""
        #		content =content or self.content
        if self.isLinguaContinua(content):
            nbWords = len(
                str(content)
            )  #count the number of characters (word counting is too difficult for Chinese)
        else:
            nbWords = len(whiteSpaceRe.split(content))
        nbSentences = 0
        for line in content.split("\n"):
            num = len(self.sentenceSplit.findall(line))
            if num == 0:
                nbSentences = nbSentences + 1
            else:
                nbSentences = nbSentences + len(
                    self.sentenceSplit.findall(line))
        return nbWords, nbSentences

    def on_tagCheckBox_stateChanged(self, p0):
        self.applyConstraints()

    def on_idCheckBox_stateChanged(self, p0):
        self.applyConstraints()

    def on_classCheckBox_stateChanged(self, p0):
        self.applyConstraints()

    #@pyqtSignature("")
    pyqtSlot()

    def on_nextButton_clicked(self):
        #print 8888
        rowid, url, source = self.base.getNextSource(self.currentrowid,
                                                     self.sourceTextualName,
                                                     self.selectColumnName)
        if rowid:
            #print 777
            self.url.setText(url)
            self.currentrowid += 1
            if not len(source.strip(
            )):  # if the next page was empty, take the following one.
                #print 999
                self.on_nextButton_clicked()
                return
            self.nextButton.setEnabled(True)
            self.backButton.setEnabled(True)
            self.currentrowid = rowid
            self.showPage(source)
            if self.constraints: self.applyConstraints()
            #print 7777
#			self.sourceText.clear()
        else:
            self.nextButton.setEnabled(False)

    #@pyqtSignature("")
    pyqtSlot()

    def on_backButton_clicked(self):
        #print 111
        rowid, url, source = self.base.getLastSource(self.currentrowid,
                                                     self.sourceTextualName,
                                                     self.selectColumnName)
        if rowid:
            self.url.setText(url)
            self.currentrowid -= 1
            if not len(source.strip()):
                self.on_backButton_clicked()
                return
            self.backButton.setEnabled(True)
            self.nextButton.setEnabled(True)
            self.currentrowid = rowid
            self.showPage(source)
            if self.constraints: self.applyConstraints()
            #			self.sourceText.clear()
            if rowid == 1: self.backButton.setEnabled(False)
        else:
            self.backButton.setEnabled(False)

    def on_numElecomboBox_currentIndexChanged(self, index):

        raise NotImplementedError

    #@pyqtSignature("")
    pyqtSlot()

    def on_newcolumnButton_clicked(self):
        """
		
		the function is to insert the new textualization and columnName information into the database 
		then extract the part we choose and insert into the database 
		show the progress bar and hide the progress bar
		
		in the database, should make the textualizations.
		
		"""
        #print "mmm",self.textualName,self.textualNames,self.textualName in self.textualNames
        if self.textualName in self.textualNames:
            (self.textualId, ) = next(
                self.base.select(
                    "select id from textualizations where name='" +
                    self.textualName + "';"))
            if self.columnName not in self.columnNames:
                count = len(self.columnNames) + 1
                self.base.execute(
                    "insert into textcolumns(name) values  (?) ;",
                    (self.columnName, ))
                self.base.execute(
                    "insert into textualcolumns(textualid,columnid) values  (?,?) ;",
                    (
                        self.textualId,
                        count,
                    ))
                self.columnId = count
                self.overwrite = False
            else:
                # textualName  and  culumnName existed in the database . if the button are clicked, just overwrite
                (self.columnId, ) = next(
                    self.base.select(
                        "select id from textcolumns where name='" +
                        self.columnName + "';"))
                self.overwrite = True
        else:
            qsdf
            self.textualId = len(self.textualNames) + 1
            self.base.execute(
                "insert into textualizations(name) values  (?) ;",
                (self.textualName, ))
            self.base.execute("insert into textcolumns(name) values  (?) ;",
                              (self.columnName, ))
            (self.columnId, ) = next(
                self.base.select("select id from textcolumns where name='" +
                                 self.columnName + "';"))
            self.base.execute(
                "insert into textualcolumns(textualid,columnid) values  (?,?) ;",
                (
                    self.textualId,
                    self.columnId,
                ))
            self.overwrite = False
        while not self.base.reqs.empty():
            pass
        sleep(
            .01
        )  # wait for the database to close completely before giving back the textualName

        self.progressBar.show()
        (totalnum, ) = next(self.base.select("select count(*) from sources;"))
        self.progressBar.setMaximum(totalnum)

        #go extract the part we choose
        for i in range(1, totalnum + 1):
            source = self.base.getSourceById(
                i, self.textualName, self.selectColumnName
            )  #extract the part from the first to the last
            #			if not self.webViewIsLoading:
            self.webView.setHtml(source)

            textcontent, sourcecontent = self.applyConstraints()
            #			self.webView._wait_load()

            #			textcontent=self.html2text(self.content)
            #			if textcontent:
            nbWords, nbSentences = self.computeStat(textcontent)
            if self.textExtraction.isChecked(): enterstuff = textcontent
            else: enterstuff = "<html>\n" + sourcecontent + "\n</html>"

            self.base.enterNewText(i, self.textualId, self.columnId,
                                   enterstuff, nbSentences, nbWords,
                                   self.overwrite)

            self.progressBar.setValue(i)
            if self.base.errorState:
                #				print self.base.errorState
                QtWidgets.QMessageBox.critical(
                    self, "Problem with database", self.base.errorState +
                    "\n\nDoes another program access the database file?")
                break

        self.base.makeTextual(self.textualName, self.textualId)
        #		self.textualizationName=self.textualName

        self.progressBar.hide()
        self.progressBar.setValue(totalnum)
        #self.textualComboBox.setCurrentIndex(self.textualComboBox.count())
        #self.textualComboBox.setEnabled(False)
        self.setExtractionEnabled()

    ################## stuff for text extraction
    ################################

    def html2text(self, htmlSource):
        #		if "doubleclick" in htmlSource: print "doubleclick","\n\n", htmlSource, "\n"
        htmlSource = whiteSpaceRe.sub(
            " ",
            htmlSource)  # all white space (including new line) => simple space

        htmlSource = scriptex.sub(" ", htmlSource)
        htmlSource = styleex.sub(" ", htmlSource)
        htmlSource = rssex.sub(" ", htmlSource)
        htmlSource = commentex.sub(" ", htmlSource)
        htmlSource = imageex.sub(" ", htmlSource)

        htmlSource = self.newLineRe.sub("\n", htmlSource)
        #		if "doubleclick" in htmlSource:print "\n\navant", htmlSource, "\n\n"
        pureText = anyTagRe.sub(
            " ", htmlSource)  # the great moment: we're down to pure text !
        pureText = redoubleclick.sub(
            " ", pureText
        )  # just in case the evil guys from doubleclick where around

        #		if "doubleclick" in htmlSource:print "\n\n après", htmlSource, "\n\n"
        pureText = self._specialChar2UTF8(pureText)
        for g in getRid:  # des trucs bizarres à virer :
            pureText = re.sub(g, " ", pureText)
        # enlever les espaces et passages à la ligne successifs :
        pureText = re.sub("[ \t\r\f\v\n]*\n+[ \t\r\f\v\n]*", "\n", pureText)
        pureText = re.sub("[ \t\r\f\v]+", " ", pureText)[1:-1]
        return pureText

    def _specialChar2UTF8(self, codeHTML):
        """
		trying to replace things of type &#1234; and &eacute; by the unicode chars
		"""
        codeHTML = re.sub("&.+?;", self._replacementHtmlUnicode, codeHTML)
        return codeHTML

    def _replacementHtmlUnicode(self, s):
        match = s.group()[1:-1]  # get rid of & and ;

        if match[:2] == "#x":  # if of type &#xabcd;
            try:
                return chr(int(match[2:], 16))
            except Exception as e:
                if verbose: print("0. strange html like thing:", match, e)
        elif match[0] == "#":
            i = int(match[1:])
            if i in windowsGarbage:
                return windowsGarbage[i]  #.decode("utf-8")
            else:
                try:
                    return chr(i)  # if of type &#1234;
                except Exception as e:
                    if verbose: print("1. strange html like thing:", match, e)
                    return " "
        try:
            return chr(name2codepoint[match])
        except Exception as e:
            if verbose: print("2. strange html like thing:", match, e)
            return " "

    def isLinguaContinua(self, text, threshold=0.9):
        """
		returns true if the percentage of spaces in the text is below 10%
		"""
        txt = spaceRe.sub("", text)
        return (float(len(txt)) / len(text + " ") > threshold)
class PIDRunner(QObject):
    status_sig = pyqtSignal(list)
    pid_output_signal = pyqtSignal(dict)

    def __init__(self,model_class,
                 move_done_signals=[],
                 grab_done_signals=[],
                 move_modules_commands=[],
                 detector_modules_commands=[],
                 params=dict([]), filter=dict([]),
                 det_averaging = []
                 ):
        """
        Init the PID instance with params as initial conditions

        Parameters
        ----------
        params: (dict) Kp=1.0, Ki=0.0, Kd=0.0,setpoint=0, sample_time=0.01, output_limits=(None, None),
                 auto_mode=True,
                 proportional_on_measurement=False)
        """
        super().__init__()
        self.model_class = model_class
        self.move_done_signals = move_done_signals
        self.grab_done_signals = grab_done_signals
        self.det_averaging = det_averaging
        self.move_modules_commands = move_modules_commands
        self.detector_modules_commands = detector_modules_commands

        self.current_time = 0
        self.input = 0
        self.output = None
        self.output_to_actuator = None
        self.output_limits = None, None
        self.filter = filter #filter=dict(enable=self.settings.child('main_settings', 'filter', 'filter_enable').value(),                                         value=self.settings.child('main_settings', 'filter', 'filter_step').value())
        self.pid = PID(**params) ##PID(object):
        self.pid.set_auto_mode(False)
        self.refreshing_ouput_time = 200
        self.running = True
        self.timer = self.startTimer(self.refreshing_ouput_time)
        self.det_done_datas = OrderedDict()
        self.move_done_positions = OrderedDict()
        self.move_done_flag = False
        self.det_done_flag = False
        self.paused = True
        self.timeout_timer = QtCore.QTimer()
        self.timeout_timer.setInterval(10000)
        self.timeout_scan_flag = False
        self.timeout_timer.timeout.connect(self.timeout)


    def timerEvent(self, event):
        if self.output_to_actuator is not None:
            self.pid_output_signal.emit(dict(output=self.output_to_actuator, input=[self.input]))
        else:
            self.pid_output_signal.emit(dict(output=[0], input=[self.input]))

    def timeout(self):
        self.status_sig.emit(["Update_Status", 'Timeout occured', 'log'])
        self.timeout_scan_flag = True

    def wait_for_det_done(self):
        self.timeout_scan_flag=False
        self.timeout_timer.start()
        while not(self.det_done_flag or  self.timeout_scan_flag):
            #wait for grab done signals to end
            QtWidgets.QApplication.processEvents()
        self.timeout_timer.stop()

    def wait_for_move_done(self):
        self.timeout_scan_flag=False
        self.timeout_timer.start()
        while not(self.move_done_flag or  self.timeout_scan_flag):
            #wait for move done signals to end
            QtWidgets.QApplication.processEvents()
        self.timeout_timer.stop()

    @pyqtSlot(ThreadCommand)
    def queue_command(self, command=ThreadCommand()):
        """
        """
        if command.command == "start_PID":
            self.start_PID(*command.attributes)

        elif command.command == "run_PID":
            self.run_PID(*command.attributes)

        elif command.command == "pause_PID":
            self.pause_PID(*command.attributes)

        elif command.command == "stop_PID":
            self.stop_PID()

        elif command.command == 'update_options':
            self.set_option(**command.attributes)

        elif command.command == 'input':
            self.update_input(*command.attributes)

        elif command.command == 'update_timer':
            if command.attributes[0] == 'refresh_plot_time':
                self.killTimer(self.timer)
                self.refreshing_ouput_time = command.attributes[1]
                self.timer = self.startTimer(self.refreshing_ouput_time)
            elif command.attributes[0] =='timeout':
                self.timeout_timer.setInterval(command.attributes[1])


        elif command.command == 'update_filter':
            self.filter = command.attributes[0]

        # elif command.command == "move_Abs":
        #     self.set_option(dict(setpoint=command.attributes[0]))


    def update_input(self, measurements):
        self.input =self.model_class.convert_input(measurements)

    def start_PID(self, input = None):
        try:
            for sig in self.move_done_signals:
                sig.connect(self.move_done)
            for sig in self.grab_done_signals:
                sig.connect(self.det_done)


            self.current_time = time.perf_counter()
            self.status_sig.emit(["Update_Status", 'PID loop starting', 'log'])
            while self.running:
                #print('input: {}'.format(self.input))
                ## GRAB DATA FIRST AND WAIT ALL DETECTORS RETURNED

                self.det_done_flag = False
                self.det_done_datas = OrderedDict()
                for ind_det, cmd in enumerate(self.detector_modules_commands):
                    cmd.emit(ThreadCommand("single",
                                  [self.det_averaging[ind_det]]))
                    QtWidgets.QApplication.processEvents()
                self.wait_for_det_done()

                self.input = self.model_class.convert_input(self.det_done_datas)

                ## EXECUTE THE PID
                output = self.pid(self.input)

                ## PROCESS THE OUTPUT IF NEEDED
                if output is not None and self.output is not None:
                    if self.filter['enable']:
                        if np.abs(output-self.output) <= self.filter['value']:
                            self.output = output
                        else:
                            self.output += np.abs(self.filter['value'])*np.sign(output - self.output)
                            self.pid._last_output = self.output
                    else:
                        self.output = output
                else:
                    self.output = output

                ## APPLY THE PID OUTPUT TO THE ACTUATORS
                #print('output: {}'.format(self.output))

                if self.output is None:
                    self.output = self.pid.setpoint


                dt = time.perf_counter() - self.current_time
                self.output_to_actuator = self.model_class.convert_output(self.output, dt, stab=True)

                if not self.paused:
                    self.move_done_positions = OrderedDict()
                    for ind_mov, cmd in enumerate(self.move_modules_commands):
                        cmd.emit(ThreadCommand('move_Abs',[self.output_to_actuator[ind_mov]]))
                        QtWidgets.QApplication.processEvents()
                    self.wait_for_move_done()

                self.current_time = time.perf_counter()
                QtWidgets.QApplication.processEvents()
                QThread.msleep(int(self.pid.sample_time*1000))

            self.status_sig.emit(["Update_Status", 'PID loop exiting', 'log'])
            for sig in self.move_done_signals:
                sig.disconnect(self.move_done)
            for sig in self.grab_done_signals:
                sig.disconnect(self.det_done)
        except Exception as e:
            self.status_sig.emit(["Update_Status", str(e), 'log'])

    pyqtSlot(OrderedDict) #OrderedDict(name=self.title,data0D=None,data1D=None,data2D=None)
    def det_done(self,data):
        """
        """
        try:
            if data['name'] not in list(self.det_done_datas.keys()):
                self.det_done_datas[data['name']]=data
            if len(self.det_done_datas.items())==len(self.grab_done_signals):
                self.det_done_flag=True
        except Exception as e:
            self.status_sig.emit(["Update_Status", str(e), 'log'])


    pyqtSlot(str,float)
    def move_done(self,name,position):
        """
            | Update the move_done_positions attribute if needed.
            | If position attribute is setted, for all move modules launched, update scan_read_positions with a [modulename, position] list.

            ============== ============ =================
            **Parameters**    **Type**    **Description**
            *name*            string     the module name
            *position*        float      ???
            ============== ============ =================
        """
        try:
            if name not in list(self.move_done_positions.keys()):
                self.move_done_positions[name]=position

            if len(self.move_done_positions.items())==len(self.move_done_signals):
                self.move_done_flag=True

        except Exception as e:
            self.status_sig.emit(["Update_Status",str(e),'log'])

    def set_option(self,**option):
        for key in option:
            if hasattr(self.pid, key):
                if key == 'sample_time':
                    setattr(self.pid, key, option[key]/1000)
                else:
                    setattr(self.pid,key, option[key])
            if key == 'setpoint' and not self.pid.auto_mode:
                dt = time.perf_counter() - self.current_time
                self.output = option[key]
                self.output_to_actuator = self.model_class.convert_output(self.output, dt, stab=False)

                for ind_move, cmd in enumerate(self.move_modules_commands):
                    cmd.emit(ThreadCommand('move_Abs', [self.output_to_actuator[ind_move]]))
                self.current_time = time.perf_counter()
            if key == 'output_limits':
                self.output_limits = option[key]



    def run_PID(self, last_value):
        self.status_sig.emit(["Update_Status", 'Stabilization started', 'log'])
        self.running = True
        self.pid.set_auto_mode(True, last_value)


    def pause_PID(self, pause_state):
        if pause_state:
            self.pid.set_auto_mode(False, self.output)
            self.status_sig.emit(["Update_Status", 'Stabilization paused', 'log'])
        else:
            self.pid.set_auto_mode(True, self.output)
            self.status_sig.emit(["Update_Status", 'Stabilization restarted from pause', 'log'])
        self.paused = pause_state

    def stop_PID(self):
        self.running = False
        self.status_sig.emit(["Update_Status", 'PID loop exiting', 'log'])
Exemple #22
0
class PIDModelMichelsonDemo(PIDModelGeneric):
    params = [
        {'title': 'Stabilization', 'name': 'stabilization', 'type': 'group', 'children': [
            {'title': 'Set as zero:', 'name': 'set_zero', 'type': 'bool', 'value': False},
            {'title': 'Laser wavelength (nm):', 'name': 'laser_wl', 'type': 'float', 'value': 632.0},
            {'title': 'Interfero phase (deg):', 'name': 'interfero_phase', 'type': 'float', 'value': 0},
            {'title': 'Interfero position (nm):', 'name': 'interfero_position', 'type': 'float', 'value': 0},
            {'title': 'phase sign:', 'name': 'phase_sign', 'type': 'int', 'value': 1, 'min': -1, 'max': 1, 'step': 2},
            {'title': 'Offsets', 'name': 'offsets', 'type': 'group', 'children': [
                {'title': 'Phase offset (deg):', 'name': 'phase_offset', 'type': 'float', 'value': 0},
                {'title': 'Interfero (nm):', 'name': 'interfero_offset', 'type': 'float', 'value': 0},
                {'title': 'Piezo (nm):', 'name': 'piezo_offset', 'type': 'float', 'value': 0},
            ]},
        ]},
        {'title': 'Calibration', 'name': 'calibration', 'type': 'group', 'expanded': True, 'visible': True, 'children': [
            {'title': 'Do calibration:', 'name': 'do_calibration', 'type': 'bool', 'value': False},
            {'title': 'Timeout:', 'name': 'timeout', 'type': 'int', 'value': 10000},

            {'title': 'Calibration', 'name': 'calibration_move', 'type': 'group', 'expanded': True, 'visible': True, 'children': [
                {'title': 'Start pos:', 'name': 'start', 'type': 'float', 'value': 7.},
                {'title': 'Stop pos:', 'name': 'stop', 'type': 'float', 'value': 8.},
                {'title': 'Step size:', 'name': 'step', 'type': 'float', 'value': 0.04},
                {'title': 'Averaging:', 'name': 'average', 'type': 'int', 'value': 1},
                ]},
            {'title': 'Ellipse params', 'name': 'calibration_ellipse', 'type': 'group', 'expanded': True, 'visible': True,
             'children': [
                 {'title': 'Dx:', 'name': 'dx', 'type': 'float', 'value': 0.0},
                 {'title': 'Dy:', 'name': 'dy', 'type': 'float', 'value': 0.0},
                 {'title': 'x0:', 'name': 'x0', 'type': 'float', 'value': 0.00},
                 {'title': 'y0:', 'name': 'y0', 'type': 'float', 'value': 0.00},
                 {'title': 'phi (°):', 'name': 'theta', 'type': 'float', 'value': 0.00},
             ]},
        ]},


    ]

    actuators = ['PI']
    actuators_name = ['Axis test PID']

    detectors_type = ['DAQ2D']  # with entries either 'DAQ0D', 'DAQ1D' or 'DAQ2D'or 'DAQND'
    detectors = ['OpenCVCam']
    detectors_name = ['Testing PID']

    check_modules(detectors, detectors_type, actuators)


    def __init__(self, pid_controller):
        super().__init__(pid_controller)
        self.running = False
        self.det_done_flag = False
        self.move_done_flag = False
        self.timeout_scan_flag = False

        self.curr_time = time.perf_counter()

        self.lsqe = LSqEllipse()

        self.phases = np.zeros((100,))
        self.curr_phase = 0
        self.curr_position = 0

        self.dock_calib = Dock('Calibration')
        widget_calib = QtWidgets.QWidget()
        self.viewer_calib = Viewer1D(widget_calib)
        widget_ellipse = QtWidgets.QWidget()
        self.viewer_ellipse = Viewer1D(widget_ellipse)
        self.viewer_ellipse.show_data([np.zeros((10,)), np.zeros((10,))])
        self.dock_calib.addWidget(widget_calib)
        self.dock_calib.addWidget(widget_ellipse, row=0, col = 1)
        self.pid_controller.dock_area.addDock(self.dock_calib)
        self.dock_calib.float()

        self.timer = QTimer()
        self.timer.setSingleShot(True)
        self.timer.timeout.connect(self.timeout)

    def ini_model(self):
        """
        Defines all the action to be performed on the initialized modules (main pid, actuators, detectors)
        Either here for specific things (ROI, ...) or within the preset of the current model

        """
        model_name = self.pid_controller.settings.child('models', 'model_class').value()

        self.pid_controller.detector_modules[0].ui.viewers[0].ui.roiBtn.click()

        #try to get corresponding roi file
        filename = os.path.join(get_set_pid_path(), model_name + '.roi2D')
        if os.path.isfile(filename):
            self.pid_controller.detector_modules[0].ui.viewers[0].load_ROI(filename)

        QtWidgets.QApplication.processEvents()
        if self.pid_controller.detector_modules[0].Initialized_state:
            #self.pid_controller.detector_modules[0].settings.child('main_settings', 'wait_time').setValue(0)
            self.pid_controller.detector_modules[0].grab_data()
        QThread.msleep(500)
        QtWidgets.QApplication.processEvents()

        self.pid_controller.settings.child('main_settings', 'update_modules').setValue(True)
        QtWidgets.QApplication.processEvents()
        QThread.msleep(500)
        QtWidgets.QApplication.processEvents()

        items = self.pid_controller.settings.child('main_settings', 'detector_modules').value().copy()
        if items is not None:
            items['selected'] = items['all_items'][0:2]
            self.pid_controller.settings.child('main_settings', 'detector_modules').setValue(items)

        self.pid_controller.settings.child('main_settings', 'pid_controls', 'output_limits',
                                           'output_limit_min').setValue(0) #in microns
        self.pid_controller.settings.child('main_settings', 'pid_controls', 'output_limits',
                                           'output_limit_min_enabled').setValue(True)
        self.pid_controller.settings.child('main_settings', 'pid_controls', 'output_limits',
                                           'output_limit_max').setValue(15) #in microns
        self.pid_controller.settings.child('main_settings', 'pid_controls', 'output_limits',
                                           'output_limit_max_enabled').setValue(True)

        self.pid_controller.settings.child('main_settings', 'pid_controls', 'pid_constants', 'kp').setValue(0.5)
        self.pid_controller.settings.child('main_settings', 'pid_controls', 'pid_constants', 'ki').setValue(0.2)
        self.pid_controller.settings.child('main_settings', 'pid_controls', 'pid_constants', 'kd').setValue(0.0001)

        self.pid_controller.settings.child('main_settings', 'pid_controls', 'filter', 'filter_enable').setValue(True)
        self.pid_controller.settings.child('main_settings', 'pid_controls', 'filter',
               'filter_step').setValue(self.settings.child('stabilization', 'laser_wl').value()/1000/6/2) #in microns

        self.pid_controller.setpoint_sb.setValue(7.5)
        self.pid_controller.settings.child('main_settings', 'pid_controls', 'sample_time').setValue(50)

    def get_ellipse_fit(self, center, width, height, theta):

        t = np.linspace(0, 2 * np.pi, 1000)
        ellipse_x = center[0] + width * np.cos(t) * np.cos(theta) - height * np.sin(t) * np.sin(theta)
        ellipse_y = center[1] + width * np.cos(t) * np.sin(theta) + height * np.sin(t) * np.cos(theta)

        return ellipse_x, ellipse_y




    def update_settings(self, param):
        """
        Get a parameter instance whose value has been modified by a user on the UI
        Parameters
        ----------
        param: (Parameter) instance of Parameter object
        """
        if param.name() == 'do_calibration':
            if param.value():
                self.running = True
                self.do_calibration()
                QtWidgets.QApplication.processEvents()

            else:
                self.running = False
        elif param.name() == 'set_zero':
            self.phases = np.zeros((100,))
            position = self.pid_controller.actuator_modules[0].current_position
            self.settings.child('stabilization', 'offsets', 'phase_offset').setValue(self.curr_phase)
            self.settings.child('stabilization', 'offsets', 'interfero_offset').setValue(position*1000)
            self.settings.child('stabilization', 'offsets', 'piezo_offset').setValue(position*1000)
            data = self.pid_controller.detector_modules[0].data_to_save_export
            data_export = OrderedDict()
            data_export[data['name']] = data
            self.pid_controller.command_pid.emit(ThreadCommand('input', [data_export]))
            QtWidgets.QApplication.processEvents()
            self.settings.child('stabilization', 'set_zero').setValue(False)



    def do_calibration(self):
        Naverage = self.settings.child('calibration', 'calibration_move', 'average').value()

        steps = linspace_step(self.settings.child('calibration', 'calibration_move', 'start').value(),
                              self.settings.child('calibration', 'calibration_move', 'stop').value(),
                              self.settings.child('calibration', 'calibration_move', 'step').value())

        self.detector_data = np.zeros((steps.size,2))
        self.detector_data_average = np.zeros((steps.size, 2))

        for mod in self.pid_controller.actuator_modules:
            mod.move_done_signal.connect(self.move_done)
        for mod in self.pid_controller.detector_modules:
            mod.grab_done_signal.connect(self.det_done)

        self.viewer_calib.x_axis = steps




        for ind_average in range(Naverage):
            for ind_step, step in enumerate(steps):
                self.move_done_flag = False
                self.pid_controller.actuator_modules[0].move_Abs(step)
                self.wait_for_move_done()

                self.det_done_flag = False
                self.pid_controller.detector_modules[0].grab_data()
                self.wait_for_det_done()
                for ind_data, name in enumerate(self.data_names):
                    self.detector_data[ind_step, ind_data] = \
                    self.pid_controller.detector_modules[0].data_to_save_export[name[1]][name[2]]
                if not self.running:
                    break
            self.detector_data_average = (ind_average*self.detector_data_average+self.detector_data)/(ind_average+1)
            self.viewer_calib.show_data([self.detector_data_average[:,0], self.detector_data_average[:,1]])

            self.lsqe.fit([self.detector_data_average[:,0], self.detector_data_average[:,1]])
            center, width, height, theta = self.lsqe.parameters()
            ellipse_x, ellipse_y = self.get_ellipse_fit(center, width, height, theta)

            self.viewer_ellipse.plot_channels[0].setData(x=self.detector_data_average[:,0], y=self.detector_data_average[:,1])
            self.viewer_ellipse.plot_channels[1].setData(x=ellipse_x, y=ellipse_y)

            self.settings.child('calibration', 'calibration_ellipse', 'x0').setValue(center[0])
            self.settings.child('calibration', 'calibration_ellipse', 'y0').setValue(center[1])
            self.settings.child('calibration', 'calibration_ellipse', 'dx').setValue(width)
            self.settings.child('calibration', 'calibration_ellipse', 'dy').setValue(height)
            self.settings.child('calibration', 'calibration_ellipse', 'theta').setValue(np.rad2deg(theta))
            if not self.running:
                break

            QtWidgets.QApplication.processEvents()
        self.pid_controller.setpoint_sb.setValue(self.pid_controller.setpoint_sb.value())
        self.settings.child('calibration', 'do_calibration').setValue(False)
        for mod in self.pid_controller.actuator_modules:
            mod.move_done_signal.disconnect(self.move_done)
        for mod in self.pid_controller.detector_modules:
            mod.grab_done_signal.disconnect(self.det_done)

    def timeout(self):
        """
            Send the status signal *'Time out during acquisition'* and stop the timer.
        """
        self.timeout_scan_flag=True
        self.timer.stop()
        self.pid_controller.update_status("Timeout during acquisition",log_type='log')



    def wait_for_det_done(self):
        self.timeout_scan_flag=False
        self.timer.start(self.settings.child('calibration','timeout').value())
        while not(self.det_done_flag or  self.timeout_scan_flag):
            #wait for grab done signals to end
            QtWidgets.QApplication.processEvents()
        self.timer.stop()

    pyqtSlot(OrderedDict) #edict(name=self.title,data0D=None,data1D=None,data2D=None)
    def det_done(self,data):
        """
            | Initialize 0D/1D/2D datas from given data parameter.
            | Update h5_file group and array.
            | Save 0D/1D/2D datas.

            =============== ============================== ======================================
            **Parameters**    **Type**                      **Description**
            *data*          Double precision float array   The initializing data of the detector
            =============== ============================== ======================================
        """
        #print(data['data0D']['OpenCV_Integrated_ROI_00'])
        if not (self.settings.child('calibration', 'do_calibration').value() or self.pid_controller.run_action.isChecked()):
            det_done_datas = OrderedDict()
            det_done_datas[data['name']] = data
            self.convert_input(det_done_datas)

        self.det_done_flag = True

    def wait_for_move_done(self):
        self.timeout_scan_flag=False
        self.timer.start(self.settings.child('calibration','timeout').value())
        while not(self.move_done_flag or  self.timeout_scan_flag):
            #wait for move done signals to end
            QtWidgets.QApplication.processEvents()
        self.timer.stop()

    pyqtSlot(str,float)
    def move_done(self,name,position):
        #print(position)
        self.curr_position = position
        self.move_done_flag=True


    def get_phi_from_xy(self,x,y):
        x0 = self.settings.child('calibration', 'calibration_ellipse', 'x0').value()
        y0 = self.settings.child('calibration', 'calibration_ellipse', 'y0').value()
        dx = self.settings.child('calibration', 'calibration_ellipse', 'dx').value()
        dy = self.settings.child('calibration', 'calibration_ellipse', 'dy').value()
        theta = np.deg2rad(self.settings.child('calibration', 'calibration_ellipse', 'theta').value())

        #apply rotation of -theta to get ellipse on main axes
        v = np.array([x, y])
        rot = rot = np.array([[np.cos(-theta), -np.sin(-theta)],[np.sin(-theta),np.cos(-theta)]])
        vprim = rot @ v

        phi = np.arctan2((vprim[1]+x0*np.sin(theta)-y0*np.cos(theta))/dy,
                         (vprim[0]-x0*np.cos(theta)-y0*np.sin(theta))/dx)
        self.settings.child('stabilization', 'interfero_phase').setValue(phi)
        self.curr_phase = phi
        return phi


    def interfero_from_phase(self, phi):
        laser_wl = self.settings.child('stabilization', 'laser_wl').value()
        phi_offset = self.settings.child('stabilization', 'offsets', 'phase_offset').value()
        interfero_offset = self.settings.child('stabilization', 'offsets', 'interfero_offset').value()
        phase_sign = self.settings.child('stabilization', 'phase_sign').value()

        self.phases = np.append(self.phases, [phi])
        self.phases = np.unwrap(self.phases[1:])

        interfero_position = interfero_offset+phase_sign*laser_wl/(2*np.pi*2)*(self.phases[-1]-phi_offset)
        return interfero_position

    def convert_input(self, measurements):
        """
        Convert the measurements in the units to be fed to the PID (same dimensionality as the setpoint)
        Parameters
        ----------
        measurements: (list) List of object from which the model extract a value of the same units as the setpoint

        Returns
        -------
        float: the converted input

        """
        #print('input conversion done')

        x = measurements[self.data_names[0][0]][self.data_names[0][1]][self.data_names[0][2]]
        y = measurements[self.data_names[1][0]][self.data_names[1][1]][self.data_names[1][2]]
        phi = self.get_phi_from_xy(x, y)

        pos = self.interfero_from_phase(phi) #in nm
        self.settings.child('stabilization', 'interfero_position').setValue(pos)
        self.curr_input = pos/1000
        return pos/1000 # in microns for the PI stage

    def convert_output(self, output, dt, stab=True):
        """
        Convert the output of the PID in units to be fed into the actuator
        Parameters
        ----------
        output: (float) output value from the PID from which the model extract a value of the same units as the actuator

        Returns
        -------
        list: the converted output as a list (if there are a few actuators)

        """
        #print('output converted')
        #no conversion needed
        self.curr_output = output
        if stab:
            offset = 0#self.settings.child('stabilization', 'offsets', 'piezo_offset').value()
        else:
            offset = 0
        return [output+offset]
class Server(QObject):
    debug = True
    log = sys.stderr
    username = '******'
    password = '******'
    stopServing = pyqtSlot()

    def __init__(self, parent=None):
        super(Server, self).__init__(parent)
        self.proxy_server = QTcpServer(self)
        self.proxy_server.listen(QHostAddress.Any, 8000)
        self.proxy_server.newConnection.connect(self.manage_request)

        if self.debug:
            self.log.write('Server running on localhost port %s\n\n' %
                           self.port())

    def port(self):
        return self.proxy_server.serverPort()

    def addr(self):
        return self.proxy_server.serverAddress().toString()

    def stopServing(self):
        if self.debug:
            self.log.write('Service is stopping...\n\n')

        # does not "close" the server, just stop listening...
        self.proxy_server.close()

        if self.proxy_server.hasPendingConnections():
            socket = self.proxy_server.nextPendingConnection()
            while socket:
                socket.abort()
                socket = self.proxy_server.nextPendingConnection()

    def manage_request(self):
        proxy_server = self.sender()
        # Qt docs says that the caller of nextPendingConnection()
        # is the parent of the socket
        socket = proxy_server.nextPendingConnection()
        socket.readyRead.connect(self.process_request)
        socket.disconnected.connect(socket.deleteLater)

    def authorize_request(self, request_data):
        return True
        header = QHttpRequestHeader(QString(request_data))
        if self.debug:
            self.log.write(header.toString())

        auth = header.value('Proxy-Authorization')
        if not auth:
            return False

        challenge = base64.b64encode(self.username + ':' + self.password)
        return challenge == str(auth).split()[1]

    def process_request(self):
        socket = self.sender()
        request_data = socket.readAll()

        if not self.authorize_request(request_data):
            socket.write('HTTP/1.1 407 Proxy Authentication Required\r\n')
            if self.debug:
                self.log.write('407 Proxy Authentication Required\n\n')
            socket.write('Proxy-Authenticate: Basic realm="test"\r\n')
            socket.write('\r\n')
            socket.disconnectFromHost()
            return
        else:
            # remove Proxy-Authorization header
            start = request_data.indexOf('Proxy-Authorization:')
            end = request_data.lastIndexOf('\r\n')
            request_data.remove(start, end)
            request_data.append('\r\n')

        pos = request_data.indexOf('\r\n')
        request_line = request_data.left(pos)
        request_data.remove(0, pos + 2)

        entries = request_line.split(' ')
        method = entries[0]
        address = entries[1]
        version = entries[2]
        port = '80'

        if address.count(':') > 1:
            protocol, host, port = address.split(':')
        else:
            protocol, host = address.split(':')

        print('address' + str(address))

        #url = QUrl( protocol + host )
        url = QUrl.fromEncoded(address)
        #url.setHost( host )
        #url.setPort( int(port) )

        if not url.isValid():
            if self.debug:
                self.log.write('Invalid URL: %s\n\n', url)
            socket.disconnectFromHost()
            return

        host = url.host()
        port = 80 if (url.port() < 0) else url.port()
        req = url.encodedPath()
        if url.hasQuery():
            req.append('?').append(url.encodedQuery())
        request_line = method + ' ' + req + ' ' + version + '\r\n'
        request_data.prepend(request_line)

        if self.debug:
            self.log.write(method + ' ' + address + ' ' + version + '\n\n')

        key = host + ':' + QString.number(port)
        proxy_socket = socket.findChild(QTcpSocket, key)
        if proxy_socket:
            proxy_socket.setObjectName(key)
            proxy_socket.setProperty('url', url)
            proxy_socket.setProperty('request_data', request_data)
            proxy_socket.write(request_data)
        else:
            proxy_socket = QTcpSocket(socket)
            proxy_socket.setObjectName(key)
            proxy_socket.setProperty('url', url)
            proxy_socket.setProperty('request_data', request_data)
            proxy_socket.connected.connect(self.send_request)
            proxy_socket.readyRead.connect(self.transfer_data)
            proxy_socket.disconnected.connect(self.close_connection)
            proxy_socket.error.connect(self.close_connection)
            proxy_socket.connectToHost(host, port)

    def send_request(self):
        proxy_socket = self.sender()
        request_data = proxy_socket.property('request_data').toByteArray()
        proxy_socket.write(request_data)

    def transfer_data(self):
        proxy_socket = self.sender()
        socket = proxy_socket.parent()
        socket.write(proxy_socket.readAll())

    def close_connection(self):
        proxy_socket = self.sender()
        if proxy_socket:
            socket = proxy_socket.parent()
            if isinstance(socket, QTcpSocket) and socket:
                socket.disconnectFromHost()
            if proxy_socket.error() != QTcpSocket.RemoteHostClosedError:
                url = proxy_socket.property('url').toUrl()
                error_string = proxy_socket.errorString()

                if self.debug:
                    self.log.write('Error for %s %s\n\n' % (url, error_string))

            proxy_socket.deleteLater()
Exemple #24
0
class SuperGrep(QMainWindow):
    def __init__(self):
        super(SuperGrep, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.tableSearch()
        self.setWindowIcon(QIcon("resources/lupa.png"))
        self.ui.btn_rutaExaminar.setIcon(
            QIcon(QPixmap("resources/carpeta.png")))
        self.ui.btn_rutaExaminar.setLayoutDirection(Qt.RightToLeft)

        self.ui.btn_excluirExaminar.setIcon(
            QIcon(QPixmap("resources/carpeta.png")))
        self.ui.btn_excluirExaminar.setLayoutDirection(Qt.RightToLeft)

        self.ui.btn_buscar.setIcon(QIcon(QPixmap("resources/encontrar.png")))
        self.ui.btn_buscar.setLayoutDirection(Qt.RightToLeft)

        self.ui.btn_rutaExaminar.clicked.connect(
            partial(self.browse, self.ui.txt_ruta))
        self.ui.btn_excluirExaminar.clicked.connect(
            partial(self.browse, self.ui.txt_excluirRuta))
        self.ui.btn_buscar.clicked.connect(self.scan)
        self.ui.btn_pausar.clicked.connect(self.toggle_status)
        self.ui.btn_parar.clicked.connect(self.stop)
        self.ui.tableSearch.currentCellChanged.connect(self.dataRow)
        self.result_search = list()
        self.list_files = list()
        self.count = 0
        self.flag_thread = False

    def browse(self, edit):
        fileName = QFileDialog.getExistingDirectory(self, 'Select directory')
        if fileName:
            edit.setText(fileName)

    def toggle_status(self):
        self.flag_thread = not self.flag_thread
        if self.flag_thread:
            self.pause()
            self.ui.btn_pausar.setText('Start')
        else:
            self.resume()
            self.ui.btn_pausar.setText('Pause')

    def resume(self):
        self.searcher.resume()

    def pause(self):
        self.searcher.pause()

    def stop(self):
        self.searcher.stop()

    def scan(self):
        ruta = self.ui.txt_ruta.text()
        excluido = list()
        excluir_ruta = Path(self.ui.txt_excluirRuta.text())
        self.searcher = Searcher(ruta, self.ui.txt_consulta.text(),
                                 excluir_ruta, excluido)
        self.searcher.updated.connect(self.add_row)
        self.searcher.files.connect(self.countFiles)
        self.searcher.finished.connect(self.endScan)
        self.searcher.start()

    def dataRow(self, row, column):
        # Sumary
        self.ui.tedit_sumary.clear()
        r_files = []
        contador = 0
        self.ui.tedit_sumary.appendHtml("Resultados de la busqueda:  ")

        self.ui.tedit_sumary.appendHtml("<br>Palabra: <b>" +
                                        self.ui.txt_consulta.text() + " <b>")

        for j in range(len(self.result_search)):
            if self.ui.txt_consulta.text() == self.result_search[j][6]:
                if self.result_search[j][0] not in r_files:
                    r_files.append(self.result_search[j][0])
                contador += 1

        self.ui.tedit_sumary.appendHtml("Cantidad coincidencias: " +
                                        str(contador))
        self.ui.tedit_sumary.appendHtml("Cantidad Archivos: " +
                                        str(len(r_files)) + "<br>")

        for r_file in r_files:
            self.ui.tedit_sumary.appendHtml(r_file)
        r_files.clear()

        # hints
        self.ui.tedit_hints.clear()
        self.ui.tedit_hints.appendHtml("<b>Archivo:</b> " +
                                       self.result_search[row][0])
        self.ui.tedit_hints.appendHtml("<b>Extension:</b> " +
                                       self.result_search[row][1])
        self.ui.tedit_hints.appendHtml("<b>Ruta:</b> " +
                                       self.result_search[row][2])
        self.ui.tedit_hints.appendHtml("<b>Palabra encontrada:</b> " +
                                       self.result_search[row][3])
        self.ui.tedit_hints.appendHtml("<b>Palabra buscada:</b> " +
                                       self.result_search[row][6])
        self.ui.tedit_hints.appendHtml("<b>Nro Linea:</b> " +
                                       str(self.result_search[row][4]))
        linea = html.escape(self.result_search[row][5])
        linea = linea.replace(
            self.result_search[row][3],
            "<font color=\"red\">" + self.result_search[row][3] + "</font>")
        self.ui.tedit_hints.appendHtml("<b>Linea:</b> <br><br>" + linea)

    def endScan(self):
        QMessageBox.information(self, "SuperGrep", "Busqueda finalizada",
                                QMessageBox.Ok)

    pyqtSlot(str)

    def countFiles(self, files):
        if files not in self.list_files:
            self.list_files.append(files)
            self.statusBar().showMessage(
                'Archivos buscados: %i    Resultados Encontrados: %i' %
                (len(self.list_files), self.count))

    pyqtSlot(list)

    def add_row(self, result):
        self.count += 1
        self.result_search.append(result)
        rowPosition = self.ui.tableSearch.rowCount()
        self.ui.tableSearch.insertRow(rowPosition)

        header = self.ui.tableSearch.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(2, QHeaderView.ResizeToContents)

        item1 = QTableWidgetItem(result[0])
        item2 = QTableWidgetItem(result[1])
        item3 = QTableWidgetItem(result[2])
        item4 = QTableWidgetItem(result[3])
        item5 = QTableWidgetItem(str(result[4]))

        item1.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter
                               | Qt.AlignCenter)
        item2.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter
                               | Qt.AlignCenter)
        item3.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter
                               | Qt.AlignCenter)
        item4.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter
                               | Qt.AlignCenter)
        item5.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter
                               | Qt.AlignCenter)

        self.ui.tableSearch.setItem(rowPosition, 0,
                                    QTableWidgetItem(item1))  # item1
        self.ui.tableSearch.setItem(rowPosition, 1,
                                    QTableWidgetItem(item2))  # item2
        self.ui.tableSearch.setItem(rowPosition, 2,
                                    QTableWidgetItem(item3))  # item3
        self.ui.tableSearch.setItem(rowPosition, 3,
                                    QTableWidgetItem(item4))  # item4
        self.ui.tableSearch.setItem(rowPosition, 4,
                                    QTableWidgetItem(item5))  # item5

    def tableSearch(self):
        # Deshabilitar edición
        self.ui.tableSearch.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # Deshabilitar el comportamiento de arrastrar y soltar
        self.ui.tableSearch.setDragDropOverwriteMode(False)
        # Seleccionar toda la fila
        self.ui.tableSearch.setSelectionBehavior(QAbstractItemView.SelectRows)
        # Establecer el número de columnas
        self.ui.tableSearch.setColumnCount(5)
        # Establecer el número de filas
        self.ui.tableSearch.setRowCount(0)
        # Alineación del texto del encabezado
        self.ui.tableSearch.horizontalHeader().setDefaultAlignment(
            Qt.AlignHCenter | Qt.AlignVCenter | Qt.AlignCenter)
        # Ocultar encabezado vertical
        self.ui.tableSearch.verticalHeader().setVisible(False)
        nombreColumnas = ('Nombre Archivo', 'Extension', 'Ruta', 'Palabra',
                          'Linea #')
        # Establecer las etiquetas de encabezado horizontal usando etiquetas
        self.ui.tableSearch.setHorizontalHeaderLabels(nombreColumnas)
        # todo los headers de la tabla se ponen del mismo tamaño
        self.ui.tableSearch.horizontalHeader().setSectionResizeMode(
            QHeaderView.Stretch)
Exemple #25
0
 def method(*args, **kwargs):
     return pyqtSlot(*args, **kwargs)
 def enableFindButton(self, text):
     self.findButton.setEnabled(bool(text)) @ pyqtSlot()
Exemple #27
0
from PyQt5.uic import loadUiType
from PyQt5.QtGui import QPixmap, QImage

from graphviz import Digraph

import os.path
from gui.read_data import read_data
from gui.error_message import error
from gui.tablewidget import tw
import pandas as pd
import datetime as dt
from logic.math import *

form_class, base_class = loadUiType(os.path.join(os.path.dirname(__file__), 'main_form.ui'))

scaleUp = pyqtSlot()
scaleDown = pyqtSlot()

class MainWindow(QDialog):
    def __init__(self, *args):
        super(MainWindow, self).__init__(*args)


        self.ui = form_class()
        self.ui.setupUi(self)
        self.ui.tabWidget.setCurrentIndex(0)

        self.graph = Digraph(comment='Когнитивная карта', name='Cognitive map', format='png')
        self.labels = None
        self.matrix = None
Exemple #28
0
class ScanSelector(QObject):

    scan_select_signal = pyqtSignal(ROI)

    params = [
        {
            'title':
            'Scan options',
            'name':
            'scan_options',
            'type':
            'group',
            'children': [
                {
                    'title': 'Sources:',
                    'name': 'sources',
                    'type': 'list',
                },
                {
                    'title': 'Viewers:',
                    'name': 'viewers',
                    'type': 'list',
                },
                {
                    'title': 'Scan type:',
                    'name': 'scan_type',
                    'type': 'list',
                    'values': ['Scan1D', 'Scan2D'],
                    'value': 'Scan2D'
                },
            ]
        },
        {
            'title':
            'Scan Area',
            'name':
            'scan_area',
            'type':
            'group',
            'children': [
                {
                    'title':
                    'ROI select:',
                    'name':
                    'ROIselect',
                    'type':
                    'group',
                    'visible':
                    True,
                    'children': [
                        {
                            'title': 'x0:',
                            'name': 'x0',
                            'type': 'int',
                            'value': 0,
                            'min': 0
                        },
                        {
                            'title': 'y0:',
                            'name': 'y0',
                            'type': 'int',
                            'value': 0,
                            'min': 0
                        },
                        {
                            'title': 'width:',
                            'name': 'width',
                            'type': 'int',
                            'value': 10,
                            'min': 1
                        },
                        {
                            'title': 'height:',
                            'name': 'height',
                            'type': 'int',
                            'value': 10,
                            'min': 1
                        },
                    ]
                },
                {
                    'title': 'Coordinates:',
                    'name': 'coordinates',
                    'type': 'itemselect',
                    'visible': True
                },
            ]
        },
    ]

    def __init__(self, viewer_items=[], scan_type='Scan2D', positions=[]):
        """

        Parameters
        ----------
        viewer_items: dict where the keys are the titles of the sources while the values are dict with keys
                        viewers: list of plotitems
                        names: list of viewer titles
        scan_type: (str) either 'Scan1D' correspondign to a polyline ROI or 'Scan2D' for a rect Roi
        positions: list
                        in case of 'Scan1D', should be a sequence of 2 floats sequence [(x1,y1),(x2,y2),(x3,y3),...]
                        in case of 'Scan2D', should be a sequence of 4 floats (x, y , w, h)
        """
        super(ScanSelector, self).__init__()
        self._viewers_items = viewer_items
        self.sources_names = list(viewer_items.keys())
        if len(viewer_items) != 0:
            self.scan_selector_source = viewer_items[
                self.sources_names[0]]['viewers'][0]
        else:
            self.scan_selector_source = None
        self.scan_selector = None
        self.setupUI()
        self.settings.child('scan_options', 'scan_type').setValue(scan_type)

        self.remove_scan_selector()
        if self.scan_selector_source is not None:
            if len(viewer_items[self.sources_names[0]]['viewers']) == 1:
                self.settings.child('scan_options', 'viewers').hide()
        else:
            self.settings.child('scan_options', 'viewers').hide()
        self.update_scan_area_type()

        if scan_type == "Scan1D" and positions != []:
            self.scan_selector.setPoints(positions)
        elif scan_type == 'Scan2D' and positions != []:
            self.scan_selector.setPos(positions[:2])
            self.scan_selector.setSize(positions[3:])

    @property
    def viewers_items(self):
        return self._viewers_items

    @viewers_items.setter
    def viewers_items(self, items):
        self._viewers_items = items
        self.sources_names = list(items.keys())
        self.scan_selector_source = items[self.sources_names[0]]['viewers'][0]
        self.settings.child('scan_options',
                            'sources').setOpts(limits=self.sources_names)
        viewer_names = self._viewers_items[self.sources_names[0]]['names']
        self.settings.child('scan_options',
                            'viewers').setOpts(limits=viewer_names)

    def show(self, visible=True):
        self.show_scan_selector(visible)
        if visible:
            self.widget.show()
        else:
            self.widget.hide()

    def hide(self):
        self.show(False)

    def setupUI(self):
        self.widget = QtWidgets.QWidget()
        layout = QtWidgets.QVBoxLayout()

        self.settings_tree = ParameterTree()
        layout.addWidget(self.settings_tree, 10)
        self.settings_tree.setMinimumWidth(300)
        self.settings = Parameter.create(name='Settings',
                                         type='group',
                                         children=self.params)
        self.settings_tree.setParameters(self.settings, showTop=False)

        self.settings.child('scan_options',
                            'sources').setOpts(limits=self.sources_names)
        if len(self.viewers_items):
            viewer_names = self._viewers_items[self.sources_names[0]]['names']
        else:
            viewer_names = []
        self.settings.child('scan_options',
                            'viewers').setOpts(limits=viewer_names)

        self.settings.sigTreeStateChanged.connect(self.source_changed)
        self.widget.setLayout(layout)

        #self.widget.show()
        self.widget.setWindowTitle('Scan Selector')

    def source_changed(self, param, changes):
        for param, change, data in changes:
            path = self.settings.childPath(param)
            if path is not None:
                childName = '.'.join(path)
            else:
                childName = param.name()
            if change == 'childAdded':
                pass

            elif change == 'value':
                if param.name() == 'sources' and param.value() is not None:
                    viewer_names = self._viewers_items[param.value()]['names']
                    self.settings.child('scan_options',
                                        'viewers').setOpts(limits=viewer_names)
                    if len(viewer_names) == 1:
                        self.settings.child('scan_options', 'viewers').hide()

                    self.remove_scan_selector()
                    self.scan_selector_source = self._viewers_items[
                        param.value()]['viewers'][0]
                    self.update_scan_area_type()

                if param.name() == 'scan_type':

                    if param.value() == 'Scan1D':
                        self.settings.child('scan_area', 'ROIselect').hide()
                        self.settings.child('scan_area', 'coordinates').show()
                        self.remove_scan_selector()
                        self.update_scan_area_type()
                    else:
                        self.settings.child('scan_area', 'ROIselect').show()
                        self.settings.child('scan_area', 'coordinates').hide()
                        self.remove_scan_selector()
                        self.update_scan_area_type()
                    self.scan_selector.sigRegionChangeFinished.emit(
                        self.scan_selector)

            elif change == 'parent':
                pass

    def remove_scan_selector(self):
        if self.scan_selector_source is not None:
            try:
                self.scan_selector_source.image_widget.plotitem.removeItem(
                    self.scan_selector)
            except:
                pass

    pyqtSlot(str)

    def update_scan_area_type(self):

        if self.settings.child('scan_options',
                               'scan_type').value() == 'Scan1D':
            scan_area_type = 'PolyLines'
        else:
            scan_area_type = 'Rect'

        self.remove_scan_selector()
        if scan_area_type == 'Rect':
            self.scan_selector = RectROI([0, 0], [10, 10])

        elif scan_area_type == 'PolyLines':
            self.scan_selector = PolyLineROI_custom([(0, 0), [10, 10]])
        if self.scan_selector_source is not None:
            self.scan_selector.sigRegionChangeFinished.connect(
                self.update_scan)
            self.scan_selector_source.image_widget.plotitem.addItem(
                self.scan_selector)
            self.show_scan_selector()

            self.scan_selector.sigRegionChangeFinished.emit(self.scan_selector)

    def show_scan_selector(self, visible=True):
        self.scan_selector.setVisible(visible)

    def update_scan(self, roi):
        if self.scan_selector_source is not None:
            if isinstance(roi, RectROI):
                self.settings.child('scan_area', 'ROIselect',
                                    'x0').setValue(roi.pos().x())
                self.settings.child('scan_area', 'ROIselect',
                                    'y0').setValue(roi.pos().y())
                self.settings.child('scan_area', 'ROIselect',
                                    'width').setValue(roi.size().x())
                self.settings.child('scan_area', 'ROIselect',
                                    'height').setValue(roi.size().y())
            elif isinstance(roi, PolyLineROI_custom):
                self.settings.child('scan_area', 'coordinates').setValue(
                    dict(all_items=[
                        '({:.03f} , {:.03f})'.format(pt.x(), pt.y())
                        for pt in roi.get_vertex()
                    ],
                         selected=[]))

            self.scan_select_signal.emit(roi)
Exemple #29
0
class ImageProc(QMainWindow):
    def __init__(self):

        super(ImageProc,self).__init__()
        loadUi('showgui.ui',self)
        self.image=None
        newImage=None
        self.loadButton.clicked.connect(self.loadClicked)
        self.saveButton.clicked.connect(self.saveClicked)
        self.action_Load_Image.triggered.connect(self.loadClicked)
        self.action_Save_Image.triggered.connect(self.saveClicked)
        self.actionGrayscale.triggered.connect(self.grayClicked)
        self.actionBrightness.triggered.connect(self.brightClicked)
        self.actionSimple_Contrast.triggered.connect(self.contrastClicked)
        self.actionAuto_Contrast_2.triggered.connect(self.autocontrastClicked)
        self.actionNegative_Image.triggered.connect(self.negatifClicked)
        self.actionGrayscale_Histogram.triggered.connect(self.GrayHistogramClicked)
        self.actionRGB_Histogram.triggered.connect(self.RGBHistogramClicked)
        self.actionBiner_Image.triggered.connect(self.BinerClicked)
        self.actionPerataan_Histogram.triggered.connect(self.EqualHistogramClicked)
        self.action_min_45_Derajat.triggered.connect(self.RotasiMin45Clicked)
        self.action_plus_45Derajat.triggered.connect(self.RotasiPlus45Clicked)
        self.action_Min_90_Derajat.triggered.connect(self.RotasiMin90Clicked)
        self.action_plus_90_Derajat .triggered.connect(self.RotasiPlus90Clicked)
        self.action180_Derajat.triggered.connect(self.Rotasi180Clicked)
        self.actionTranslasi.triggered.connect(self.TranslasiClicked)
        self.actionTranspose.triggered.connect(self.TransposeClicked)
        self.actionLinear_Interpolation.triggered.connect(self.Linear_InterpolationClicked)
        self.actionCubic_Interppolation.triggered.connect(self.Cubic_InterppolationClicked)
        self.actionSkewed_Size.triggered.connect(self.skewed_SizeClicked)
        self.actionCroping.triggered.connect(self.CropingClicked)
        self.actionPenambahan_Citra.triggered.connect(self.aritmatika_CitraClicked)
        self.actionLogika_Not.triggered.connect(self.Logika_NotClicked)
        self.actionLogika_AND.triggered.connect(self.Logika_ANDClicked)
        self.actionSmoothing_Image.triggered.connect(self.SmoothClicked)
        self.actionSharpening_Image.triggered.connect(self.SharpClicked)
        self.actionMean.triggered.connect(self.MeanClicked)
        self.actionMedian.triggered.connect(self.MedianClicked)
        self.actionMax_Filter.triggered.connect(self.MaxClicked)
        self.actionMin_Filter.triggered.connect(self.MinClicked)
        self.actionSobel.triggered.connect(self.SobelClicked)
        self.actionPrewitt.triggered.connect(self.PrewittClicked)
        self.actionCanny.triggered.connect(self.CannyClicked)


    @pyqtSlot()
    def loadClicked(self):
        flname,filter=QFileDialog.getOpenFileName(self,'Open File','D:\\Programming\\Python',"Image Files (*.jpg)")
        if flname:
            self.loadImage(flname)
        else:
            print('Invalid Image')

    @pyqtSlot()
    def saveClicked(self):
        flname, filter = QFileDialog.getSaveFileName(self, 'Save File', 'D:\\', "Image Files (*.jpg)")
        if flname:
            cv2.imwrite(flname, self.image)
        else:
            print('Error')

    @pyqtSlot()
    def grayClicked(self):

        H, W = self.image.shape[:2]
        gray = np.zeros((H, W), np.uint8)
        for i in range(H):
            for j in range(W):
                gray[i,j]= np.clip(0.299 * self.image[i, j, 0] + 0.587 * self.image[i, j, 1] + 0.114 * self.image[i, j, 2], 0, 255)
        self.image=gray
        self.displayImage(2)

    @pyqtSlot()
    def brightClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        brightness = 50
        h, w = img.shape[:2]
        for i in np.arange(h):
            for j in np.arange(w):
                a = img.item(i, j)
                b = a + brightness
                if b > 255:
                    b = 255
                elif b < 0:
                    b = 0
                else:
                    b = b

                img.itemset((i, j), b)
        self.image = img
        self.displayImage(2)

    @pyqtSlot()  # contrast
    def contrastClicked(self):
        gray = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        height = gray.shape[0]
        width = gray.shape[1]

        contrast = 1.6

        for i in np.arange(height):
            for j in np.arange(width):
                a = gray.item(i, j)
                b = math.ceil(a * contrast)
                if b > 255:
                    b = 255
                gray.itemset((i, j), b)
        self.image = gray
        self.displayImage(2)

    @pyqtSlot()
    def autocontrastClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        h, w = img.shape[:2]

        min = 255
        max = 0

        for i in np.arange(h):
            for j in np.arange(w):
                a = img.item(i, j)
                if a > max:
                    max = a
                if a < min:
                    min = a

        for i in np.arange(h):
            for j in np.arange(w):
                a = img.item(i, j)
                b = float(a - min) / (max - min) * 255
                img.itemset((i, j), b)

        self.image = img
        self.displayImage(2)

    @pyqtSlot()
    def BinerClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        thres=100
        h, w = img.shape[:2]
        for i in np.arange(h):
            for j in np.arange(w):
                a=img.item(i,j)
                if a > thres:
                    a = 1
                else:
                    a = 0
                img.itemset((i,j),a)
                print(img)

        self.image = img
        self.displayImage(2)



    @pyqtSlot()
    def negatifClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        h, w = img.shape[:2]
        max_intensity = 255
        for i in range(h):
            for j in range(w):
                a = img.item(i, j)
                b = max_intensity - a
                img.itemset((i, j), b)
        self.image = img
        self.displayImage(2)

    @pyqtSlot()
    def GrayHistogramClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        self.image = img
        self.displayImage(2)
        plt.hist(img.ravel(), 255, [0, 255])
        plt.show()

    @pyqtSlot()
    def RGBHistogramClicked(self):
        color = ('b', 'g', 'r')
        for i,col in enumerate(color):
            histo=cv2.calcHist([self.image],[i],None,[256],[0,256])
            plt.plot(histo,color=col)
            plt.xlim([0,256])
        plt.show()

    @pyqtSlot()
    def EqualHistogramClicked(self):
        hist, bins = np.histogram(self.image.flatten(), 256, [0, 256])
        cdf = hist.cumsum()
        cdf_normalized = cdf * hist.max() / cdf.max()
        cdf_m = np.ma.masked_equal(cdf, 0)
        cdf_m = (cdf_m - cdf_m.min()) * 255 / (cdf_m.max() - cdf_m.min())
        cdf = np.ma.filled(cdf_m, 0).astype('uint8')
        self.image = cdf[self.image]
        self.displayImage(2)

        plt.plot(cdf_normalized, color='b')
        plt.hist(self.image.flatten(), 256, [0, 256], color='r')
        plt.xlim([0, 256])
        plt.legend(('cdf', 'histogram'), loc='upper left')
        plt.show()

#-------------------------------------------------Operation Geometry----------------------------------------------------------------------#

    @pyqtSlot()
    def TranslasiClicked(self):
        h,w=self.image.shape[:2]
        print(h)
        print(w)
        quarter_h,quarter_w=h/4,w/4
        print(quarter_h)
        print(quarter_w)
        T=np.float32([[1,0,quarter_w],[0,1,quarter_h]])
        print(T)
        img=cv2.warpAffine(self.image,T,(w,h))

        # sx=45
        # sy=-35
        # img=cv2.cvtColor(self.image,cv2.COLOR_BGR2RGB)
        # h,w=img.shape[:2]
        # for y in np.arange(1,h):
        #     for x in np.arange(1,w):
        #         xlama=x+sx
        #         ylama=y+sy
        #         img[ylama,xlama]

        self.image = img
        self.displayImage(2)

    @pyqtSlot()
    def RotasiMin45Clicked(self):
        self.rotasi(45)
        self.displayImage(2)

    @pyqtSlot()
    def RotasiPlus45Clicked(self):
        self.rotasi(-45)
        self.displayImage(2)

    @pyqtSlot()
    def RotasiMin90Clicked(self):
        self.rotasi(-90)
        self.displayImage(2)

    @pyqtSlot()
    def RotasiPlus90Clicked(self):
        self.rotasi(90)
        self.displayImage(2)

    @pyqtSlot()
    def Rotasi180Clicked(self):
        self.rotasi(180)
        self.displayImage(2)

    def rotasi(self,degree):
        h, w = self.image.shape[:2]

        rotationMatrix = cv2.getRotationMatrix2D((w / 2, h / 2), degree, .7)
        cos = np.abs(rotationMatrix[0, 0])
        sin = np.abs(rotationMatrix[0, 1])

        nW = int((h * sin) + (w * cos))
        nH = int((h * cos) + (w * sin))

        rotationMatrix[0, 2] += (nW / 2) - w / 2
        rotationMatrix[1, 2] += (nH / 2) - h / 2
        rot_image = cv2.warpAffine(self.image, rotationMatrix, (h, w))
        self.image=rot_image

    @pyqtSlot()
    def TransposeClicked(self):
        trans_img=cv2.transpose(self.image)
        self.image=trans_img
        self.displayImage(2)

    @pyqtSlot()
    def Linear_InterpolationClicked(self):
        #make size 3/4 original image size
        cv2.imshow('Original',self.image)
        resize_img=cv2.resize(self.image,None,fx=0.50, fy=0.50)
        self.image=resize_img
        cv2.imshow('',self.image)
        #self.displayImage(2)

    @pyqtSlot()
    def Cubic_InterppolationClicked(self):
        #double size of original image size/zooming(scaling up)
        cv2.imshow('Original', self.image)
        resize_img=cv2.resize(self.image,None,fx=2,fy=2,interpolation=cv2.INTER_CUBIC)
        self.image = resize_img
        cv2.imshow('',self.image)
        #self.displayImage(2)

    @pyqtSlot()
    def skewed_SizeClicked(self):
        #resize image based on exacat dimension
        cv2.imshow('Original', self.image)
        resize_img=cv2.resize(self.image,(900,400),interpolation=cv2.INTER_AREA)
        self.image=resize_img
        cv2.imshow('',self.image)
        #self.displayImage(2)

    @pyqtSlot()
    def CropingClicked(self):
        h,w=self.image.shape[:2]
        #get the strating point of pixel coord(top left)
        start_row, start_col=int(h*.1),int(w*.1)
        #get the ending point coord (botoom right)
        end_row, end_col=int(h*.5),int(w*.5)
        crop=self.image[0:1000,0:500]
        cv2.imshow('Original',self.image)
        cv2.imshow('Crop Image',crop)

#-----------------------------------operasi aritmatika---------------------------------------------------
    @pyqtSlot()
    def aritmatika_CitraClicked(self):
        img1 = cv2.imread('img1.jpg', 0)
        img2 = cv2.imread('img2.jpg', 0)
        # img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
        # img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)
        add_img = img1 + img2
        subtract = img1 - img2
        subtract2=img2-img1
        mul = img1 * img2
        div = img1 / img2

        # titles=['Image 1','Image 2','Add','Subtract (1-2)','Subtract(2-1)','Multiply','Divided']
        # images=[img1,img2,add_img,subtract,subtract2,mul,div]
        # print()
        #
        # for i in range(8):
        #     plt.subplot(1,8,i+1)
        #     plt.imshow(images[i])
        #     plt.title(titles[i])
        #     plt.xticks([])
        #     plt.yticks([])
        # plt.show()
        cv2.imshow('Image 1', img1)
        cv2.imshow('Image 2', img2)
        cv2.imshow('Add', add_img)
        cv2.imshow('Subtraction', subtract)
        cv2.imshow('Multiply', mul)
        cv2.imshow('Divide', div)

    @pyqtSlot()
    def Logika_NotClicked(self):
        #
        img=cv2.cvtColor(self.image,cv2.COLOR_BGR2GRAY)
        #cv2.bitwise_not(img)
        img=cv2.bitwise_not(img)
        self.image=img
        self.displayImage(2)
        #
        # img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        # thres = 100
        # h, w = img.shape[:2]
        # for i in np.arange(h):
        #     for j in np.arange(w):
        #         a = img.item(i, j)
        #         if a > thres:
        #             a = 255
        #         elif a < thres:
        #             a = 0
        #         else:
        #             a = a
        #         img=img.itemset((i, j), a)
        #         img2=cv2.bitwise_not(img)
        #
        # self.image=img2
        # self.displayImage(2)


    @pyqtSlot()
    def Logika_ANDClicked(self):
        img1 = cv2.imread('img1.jpg', 1)
        img2 = cv2.imread('img2.jpg', 1)
        img1=cv2.cvtColor(img1,cv2.COLOR_BGR2RGB)
        img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)
        op_and=cv2.bitwise_and(img1,img2)
        op_or=cv2.bitwise_or(img2,img2)
        op_xor=cv2.bitwise_xor(img1,img2)

        cv2.imshow('Image 1', img1)
        cv2.imshow('Image 2', img2)
        cv2.imshow('And', op_and)
        cv2.imshow('OR', op_or)
        cv2.imshow('XOR', op_xor)

#--------------------------------------------------------OPERASI SPASIAL------------------------------------------------------------------#
    @pyqtSlot()
    def SmoothClicked(self):
        img=cv2.cvtColor(self.image,cv2.COLOR_BGR2GRAY)
        #h,w=img.shape[:2]
        gauss =(1.0 / 57)* np.array(
            [[0, 1, 2, 1, 0],
             [1, 3, 5, 3, 1],
             [2, 5, 9, 5, 2],
             [1, 3, 5, 3, 1],
             [0, 1, 2, 1, 0]])

        img_out=conv(img,gauss)

        #
        # #cv2.imshow('',img_out)
        # self.image=img_out
        # self.displayImage(i)

        plt.imshow(img_out,cmap='gray',interpolation='bicubic')
        plt.xticks([],plt.yticks([]))
        plt.show()

    pyqtSlot()
    def SharpClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        laplace = (1.0 / 16) * np.array(
            [[0, 0, -1, 0, 0],
             [0, -1, -2, -1, 0],
             [-1, -2, 16, -2, -1],
             [0, -1, -2, -1, 0],
             [0, 0, -1, 0, 0]])

        img_out = conv(img, laplace)

        plt.imshow(img_out, cmap='gray', interpolation='bicubic')
        plt.xticks([], plt.yticks([]))
        plt.show()

    pyqtSlot()
    def MeanClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        laplace = (1.0 / 9) * np.array(
            [[1, 1, 1, 1, 1],
             [1, 1, 1, 1, 1],
             [1, 1, 1, 1, 1],
             [1, 1, 1, 1, 1],
             [1, 1, 1, 1, 1]])

        img_out = conv(img, laplace)

        plt.imshow(img_out, cmap='gray', interpolation='bicubic')
        plt.xticks([], plt.yticks([]))
        plt.show()

    pyqtSlot()
    def MedianClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        img_out=img.copy()
        h,w=img.shape[:2]

        for i in np.arange(3,h-3):
            for j in np.arange(3,w-3):
                neighbors=[]
                for k in np.arange(-3,4):
                    for l in np.arange(-3,4):
                        a=img.item(i+k, j+l)
                        neighbors.append(a)
                neighbors.sort()
                median=neighbors[24]
                b=median
                img_out.itemset((i,j),b)

        plt.imshow(img_out, cmap='gray', interpolation='bicubic')
        plt.xticks([], plt.yticks([]))
        plt.show()

    @pyqtSlot()
    def MaxClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        img_out = img.copy()
        h, w = img.shape[:2]

        for i in np.arange(3, h - 3):
            for j in np.arange(3, w - 3):
                max = 0
                for k in np.arange(-3, 4):
                    for l in np.arange(-3, 4):
                        a = img.item(i + k, j + l)
                        if a > max:
                            max=a
                b=max
                img_out.itemset((i, j), b)

        plt.imshow(img_out, cmap='gray', interpolation='bicubic')
        plt.xticks([], plt.yticks([]))
        plt.show()

    @pyqtSlot()
    def MinClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        img_out = img.copy()
        h, w = img.shape[:2]

        for i in np.arange(3, h - 3):
            for j in np.arange(3, w - 3):
                min = 255
                for k in np.arange(-3, 4):
                    for l in np.arange(-3, 4):
                        a = img.item(i + k, j + l)
                        if a < min:
                            min=a
                b=min
                img_out.itemset((i, j), b)

        plt.imshow(img_out, cmap='gray', interpolation='bicubic')
        plt.xticks([], plt.yticks([]))
        plt.show()
#--------------------------------------------------------ANALISIS CITRA------------------------------------------------------------------------------#
    @pyqtSlot()
    def SobelClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        Sx = np.array([[-1, 0, 1],
                       [-2, 0, 2],
                       [-1, 0, 1]])

        Sy = np.array([[-1, -2, -1],
                       [0, 0, 0],
                       [1, 2, 1]])
        img_x = conv(img,Sx)/8.0
        img_y = conv(img,Sy)/8.0
        img_out = np.sqrt(np.power(img_x, 2) + np.power(img_y, 2))
        img_out = (img_out / np.max(img_out)) * 255

        self.image=img

        self.displayImage(2)
        plt.imshow(img_out, cmap='gray', interpolation='bicubic')
        plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
        plt.show()

    @pyqtSlot()
    def PrewittClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)

        Px = np.array([[-1, 0, 1],
                       [-1, 0, 1],
                       [-1, 0, 1]])
        Py = np.array([[-1, -1, -1],
                       [0, 0, 0],
                       [1, 1, 1]])

        img_x = conv(img, Px) / 6.0
        img_y = conv(img, Py) / 6.0

        img_out = np.sqrt(np.power(img_x, 2) + np.power(img_y, 2))
        img_out = (img_out / np.max(img_out)) * 255

        self.image = img
        self.displayImage(2)

        plt.imshow(img_out,cmap = 'gray',interpolation='bicubic')
        plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
        plt.show()

    @pyqtSlot()
    def CannyClicked(self):
        img = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        h,w=img.shape[:2]

        #step 1: reduce noise with Gaussian Filter
        gauss = (1.0 / 57) * np.array(
            [[0, 1, 2, 1, 0],
             [1, 3, 5, 3, 1],
             [2, 5, 9, 5, 2],
             [1, 3, 5, 3, 1],
             [0, 1, 2, 1, 0]])

        img_blur = conv(img, gauss)

        #step 2: Finding Gradien
        img_x=conv(img_blur,np.array([[-0.5,0,0.5]]))
        img_y=conv(img_blur,np.array([[-0.5,0,0.5]]))

        E_mag=np.sqrt(np.power(img_x,2)+np.power(img_y,2))
        E_mag=(E_mag/np.max(E_mag))*255

        #step 3: non-maximum suppresion
        t_low=4
        E_nms=np.zeros((h,w))
        for i in np.arange(1,h-1):
            for j in np.arange(1,w-1):
                dx=img_x[i,j]
                dy=img_y[i,j]
                s_theta=fg.FindingGradien(dx,dy)

                if locmax.MaxSuppesion(E_mag,i,j,s_theta,t_low):
                    E_nms[i,j]=E_mag[i,j]

        #step 4: Hysterisis Thresholding
        t_high=15
        E_bin=np.zeros((h,w))
        for i in np.arange(1,h-1):
            for j in np.arange(1,w-1):
                if E_nms[i,j]>=t_high and E_bin[i,j]==0:
                    ht.HysterisisThres(E_nms,E_bin,i,j,t_low)

        self.image=img
        self.displayImage(2)

        plt.imshow(E_bin,cmap='gray', interpolation='bicubic')
        plt.xticks([]),plt.yticks([])
        plt.show()










#--------------------------------------------------------FUNGSI UMUM----------------------------------------------------------------------#

    def loadImage(self,flname):
        self.image=cv2.imread(flname,cv2.IMREAD_COLOR)
        self.displayImage()

    def displayImage(self, windows=1):
        qformat=QImage.Format_Indexed8

        if len(self.image.shape)==3:
            if(self.image.shape[2])==4:
                qformat=QImage.Format_RGBA8888
            else:
                qformat=QImage.Format_RGB888
        img=QImage(self.image,self.image.shape[1],self.image.shape[0],self.image.strides[0],qformat)

        #BGR>RGB
        img=img.rgbSwapped()
        if windows==1:
            self.imgLabel.setPixmap(QPixmap.fromImage(img))
            self.imgLabel.setAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter)
            self.imgLabel.setScaledContents(True)
        if windows==2:
            self.hasilLabel.setPixmap(QPixmap.fromImage(img))
            self.hasilLabel.setAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter)
            self.hasilLabel.setScaledContents(True)
Exemple #30
0
class MainWindow(QMainWindow, Ui_MainWindow):
    """
    Class documentation goes here.
    """
    def __init__(self, parent=None):
        """
        Constructor

        @param parent reference to the parent widget (QWidget)
        """
        QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.progressBar = QProgressBar()
        self.progressBar.setMaximum(0)
        self.progressBar.setMaximum(0)
        self.progressBar.setEnabled(False)
        self.statusBar.addPermanentWidget(self.progressBar)
        self.statusBar.showMessage(_translate("MainWindow",
                                              "Welcome to PyDSF"))
        self.buttonBox_process.addButton(
            _translate("MainWindow", "&Start Processing"),
            QDialogButtonBox.AcceptRole)
        self.tasks = Tasks()
        self.tasks.signals.finished.connect(self.on_processing_finished)
        self.worker = None
        self.outputPath = None
        self.instrument = None
        self.populateInstrumentList()

    def populateInstrumentList(self):
        self.instruments = [AnalytikJenaqTower2()]
        for i in range(len(self.instruments)):
            instrument = self.instruments[i]
            self.comboBox_instrument.setItemText(i, instrument.name)

    def getInstrumentFromName(self, name):
        for instrument in self.instruments:
            if instrument.name == name:
                return instrument
        raise IndexError("Requested instrument not")

    def getSelectedInstrument(self):
        name = str(self.comboBox_instrument.currentText())
        instrument = self.getInstrumentFromName(name)
        return instrument

    @pyqtSlot("QAbstractButton*")
    def on_buttonBox_open_reset_clicked(self, button):
        """
        Triggered when either the open or reset button in the data file
        dialog is clicked. Spawns an open file dialog or resets the listview.
        """
        if button == self.buttonBox_open_reset.button(QDialogButtonBox.Open):
            filenames = QFileDialog.getOpenFileNames(
                self, _translate("MainWindow", "Open data file"), '',
                _translate("MainWindow", "Text files (*.txt *.csv)"))
            self.listWidget_data.addItems(filenames[0])
            if self.listWidget_data.count() > 1:
                self.groupBox_replicates.setChecked(True)
                self.radioButton_rep_files.setEnabled(True)
        elif button == self.buttonBox_open_reset.button(
                QDialogButtonBox.Reset):
            self.listWidget_data.clear()

    @pyqtSlot("QAbstractButton*")
    def on_buttonBox_output_clicked(self, button):
        if button == self.buttonBox_output.button(QDialogButtonBox.Open):
            caption = _translate('MainWindow', 'Choose output path')
            path = QFileDialog.getExistingDirectory(
                parent=self, caption=caption, options=QFileDialog.ShowDirsOnly)
            self.lineEdit_output.setText(path.strip())

    @pyqtSlot("QString")
    def on_comboBox_instrument_currentIndexChanged(self, p0):
        """
        Triggered when another instrument is selected from the combobox.
        """
        self.instrument = self.getInstrumentFromName(p0)
        if self.instrument.providesTempRange:
            self.groupBox_temp.setEnabled(False)
        else:
            self.groupBox_temp.setEnabled(True)

    def generate_plot_tab(self, name):
        tab = MplWidget(parent=self.tabWidget)
        tab.setObjectName(name)
        return tab

    def remove_plate_tabs(self):
        for i in range(self.tabWidget.count()):
            try:
                widget = self.tabWidget.widget(i)
                widget.deleteLater()
            except IndexError:
                pass
        self.tabWidget.clear()

    def generate_plate_tabs(self, plate):
        plotter = PlotResults()

        if plate.id != 'average':
            tab = self.generate_plot_tab("tab_heatmap_{}".format(plate.id))
            title = _translate("MainWindow", "Heatmap #")
            self.tabWidget.addTab(tab, title + str(plate.id))
            plotter.plot_tm_heatmap_single(plate, tab)
            if self.checkBox_saveplots.isChecked():
                tab.canvas.save("{}/heatmap_{}.svg".format(
                    self.outputPath, plate.id))

            tab = self.generate_plot_tab("tab_raw_{}".format(plate.id))
            title = _translate("MainWindow", "Raw Data #")
            self.tabWidget.addTab(tab, title + str(plate.id))
            plotter.plot_raw(plate, tab)
            if self.checkBox_saveplots.isChecked():
                tab.canvas.save("{}/raw_{}.svg".format(self.outputPath,
                                                       plate.id))

            tab = self.generate_plot_tab("tab_derivative_{}".format(plate.id))
            title = _translate("MainWindow", "Derivatives #")
            self.tabWidget.addTab(tab, title + str(plate.id))
            plotter.plot_derivative(plate, tab)
            if self.checkBox_saveplots.isChecked():
                tab.canvas.save("{}/derivatives_{}.svg".format(
                    self.outputPath, plate.id))
        else:
            tab = self.generate_plot_tab("tab_heatmap_{}".format(plate.id))
            title = _translate("MainWindow", "Heatmap ")
            self.tabWidget.addTab(tab, title + str(plate.id))
            plotter.plot_tm_heatmap_single(plate, tab)
            if self.checkBox_saveplots.isChecked():
                tab.canvas.save("{}/heatmap_{}.svg".format(
                    self.outputPath, plate.id))

    @pyqtSlot()
    def on_buttonBox_process_accepted(self):
        """
        Slot documentation goes here.
        """

        self.remove_plate_tabs()
        self.instrument = self.getSelectedInstrument()

        if self.listWidget_data.count() < 1:
            QMessageBox.critical(
                self, _translate("MainWindow", "Error"),
                _translate("MainWindow", "No data file loaded!"),
                QMessageBox.Close, QMessageBox.Close)
            return
        if (self.groupBox_output.isChecked()
                and self.lineEdit_output.text().strip() == ''):
            QMessageBox.critical(
                self, _translate("MainWindow", "Error"),
                _translate("MainWindow", "No output path set!"),
                QMessageBox.Close, QMessageBox.Close)
            return
        elif (self.groupBox_output.isChecked()
              and self.lineEdit_output.text().strip() != ''):
            path = self.lineEdit_output.text().strip()
            if os.path.isdir(path):
                self.outputPath = self.lineEdit_output.text().strip()
            else:
                QMessageBox.critical(
                    self, _translate("MainWindow", "Error"),
                    _translate("MainWindow", "Output path does not exist!"),
                    QMessageBox.Close, QMessageBox.Close)

        if self.spinBox_signal_threshold.value(
        ) == 0 and self.groupBox_signal_threshold.isChecked():
            QMessageBox.warning(
                self, _translate("MainWindow", "Warning"),
                _translate("MainWindow",
                           "Signal threshold is currently set to zero."),
                QMessageBox.Ok, QMessageBox.Ok)

        self.progressBar.setEnabled(True)
        self.statusBar.showMessage(_translate("MainWindow", "Processing..."))

        self.worker = Worker(self)
        self.tasks.add_task(self.worker)
        self.tasks.start()

    @pyqtSlot()
    def on_processing_finished(self):
        # Clear all jobs from task list
        # self.tasks.clear()
        # For now, only read the first entry
        exp = self.tasks.data[0]
        # clear data in tasks object
        self.tasks.clear_data()

        for i in range(len(self.worker.exp.plates)):

            plate = exp.plates[i]
            self.generate_plate_tabs(plate)

        if exp.avg_plate:

            plate = exp.avg_plate
            self.generate_plate_tabs(plate)

        if self.groupBox_output.isChecked():
            if self.checkBox_savetables.isChecked():
                for plate in exp.plates:
                    plate.write_tm_table('{}/plate_{}_tm.csv'.format(
                        self.outputPath, str(plate.id)))
                    plate.write_data_table('{}/plate_{}_dI_dT.csv'.format(
                        self.outputPath, str(plate.id)),
                                           dataType='derivative')
                    plate.write_data_table(
                        '{}/plate_{}_filtered_data.csv'.format(
                            self.outputPath, str(plate.id)),
                        dataType='filtered')
                    plate.write_data_table('{}/plate_{}_raw_data.csv'.format(
                        self.outputPath, str(plate.id)))

                if exp.avg_plate:
                    exp.avg_plate.write_tm_table(
                        '{}/plate_{}_tm_avg.csv'.format(
                            self.outputPath,
                            str(self.worker.exp.avg_plate.id)),
                        avg=True)

        self.progressBar.setEnabled(False)
        self.statusBar.showMessage(_translate("MainWindow", "Finished!"))

    @pyqtSlot()
    def on_buttonBox_process_rejected(self):
        """
        Slot documentation goes here.
        """
        QApplication.quit()

    pyqtSlot()

    def on_actionQuit_triggered(self):
        """
        Slot documentation goes here.
        """
        QApplication.quit()

    @pyqtSlot("bool")
    def on_groupBox_cutoff_toggled(self):
        """
        Slot documentation goes here.
        """
        self.doubleSpinBox_upper.setValue(self.doubleSpinBox_tmax.value())
        self.doubleSpinBox_lower.setValue(self.doubleSpinBox_tmin.value())

    @pyqtSlot()
    def on_actionAbout_triggered(self):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        dialog = QDialog()
        dialog.ui = Ui_DialogAbout()
        dialog.ui.setupUi(dialog)
        dialog.exec_()

    @pyqtSlot()
    def on_actionAbout_Qt_triggered(self):
        """
        Slot documentation goes here.
        """
        QApplication.aboutQt()
Exemple #31
0
class mainForm(QMainWindow):
    get_template_filename = pyqtSignal(str)
    exit_program = pyqtSignal()
    camera_changed = pyqtSignal(int)

    def __init__(self):
        super().__init__()
        self.stream = None
        self.image_difference_thread = None
        self.template_set = False
        self._countour_max_tresh = 10
        self._countour_min_tresh = 1
        self._transparency_max = 10
        self._transparency_min = 0
        self._countour_gamma_max = 10
        self._countour_gamma_min = 1
        self._color_max = 255
        self._color_min = 0
        self.screen_resolution = None
        self.grid_layout = None
        self.output_picture = None
        self.initUI()
        self.init_image_difference()
        if self.webcam_switcher.count() > 0:
            self.stream = streamCapture(self.webcam_switcher.itemData(self.webcam_switcher.currentIndex()))
            self.stream.getframe.connect(self.mat2qimage)
            self.webcam_switcher.currentIndexChanged.connect(self.camera_switcher_index_changed)
            self.camera_changed.connect(self.stream.reopenStream)
            self.stream.start()
            self.exit_program.connect(self.stream.exit)

    ### отрисовка интерфейса
    def initUI(self):
        self.screen_resolution = QApplication.desktop().screenGeometry()
        # self.resize(self.screen_resolution.size())
        # self.move(self.screen_resolution.left(), self.screen_resolution.top())
        self.grid_layout = QGridLayout()

        self.central_widget = QWidget()
        self.central_widget.setLayout(self.grid_layout)
        self.central_widget.setMaximumSize(self.screen_resolution.width() // 4 * 3,
                                           self.screen_resolution.height() // 4 * 3)
        self.setCentralWidget(self.central_widget)

        self.camera_label = QLabel("Camera:")
        self.grid_layout.addWidget(self.camera_label, 0, 0, 1, 1, Qt.AlignmentFlag.AlignHCenter)

        self.webcam_switcher = QComboBox()
        self.detect_webcam_devices(self.webcam_switcher)
        self.grid_layout.addWidget(self.webcam_switcher, 0, 1, 1, 3)

        self.output_picture = QLabel()
        self.grid_layout.addWidget(self.output_picture, 1, 0, 1, 4)

        ### creating right dock
        self.right_dock_layout = QVBoxLayout()

        self.right_dock_widget = QDockWidget()
        self.right_dock_widget.setFeatures(QDockWidget.DockWidgetFeature.DockWidgetMovable | QDockWidget.DockWidgetFeature.DockWidgetFloatable)
        self.right_dock_widget.setMinimumSize(self.screen_resolution.width() // 4, self.screen_resolution.height())
        right_dock = QWidget(self.right_dock_widget)
        right_dock.setMinimumSize(self.screen_resolution.width() // 4, self.screen_resolution.height())
        right_dock.setLayout(self.right_dock_layout)

        template_label = QLabel("Templates")
        template_label.setMinimumSize(50, 25)
        self.right_dock_layout.addWidget(template_label)

        self.filter_template_edit = QLineEdit()
        self.filter_template_edit.setPlaceholderText("Filter (Ctr + Alt + f)")
        template_label.setMinimumSize(90, 25)
        self.filter_template_edit.setStyleSheet(
            "background-image: url(../image_difference/icons/searchIcon.png); background-repeat: no-repeat; background-position: right;")

        self.right_dock_layout.addWidget(self.filter_template_edit)

        self.file_system_model = QFileSystemModel()
        self.file_system_model.setFilter(QDir.Filter.AllDirs | QDir.Filter.NoDotAndDotDot | QDir.Filter.AllEntries)
        self.file_system_model.setRootPath(QDir.currentPath())

        self.directory_tree_view = QTreeView()
        self.directory_tree_view.setModel(self.file_system_model)
        self.directory_tree_view.setMinimumSize(200, 100)
        self.directory_tree_view.hideColumn(1)
        self.directory_tree_view.hideColumn(2)
        self.directory_tree_view.hideColumn(3)
        # self.directory_tree_view.sortByColumn(0)
        self.directory_tree_view.setSortingEnabled(True)
        self.directory_tree_view.doubleClicked.connect(self.load_template)
        self.directory_tree_view.setRootIndex(self.file_system_model.index("../image_difference/"))

        self.right_dock_layout.addWidget(self.directory_tree_view)

        self.load_template_button = QPushButton("Select Template")
        self.load_template_button.setMaximumSize(self.screen_resolution.width() // 4 - 30, 30)
        self.load_template_button.clicked.connect(self.load_template)

        self.right_dock_layout.addWidget(self.load_template_button)

        self.create_template_button = QPushButton("Create Template")
        self.create_template_button.setMaximumSize(self.screen_resolution.width() // 4 - 30, 30)
        self.create_template_button.clicked.connect(self.create_template)

        self.right_dock_layout.addWidget(self.create_template_button)

        self.template_image_widget = QWidget()
        self.template_image_widget.setMinimumSize(self.screen_resolution.width() // 4 - 20,
                                                  self.screen_resolution.width() // 4 - 10)

        self.template_image_back = QLabel(self.template_image_widget)
        self.template_image_back.resize(self.screen_resolution.width() // 4 - 20,
                                        self.screen_resolution.width() // 4 - 10)
        pix = QPixmap(self.template_image_back.size())
        pix.fill(Qt.lightGray)
        rect = QRectF(0.0, 0.0, self.template_image_back.size().width(), self.template_image_back.size().height())
        painter = QPainter()
        painter.begin(pix)
        painter.setRenderHints(QPainter.Antialiasing, True)
        path = QPainterPath()
        path.addRoundedRect(rect, 5.0, 5.0)
        painter.drawPath(path)
        painter.end()
        self.template_image_back.setPixmap(pix)

        self.template_image = QLabel(self.template_image_widget)
        self.template_image.move(5, 5)
        self.template_image.resize(self.screen_resolution.width() // 4 - 30, self.screen_resolution.width() // 4 - 30)

        self.template_image_text = QLabel(self.template_image_widget, text="Current Template")
        self.template_image_text.setStyleSheet("font-weight: bold")
        self.template_image_text.move(self.screen_resolution.width() // 8 - 65, 20)

        self.right_dock_layout.addWidget(self.template_image_widget)

        self.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, self.right_dock_widget)

        ### creating bottom dock
        self.bottom_dock_layout = QGridLayout()
        self.bottom_dock_layout.setSpacing(10)

        self.bottom_dock_widget = QDockWidget()
        self.bottom_dock_widget.setMinimumSize(self.screen_resolution.width() // 4 * 3 - 10,
                                               self.screen_resolution.height() // 4 - 10)
        bottom_dock = QWidget(self.bottom_dock_widget)
        bottom_dock.setMinimumSize(self.screen_resolution.width() // 4 * 3 - 20,
                                   self.screen_resolution.height() // 4 - 20)
        bottom_dock.move(10, 10)
        bottom_dock.setLayout(self.bottom_dock_layout)

        settings_label = QLabel("Settings:")
        self.bottom_dock_layout.addWidget(settings_label, 0, 0, 1, 2,
                                          Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop)

        countour_tresh_label = QLabel("Countour Tresh:")
        self.bottom_dock_layout.addWidget(countour_tresh_label, 1, 0, 1, 1, Qt.AlignmentFlag.AlignTop)

        self.countour_tresh_slider = QSlider(Qt.Orientation.Horizontal)
        self.countour_tresh_slider.setTickPosition(QSlider.TickPosition.TicksBelow)
        self.countour_tresh_slider.setRange(self._countour_min_tresh, self._countour_max_tresh)
        self.countour_tresh_slider.setValue(2)
        self.bottom_dock_layout.addWidget(self.countour_tresh_slider, 1, 1, 1, 1, Qt.AlignmentFlag.AlignTop)

        transparency_weight_label = QLabel("Transparency:")
        self.bottom_dock_layout.addWidget(transparency_weight_label, 2, 0, 1, 1, Qt.AlignmentFlag.AlignTop)

        self.transparency_weight_slider = QSlider(Qt.Orientation.Horizontal)
        self.transparency_weight_slider.setTickPosition(QSlider.TickPosition.TicksBelow)
        self.transparency_weight_slider.setValue(6)
        self.transparency_weight_slider.setRange(self._transparency_min, self._transparency_max)
        self.bottom_dock_layout.addWidget(self.transparency_weight_slider, 2, 1, 1, 1, Qt.AlignmentFlag.AlignTop)

        countour_gamma_label = QLabel("Countour Gamma:")
        self.bottom_dock_layout.addWidget(countour_gamma_label, 3, 0, 1, 1, Qt.AlignmentFlag.AlignTop)

        self.countour_gamma_slider = QSlider(Qt.Orientation.Horizontal)
        self.countour_gamma_slider.setTickPosition(QSlider.TickPosition.TicksBelow)
        self.countour_gamma_slider.setValue(8)
        self.countour_gamma_slider.setRange(self._countour_gamma_min, self._countour_gamma_max)
        self.bottom_dock_layout.addWidget(self.countour_gamma_slider, 3, 1, 1, 1, Qt.AlignmentFlag.AlignTop)

        ### right side of settings
        countour_color_label = QLabel("Countour Color:")
        self.bottom_dock_layout.addWidget(countour_color_label, 0, 2, 1, 2,
                                          Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop)

        r_color_label = QLabel("R:")
        self.bottom_dock_layout.addWidget(r_color_label, 1, 2, 1, 1, Qt.AlignmentFlag.AlignTop)

        self.r_color_slider = QSlider(Qt.Orientation.Horizontal)
        self.r_color_slider.setTickPosition(QSlider.TickPosition.TicksBelow)
        self.r_color_slider.setRange(self._color_min, self._color_max)
        self.r_color_slider.setValue(255)
        self.bottom_dock_layout.addWidget(self.r_color_slider, 1, 3, 1, 1, Qt.AlignmentFlag.AlignTop)

        g_color_label = QLabel("G:")
        self.bottom_dock_layout.addWidget(g_color_label, 2, 2, 1, 1, Qt.AlignmentFlag.AlignTop)

        self.g_color_slider = QSlider(Qt.Orientation.Horizontal)
        self.g_color_slider.setTickPosition(QSlider.TickPosition.TicksBelow)
        self.g_color_slider.setRange(self._color_min, self._color_max)
        self.bottom_dock_layout.addWidget(self.g_color_slider, 2, 3, 1, 1, Qt.AlignmentFlag.AlignTop)

        b_color_label = QLabel("B:")
        self.bottom_dock_layout.addWidget(b_color_label, 3, 2, 1, 1, Qt.AlignmentFlag.AlignTop)

        self.b_color_slider = QSlider(Qt.Orientation.Horizontal)
        self.b_color_slider.setTickPosition(QSlider.TickPosition.TicksBelow)
        self.b_color_slider.setRange(self._color_min, self._color_max)
        self.bottom_dock_layout.addWidget(self.b_color_slider, 3, 3, 1, 1, Qt.AlignmentFlag.AlignTop)

        self.addDockWidget(Qt.DockWidgetArea.BottomDockWidgetArea, self.bottom_dock_widget)

        self.setCorner(Qt.Corner.BottomRightCorner, Qt.DockWidgetArea.RightDockWidgetArea)

    def init_image_difference(self):
        self.image_difference_thread = imageDifference()
        self.get_template_filename.connect(self.image_difference_thread.set_template_image)
        self.countour_tresh_slider.valueChanged.connect(self.image_difference_thread.set_countour_tresh_value)
        self.transparency_weight_slider.valueChanged.connect(self.image_difference_thread.set_transparency_weight_value)
        self.countour_gamma_slider.valueChanged.connect(self.image_difference_thread.set_countour_gamma_value)
        self.r_color_slider.valueChanged.connect(self.image_difference_thread.set_countour_color_r)
        self.g_color_slider.valueChanged.connect(self.image_difference_thread.set_countour_color_g)
        self.b_color_slider.valueChanged.connect(self.image_difference_thread.set_countour_color_b)
        self.image_difference_thread.output_image_defference.connect(self.mat2qimage)
        self.image_difference_thread.set_template_picture.connect(self.set_template_picture)
        self.image_difference_thread.start()

    def detect_webcam_devices(self, combo_box):
        _video_capture = cv2.VideoCapture()
        _dev_id = 0
        while (_dev_id < 3):
            if _video_capture.open(_dev_id):
                combo_box.addItem("Device #" + str(_dev_id + 1), _dev_id)
                _dev_id += 1
            else:
                _dev_id += 1
        _video_capture.release()

    def load_template(self):
        index = self.directory_tree_view.selectedIndexes()[0]
        if not QFileInfo(self.file_system_model.filePath(index)).isDir():
            # print("load template, path:", self.file_system_model.filePath(index))
            self.get_template_filename.emit(self.file_system_model.filePath(index))

    def create_template(self):
        if self.stream is not None:
            template_to_save = self.stream.get_current_frame()
            cv2.imwrite("../image_difference/examples/template.jpg", template_to_save)
            print("create template")

    pyqtSlot(np.ndarray)

    def mat2qimage(self, image):
        rgbImage = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        rgbImage = cv2.resize(rgbImage, (self.output_picture.size().width(),
                                         self.output_picture.size().height()))
        # rgbImage = imutils.resize(rgbImage, height=self.output_picture.height())
        h, w, ch = rgbImage.shape
        bytesPerLine = ch * w
        result_image = QImage(rgbImage.data, w, h, bytesPerLine, QImage.Format_RGB888)
        self.output_picture.setPixmap(QPixmap.fromImage(result_image))

    pyqtSlot(np.ndarray)

    def set_template_picture(self, image):
        rgbImage = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        # rgbImage = cv2.resize(rgbImage, (self.template_image.size().width(),
        #                                  self.template_image.size().height()))
        rgbImage = imutils.resize(rgbImage, self.template_image.size().width())
        h, w, ch = rgbImage.shape
        bytesPerLine = ch * w
        result_image = QImage(rgbImage.data, w, h, bytesPerLine, QImage.Format_RGB888)
        self.template_image.setPixmap(QPixmap.fromImage(result_image))
        if not self.template_set:
            self.template_set = True
            self.stream.getframe.disconnect(self.mat2qimage)
            self.stream.getframe.connect(self.image_difference_thread.get_image)
            self.image_difference_thread.output_image_defference.connect(self.mat2qimage)

    def camera_switcher_index_changed(self, index):
        self.camera_changed.emit(self.webcam_switcher.itemData(index))
        print("current index:", index)
        print("item data:", self.webcam_switcher.itemData(index))

    def closeEvent(self, event):
        self.exit_program.emit()
        event.accept()
class ProductRepositoryModule(QWidget, Ui_Form):

    def __init__(self, parent=None):
        super(ProductRepositoryModule, self).__init__(parent)
        self.setupUi(self)

        if '42' not in user.powers:
            self.close()
        if user.powers['42'] == 0:
            self.close()
        self.power = '{:03b}'.format(user.powers['42'])

        self.WC = WarehouseController()
        self.LC = LabrecordsController()
        self.PC = ProductController()
        self.current_button = self.radioButton_batchno
        self.get_product_list()

    def get_product_list(self):
        if self.current_button == self.radioButton_batchno:
            self.treeWidget_productbatchnolist.setVisible(True)
            self.treeWidget_productkindlist.setVisible(False)
            current_tree = self.treeWidget_productbatchnolist
            current_tree.hideColumn(0)
        elif self.current_button == self.radioButton_kind:
            self.treeWidget_productbatchnolist.setVisible(False)
            self.treeWidget_productkindlist.setVisible(True)
            current_tree = self.treeWidget_productkindlist
        else:
            return

        current_tree.clear()
        key_dict = {'stockamount__gt': 0}
        product_list = self.WC.get_productrepository(
            False, **key_dict
        )
        if not len(product_list):
            return

        if current_tree == self.treeWidget_productbatchnolist:
            self.set_batchno_tree(current_tree, product_list)
            for i in range(1, 15):
                current_tree.resizeColumnToContents(i)
        elif current_tree == self.treeWidget_productkindlist:
            self.set_kind_tree(current_tree, product_list)
            for i in range(0, 6):
                current_tree.resizeColumnToContents(i)
        else:
            return

    def set_batchno_tree(self, current_tree, product_list):
        p_list = product_list.values(*VALUES_TUPLE_BATCHNO)
        """
        .extra(
            select={
                'prodid': 'prodid', 'prodname': 'prodname', 'spec': 'spec',
                'commonname': 'commonname', 'batchno': 'batchno',
                'package': 'package', 'spunit': 'spunit',
                'makedate': 'makedate', 'expireddates': 'expireddates'
            },
            tables=['producingplan'],
            where=['producingplan.autoid=ppid']
        )
        """
        for item in p_list:
            qtreeitem = QTreeWidgetItem(current_tree)
            qtreeitem.setText(0, str(item['autoid']))
            qtreeitem.setText(1, SOURCE[item['pisource']])
            qtreeitem.setText(2, item['prodid'] + ' ' + item['prodname'])
            qtreeitem.setText(3, item['commonname'])
            if item['pisource'] == 2:
                key_dict = {'autoid': item['hxid']}
                hx_batchno_list = self.PC.get_producingplan(
                    True, *VALUES_TUPLE_PRODUCINGPLAN, **key_dict
                )
                hx_batchno = ''
                if len(hx_batchno_list):
                    hx_batchno = hx_batchno_list[0]
                qtreeitem.setText(4, item['batchno'] + ' ' + hx_batchno)

                qtreeitem.setText(
                    7, to_str((item['piamount'] - item[
                        'hxamount'])) + '+' +
                       to_str(item['hxamount'])
                )
                qtreeitem.setText(
                    8, to_str(item['stockamount'] - item[
                        'hxstockamount']) + '+' + to_str(item['hxstockamount'])
                )
            else:
                qtreeitem.setText(4, item['batchno'])
                qtreeitem.setText(7, str(item['piamount']))
                qtreeitem.setText(8, str(item['stockamount']))

            qtreeitem.setText(5, item['spec'])
            qtreeitem.setText(6, item['package'])
            qtreeitem.setText(9, item['spunit'])
            qtreeitem.setText(10, item['position'])

            qtreeitem.setText(11, str(item['indate']))
            if type(item['makedate']) is datetime.date:
                qtreeitem.setText(12, str(item['makedate']))
                qtreeitem.setText(13, str(item['expireddate']))
            qtreeitem.setText(
                14, item['warehousemanid'] + item['warehousemanname']
            )

    def set_kind_tree(self, current_tree, product_list):
        kind_list = product_list.values(*VALUES_TUPLE_KIND).annotate(
            stockamount=Sum('stockamount'), piamount=Sum('piamount')
        )
        """
        .extra(
            select={
                'prodid': 'prodid', 'prodname': 'prodname', 'spec': 'spec',
                'commonname': 'commonname', 'package': 'package',
                'spunit': 'spunit'
            },
            tables=['producingplan'],
            where=['producingplan.autoid=ppid']
        ). \
        """
        for item in kind_list:
            qtreeitem = QTreeWidgetItem(current_tree)
            qtreeitem.setText(0, item['prodid'] + item['prodname'])
            qtreeitem.setText(1, item['commonname'])
            qtreeitem.setText(2, item['spec'])
            qtreeitem.setText(3, item['package'])
            qtreeitem.setText(4, to_str(item['piamount']))
            qtreeitem.setText(5, to_str(item['stockamount']))
            qtreeitem.setText(6, item['spunit'])

    pyqtSlot(bool)

    def on_radioButton_batchno_toggled(self, p_bool):
        if p_bool:
            self.current_button = self.radioButton_batchno
            self.get_product_list()

    pyqtSlot(bool)
    def on_radioButton_kind_toggled(self, p_bool):
        if p_bool:
            self.current_button = self.radioButton_kind
            self.get_product_list()

    @pyqtSlot(QPoint)
    def on_treeWidget_productbatchnolist_customContextMenuRequested(self, pos):
        if self.power[1] == '0':
            return
        id = 0
        batchno = ''
        sender_widget = self.sender()
        current_item = sender_widget.currentItem()
        if current_item is None:
            return

        id = int(current_item.text(0))
        prodid, stuffname = current_item.text(2).split(' ')
        batchno = current_item.text(4)

        menu = QMenu()
        button1 = menu.addAction("查看检验报告")

        global_pos = sender_widget.mapToGlobal(pos)
        action = menu.exec(global_pos)

        if action == button1:
            detail = FindCheckReportModule(prodid, batchno, self)
            detail.show()