コード例 #1
0
class FFTPlotter(QDialog):
    def __init__(self, update, t):
        super(FFTPlotter, self).__init__()
        self.populate()
        self.show_plot(update, t)

    def populate(self):
        self.setWindowTitle("FFT")
        self.canvas = MplCanvas()
        self.nav = NavigationToolbar(self.canvas, self)
        '''Changed nav toolbar'''

        self.layout = QGridLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)

        self.layout.addWidget(self.nav)
        self.layout.addWidget(self.canvas)

        self.setLayout(self.layout)
        width = self.canvas.width()
        height = self.nav.height() + self.canvas.height()
        self.setFixedSize(width, height)

    def show_plot(self, update, t, trace='gnd'):
        self.canvas.ax.set_facecolor('xkcd:pinkish grey')
        for message_type, message in update.items():
            value = message.get('cavity_probe_pico')
        if message_type == 'record' and value is not None:
            data, ts = get_cavity_data(value, trace)
            Pxx, freqs, t0 = show_fft(data, ts, t)
            self.setWindowTitle('FFT at time {} s'.format(t0))
            self.canvas.ax.clear()
            self.canvas.ax.plot(freqs * 1e-6, Pxx, 'k')
            self.canvas.ax.set_xlim((0, 10))
            self.canvas.ax.set_xlabel("Freq (MHz)")
            self.canvas.draw()
