Esempio n. 1
0
class SingleMeasureWidget(QWidget):

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

        self._domain = domain

        self._plot = PlotWidget(parent=None, toolbar=True)

        self._layout = QHBoxLayout()
        self._layout.addWidget(self._plot)
        self.setLayout(self._layout)

        self._init()

    def _init(self):
        self._plot.subplots_adjust(bottom=0.150)
        self._plot.set_title('Коэффициент преобразования для N-гармоники')
        self._plot.set_xscale('log')
        self._plot.set_xlabel('F, Гц', labelpad=-2)
        self._plot.set_ylabel('К-т пр., дБ', labelpad=-2)
        self._plot.grid(b=True, which='minor', color='0.7', linestyle='--')
        self._plot.grid(b=True, which='major', color='0.5', linestyle='-')

    def clear(self):
        self._plot.clear()
        self._init()

    def plot(self):
        print('plotting single measurement')
        self.clear()
        self._plot.plot(self._domain.singleMeasureXs, self._domain.singleMeasureYs, color='0.4')
class PrimaryPlotWidget(QWidget):
    def __init__(self, parent=None, model=None):
        super().__init__(parent)
        self._model = model

        self._plot = PlotWidget(parent=None, toolbar=True)

        self._grid = QGridLayout()
        self._grid.addWidget(self._plot, 0, 0)
        self.setLayout(self._grid)

        self._init()

    def _init(self):
        self._plot.subplots_adjust(bottom=0.150)
        self._plot.set_xlabel(self._model.xLabel)
        self._plot.set_ylabel(self._model.yLabel)
        self._plot.grid(b=True, which='major', color='0.5', linestyle='-')

    def clear(self):
        self._plot.clear()

    def plot(self):
        self.clear()
        self._init()

        self._plot.plot(self._model.xs, self._model.ys)
        self._plot.plot(self._model.xs, self._model.filteredYs)
Esempio n. 3
0
class PowSweepWidget(QWidget):
    def __init__(self, parent=None, controller=None):
        super().__init__(parent=parent)
        self._controller = controller

        self._ui = uic.loadUi('powsweepwidget.ui', self)

        self._plot = PlotWidget(parent=None, toolbar=True)
        # self._ui.verticalLayout.addWidget(self._plot)
        self._ui.btnPowSweep.hide()

        self._init()

    def _init(self):
        self._plot.set_title('Прогон по мощности')
        self._plot.set_xlabel('F, GHz', labelpad=-2)
        self._plot.set_ylabel('Pow, dB', labelpad=-2)
        self._plot.set_xlim(4, 8)
        # self._plot.set_ylim(pars['ylim'][0], pars['ylim'][1])
        self._plot.grid(b=True, which='major', color='0.5', linestyle='-')
        self._plot.tight_layout()

    @pyqtSlot()
    def on_btnPowSweep_clicked(self):
        freqs, amps = self._controller.pow_sweep()
        self._plot.clear()
        self._init()

        self._plot.plot(freqs, amps)
Esempio n. 4
0
class PhasePlotWidget(QWidget):
    def __init__(self, parent=None, domain=None):
        super().__init__(parent)

        self._domain = domain

        self._plot = PlotWidget(parent=None, toolbar=True)

        self._layout = QVBoxLayout()
        self._layout.addWidget(self._plot)

        self.setLayout(self._layout)

        self._title = ''
        self._stats = list()

        self._init()

    def _init(self):
        self._plot.set_title(self._title)
        self._plot.set_xlabel('Offset frequency, Hz')
        self._plot.set_ylabel('Phase noise, dBc/Hz')
        self._plot.set_xscale('log')
        # self._plot.set_xlim(pars['xlim'][0], pars['xlim'][1])
        # self._plot.set_ylim(pars['ylim'][0], pars['ylim'][1])
        self._plot.grid(b=True, which='major', color='0.5', linestyle='--')

    def clear(self):
        self._plot.clear()

    def plot(self):
        legend = [
            Line2D([0], [0], color='0.2', linestyle='-', label=lbl)
            for lbl in self._stats
        ]
        self._plot.clear()
        self._init()
        self._plot.legend(handles=legend)
        self._plot.plot(self._domain.xs, self._domain.ys)
        self._plot.plot(self._domain.xs, self._domain.smoothYs)

    def addMarkers(self, markers):
        for marker in markers:
            self._plot.axvline(marker,
                               0,
                               1,
                               linewidth=0.8,
                               color='0.3',
                               linestyle='-')

    def tightLayout(self):
        self._plot.tight_layout()
