Exemplo n.º 1
0
    def __init__(self, parent):
        QLocale.setDefault(QLocale(QLocale.English, QLocale.UnitedStates))
        super(Ui_Form, self).__init__()
        self.ui = Ui_Form()
        self.ui.setupUi(parent)

        self.widg = QtWidgets.QWidget()
        self.fourierfilt = FourierFilterer(self.widg)
        self.ui.splitter_2.addWidget(self.widg)
        self.ui.graph1D = self.fourierfilt.viewer1D.plotwidget
        QtWidgets.QApplication.processEvents()

        self.ui.splitter.setSizes([200, 400])
        self.ui.statusbar = QtWidgets.QStatusBar(parent)
        self.ui.statusbar.setMaximumHeight(15)
        self.ui.StatusBarLayout.addWidget(self.ui.statusbar)
        self.wait_time = 1000
        self.parent = parent
        self.xdata = None
        self.ydata = None

        self.measurement_types = Measurement_type.names()
        self.measurement_type = Measurement_type(0)
        self.ui.measurement_type_combo.clear()
        self.ui.measurement_type_combo.addItems(self.measurement_types)

        self.ui.fit_curve = self.fourierfilt.viewer1D.plotwidget.plot()
        self.ui.fit_curve.setPen("y")
        self.ui.fit_curve.setVisible(False)

        self.ui.selected_region = self.fourierfilt.viewer1D.ROI
        self.ui.selected_region.setZValue(-10)
        self.ui.selected_region.setBrush('b')
        self.ui.selected_region.setOpacity(0.2)
        self.ui.selected_region.setVisible(True)
        self.fourierfilt.viewer1D.plotwidget.addItem(self.ui.selected_region)

        ##Connecting buttons:
        self.ui.Quit_pb.clicked.connect(self.Quit_fun,
                                        type=Qt.QueuedConnection)
        self.ui.measurement_type_combo.currentTextChanged[str].connect(
            self.update_measurement_subtype)
        self.ui.measure_subtype_combo.currentTextChanged[str].connect(
            self.update_measurement)
        self.update_measurement_subtype(
            self.ui.measurement_type_combo.currentText(), update=False)
        self.ui.selected_region.sigRegionChanged.connect(
            self.update_measurement)
        self.ui.result_sb.valueChanged.connect(self.ui.result_lcd.display)