コード例 #2
0
class CavityClockGui(QDialog):
    def __init__(self):
        super(CavityClockGui, self).__init__(None)
        self.update_id = np.random.randint(0, 2**31 - 1)
        self.expt = "Waiting for updates"
        self.data_path = None
        self.update = None
        #Specify analysis frameworks
        self.analysis_script = fits.do_gaussian_fit
        self.mode = lambda update, preset: None
        self.connect_to_labrad_cav()
        self.connect_to_labrad_clock()
        self.populate()

        #self.Plotter = LivePlotter(self)

    def populate(self):
        self.setWindowTitle("Clock + cavity gui")
        self.canvas = MplCanvas()

        self.nav = NavigationToolbar(self.canvas, self)
        #self.nav.addAction('Select analysis method')
        #self.nav.addAction('Launch live plotter', self.launch_plotter)

        self.layout = QGridLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)

        self.layout.addWidget(self.nav)
        self.layout.addWidget(self.canvas)

        self.setLayout(self.layout)
        width = self.canvas.width()
        height = self.nav.height() + self.canvas.height()
        self.setFixedSize(width, height)

        self.add_subplot_buttons()

    # Labrad connection:
    @inlineCallbacks
    def connect_to_labrad_cav(self):
        #self.cxn = connect(name=self.name)
        self.cxn = connection()
        yield self.cxn.connect(name='cavity viewer')
        server = yield self.cxn.get_server('cavity_probe_pico')
        yield server.signal__update(self.update_id)
        yield server.addListener(listener=self.receive_update,
                                 source=None,
                                 ID=self.update_id)
        print('connected to cavity probe pico server')

    @inlineCallbacks
    def connect_to_labrad_clock(self):
        #self.cxn = connect(name=self.name)
        self.cxn = connection()
        yield self.cxn.connect(name='clock viewer')
        server = yield self.cxn.get_server('clock_pico')
        yield server.signal__update(self.update_id)
        yield server.addListener(listener=self.receive_update,
                                 source=None,
                                 ID=self.update_id)
        print('connected to clock pico server')

    def preserve_lim(self):
        all_ax = self.canvas.trace_axes + self.canvas.data_axes
        lims = np.zeros((len(all_ax), 4))
        for i in np.arange(len(all_ax)):
            lims[i, 0:2] = all_ax[i].get_xlim()
            lims[i, 2:4] = all_ax[i].get_ylim()
        return lims

    def enforce_lim(self, lims, preset):
        all_ax = self.canvas.trace_axes + self.canvas.data_axes
        for i in np.arange(len(all_ax)):
            if preset[i]:
                all_ax[i].set_xlim(lims[i, 0:2])
                current_y = all_ax[i].get_ylim()
                if current_y[1] > lims[i, 3]:
                    lims[i, 3] = current_y[1]
                if current_y[0] < lims[i, 2]:
                    lims[i, 2] = current_y[0]
                all_ax[i].set_ylim(lims[i, 2:4])

    def save_fig(self, ax, fig, title):
        #https://stackoverflow.com/questions/4325733/save-a-subplot-in-matplotlib
        extent = ax.get_window_extent().transformed(
            fig.dpi_scale_trans.inverted())
        extent_expanded = extent.expanded(1.5, 2)
        fig.savefig(title, bbox_inches=extent_expanded)

    def receive_update(self, c, update_json):
        update = json.loads(update_json)
        self.update = update
        this_expt, this_path = listeners.get_expt(update)
        if this_expt is not None and self.expt != this_expt:
            if (not self.expt.isnumeric()) and (self.data_path is not None):
                #Save data traces when expt ends
                folder_path = os.path.join(self.data_path, self.expt)
                np.save(os.path.join(folder_path, "processed_data_x"),
                        self.canvas.data_x)
                np.save(os.path.join(folder_path, "processed_data_y"),
                        self.canvas.data_y)
                self.save_fig(self.canvas.data_axes[0], self.canvas.fig,
                              os.path.join(folder_path, 'fig_0.png'))
                self.save_fig(self.canvas.data_axes[1], self.canvas.fig,
                              os.path.join(folder_path, 'fig_1.png'))
                print('Saved data in folder: ' + folder_path)
            if this_expt.isnumeric():
                self.canvas.fig.suptitle(self.expt + " ended")
                self.expt = this_expt
            else:
                print(this_expt)
                self.canvas.reset_data()
                self.expt = this_expt
                self.data_path = this_path
                self.canvas.fig.suptitle(self.expt)
                self.canvas.lim_set = self.canvas.lim_default

        #Get current lims to prevent re-scaling
        lims = self.preserve_lim()
        preset = self.canvas.lim_set.copy()

        #!!Specify listeners for diff axes:

        #Comment/uncomment next lines to turn off/on pmt listeners:
        self.mode(update, preset)
        listeners.atom_number(update,
                              self.canvas.data_axes[1],
                              self.canvas.data_x[1],
                              self.canvas.data_y[1],
                              bad_points=self.canvas.bad_data,
                              freq_domain=False)

        #Cavity single-tone traces:
        listeners.bare_cavity_single_tone(update, self.canvas.trace_axes[1],
                                          'gnd')
        listeners.bare_cavity_single_tone(update, self.canvas.trace_axes[2],
                                          'exc')

        #Cavity 2-tone probing clock operation:
        '''
        try:
            returned, vrs_gnd = listeners.cavity_probe_two_tone(update, self.canvas.trace_axes[1]) 
            self.canvas.lim_set[1] = returned or preset[1]
            print('fit one')
            returned, vrs_exc = listeners.cavity_probe_two_tone(update, self.canvas.trace_axes[2], 'exc') 
            self.canvas.lim_set[2] = returned or preset[2]
            
            listeners.exc_frac_cavity(update, self.canvas.data_axes[1], self.canvas.data_x[1], self.canvas.data_y[1], vrs_gnd, vrs_exc, 'sequencer.clock_phase')
            
        except:
            print('cannot extract tones')
        '''

        #Add back past lims to prevent rescaling
        self.enforce_lim(lims, preset)
        self.canvas.draw()