Esempio n. 5
0
class HarmonicMeasureWidget(QWidget):

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

        self._domain = domain

        self._plot = PlotWidget(parent=None, toolbar=True)

        self.btnMeasure = QPushButton('Измерить')
        self.btnMeasure.setEnabled(False)

        self._hlay = QHBoxLayout()
        self._hlay.addWidget(self.btnMeasure)
        self._hlay.addStretch()

        self._layout = QVBoxLayout()
        self._layout.addItem(self._hlay)
        self._layout.addWidget(self._plot)
        self.setLayout(self._layout)

        self._init()

    def _init(self):
        self._plot.subplots_adjust(bottom=0.150)
        self._plot.set_title('Подавление 2й и 3й гармоник')
        self._plot.set_xlabel('Код', labelpad=-2)
        self._plot.set_ylabel('Подавление, дБ', labelpad=-2)
        self._plot.grid(b=True, which='minor', color='0.7', linestyle='--')
        self._plot.grid(b=True, which='major', color='0.5', linestyle='-')

    def clear(self):
        self._plot.clear()
        self._init()

    def plot(self):
        print(f'plotting harmonic deltas')
        for key, values in self._domain.harm_deltas.items():
            self._plot.plot(self._domain.codes, values, label=f'f x {key}')
        self._plot.legend()