Exemplo n.º 2
0
class DAQ_Measurement(Ui_Form, QObject):
    """
        =================== ================================== =======================================
        **Attributes**       **Type**                          **Description**


        *ui*                 QObject                           The local instance of User Interface
        *wait_time*          int                               The default delay of showing
        *parent*             QObject                           The QObject initializing the UI
        *xdata*              1D numpy array                    The x axis data
        *ydata*              1D numpy array                    The y axis data
        *measurement_types*  instance of daq_utils.DAQ_enums   The type of the measurement, between:
                                                                    * 'Cursor_Integration'
                                                                    * 'Max'
                                                                    * 'Min'
                                                                    * 'Gaussian_Fit'
                                                                    * 'Lorentzian_Fit'
                                                                    * 'Exponential_Decay_Fit'
        =================== ================================== =======================================

        References
        ----------
        Ui_Form, QObject, PyQt5, pyqtgraph
    """
    measurement_signal = pyqtSignal(list)

    def __init__(self, parent):
        QLocale.setDefault(QLocale(QLocale.English, QLocale.UnitedStates))
        super(Ui_Form, self).__init__()
        self.ui = Ui_Form()
        self.ui.setupUi(parent)

        self.widg = QtWidgets.QWidget()
        self.fourierfilt = FourierFilterer(self.widg)
        self.ui.splitter_2.addWidget(self.widg)
        self.ui.graph1D = self.fourierfilt.viewer1D.plotwidget
        QtWidgets.QApplication.processEvents()

        self.ui.splitter.setSizes([200, 400])
        self.ui.statusbar = QtWidgets.QStatusBar(parent)
        self.ui.statusbar.setMaximumHeight(15)
        self.ui.StatusBarLayout.addWidget(self.ui.statusbar)
        self.wait_time = 1000
        self.parent = parent
        self.xdata = None
        self.ydata = None

        self.measurement_types = Measurement_type.names()
        self.measurement_type = Measurement_type(0)
        self.ui.measurement_type_combo.clear()
        self.ui.measurement_type_combo.addItems(self.measurement_types)

        self.ui.fit_curve = self.fourierfilt.viewer1D.plotwidget.plot()
        self.ui.fit_curve.setPen("y")
        self.ui.fit_curve.setVisible(False)

        self.ui.selected_region = self.fourierfilt.viewer1D.ROI
        self.ui.selected_region.setZValue(-10)
        self.ui.selected_region.setBrush('b')
        self.ui.selected_region.setOpacity(0.2)
        self.ui.selected_region.setVisible(True)
        self.fourierfilt.viewer1D.plotwidget.addItem(self.ui.selected_region)

        ##Connecting buttons:
        self.ui.Quit_pb.clicked.connect(self.Quit_fun,
                                        type=Qt.QueuedConnection)
        self.ui.measurement_type_combo.currentTextChanged[str].connect(
            self.update_measurement_subtype)
        self.ui.measure_subtype_combo.currentTextChanged[str].connect(
            self.update_measurement)
        self.update_measurement_subtype(
            self.ui.measurement_type_combo.currentText(), update=False)
        self.ui.selected_region.sigRegionChanged.connect(
            self.update_measurement)
        self.ui.result_sb.valueChanged.connect(self.ui.result_lcd.display)

    @pyqtSlot(dict)
    def update_fft_filter(self, d):
        self.frequency = d['frequency']
        self.phase = d['phase']
        self.update_measurement()

    def Quit_fun(self):
        """
            close the current instance of daq_measurement.

        """
        # insert anything that needs to be closed before leaving
        self.parent.close()

    def update_status(self, txt, wait_time=0):
        """
            Update the statut bar showing the given text message with a delay of wait_time ms (0s by default).

            =============== ========= ===========================
            **Parameters**

            *txt*             string   the text message to show

            *wait_time*       int      the delay time of waiting
            =============== ========= ===========================

        """
        self.ui.statusbar.showMessage(txt, wait_time)

    @pyqtSlot(str)
    def update_measurement_subtype(self, mtype, update=True):
        """
            | Update the ui-measure_subtype_combo from subitems and formula attributes, if specified by update parameter.
            | Linked with the update_measurement method

            ================ ========== =====================================================================================
            **Parameters**    **Type**   **Description**

            mtype             string      the Measurement_type index of the Measurement_type array (imported from daq_utils)

            update            boolean     the update boolean link with the update_measurement method
            ================ ========== =====================================================================================

            See Also
            --------
            update_measurement_subtype, update_measurement, update_status

        """
        self.measurement_type = Measurement_type[mtype]
        [variables, self.formula,
         self.subitems] = Measurement_type.update_measurement_subtype(mtype)

        try:
            self.ui.measure_subtype_combo.clear()
            self.ui.measure_subtype_combo.addItems(self.subitems)
            self.ui.formula_edit.setPlainText(self.formula)

            if update:
                self.update_measurement()
        except Exception as e:
            self.update_status(str(e), wait_time=self.wait_time)

    def update_measurement(self):
        """
            Update :
             * the measurement results from the update_measurements method
             * the statut bar on cascade (if needed)
             * the User Interface function curve state and data (if needed).

            Emit the measurement_signal corresponding.

            See Also
            --------
            update_measurement, update_status

        """
        try:
            xlimits = self.ui.selected_region.getRegion()
            mtype = self.ui.measurement_type_combo.currentText()
            msubtype = self.ui.measure_subtype_combo.currentText()
            if mtype == 'Sinus':

                # boundaries = utils.find_index(self.xdata, [xlimits[0], xlimits[1]])
                # sub_xaxis = self.xdata[boundaries[0][0]:boundaries[1][0]]
                # sub_data = self.ydata[boundaries[0][0]:boundaries[1][0]]
                #self.fourierfilt.parent.setVisible(True)
                self.fourierfilt.show_data(
                    dict(data=self.ydata, xaxis=self.xdata))
            else:
                #self.fourierfilt.parent.setVisible(False)
                pass

            measurement_results = self.do_measurement(xlimits[0], xlimits[1],
                                                      self.xdata, self.ydata,
                                                      mtype, msubtype)
            if measurement_results['status'] is not None:
                self.update_status(measurement_results['status'],
                                   wait_time=self.wait_time)
                return
            self.ui.result_sb.setValue(measurement_results['value'])
            self.measurement_signal.emit([measurement_results['value']])
            if measurement_results['datafit'] is not None:
                self.ui.fit_curve.setVisible(True)
                self.ui.fit_curve.setData(measurement_results['xaxis'],
                                          measurement_results['datafit'])
            else:
                self.ui.fit_curve.setVisible(False)
        except Exception as e:
            self.update_status(str(e), wait_time=self.wait_time)

    def eval_func(self, x, *args):
        dic = dict(zip(self.subitems, args))
        dic.update(dict(np=np, x=x))
        return eval(self.formula, dic)

    def do_measurement(self, xmin, xmax, xaxis, data1D, mtype, msubtype):
        try:
            boundaries = utils.find_index(xaxis, [xmin, xmax])
            sub_xaxis = xaxis[boundaries[0][0]:boundaries[1][0]]
            sub_data = data1D[boundaries[0][0]:boundaries[1][0]]
            mtypes = Measurement_type.names()
            if msubtype in self.subitems:
                msub_ind = self.subitems.index(msubtype)

            measurement_results = dict(status=None,
                                       value=0,
                                       xaxis=np.array([]),
                                       datafit=np.array([]))

            if mtype == 'Cursor_Integration':  # "Cursor Intensity Integration":
                if msubtype == "sum":
                    result_measurement = np.sum(sub_data)
                elif msubtype == "mean":
                    result_measurement = np.mean(sub_data)
                elif msubtype == "std":
                    result_measurement = np.std(sub_data)
                else:
                    result_measurement = 0

            elif mtype == 'Max':  # "Max":
                result_measurement = np.max(sub_data)

            elif mtype == 'Min':  # "Min":
                result_measurement = np.min(sub_data)

            elif mtype == 'Gaussian_Fit':  # "Gaussian Fit":
                measurement_results['xaxis'] = sub_xaxis
                offset = np.min(sub_data)
                amp = np.max(sub_data) - np.min(sub_data)
                m = utils.my_moment(sub_xaxis, sub_data)
                p0 = [amp, m[1], m[0], offset]
                popt, pcov = curve_fit(self.eval_func,
                                       sub_xaxis,
                                       sub_data,
                                       p0=p0)
                measurement_results['datafit'] = self.eval_func(
                    sub_xaxis, *popt)
                result_measurement = popt[msub_ind]

            elif mtype == 'Lorentzian_Fit':  # "Lorentzian Fit":
                measurement_results['xaxis'] = sub_xaxis
                offset = np.min(sub_data)
                amp = np.max(sub_data) - np.min(sub_data)
                m = utils.my_moment(sub_xaxis, sub_data)
                p0 = [amp, m[1], m[0], offset]
                popt, pcov = curve_fit(self.eval_func,
                                       sub_xaxis,
                                       sub_data,
                                       p0=p0)
                measurement_results['datafit'] = self.eval_func(
                    sub_xaxis, *popt)
                if msub_ind == 4:  # amplitude
                    result_measurement = popt[0] * 2 / (np.pi * popt[1]
                                                        )  # 2*alpha/(pi*gamma)
                else:
                    result_measurement = popt[msub_ind]

            elif mtype == 'Exponential_Decay_Fit':  # "Exponential Decay Fit":
                ind_x0 = utils.find_index(sub_data, np.max(sub_data))[0][0]
                x0 = sub_xaxis[ind_x0]
                sub_xaxis = sub_xaxis[ind_x0:]
                sub_data = sub_data[ind_x0:]
                offset = min([sub_data[0], sub_data[-1]])
                measurement_results['xaxis'] = sub_xaxis
                N0 = np.max(sub_data) - offset
                t37 = sub_xaxis[utils.find_index(sub_data - offset,
                                                 0.37 * N0)[0][0]] - x0
                #polynome = np.polyfit(sub_xaxis, -np.log((sub_data - 0.99 * offset) / N0), 1)
                p0 = [N0, t37, x0, offset]
                popt, pcov = curve_fit(self.eval_func,
                                       sub_xaxis,
                                       sub_data,
                                       p0=p0)
                measurement_results['datafit'] = self.eval_func(
                    sub_xaxis, *popt)
                result_measurement = popt[msub_ind]

            elif mtype == 'Sinus':  #
                offset = np.mean(sub_data)
                A = (np.max(sub_data) - np.min(sub_data)) / 2
                phi = self.fourierfilt.phase
                dx = 1 / self.fourierfilt.frequency
                measurement_results['xaxis'] = sub_xaxis
                p0 = [A, dx, phi, offset]
                popt, pcov = curve_fit(self.eval_func,
                                       sub_xaxis,
                                       sub_data,
                                       p0=p0)
                measurement_results['datafit'] = self.eval_func(
                    sub_xaxis, *popt)
                result_measurement = popt[msub_ind]

            # elif mtype=="Custom Formula":
            #    #offset=np.min(sub_data)
            #    #amp=np.max(sub_data)-np.min(sub_data)
            #    #m=utils.my_moment(sub_xaxis,sub_data)
            #    #p0=[amp,m[1],m[0],offset]
            #    popt, pcov = curve_fit(self.custom_func, sub_xaxis, sub_data,p0=[140,750,50,15])
            #    self.curve_fitting_sig.emit([sub_xaxis,self.gaussian_func(sub_xaxis,*popt)])
            #    result_measurement=popt[msub_ind]
            else:
                result_measurement = 0

            measurement_results['value'] = result_measurement

            return measurement_results
        except Exception as e:
            result_measurement = 0
            measurement_results['status'] = str(e)
            return measurement_results

    def update_data(self, xdata=None, ydata=None):
        """
            | Update xdata attribute with the numpy linspcae regular distribution (if param is none) and update the User Interface curve data.
            | Call the update_measurement method synchronously to keep same values.

            =============== ============   ======================
            **Parameters**   **Type**       **Description**

            *xdata*          float list    the x axis data
            *ydata*          float list    the y axis data
            =============== ============   ======================

            See Also
            --------
            update_measurement

        """
        if xdata is None:
            self.xdata = np.linspace(0, len(ydata) - 1, len(ydata))
        else:
            self.xdata = xdata
        self.ydata = ydata
        self.fourierfilt.show_data(dict(data=self.ydata, xaxis=self.xdata))
        self.update_measurement()