#Different potential plotter configs

    def set_freq(self):
        def freq_update(update, preset):
            self.canvas.lim_set[0] = listeners.pmt_trace(
                update, self.canvas.trace_axes[0]) or preset[0]
            exc_called = listeners.exc_frac(update, self.canvas.data_axes[0],
                                            self.canvas.data_x[0],
                                            self.canvas.data_y[0])

        return freq_update

    def set_time(self, time_name):
        def time_update(update, preset):
            self.canvas.lim_set[0] = listeners.pmt_trace(
                update, self.canvas.trace_axes[0]) or preset[0]
            exc_called = listeners.exc_frac(update,
                                            self.canvas.data_axes[0],
                                            self.canvas.data_x[0],
                                            self.canvas.data_y[0],
                                            time_domain=True,
                                            time_name=time_name)

        return time_update

    def set_phase(self):
        def phase_update(update, preset):
            self.canvas.lim_set[0] = listeners.pmt_trace(
                update, self.canvas.trace_axes[0]) or preset[0]
            exc_called = listeners.exc_frac(update,
                                            self.canvas.data_axes[0],
                                            self.canvas.data_x[0],
                                            self.canvas.data_y[0],
                                            time_domain=True,
                                            time_name='sequencer.clock_phase')

        return phase_update

    def set_shot(self):
        def shot_update(update, preset):
            bad_shot = self.canvas.bad_data[-1]
            self.canvas.lim_set[0] = listeners.pmt_trace(
                update, self.canvas.trace_axes[0]) or preset[0]
            exc_called = listeners.exc_frac(update,
                                            self.canvas.data_axes[0],
                                            self.canvas.data_x[0],
                                            self.canvas.data_y[0],
                                            freq_domain=False,
                                            n_avg=1,
                                            bad_shot=bad_shot)

        return shot_update

#Add buttons to select config, fit methods

    def add_subplot_buttons(self):
        self.nav.addAction('Fit', self.do_fit)

        #Add fft client option to left cavity trace
        self.fft_left = QPushButton(self)
        self.fft_left.setText('FFT on click')
        self.fft_left.move(500, 380)
        self.fft_left.clicked.connect(self.show_fft)

        #Add dropdown for setting data x axis
        self.dropdown = QComboBox(self)
        self.labels = [
            "Frequency", "Phase", "Dark time", "Pi time", "Shot num"
        ]
        self.fxns = [
            self.set_freq(),
            self.set_phase(),
            self.set_time('sequencer.t_dark'),
            self.set_time('sequencer.t_pi'),
            self.set_shot()
        ]
        self.dropdown.addItems(self.labels)
        self.dropdown.currentIndexChanged.connect(self.select_mode)
        self.dropdown.move(870, 4)
        self.mode = self.fxns[0]

        #Add dropdown for setting analysis fxn
        self.fxn_drop = QComboBox(self)
        self.fit_labels = [
            "Gaussian", "Inv. Gauss", "Phase fringe", "Local max", "Local min"
        ]
        self.fit_fxns = [
            fits.do_gaussian_fit, fits.do_inverted_gaussian_fit,
            fits.do_phase_fit, fits.do_local_max, fits.do_local_min
        ]
        self.fxn_drop.addItems(self.fit_labels)
        self.analysis_script = self.fit_fxns[0]
        self.fxn_drop.move(1000, 4)
        self.fxn_drop.currentIndexChanged.connect(self.select_script)

    def select_mode(self):
        txt = self.dropdown.currentText()
        ix = self.dropdown.currentIndex()
        self.mode = self.fxns[ix]
        self.canvas.reset_data()
        print(txt)

    def select_script(self):
        ix = self.fxn_drop.currentIndex()
        self.analysis_script = self.fit_fxns[ix]

    def do_fit(self):
        self.analysis_script(self.canvas.data_axes[0], self.canvas.data_x[0],
                             self.canvas.data_y[0])

    def show_fft(self):
        self.mouse_listener = self.canvas.mpl_connect('button_press_event',
                                                      self.process_click)

    def process_click(self, event):
        t_click = event.xdata
        self.canvas.mpl_disconnect(self.mouse_listener)
        self.FFTPlot = FFTPlotter(self.update, t_click)
        self.FFTPlot.show()

    def show_fft(self):
        self.mouse_listener = self.canvas.mpl_connect('button_press_event',
                                                      self.process_click)