Esempio n. 6
0
class AttPlotWidget(QWidget):
    params = {
        0: {
            '00': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'S21, дБ, 0гр',
                'ylim': []
            },
            '01': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'S21, дБ, 5гр',
                'ylim': []
            },
            '02': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'S21, дБ, 11гр',
                'ylim': []
            },
            '03': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'S21, дБ, 22гр',
                'ylim': []
            },
            '10': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'S21, дБ, 45гр',
                'ylim': []
            },
            '11': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'S21, дБ, 90гр',
                'ylim': []
            },
            '12': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'S21, дБ, 180гр',
                'ylim': []
            },
            '13': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'S21, дБ, 360гр',
                'ylim': []
            },
        },
    }

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

        self._result = result
        self.only_main_states = False

        self._grid = QGridLayout()

        self._plot000000 = PlotWidget(parent=None, toolbar=True)
        self._plot000001 = PlotWidget(parent=None, toolbar=True)
        self._plot000010 = PlotWidget(parent=None, toolbar=True)
        self._plot000100 = PlotWidget(parent=None, toolbar=True)
        self._plot001000 = PlotWidget(parent=None, toolbar=True)
        self._plot010000 = PlotWidget(parent=None, toolbar=True)
        self._plot100000 = PlotWidget(parent=None, toolbar=True)
        self._plot111111 = PlotWidget(parent=None, toolbar=True)

        self._grid.addWidget(self._plot000000, 0, 0)
        self._grid.addWidget(self._plot000001, 0, 1)
        self._grid.addWidget(self._plot000010, 0, 2)
        self._grid.addWidget(self._plot000100, 0, 3)
        self._grid.addWidget(self._plot001000, 1, 0)
        self._grid.addWidget(self._plot010000, 1, 1)
        self._grid.addWidget(self._plot100000, 1, 2)
        self._grid.addWidget(self._plot111111, 1, 3)

        self.setLayout(self._grid)

        self._init()

    def _init(self, dev_id=0):
        def setup_plot(plot, pars: dict):
            plot.set_tight_layout(True)
            plot.subplots_adjust(bottom=0.150)
            # plot.set_title(pars['title'])
            plot.set_xlabel(pars['xlabel'], labelpad=-2)
            plot.set_ylabel(pars['ylabel'], labelpad=-2)
            # plot.set_xlim(pars['xlim'][0], pars['xlim'][1])
            # plot.set_ylim(pars['ylim'][0], pars['ylim'][1])
            plot.grid(b=True, which='major', color='0.5', linestyle='-')
            plot.tight_layout()

        setup_plot(self._plot000000, self.params[dev_id]['00'])
        setup_plot(self._plot000001, self.params[dev_id]['01'])
        setup_plot(self._plot000010, self.params[dev_id]['02'])
        setup_plot(self._plot000100, self.params[dev_id]['03'])
        setup_plot(self._plot001000, self.params[dev_id]['10'])
        setup_plot(self._plot010000, self.params[dev_id]['11'])
        setup_plot(self._plot100000, self.params[dev_id]['12'])
        setup_plot(self._plot111111, self.params[dev_id]['13'])

    def clear(self):
        self._plot000000.clear()
        self._plot000001.clear()
        self._plot000010.clear()
        self._plot000100.clear()
        self._plot001000.clear()
        self._plot010000.clear()
        self._plot100000.clear()
        self._plot111111.clear()

    def plot(self, dev_id=0):
        print('plotting att response')
        self.clear()
        self._init(dev_id)

        freqs = self._result.freqs
        s21s_ph = self._result.s21_phase_norm

        # TODO rename to result._psm_codes
        n = len(set(self._result._att_codes))

        psm_indices = []
        for i in main_states:
            try:
                psm_indices.append(self._result._phase_codes.index(i))
            except ValueError:
                psm_indices.append(-1)
        psm_indices = [idx for idx in psm_indices if idx >= 0]

        def chunks(lst, n):
            for i in range(0, len(lst), n):
                yield lst[i:i + n]

        idx = psm_indices[0]
        for xs, ys in zip(itertools.repeat(freqs, n),
                          (chunk[idx] for chunk in chunks(s21s_ph, n))):
            self._plot000000.plot(xs, ys)

        idx = psm_indices[1]
        for xs, ys in zip(itertools.repeat(freqs, n),
                          (chunk[idx] for chunk in chunks(s21s_ph, n))):
            self._plot000001.plot(xs, ys)

        idx = psm_indices[2]
        for xs, ys in zip(itertools.repeat(freqs, n),
                          (chunk[idx] for chunk in chunks(s21s_ph, n))):
            self._plot000010.plot(xs, ys)

        idx = psm_indices[3]
        for xs, ys in zip(itertools.repeat(freqs, n),
                          (chunk[idx] for chunk in chunks(s21s_ph, n))):
            self._plot000100.plot(xs, ys)

        idx = psm_indices[4]
        for xs, ys in zip(itertools.repeat(freqs, n),
                          (chunk[idx] for chunk in chunks(s21s_ph, n))):
            self._plot001000.plot(xs, ys)

        idx = psm_indices[5]
        for xs, ys in zip(itertools.repeat(freqs, n),
                          (chunk[idx] for chunk in chunks(s21s_ph, n))):
            self._plot010000.plot(xs, ys)

        idx = psm_indices[6]
        for xs, ys in zip(itertools.repeat(freqs, n),
                          (chunk[idx] for chunk in chunks(s21s_ph, n))):
            self._plot100000.plot(xs, ys)

        idx = psm_indices[7]
        for xs, ys in zip(itertools.repeat(freqs, n),
                          (chunk[idx] for chunk in chunks(s21s_ph, n))):
            self._plot111111.plot(xs, ys)

    def save(self, img_path='./image'):
        try:
            os.makedirs(img_path)
        except OSError as ex:
            if ex.errno != errno.EEXIST:
                raise IOError('Error creating image dir.')

        for plot, name in zip([
                self._plot000000, self._plot000001, self._plot000010,
                self._plot000100
        ], ['stats.png', 'cutoff.png', 'delta.png', 'double-triple.png']):
            plot.savefig(img_path + name, dpi=400)