コード例 #3
0
class PMTViewer(QtWidgets.QDialog):
    pmt_name = None
    data_dir = None

    def __init__(self, reactor, cxn=None):
        super(PMTViewer, self).__init__(None)
        self.reactor = reactor
        self.cxn = cxn
        print(self.data_dir)

        self.update_id = np.random.randint(0, 2**31 - 1)
        self.loading = False
        self.connect()
   
    @inlineCallbacks
    def connect(self):
        if self.cxn is None:
            self.cxn = connection()
            cname = 'pmt - {} - client'.format(self.pmt_name)
            yield self.cxn.connect(name=cname)

        self.populate()
        yield self.connect_signals()

    def populate(self):
        self.setWindowTitle(self.pmt_name)
        self.canvas = MplCanvas()
        self.nav = NavigationToolbar(self.canvas, self)
        
        self.layout = QtWidgets.QGridLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)
        
        self.layout.addWidget(self.nav)
        self.layout.addWidget(self.canvas)

        self.setLayout(self.layout)
       
        width = self.canvas.width()
        height = self.nav.height() + self.canvas.height() + 20
        self.setFixedSize(width, height)
        self.setWindowTitle('pmt_viewer')

    @inlineCallbacks
    def connect_signals(self):
        pmt_server = yield self.cxn.get_server('pmt')
        yield pmt_server.signal__update(self.update_id)
        yield pmt_server.addListener(listener=self.receive_update, source=None, 
                                     ID=self.update_id)

    def receive_update(self, c, signal_json):
        signal = json.loads(signal_json)
        for message_type, message in signal.items():
            # print(message_type, message)
            device_message = message.get(self.pmt_name)
            if (message_type == 'record') and (device_message is not None):
                self.replot(device_message)

    def replot(self, rel_data_path):
        abs_data_path = os.path.join(self.data_dir, rel_data_path) + '.hdf5'
        
        with h5py.File(abs_data_path, mode ='r') as h5f:
            gnd = h5f['gnd']
            exc = h5f['exc']
            bac = h5f['bac']
            self.canvas.ax.clear()
            self.canvas.ax.plot(gnd, label='gnd')
            self.canvas.ax.plot(exc, label='exc')
            self.canvas.ax.plot(bac, label='bac')
            self.canvas.ax.legend()
        self.canvas.draw()
    
    def closeEvent(self, x):
        self.reactor.stop()