Esempio n. 7
0
class PrimaryPlotWidget(QWidget):
    main_states = [0, 1, 2, 4, 8, 16, 32, 63]

    params = {
        0: {
            '00': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'S21, дБм',
                'ylim': []
            },
            '01': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'КСВ вх, дБм',
                'ylim': []
            },
            '11': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'КСВ вых, дБм',
                'ylim': []
            },
        },
    }

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

        self._result = result
        self.only_main_states = False

        self._grid = QGridLayout()

        self._plotS21 = PlotWidget(parent=None, toolbar=True)
        self._plotVswrIn = PlotWidget(parent=None, toolbar=True)
        self._plotVswrOut = PlotWidget(parent=None, toolbar=True)

        self._grid.addWidget(self._plotS21, 0, 0)
        self._grid.addWidget(self._plotVswrIn, 0, 1)
        self._grid.addWidget(self._plotVswrOut, 1, 1)

        self.setLayout(self._grid)

        self._init()

    def _init(self, dev_id=0):
        def setup_plot(plot, pars: dict):
            plot.set_tight_layout(True)
            plot.subplots_adjust(bottom=0.150)
            # plot.set_title(pars['title'])
            plot.set_xlabel(pars['xlabel'], labelpad=-2)
            plot.set_ylabel(pars['ylabel'], labelpad=-2)
            # plot.set_xlim(pars['xlim'][0], pars['xlim'][1])
            # plot.set_ylim(pars['ylim'][0], pars['ylim'][1])
            plot.grid(b=True, which='major', color='0.5', linestyle='-')
            plot.tight_layout()

        setup_plot(self._plotS21, self.params[dev_id]['00'])
        setup_plot(self._plotVswrIn, self.params[dev_id]['01'])
        setup_plot(self._plotVswrOut, self.params[dev_id]['11'])

    def clear(self):
        self._plotS21.clear()
        self._plotVswrIn.clear()
        self._plotVswrOut.clear()

    def plot(self, dev_id=0):
        print('plotting primary stats')
        self.clear()
        self._init(dev_id)

        for_states = self.main_states if self.only_main_states else range(64)
        # for_states = range(len(self.main_states))

        freqs = self._result.freqs
        s21s = self._result.s21[:1]
        vswr_in = self._result.vswr_in[:1]
        vswr_out = self._result.vswr_out[:1]

        n = len(s21s)

        for xs, ys in zip(itertools.repeat(freqs, n), s21s):
            self._plotS21.plot(xs, ys)

        for xs, ys in zip(itertools.repeat(freqs, n), vswr_in):
            self._plotVswrIn.plot(xs, ys)

        for xs, ys in zip(itertools.repeat(freqs, n), vswr_out):
            self._plotVswrOut.plot(xs, ys)