コード例 #4
0
class AnalogVoltageEditor(QtWidgets.QDialog):
    sequence_parameters = {}

    def __init__(self, channel, sequence, cxn, reactor, parent=None):
        super(AnalogVoltageEditor, self).__init__(parent)
        self.channel = str(channel)
        self.sequence = sequence
        self.ramp_maker = RampMaker
        self.parent = parent
        self.cxn = cxn
        self.reactor = reactor

        self.conductor_update_id = np.random.randint(0, 2**31 - 1)

        self.loading = False
        self.connect()

    @inlineCallbacks
    def connect(self):
        #        self.cxn = connection()
        #        yield self.cxn.connect()
        yield self.get_sequence_parameters()
        self.populate()
        yield self.connect_signals()

    def populate(self):
        self.setWindowTitle(self.channel)

        self.canvas = MplCanvas()
        self.nav = NavigationToolbar(self.canvas, self)
        self.ramp_table = RampTable(self.ramp_maker)
        self.ramp_scroll = QtWidgets.QScrollArea()
        self.buttons = QtWidgets.QDialogButtonBox(
            QtWidgets.QDialogButtonBox.Ok
            | QtWidgets.QDialogButtonBox.Cancel, QtCore.Qt.Horizontal, self)

        self.ramp_scroll.setWidget(self.ramp_table)
        self.ramp_scroll.setFixedHeight(
            self.ramp_table.height() +
            self.ramp_scroll.horizontalScrollBar().height() - 10)
        self.ramp_scroll.setWidgetResizable(True)
        self.buttons.button(QtWidgets.QDialogButtonBox.Ok).setDefault(False)

        self.layout = QtWidgets.QGridLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)

        self.layout.addWidget(self.nav)
        self.layout.addWidget(self.canvas)
        self.layout.addWidget(self.ramp_scroll)
        self.layout.addWidget(self.buttons)

        self.setLayout(self.layout)

        width = self.canvas.width()
        height = self.nav.height() + self.canvas.height(
        ) + self.ramp_scroll.height() + 20
        self.setFixedSize(width, height)
        self.set_columns()
        self.replot()

    @inlineCallbacks
    def connect_signals(self):
        # pyqt signals
        for c in self.ramp_table.cols:
            c.ramp_select.currentIndexChanged.connect(self.replot)
            for pw in c.parameter_widgets.values():
                for pb in pw.pboxes.values():
                    pb.returnPressed.connect(self.replot)

        for i, c in enumerate(self.ramp_table.cols):
            c.add.clicked.connect(self.add_column(i))
            c.dlt.clicked.connect(self.dlt_column(i))

        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)

        # labrad signals
        conductor = yield self.cxn.get_server(self.parent.conductor_servername)
        yield conductor.signal__update(self.conductor_update_id)
        yield conductor.addListener(listener=self.receive_conductor_update,
                                    source=None,
                                    ID=self.conductor_update_id)

    @inlineCallbacks
    def get_sequence_parameters(self):
        conductor = yield self.cxn.get_server(self.parent.conductor_servername)
        parameter_names = get_sequence_parameters(self.sequence)
        request = {
            parameter_name.replace('*', 'sequencer.'): None
            for parameter_name in parameter_names
        }
        parameter_values_json = yield conductor.get_parameter_values(
            json.dumps(request))
        parameter_values = json.loads(parameter_values_json)
        self.sequence_parameters = {
            name.replace('sequencer.', '*'): value
            for name, value in parameter_values.items()
        }

    def receive_conductor_update(self, c, signal_json):
        signal = json.loads(signal_json)
        for message_type, message in signal.items():
            if message_type in [
                    'set_parameter_values', 'get_parameter_values'
            ]:
                update = {
                    name.replace('sequencer.', '*'): value
                    for name, value in message.items()
                }
                self.sequence_parameters.update(update)
                self.replot()

    def set_columns(self):
        self.loading = True
        for c in self.ramp_table.cols:
            c.hide()

        for s, c in zip(self.sequence[self.channel], self.ramp_table.cols):
            ramp_type = s['type']
            c.show()
            c.ramp_select.setCurrentIndex(c.ramp_select.findText(ramp_type))
            for k in c.parameter_widgets[ramp_type].pboxes.keys():
                c.parameter_widgets[ramp_type].pboxes[k].display(
                    s[k])  # Plot Sequence in Analog Boxes

        self.loading = False
        self.replot()

    def add_column(self, i):
        def ac():
            sequence = self.get_sequence()
            for c in sequence.keys():
                if 'type' in sequence[c][i].keys():
                    a = {}
                    dt = sequence[c][i]['dt']
                    vf = sequence[c][i]['vf']
                    a.update({'type': 's', 'dt': dt, 'vf': vf})
                    sequence[c].insert(i + 1, a)
                else:
                    sequence[c].insert(i, sequence[c][i])
                # sequence[c].insert(i, sequence[c][i])
            self.set_sequence(sequence)

        return ac

    def dlt_column(self, i):
        def dc():
            sequence = self.get_sequence()
            for c in sequence.keys():
                sequence[c].pop(i)
            self.set_sequence(sequence)

        return dc

    def set_sequence(self, sequence):
        self.sequence = sequence
        self.set_columns()

    def get_plottable_sequence(self):
        sequence = self.ramp_table.get_channel_sequence()
        plottable_sequence = substitute_sequence_parameters(
            sequence, self.sequence_parameters)
        return self.ramp_maker(plottable_sequence).get_plottable()

    def get_sequence(self):
        channel_sequence = self.ramp_table.get_channel_sequence()
        self.sequence.update({self.channel: channel_sequence})
        return self.sequence

    def replot(self, c=None):
        if not self.loading:
            T, V = self.get_plottable_sequence()
            self.canvas.make_figure(T, V)
            self.canvas.draw()

    def getEditedSequence(self):
        return self.get_sequence()

    def keyPressEvent(self, c):
        if QtWidgets.QApplication.keyboardModifiers(
        ) == QtCore.Qt.ControlModifier:
            if c.key() == QtCore.Qt.Key_Return:
                self.buttons.accepted.emit()
            if c.key() == QtCore.Qt.Key_Q:
                self.buttons.rejected.emit()
        else:
            QtWidgets.QWidget().keyPressEvent(c)