Esempio n. 8
0
class PrimaryPlotWidget(QWidget):

    params = {
        0: {
            '11': {
                'title': 'SWR in',
                'xlabel': 'F, GHz',
                'xlim': [1, 1.6],
                'ylabel': 'loss, dB',
                'ylim': []
            },
            '12': {
                'title': 'SWR out',
                'xlabel': 'F, GHz',
                'xlim': [1, 1.6],
                'ylabel': 'loss, dB',
                'ylim': []
            },
            '21': {
                'title': f'Phase',
                'xlabel': 'F, GHz',
                'xlim': [1, 1.6],
                'ylabel': 'phase, deg',
                'ylim': []
            },
            '22': {
                'title': 'Phase error',
                'xlabel': 'F, GHz',
                'xlim': [1, 1.6],
                'ylabel': 'Phase error, deg',
                'ylim': []
            }
        },
    }

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

        self._result = result

        self._grid = QGridLayout()

        self._plot11 = PlotWidget(parent=None, toolbar=True)
        self._plot12 = PlotWidget(parent=None, toolbar=True)
        self._plot21 = PlotWidget(parent=None, toolbar=True)
        self._plot22 = PlotWidget(parent=None, toolbar=True)

        self._grid.addWidget(self._plot11, 0, 0)
        self._grid.addWidget(self._plot12, 0, 1)
        self._grid.addWidget(self._plot21, 1, 0)
        self._grid.addWidget(self._plot22, 1, 1)

        self.setLayout(self._grid)

        self._init()

    def _init(self, dev_id=0):
        def setup_plot(plot, pars: dict):
            # plot.set_tight_layout(True)
            plot.subplots_adjust(bottom=0.150)
            plot.set_title(pars['title'])
            plot.set_xlabel(pars['xlabel'], labelpad=-2)
            plot.set_ylabel(pars['ylabel'], labelpad=-2)
            plot.set_xlim(pars['xlim'][0], pars['xlim'][1])
            # plot.set_ylim(pars['ylim'][0], pars['ylim'][1])
            plot.grid(b=True, which='major', color='0.5', linestyle='-')
            plot.tight_layout()

        setup_plot(self._plot11, self.params[dev_id]['11'])
        setup_plot(self._plot12, self.params[dev_id]['12'])
        setup_plot(self._plot21, self.params[dev_id]['21'])
        setup_plot(self._plot22, self.params[dev_id]['22'])

    def clear(self):
        self._plot11.clear()
        self._plot12.clear()
        self._plot21.clear()
        self._plot22.clear()

    def plot(self, dev_id=0):
        self.clear()
        self._init(dev_id)
        self._result.process()

        print('plotting primary stats')

        swr_out = self._result.swr_out
        swr_in = self._result.swr_in
        phase = self._result.phase
        phase_err = self._result.phase_err

        freqs = [f / 1_000_000_000 for f in self._result.freqs]
Esempio n. 9
0
class StatPlotWidget(QWidget):
    def __init__(self, parent=None, domain=None):
        super().__init__(parent)

        self._domain = domain

        self._grid = QGridLayout()

        self._plot11 = PlotWidget(parent=None, toolbar=True)
        self._plot12 = PlotWidget(parent=None, toolbar=True)
        self._plot21 = PlotWidget(parent=None, toolbar=True)
        self._plot22 = PlotWidget(parent=None, toolbar=True)

        self._grid.addWidget(self._plot11, 0, 0)
        self._grid.addWidget(self._plot12, 0, 1)
        self._grid.addWidget(self._plot21, 1, 0)
        self._grid.addWidget(self._plot22, 1, 1)

        self.setLayout(self._grid)

        self._init()

    def _init(self):
        # self._plot11.set_tight_layout(True)
        self._plot11.subplots_adjust(bottom=0.150)
        self._plot11.set_title('Коэффициент преобразования')
        self._plot11.set_xscale('log')
        self._plot11.set_xlabel('F, Гц', labelpad=-2)
        self._plot11.set_ylabel('К-т пр., дБ', labelpad=-2)
        # self._plot11.set_ylim([-60, 30])
        self._plot11.grid(b=True, which='minor', color='0.7', linestyle='--')
        self._plot11.grid(b=True, which='major', color='0.5', linestyle='-')

        # self._plot12.set_tight_layout(True)
        self._plot12.subplots_adjust(bottom=0.150)
        self._plot12.set_title(
            f'Частота среза по уровню {self._domain.cutoffMag} дБ')
        self._plot12.set_xlabel('Код', labelpad=-2)
        self._plot12.set_ylabel('F, МГц', labelpad=-2)
        self._plot12.set_yscale('log')
        self._plot12.grid(b=True, which='minor', color='0.7', linestyle='--')
        self._plot12.grid(b=True, which='major', color='0.5', linestyle='-')

        # self._plot21.set_tight_layout(True)
        self._plot21.subplots_adjust(bottom=0.150)
        self._plot21.set_title('Дельта частоты среза')
        self._plot21.set_xlabel('Код')
        self._plot21.set_ylabel('dF, МГц')
        self._plot21.grid(b=True, which='major', color='0.5', linestyle='-')

        # self._plot22.set_tight_layout(True)
        self._plot22.subplots_adjust(bottom=0.150)
        self._plot22.set_title('Затухание на x2 и x3 частоте среза')
        self._plot22.set_xlabel('Код')
        self._plot22.set_ylabel('Подавление, дБ')
        # self._plot22.set_ylim([-60, 30])
        self._plot22.grid(b=True, which='major', color='0.5', linestyle='-')

    def clear(self):
        self._plot11.clear()
        self._plot12.clear()
        self._plot21.clear()
        self._plot22.clear()
        self._init()

    def plotCode(self):
        print('plotting code')
        self._plot11.plot(self._domain.lastXs,
                          self._domain.lastYs,
                          color='0.4')

    def plotStats(self):
        print('plotting stats')
        self._plot12.plot(self._domain.cutoffXs,
                          self._domain.cutoffYs,
                          color='0.4')
        self._plot21.plot(self._domain.deltaXs,
                          self._domain.deltaYs,
                          color='0.4')
        self._plot22.plot(self._domain.lossDoubleXs,
                          self._domain.lossDoubleYs,
                          color='0.4')
        self._plot22.plot(self._domain.lossTripleXs,
                          self._domain.lossTripleYs,
                          color='0.4')

        self._plot11.axhline(self._domain.cutoffAmp,
                             0,
                             1,
                             linewidth=0.8,
                             color='0.3',
                             linestyle='--')
        self._plot11.set_yticks(
            sorted(
                set(
                    list(self._plot11.get_yticks()[0]) +
                    [self._domain.cutoffMag])))

    def save(self, img_path='./image'):
        try:
            os.makedirs(img_path)
        except OSError as ex:
            if ex.errno != errno.EEXIST:
                raise IOError('Error creating image dir.')

        for plot, name in zip(
            [self._plot11, self._plot12, self._plot21, self._plot22],
            ['stats.png', 'cutoff.png', 'delta.png', 'double-triple.png']):
            plot.savefig(img_path + name, dpi=400)