コード例 #5
0
class CameraGui(QDialog):
    def set_vars(self):
        self.camera = 'vertical_mot'
        self.name = self.camera
        self.fluorescence_mode = True
        self.update_id = np.random.randint(0, 2**31 - 1)
        self.ROI = None
        self.no_lim = True

    def __init__(self):
        super(CameraGui, self).__init__(None)
        self.set_vars()
        self.connect_to_labrad()
        self.populate()
        self.Plotter = LivePlotter(self)

    def populate(self):
        self.setWindowTitle(self.name)
        self.canvas = MplCanvas()

        self.nav = NavigationToolbar(self.canvas, self)
        #select_cam = self.nav.addAction('&Select camera')
        #select_cam.addAction('horizontal mot')
        #select_cam.addAction('vertical mot (cavity)')
        self.nav.addAction('Launch live plotter', self.launch_plotter)

        self.layout = QGridLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)

        self.layout.addWidget(self.nav)
        self.layout.addWidget(self.canvas)

        self.setLayout(self.layout)
        width = self.canvas.width()
        height = self.nav.height() + self.canvas.height()
        self.setFixedSize(width, height)

    #Labrad connection:
    @inlineCallbacks
    def connect_to_labrad(self):
        #self.cxn = connect(name=self.name)
        self.cxn = connection()
        yield self.cxn.connect(name='camera viewer')
        server = yield self.cxn.get_server('camera')
        yield server.signal__update(self.update_id)
        yield server.addListener(listener=self.receive_update,
                                 source=None,
                                 ID=self.update_id)
        print('connected')

    def receive_update(self, c, update_json):
        update = json.loads(update_json)
        for key, value in update.items():
            if key == self.camera:
                if self.fluorescence_mode:
                    if not (('exc' in value[0]) or ('background' in value[0])):
                        print(value)
                        if 'gnd' in value[0]:
                            print(value[0])
                            str_end = '_fluorescence.png'
                            keyword = 'mot_cavity_'
                            split_str = value[0].partition(str_end)
                            parse_name = split_str[0].partition(keyword)
                            print(parse_name)
                            beginning = parse_name[0]
                            shot_num = int(parse_name[-1])
                            offset = 3
                            mod_shot = shot_num - offset
                            new_path = beginning + keyword + str(
                                mod_shot) + str_end
                            print(new_path)
                            self.file_to_show = new_path  #value[0]
                        else:
                            self.file_to_show = value[0]
                        print(self.file_to_show)

                        time.sleep(.1)
                        self.Plotter.show_window()
                        self.show_window()

    def show_window(self):
        try:
            if not self.no_lim:
                xlim = self.canvas.ax.get_xlim()
                ylim = self.canvas.ax.get_ylim()
            #self.canvas.ax.clear() #MOVED to after attempt to load fig
            it.fig_gui_window_ROI(self.file_to_show, self.canvas.ax, self.ROI)
            if not self.no_lim:
                self.canvas.ax.set_xlim(xlim)
                self.canvas.ax.set_ylim(ylim)
            else:
                self.no_lim = False
            print(self.canvas.ax.get_xlim())
            self.canvas.ax.set_title("{:.3e}".format(self.Plotter.title),
                                     color='w',
                                     y=.85,
                                     size=42)
            self.canvas.draw()
            print('redrawn')
        except:
            #self.no_lim = True
            print('Error loading file: not refreshed')

    def launch_plotter(self):
        self.Plotter.show()