Esempio n. 10
0
class SParamPlotWidget(QWidget):
    params = {
        0: {
            '00': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'S11, дБ',
                'ylim': []
            },
            '01': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'S22, дБ',
                'ylim': []
            },
            '10': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'S21, дБ',
                'ylim': []
            },
            '11': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'S12, дБ',
                'ylim': []
            },
        },
    }

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

        self._result = result
        self.only_main_states = False

        self._grid = QGridLayout()

        self._plotS11 = PlotWidget(parent=None, toolbar=True)
        self._plotS12 = PlotWidget(parent=None, toolbar=True)
        self._plotS21 = PlotWidget(parent=None, toolbar=True)
        self._plotS22 = PlotWidget(parent=None, toolbar=True)

        self._grid.addWidget(self._plotS11, 0, 0)
        self._grid.addWidget(self._plotS22, 0, 1)
        self._grid.addWidget(self._plotS21, 1, 0)
        self._grid.addWidget(self._plotS12, 1, 1)

        self.setLayout(self._grid)

        self._init()

    def _init(self, dev_id=0):
        def setup_plot(plot, pars: dict):
            plot.set_tight_layout(True)
            plot.subplots_adjust(bottom=0.150)
            # plot.set_title(pars['title'])
            plot.set_xlabel(pars['xlabel'], labelpad=-2)
            plot.set_ylabel(pars['ylabel'], labelpad=-2)
            # plot.set_xlim(pars['xlim'][0], pars['xlim'][1])
            # plot.set_ylim(pars['ylim'][0], pars['ylim'][1])
            plot.grid(b=True, which='major', color='0.5', linestyle='-')
            plot.tight_layout()

        setup_plot(self._plotS11, self.params[dev_id]['00'])
        setup_plot(self._plotS22, self.params[dev_id]['01'])
        setup_plot(self._plotS21, self.params[dev_id]['10'])
        setup_plot(self._plotS12, self.params[dev_id]['11'])

    def clear(self):
        self._plotS11.clear()
        self._plotS22.clear()
        self._plotS21.clear()
        self._plotS12.clear()

    def plot(self, dev_id=0):
        print('plotting S-params with att=0')
        self.clear()
        self._init(dev_id)

        freqs = self._result.freqs
        s11s = self._result.s11
        s22s = self._result.s22
        s21s = self._result.s21
        s12s = self._result.s12

        # TODO rename to result._psm_codes
        n = len(set(self._result._phase_codes))

        for xs, ys in zip(itertools.repeat(freqs, n), s11s[:n]):
            self._plotS11.plot(xs, ys)

        for xs, ys in zip(itertools.repeat(freqs, n), s22s[:n]):
            self._plotS22.plot(xs, ys)

        for xs, ys in zip(itertools.repeat(freqs, n), s21s[:n]):
            self._plotS21.plot(xs, ys)

        for xs, ys in zip(itertools.repeat(freqs, n), s12s[:n]):
            self._plotS12.plot(xs, ys)

    def save(self, img_path='./image'):
        try:
            os.makedirs(img_path)
        except OSError as ex:
            if ex.errno != errno.EEXIST:
                raise IOError('Error creating image dir.')

        for plot, name in zip(
            [self._plotS11, self._plotS12, self._plotS21, self._plotS22],
            ['stats.png', 'cutoff.png', 'delta.png', 'double-triple.png']):
            plot.savefig(img_path + name, dpi=400)
class PrimaryPlotWidget(QWidget):

    params = {
        0: {
            '00': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'S21, дБм',
                'ylim': []
            },
            '01': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'КСВ вх, дБм',
                'ylim': []
            },
            '10': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'КСВ вых, дБм',
                'ylim': []
            },
            '11': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'φ ош, град',
                'ylim': []
            },
            '02': {
                'xlabel': 'V, В',
                'xlim': [0, 20],
                'ylabel': 'φ(v)',
                'ylim': [-100, 300]
            },
            '12': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'S21 ош, дБ',
                'ylim': []
            },
            '03': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'S21 ско',
                'ylim': []
            },
            '13': {
                'xlabel': 'F, ГГц',
                'xlim': [],
                'ylabel': 'helper',
                'ylim': []
            },
        },
    }

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

        self._result = result
        self.only_main_states = False

        self._grid = QGridLayout()

        self._plotS21 = PlotWidget(parent=None, toolbar=True)
        self._plotVswrIn = PlotWidget(parent=None, toolbar=True)
        self._plotVswrOut = PlotWidget(parent=None, toolbar=True)
        self._plotS21PhaseErr = PlotWidget(parent=None, toolbar=True)
        self._plotS21PhaseRmse = PlotWidget(parent=None, toolbar=True)
        self._plotS21Err = PlotWidget(parent=None, toolbar=True)
        self._plotS21Rmse = PlotWidget(parent=None, toolbar=True)
        self._plotMisc = PlotWidget(parent=None, toolbar=True)

        self._grid.addWidget(self._plotS21, 0, 0)
        self._grid.addWidget(self._plotVswrIn, 0, 1)
        self._grid.addWidget(self._plotVswrOut, 1, 0)
        self._grid.addWidget(self._plotS21PhaseErr, 1, 1)
        self._grid.addWidget(self._plotS21PhaseRmse, 0, 2)
        # self._grid.addWidget(self._plotS21Err, 1, 2)
        # self._grid.addWidget(self._plotS21Rmse, 0, 3)
        # self._grid.addWidget(self._plotMisc, 1, 3)

        self.setLayout(self._grid)

        self._init()

    def _init(self, dev_id=0):

        def setup_plot(plot, pars: dict):
            plot.set_tight_layout(True)
            plot.subplots_adjust(bottom=0.150)
            # plot.set_title(pars['title'])
            plot.set_xlabel(pars['xlabel'], labelpad=-2)
            plot.set_ylabel(pars['ylabel'], labelpad=-2)
            # plot.set_xlim(pars['xlim'][0], pars['xlim'][1])
            # plot.set_ylim(pars['ylim'][0], pars['ylim'][1])
            plot.grid(b=True, which='major', color='0.5', linestyle='-')
            plot.tight_layout()

        setup_plot(self._plotS21, self.params[dev_id]['00'])
        setup_plot(self._plotVswrIn, self.params[dev_id]['01'])
        setup_plot(self._plotVswrOut, self.params[dev_id]['10'])
        setup_plot(self._plotS21PhaseErr, self.params[dev_id]['11'])
        setup_plot(self._plotS21PhaseRmse, self.params[dev_id]['02'])
        # setup_plot(self._plotS21Err, self.params[dev_id]['12'])
        # setup_plot(self._plotS21Rmse, self.params[dev_id]['03'])
        # setup_plot(self._plotMisc, self.params[dev_id]['13'])

    def clear(self):
        self._plotS21.clear()
        self._plotVswrIn.clear()
        self._plotVswrOut.clear()
        self._plotS21PhaseErr.clear()
        self._plotS21PhaseRmse.clear()
        self._plotS21Err.clear()
        self._plotS21Rmse.clear()
        # self._plotMisc.clear()

    def plot(self, dev_id=0):
        print('plotting primary stats')
        self.clear()
        self._init(dev_id)

        freqs = self._result.freqs
        s21s = self._result.s21
        vswr_in = self._result.vswr_in
        vswr_out = self._result.vswr_out
        phase_errs = self._result.phase_err
        phase_v = self._result.phase_v
        volts = self._result._volts
        # s21_err = self._result.s21_err
        # s21_rmse = self._result.s21_rmse
        # misc = self._result.misc

        n = len(s21s)

        for xs, ys in zip(itertools.repeat(freqs, n), s21s):
            self._plotS21.plot(xs, ys)

        for xs, ys in zip(itertools.repeat(freqs, n), vswr_in):
            self._plotVswrIn.plot(xs, ys)

        for xs, ys in zip(itertools.repeat(freqs, n), vswr_out):
            self._plotVswrOut.plot(xs, ys)

        for xs, ys in zip(itertools.repeat(freqs, n - 1), phase_errs):
            self._plotS21PhaseErr.plot(xs, ys)
        self._plotS21PhaseErr.axhline(0, 0, 1, linewidth=0.8, color='0.3', linestyle='-')

        for xs, ys in zip(itertools.repeat(volts, len(phase_v)), phase_v):
            self._plotS21PhaseRmse.plot(xs, ys)

        # for xs, ys in zip(itertools.repeat(freqs, n), s21_err):
        #     self._plotS21Err.plot(xs, ys)
        #
        # for xs, ys in zip([freqs], [s21_rmse]):
        #     self._plotS21Rmse.plot(xs, ys)

        # for xs, ys in zip([freqs] * len(misc), misc):
        #     self._plotMisc.plot(xs, ys)

    def save(self, img_path='./image'):
        try:
            os.makedirs(img_path)
        except OSError as ex:
            if ex.errno != errno.EEXIST:
                raise IOError('Error creating image dir.')

        for plot, name in zip([self._plotS21, self._plotVswrIn, self._plotVswrOut, self._plotS21PhaseErr], ['stats.png', 'cutoff.png', 'delta.png', 'double-triple.png']):
            plot.savefig(img_path + name, dpi=400)