コード例 #6
0
class LivePlotter(QDialog):
    def set_class_vars(self):
        self.script = it.fig_plotter
        self.n_show = 30
        self.live_data = np.full(self.n_show, None)

    def __init__(self, parent):
        super(LivePlotter, self).__init__()
        self.parent = parent
        self.set_class_vars()
        self.populate()

    def populate(self):
        self.setWindowTitle('Live plotter')
        self.canvas = MplCanvas()
        self.nav = NavigationToolbar(self.canvas, self)
        '''Changed nav toolbar'''
        self.nav.addAction('Reset optimizer', self.reset_opt)

        self.layout = QGridLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)

        self.layout.addWidget(self.nav)
        self.layout.addWidget(self.canvas)

        self.setLayout(self.layout)
        #self.canvas.ax.set_ylim((0, 5e-5))
        #self.canvas.ax.set_xlim((0, .04))
        width = self.canvas.width()
        height = self.nav.height() + self.canvas.height() + 20
        self.setFixedSize(width, height)

    def reset_opt(self):
        self.live_data = np.full(self.n_show, None)

    def live_plot(self):
        #try:
        roi = self.get_ROI()
        this_shot = self.script(self.parent.file_to_show, roi)
        self.title = this_shot
        empty_data = np.where(self.live_data == None)
        if len(empty_data[0]) == 0:
            self.live_data[0:self.n_show - 1] = self.live_data[1:self.n_show]
            self.live_data[-1] = this_shot
        else:
            self.live_data[empty_data[0][0]] = this_shot

    #except AttributeError:
    #   print('Not loaded')

    def get_ROI(self):
        xlim = self.parent.canvas.ax.get_xlim()
        ylim = self.parent.canvas.ax.get_ylim()
        ROI_exact = [xlim[0], ylim[0], xlim[1] - xlim[0], ylim[1] - ylim[0]]
        return [int(x) for x in ROI_exact]

    def show_window(self):
        self.live_plot()
        self.canvas.ax.clear()
        self.canvas.ax.plot(self.live_data, 'o')
        #self.canvas.ax.title(np.std(self.live_data))
        self.canvas.draw()
コード例 #7
0
class PDViewer(QtWidgets.QDialog):
    pd_name = None
    data_dir = None

    boxHeight = 50
    boxWidth = 220

    def __init__(self, reactor, cxn=None):
        super(PDViewer, self).__init__(None)
        self.reactor = reactor
        self.cxn = cxn
        print(self.data_dir)

        self.update_id = np.random.randint(0, 2**31 - 1)
        self.loading = False
        self.connect()

    @inlineCallbacks
    def connect(self):
        if self.cxn is None:
            self.cxn = connection()
            cname = 'pd - {} - client'.format(self.pd_name)
            yield self.cxn.connect(name=cname)

        self.populate()
        yield self.connect_signals()

    def populate(self):
        self.setWindowTitle(self.pd_name)
        self.canvas = MplCanvas()
        self.nav = NavigationToolbar(self.canvas, self)

        self.nameLabel1 = ClickableLabel('Parameter 1: ')
        self.nameLabel1.setFont(QtGui.QFont("Times", 18))
        self.nameBox1 = QtWidgets.QLineEdit()
        self.nameBox1.setFixedSize(self.boxWidth, self.boxHeight)

        self.valueLabel1 = ClickableLabel('Value 1: ')
        self.valueLabel1.setFont(QtGui.QFont("Times", 18))
        self.valueBox1 = NeatSpinBox()
        self.valueBox1.setFixedSize(self.boxWidth, self.boxHeight)

        self.nameLabel2 = ClickableLabel('Parameter 2: ')
        self.nameLabel2.setFont(QtGui.QFont("Times", 18))
        self.nameBox2 = QtWidgets.QLineEdit()
        self.nameBox2.setFixedSize(self.boxWidth, self.boxHeight)

        self.valueLabel2 = ClickableLabel('Value 2: ')
        self.valueLabel2.setFont(QtGui.QFont("Times", 18))
        self.valueBox2 = NeatSpinBox()
        self.valueBox2.setFixedSize(self.boxWidth, self.boxHeight)

        self.layout = QtWidgets.QGridLayout()
        self.layout.setSpacing(1)
        self.layout.setContentsMargins(2, 2, 2, 2)

        self.layout.addWidget(self.nav, 1, 0, 1, 5)
        self.layout.addWidget(self.canvas, 2, 0, 4, 4)

        self.layout.addWidget(self.nameLabel1, 7, 0, 1, 1,
                              QtCore.Qt.AlignRight)
        self.layout.addWidget(self.nameBox1, 7, 1)
        self.layout.addWidget(self.valueLabel1, 7, 2, 1, 1,
                              QtCore.Qt.AlignRight)
        self.layout.addWidget(self.valueBox1, 7, 3)

        # self.layout.addWidget(self.nameLabel2, 8, 0, 1, 1,
        #                       QtCore.Qt.AlignRight)
        # self.layout.addWidget(self.nameBox2, 8, 1)
        # self.layout.addWidget(self.valueLabel2, 8, 2, 1, 1,
        #                       QtCore.Qt.AlignRight)
        # self.layout.addWidget(self.valueBox2, 8, 3)

        self.setLayout(self.layout)

        width = self.canvas.width() + 20
        height = self.nav.height() + self.canvas.height(
        ) + self.nameBox1.height() * 2 + 60
        self.setFixedSize(width, height)
        self.setWindowTitle('pd_viewer')

    @inlineCallbacks
    def connect_signals(self):
        pd_server = yield self.cxn.get_server('pd')
        yield pd_server.signal__update(self.update_id)
        yield pd_server.addListener(listener=self.receive_update,
                                    source=None,
                                    ID=self.update_id)

    def receive_update(self, c, signal_json):
        signal = json.loads(signal_json)
        for message_type, message in signal.items():
            device_message = message.get(self.pd_name)
            if (message_type == 'record') and (device_message is not None):
                print(message_type, message)
                self.replot(device_message)
            elif (message_type == 'loading_rate') and (device_message
                                                       is not None):
                print(message_type, message)
                sample_rate = message.get('sample_rate')
                loading_rate, loss_rate, volt_to_number = process_signal(
                    sample_rate, device_message, message_type)
                # self.GetParameter()
                # self.GetValue()
                self.replot_loading(sample_rate, device_message, loading_rate,
                                    loss_rate)

    def replot(self, rel_data_path):
        abs_data_path = os.path.join(self.data_dir, rel_data_path) + '.hdf5'
        save_data_path = os.path.join(self.data_dir, rel_data_path) + '.png'
        with h5py.File(abs_data_path) as h5f:
            exp = h5f['exp']
            self.canvas.ax.clear()
            self.canvas.ax.plot(exp, label='exp')
            self.canvas.ax.legend()
            self.canvas.ax.set_xlabel('Points')
            self.canvas.ax.set_ylabel('Voltage [V]')
        self.canvas.fig.savefig(save_data_path)
        self.canvas.draw()

    def replot_loading(self, sample_rate, rel_data_path, loading_rate,
                       loss_rate):
        abs_data_path = os.path.join(self.data_dir, rel_data_path) + '.hdf5'
        save_data_path = os.path.join(self.data_dir, rel_data_path) + '.png'
        with h5py.File(abs_data_path) as h5f:
            exp = h5f['exp']
            self.canvas.ax.clear()
            x = np.linspace(0, len(exp) / sample_rate, len(exp))
            self.canvas.ax.plot(x, exp, label='exp', c='black')
            self.canvas.ax.plot(x,
                                fit_loading(x, loading_rate, loss_rate),
                                label='fitted',
                                c='red',
                                linestyle='dashed')
            self.canvas.ax.legend()
            self.canvas.ax.set_xlabel('Time [s]')
            self.canvas.ax.set_ylabel('Voltage [V]')
        self.canvas.fig.savefig(save_data_path)
        self.canvas.draw()

    def closeEvent(self, x):
        self.reactor.stop()