def update_parameter(self):
        self.sig_task.close()
        self.pulse_task.close()
        samp_rate = int(self.parameters['sampling_rate'])
        pulse_data = pulse_interpreter(
            BASE_FOLDER + '\pyqt_circulation_measurement\pulse_sequences\\' +
            self.parameters['pulse_file'], samp_rate,
            int(self.parameters['iteration']))
        self.samp_num = len(pulse_data)
        self.sig_task = Task('signal_task')
        self.pulse_task = Task('pulse task')
        for key, item in self.parameters.items():
            if 'channel' in key:
                if 'pulse' in key:
                    self.pulse_task.ao_channels.add_ao_voltage_chan(item)
                else:
                    self.sig_task.ai_channels.add_ai_voltage_chan(
                        physical_channel=item,
                        terminal_config=constants.TerminalConfiguration.
                        DIFFERENTIAL)

        self.pulse_task.timing.cfg_samp_clk_timing(
            rate=samp_rate,
            samps_per_chan=self.samp_num,
            sample_mode=constants.AcquisitionType.FINITE)
        self.sig_task.timing.cfg_samp_clk_timing(
            rate=samp_rate,
            source='/Dev1/ao/SampleClock',
            samps_per_chan=self.samp_num,
            sample_mode=constants.AcquisitionType.FINITE)
        self.pulse_task.write(pulse_data)
        self.time_data = np.linspace(0, (self.samp_num / samp_rate),
                                     self.samp_num)
        self.time_data = np.reshape(self.time_data, (1, self.samp_num))
    def __define_tasks__(self, write_data, sample_rate, number_of_samples):
        """Here we define the read and write tasks, including their timing"""
        self.readTask = Task()
        # Set channel to read from
        self.readTask.ai_channels.add_ai_voltage_chan(
            physical_channel='myDAQ1/ai0')
        self.readTask.ai_channels.add_ai_voltage_chan(
            physical_channel='myDAQ1/ai1')

        # Configure timing
        self.readTask.timing.cfg_samp_clk_timing(
            rate=sample_rate,
            samps_per_chan=number_of_samples,
            sample_mode=constants.AcquisitionType.FINITE)

        # We define and configure the write task
        self.writeTask = Task()
        # Set channel
        self.writeTask.ao_channels.add_ao_voltage_chan('myDAQ1/ao0')
        self.writeTask.ao_channels.add_ao_voltage_chan('myDAQ1/ao1')
        # Set timing
        self.writeTask.timing.cfg_samp_clk_timing(
            rate=sample_rate,
            samps_per_chan=number_of_samples,
            sample_mode=constants.AcquisitionType.FINITE)

        self.xarr_fit = np.linspace(0, number_of_samples / sample_rate,
                                    number_of_samples)
        self.yarr_fit = np.sin(2 * np.pi * self.freq * self.xarr_fit)
        #self.fitfreq = (number_of_samples / sample_rate)/5.
        #self.fit_data = 3*np.sin(2*np.pi*self.fitfreq*self.xarr_fit)
        self.writeTask.write([list(self.yarr_fit), list(write_data)])
Exemple #3
0
def open_niboard(sample_rate, n_samples, conf):
    with Task() as read_task, Task() as write_task_z, Task() as write_task_xy:
        try:
            yield NIBoards(
                sample_rate,
                n_samples,
                conf,
                read_task=read_task,
                write_task_z=write_task_z,
                write_task_xy=write_task_xy,
            )
        finally:
            pass
Exemple #4
0
    def _initialize(self):
        self._task = Task()

        for channel in self.channels:
            if self.zero_based:
                channel_no = channel
            else:
                channel_no = channel - 1
            chan_name = 'Dev' + self.dev + '/ai' + str(channel_no)
            self._task.ai_channels.add_ai_voltage_chan(chan_name)

        self._task.timing.cfg_samp_clk_timing(
            rate=self.rate, sample_mode=AcquisitionType.FINITE)
def config_for_task(name_task='', frequency=1000.0, port='Dev1/ai0'):
    """

    :param name_task: name of task
    :param frequency: in Hz
    :return:
    """
    from nidaqmx.task import Task
    configed_task = Task(name_task)
    configed_task.ai_channels.add_ai_voltage_chan(port)
    configed_task.timing.cfg_samp_clk_timing(rate=frequency)

    return configed_task
Exemple #6
0
def init_task(task_name="ttl_pulse",
              min_val=0.0,
              max_val=1.0,
              chan_path='Dev1/ao0',
              chan_des="mychan"):
    if _got_nidaqmx:
        global _ni_tasks

        if task_name in _ni_tasks.keys():
            return _ni_tasks[task_name]
        else:
            _ni_tasks[task_name] = Task(task_name)
            _ni_tasks[task_name].ao_channels.add_ao_voltage_chan(
                chan_path, chan_des, min_val, max_val)
            return _ni_tasks[task_name]
    else:
        print("Unable to setup ni Task! No sync pulses will be made.")
        return None
    def __init__(self, parent):
        from nidaqmx.stream_readers import AnalogSingleChannelReader
        from nidaqmx._task_modules.in_stream import InStream
        super(DisplayHrRr, self).__init__(parent)
        ui_path = str(pathlib.Path(__file__).parent) + "\\display.ui"
        self.ui = uic.loadUi(ui_path, self)

        info = read_config_file()
        configed_task = Task('Task read I signal')
        configed_task.ai_channels.add_ai_voltage_chan(info['port'])
        configed_task.timing.cfg_samp_clk_timing(
            rate=100,
            source=u'',
            active_edge=Edge.RISING,
            sample_mode=AcquisitionType.FINITE,
            samps_per_chan=1500)

        self.data_raw = np.zeros(shape=(1500, ))
        self.instream_analog_task = AnalogSingleChannelReader(
            InStream(configed_task))

        # init
        self.progress.setValue(0)
        self.init_state_button()

        self.button_auto.clicked.connect(self.button_auto_event)
        self.button_manual.clicked.connect(self.button_manual_event)
        self.button_refresh.clicked.connect(self.refresh)

        # click predict
        self.combobox_mode.addItems(["Tự động", "Thủ công"])
        self.manual_mode = False
        self.combobox_mode.currentIndexChanged.connect(self.update_mode)

        # event button
        self.button_predict.clicked.connect(self.predict)

        #thread read data temp
        import threading
        import src.utils.read_data_temp as rdt
        thread_read_data = threading.Thread(target=rdt.read_data_temp,
                                            daemon=True)
        thread_read_data.start()
Exemple #8
0
from nidaqmx.task import Task
from nidaqmx import constants
import numpy as np
from numpy import pi
import matplotlib.pylab as plt

samp_rate = 1000000
duration = 1
sample_num = 1000000
time = np.linspace(0, duration, sample_num)
freq = 1000

test_task = Task('ao_test')
test_task.ao_channels.add_ao_voltage_chan('/Dev1/ao1')
test_task.timing.cfg_samp_clk_timing(
    rate=samp_rate,
    #source = '/Dev1/ai/SampleClock', \
    samps_per_chan=sample_num,
    sample_mode=constants.AcquisitionType.CONTINUOUS)
pulse_data = np.sin(2 * pi * freq * time)
test_task.write(pulse_data)
test_task.start()

#test_task.wait_until_done()
test_task.stop()
test_task.close()
from nidaqmx.task import Task
from nidaqmx import constants
import numpy as np
import matplotlib.pylab as plt

samp_rate = 1000000
sample_num = 1000000
duration = 1
time = np.linspace(0,duration,sample_num)

test_task = Task('ai_test')
test_task.ai_channels.add_ai_voltage_chan(physical_channel = '/Dev1/ai1',
                terminal_config = constants.TerminalConfiguration.DIFFERENTIAL)
test_task.timing.cfg_samp_clk_timing(rate =samp_rate,
                 #source = '/Dev1/ai/SampleClock', \
                 samps_per_chan = sample_num, 
                 sample_mode=constants.AcquisitionType.FINITE)
test_task.start()
ai_data = test_task.read(number_of_samples_per_channel  = sample_num)
plt.plot(time,ai_data)
test_task.wait_until_done()
test_task.stop()
test_task.close()
Exemple #10
0
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__()

        self.setWindowTitle('Dissolution DNP Measurement (NSOR project)')
        self.setWindowIcon(
            QIcon(BASE_FOLDER + r"\pyqt_analysis\icons\window_icon.png"))
        '''
        --------------------------setting menubar-------------------------------
        '''
        mainMenu = self.menuBar()  #create a menuBar
        fileMenu = mainMenu.addMenu('&File')  #add a submenu to the menu bar
        '''
        --------------------------setting toolbar-------------------------------
        '''
        self.toolbar = self.addToolBar(
            'nsor_toolbar')  #add a tool bar to the window
        self.toolbar.setIconSize(QSize(100, 100))

        self.statusBar()  #create a status bar
        '''
        --------------------------setting matplotlib----------------------------
        axes are contained in one dictionary
        ax['time']
        ax['freq']
        also initiate the vertical lines
        vline['time_l']
        vline['time_r']
        vline['freq_l']
        vline['freq_r']
        '''
        if app.desktop().screenGeometry().height() == 2160:
            matplotlib.rcParams.update({'font.size': 28})
        elif app.desktop().screenGeometry().height() == 1080:
            matplotlib.rcParams.update({'font.size': 14})
        canvas = FigureCanvas(Figure(figsize=(50, 15)))

        self.ax = {}
        self.vline = {}
        self.ax['nmr_time'] = canvas.figure.add_subplot(221)
        self.ax['nmr_freq'] = canvas.figure.add_subplot(222)
        self.ax['nsor_time'] = canvas.figure.add_subplot(223)
        self.ax['nsor_freq'] = canvas.figure.add_subplot(224)

        for axis in self.ax.values():
            if app.desktop().screenGeometry().height() == 2160:
                axis.tick_params(pad=20)
            elif app.desktop().screenGeometry().height() == 1080:
                axis.tick_params(pad=10)
        '''
        use pyqtgraph for optical detector because of the fast drawing speed
        '''
        self.optical_graph = pg.PlotWidget()
        self.optical_data = np.zeros(500)
        self.optical_data += 1
        self.optical_curve = self.optical_graph.plot(self.optical_data)
        self.optical_graph.setYRange(-0.1, 1.1)
        print(self.optical_graph.size)
        '''
        --------------------------setting widgets-------------------------------
        '''
        exitProgram = QAction(
            QIcon(BASE_FOLDER + r'\pyqt_analysis\icons\exit_program.png'),
            '&Exit', self)
        exitProgram.setShortcut("Ctrl+W")
        exitProgram.setStatusTip('Close the Program')
        exitProgram.triggered.connect(self.exit_program)
        fileMenu.addAction(exitProgram)

        editParameters = QAction('&Edit Parameter', self)
        editParameters.setShortcut('Ctrl+E')
        editParameters.setStatusTip('open and edit the parameter file')
        editParameters.triggered.connect(self.edit_parameters)

        saveParameters = QAction('&Save Parameter', self)
        saveParameters.setShortcut('Ctrl+S')
        saveParameters.setStatusTip('save the parameters on screen to file')
        saveParameters.triggered.connect(self.save_parameters)
        parameterMenu = mainMenu.addMenu('&Parameter')
        parameterMenu.addAction(editParameters)
        parameterMenu.addAction(saveParameters)

        startExpBtn = QPushButton('START', self)
        startExpBtn.clicked.connect(self.fluid_detector_read)
        calibrateBtn = QPushButton('CALIBRATE', self)
        calibrateBtn.clicked.connect(self.calibrate_fluid_detector)
        self.readyBtn = QRadioButton('READY', self)
        self.stopBtn = QPushButton('STOP', self)
        self.stopBtn.setCheckable(True)

        injBtn = QPushButton('INJECT', self)
        injBtn.clicked.connect(lambda: self.switch_mode('inject'))
        loadBtn = QPushButton('LOAD', self)
        loadBtn.clicked.connect(lambda: self.switch_mode('load'))
        '''
        --------------------------setting layout/mix widget set-----------------
        '''
        tabs = QTabWidget()
        tabs.setDocumentMode(True)
        tabs.setTabPosition(QTabWidget.North)
        tabs.setMovable(True)

        tab = {'parameter': QWidget(), 'data': QWidget()}
        tab_layout = {'parameter': QVBoxLayout(), 'data': QHBoxLayout()}
        parameter_tab_layout = QFormLayout()
        sub_tab_layout = {'time': QVBoxLayout(), 'freq': QVBoxLayout()}
        optical_layout = QHBoxLayout()
        '''
        importing edits from paramter
        '''
        self.edits = {}
        self.parameters = read_parameter(PARAMETER_FILE)
        for key, value in self.parameters.items():
            if type(value) == list:
                value = str(value[0]) + ' ' + str(value[1])
            self.edits[key] = MyLineEdit(key, value, self)
            self.edits[key].setStatusTip(f'{key}')
            if 'nmr' in key:
                key_str = 'NMR Channel'
            elif 'nsor' in key:
                key_str = 'NSOR Channel'
            else:
                key_str = key.replace('_', ' ').title()

            if not ('time' in key or 'freq' in key):
                '''
                parameter tab layout:
                file_name; pulse_file; samp_rate; iteration; average; pulse_chan;
                nmr_chan; nsor_chan; laser_chan
                '''
                layout_temp = QHBoxLayout()
                layout_temp.addWidget(self.edits[key])
                if 'file' in key:
                    self.edits[key].setFixedWidth(1250)
                else:
                    layout_temp.addStretch(1)

                parameter_tab_layout.addRow(key_str, layout_temp)

            else:
                '''
                data tab layout:
                time_x_limit; time_y_limit; freq_x_limit; freq_y_limit;
                time_cursor; freq_cursor
                '''
                sub_tab_layout[key[0:4]].addWidget(QLabel(key_str, self))
                sub_tab_layout[key[0:4]].addWidget(self.edits[key])
                if 'freq' in key:
                    self.edits[key].setFixedWidth(250)

        for key in sub_tab_layout.keys():
            sub_tab_layout[key].addStretch(1)

        tab_layout['parameter'].addLayout(parameter_tab_layout)
        tab_layout['parameter'].addLayout(optical_layout)

        button_layout = QVBoxLayout()
        button_layout.addWidget(injBtn)
        button_layout.addWidget(loadBtn)
        button_layout.addWidget(startExpBtn)
        button_layout.addWidget(self.stopBtn)
        button_layout.addWidget(calibrateBtn)
        button_layout.addWidget(self.readyBtn)

        button_layout.addStretch(1)

        optical_layout.addLayout(button_layout)
        optical_layout.addWidget(self.optical_graph)

        # tab_layout['parameter'].addStretch(1)
        tab_layout['data'].addLayout(sub_tab_layout['time'])
        tab_layout['data'].addWidget(canvas)
        tab_layout['data'].addLayout(sub_tab_layout['freq'])
        for key in tab.keys():
            tabs.addTab(tab[key], key)
            tab[key].setLayout(tab_layout[key])

        _main = QWidget()
        self.setCentralWidget(_main)
        layout1 = QVBoxLayout(_main)
        layout1.addWidget(tabs)
        '''
        --------------------------Multithreading preparation--------------------
        '''
        self.threadpool = QThreadPool()  #Multithreading
        '''
        --------------------------Daqmx Task initialization---------------------
        '''
        di_line = 'Dev1/port2/line2'
        self.di_task = Task('di_task')
        self.di_task.di_channels.add_di_chan(di_line)

        do_line = 'Dev1/port1/line0, Dev1/port1/line1, Dev1/port1/line5'
        self.do_task = Task('do_task')
        self.do_task.do_channels.add_do_chan(do_line)
        self.do_task.start()
        '''
Exemple #11
0
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__()

        self.setWindowTitle('Pulse Visualizer')  # set the title of the window
        # set the icon for the window
        self.setWindowIcon(QIcon(BASE_FOLDER + r'\icons\window_icon.png'))
        '''
        --------------------------setting menubar-------------------------------
        '''
        mainMenu = self.menuBar()  #create a menuBar
        fileMenu = mainMenu.addMenu('&File')  #add a submenu to the menu bar

        self.statusBar()  #create a status bar
        '''
        --------------------------setting matplotlib----------------------------
        '''
        # depending on the resolution of the monitor, change the font size
        # in the matplotlib accordingly
        if app.desktop().screenGeometry().height() == 2160:
            matplotlib.rcParams.update({'font.size': 28})
        elif app.desktop().screenGeometry().height() == 1080:
            matplotlib.rcParams.update({'font.size': 14})

        # set the plotting area and decide the size in (w,h)
        self.canvas = FigureCanvas(Figure(figsize=(25, 15)))
        # include the built-in toolbar of the matplotlib
        self.addToolBar(NavigationToolbar(self.canvas, self))

        # add the first figure for time domain data
        self.ax = self.canvas.figure.add_subplot(121)
        # add the second figure for fourier data
        self.ax_f = self.canvas.figure.add_subplot(122)
        # change the axis tick position depending on the resolution of the
        # monitor
        if app.desktop().screenGeometry().height() == 2160:
            self.ax.tick_params(pad=20)
            self.ax_f.tick_params(pad=20)
        elif app.desktop().screenGeometry().height() == 1080:
            self.ax.tick_params(pad=10)
            self.ax_f.tick_params(pad=10)
        '''
        --------------------------setting widgets-------------------------------
        '''

        # setting the exit action,
        # 1. set it as an QAction, and give it some icon
        # 2. set the keyboard shortcut C+W
        # 3. when the mouse is hover over the icon, show the status tip at the bottom
        # 4. set if this action is triggered, what will happen, in this case,
        # a class method called exit_program is run, it can be found inside the
        # class defination after the initiation function
        # 5. add this action the the file menu
        exitProgram = QAction(QIcon(BASE_FOLDER + r'\icons\exit_program.png'),
                              '&Exit', self)
        exitProgram.setShortcut("Ctrl+W")
        exitProgram.setStatusTip('Close the Program')
        exitProgram.triggered.connect(self.exit_program)
        fileMenu.addAction(exitProgram)

        # set a start button
        # 1. set a button with 'Start' as the text on it
        # 2. set what happens if the button is clicked, in this case, a class
        # method called start_acq is run
        startAcq = QPushButton('START', self)
        startAcq.clicked.connect(self.start_acq)
        self.start_status = False

        # set a stop acquisition button
        # set the stop button to be a check button (if pushed won't bounce
        # back, need to be pushed again to bounce)
        # the stop button's push status is set to be read by other functions so
        # it does not associatate with any class method as the previous two
        self.stopAcq = QPushButton('STOP', self)
        self.stopAcq.setCheckable(True)
        '''
        --------------------------setting layout--------------------------------
        '''

        # set a virtual widget to place it in the center, nothing is shown
        _main = QWidget()
        self.setCentralWidget(_main)
        # add the first layout to be vertical layout and set it as the child of
        # the center widget
        layout1 = QVBoxLayout(_main)

        # add the second layout to be horizontal
        layout2 = QHBoxLayout()
        # set the startacq button, stopacq button to be horizontally placed
        layout2.addWidget(startAcq)
        layout2.addWidget(self.stopAcq)
        # instead of equally space the widgets, push them to the left by adding
        # a large white space to their right
        layout2.addStretch(1)

        # add the canvas to the first layout
        layout1.addWidget(self.canvas)
        # nest the second layout into the first one
        layout1.addLayout(layout2)
        '''
        --------------------------Multithreading preparation--------------------
        '''
        # initiate the multithreading pool
        self.threadpool = QThreadPool()  #Multithreading
        '''
        --------------------------configure daq task----------------------------
        '''
        # initiate the task with name 'signal_task'
        self.sig_task = Task('signal_task')

        samp_rate = 100000

        # add the voltage channel with physical channel name, also set the
        # channel read mode to be differential
        self.sig_task.ai_channels.add_ai_voltage_chan(
            physical_channel=r"Dev1/ai1",
            terminal_config=constants.TerminalConfiguration.DIFFERENTIAL)
        # set the timing for the signal task, the sampling rate, sample number
        # and sample mode are set here
        self.sig_task.timing.cfg_samp_clk_timing(
            rate=samp_rate,
            samps_per_chan=samp_rate * 1,
            sample_mode=constants.AcquisitionType.FINITE)

        # create the time axis
        self.time_data = np.linspace(0, 1, samp_rate)
        # create the corresponding frequency axis
        f_max = samp_rate / 2
        self.freq_data_x = np.linspace(0, f_max,
                                       int(len(self.time_data) / 2) + 1)
Exemple #12
0
def start_acquistion():
    '''
    set necessary constants
    '''
    samp_rate = int(float(samp_rate_entry.get()) * 1000000)
    iteration = int(iteration_entry.get())
    average = int(avg_entry.get())
    pulse_chan = pulse_channel_entry.get()
    nmr_chan = nmr_channel_entry.get()
    nsor_chan = nsor_channel_entry.get()
    laser_intensity_chan = laser_intensity_channel_entry.get()
    pulse_file_path = pulse_entry.get()
    file_path = file_path_entry.get()
    file_name = file_name_entry.get()

    pulse_data = pulse_interpreter(pulse_file_path, samp_rate, iteration)
    samp_num = len(pulse_data)
    '''
    configure the ao/ai tasks
    '''
    for current_iter in range(iteration):
        # note: displayed iteration starts with index of 1 while the iteration used in program starts with index of 0
        '''
        run, display and stored files
        '''
        current_iter_label.config(text=f'Current Iteration: {current_iter+1}')

        with Task('signal_task') as sig_task, Task('pulse_task') as pulse_task:
            for sig_chan in [nmr_chan, nsor_chan, laser_intensity_chan]:
                sig_task.ai_channels.add_ai_voltage_chan(
                    physical_channel=sig_chan,
                    terminal_config=constants.TerminalConfiguration.
                    DIFFERENTIAL)
            pulse_task.ao_channels.add_ao_voltage_chan(pulse_chan)
            pulse_task.timing.cfg_samp_clk_timing(
                rate=samp_rate,
                samps_per_chan=samp_num,
                sample_mode=constants.AcquisitionType.FINITE)
            sig_task.timing.cfg_samp_clk_timing(
                rate=samp_rate,
                source='/Dev1/ao/SampleClock',
                samps_per_chan=samp_num,
                sample_mode=constants.AcquisitionType.FINITE)
            pulse_task.write(pulse_data)
            time_data = np.linspace(0, (samp_num / samp_rate), samp_num)
            time_data = np.reshape(time_data, (1, samp_num))
            sig_data = np.zeros((3, samp_num))
            for current_avg in range(average):
                current_avg_label.config(
                    text=f'Current Iteration: {current_avg+1}')

                sig_task.start()
                pulse_task.start()
                sig_task.wait_until_done()
                pulse_task.wait_until_done()
                sig_data = (current_avg * sig_data + np.array(
                    sig_task.read(number_of_samples_per_channel=samp_num))) / (
                        current_avg + 1)
                sig_task.stop()
                pulse_task.stop()

                np.save(file_path + '\\' + file_name + str(current_iter),
                        np.concatenate((time_data, sig_data)))
                '''
                plot the data
                '''
                tcl_v = float(tcl_entry.get())
                tcl_i = np.argmin(np.abs(time_data - tcl_v))
                tch_v = float(tch_entry.get())
                tch_i = np.argmin(np.abs(time_data - tch_v))

                nmr_freq_sig = zero_pad_sig(sig_data[0, tcl_i:tch_i], 1)
                nsor_freq_sig = zero_pad_sig(sig_data[1, tcl_i:tch_i], 1)
                freq_axis = time2freq(time_data[0, tcl_i:tch_i], 1)

                nmr_time_ax.clear()
                nmr_time_ax.plot(time_data[0, :], sig_data[0, :])
                nmr_freq_ax.clear()
                nmr_freq_ax.plot(freq_axis, nmr_freq_sig)
                nsor_time_ax.clear()
                nsor_time_ax.plot(time_data[0, :], sig_data[1, :])
                nsor_freq_ax.clear()
                nsor_freq_ax.plot(freq_axis, nsor_freq_sig)
                '''
                set axis limit
                '''
                txlim = (float(txliml_entry.get()), float(txlimh_entry.get()))
                tylim = (float(tyliml_entry.get()), float(tylimh_entry.get()))
                fxlim = (float(fxliml_entry.get()), float(fxlimh_entry.get()))
                fylim = (float(fyliml_entry.get()), float(fylimh_entry.get()))
                nmr_time_ax.set_xlim(txlim)
                nmr_time_ax.set_ylim(tylim)
                nmr_freq_ax.set_xlim(fxlim)
                nmr_freq_ax.set_ylim(fylim)
                if var_tx.get():
                    nmr_time_ax.autoscale(axis='x')
                if var_ty.get():
                    nmr_time_ax.autoscale(axis='y')
                if var_fx.get():
                    nmr_freq_ax.autoscale(axis='x')
                if var_fy.get():
                    nmr_freq_ax.autoscale(axis='y')

                nmr_time_ax.axvline(float(tcl_entry.get()), c='red')
                nmr_time_ax.axvline(float(tch_entry.get()), c='red')
                nmr_freq_ax.axvline(float(fcl_entry.get()), c='red')
                nmr_freq_ax.axvline(float(fch_entry.get()), c='red')

                figs_canvas.draw()
                avg_intensity_label.configure(
                    text=f'Laser Intensity: {np.average(sig_data[2,:])}')
Exemple #13
0
class Nidaq(_BaseDAQ):
    """
    NIDAQ stream reader device.

    Parameters
    ----------
    channels : list or tuple
        Channels to use.
    rate : float
        Sampling rate.
    samples_per_read : int
        Number of samples per channel to read in each read operation.
    dev : str, optional
        Device name. By default, 1 is used.
    zero_based : bool, optional
        If ``True``, 0-based indexing is used for channel numbering. Default is
        ``True``.
    """
    def __init__(self,
                 channels,
                 rate,
                 samples_per_read,
                 dev='1',
                 zero_based=True):
        self.channels = channels
        self.rate = rate
        self.samples_per_read = samples_per_read
        self.dev = dev
        self.zero_based = zero_based

        self._initialize()

    def _initialize(self):
        self._task = Task()

        for channel in self.channels:
            if self.zero_based:
                channel_no = channel
            else:
                channel_no = channel - 1
            chan_name = 'Dev' + self.dev + '/ai' + str(channel_no)
            self._task.ai_channels.add_ai_voltage_chan(chan_name)

        self._task.timing.cfg_samp_clk_timing(
            rate=self.rate, sample_mode=AcquisitionType.FINITE)

    def start(self):
        """Tell the device to begin streaming data. Does not do anything."""
        pass

    def read(self):
        """
        Request a sample of data from the device.

        This is a blocking method, meaning it returns only once the requested
        number of samples are available.

        Returns
        -------
        data : ndarray, shape=(total_signals, num_samples)
            Data read from the device. Each channel is a row and each column
            is a point in time.
        """
        data = self._task.read(
            number_of_samples_per_channel=self.samples_per_read)
        return np.array(data)

    def stop(self):
        """Tell the device to stop streaming data."""
        self._task.close()

    def reset(self):
        """Reset the task."""
        self._initialize()
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__()

        self.parameters = read_parameter(PARAMETER_FILE)

        self.setWindowTitle('Circulation Measurement (NSOR project)')
        self.setWindowIcon(QIcon(BASE_FOLDER + r'\icons\window_icon.png'))
        '''
        --------------------------setting menubar-------------------------------
        '''
        mainMenu = self.menuBar()  #create a menuBar
        fileMenu = mainMenu.addMenu('&File')  #add a submenu to the menu bar
        '''
        --------------------------setting toolbar-------------------------------
        '''
        self.toolbar = self.addToolBar(
            'nsor_toolbar')  #add a tool bar to the window
        self.toolbar.setIconSize(QSize(100, 100))

        self.statusBar()  #create a status bar
        '''
        --------------------------setting matplotlib----------------------------
        axes are contained in one dictionary
        ax['nmr_time']
        ax['nmr_freq']
        ax['nsor_time']
        ax['nsor_freq']
        also initiate the vertical lines
        vline['time_l']
        vline['time_r']
        vline['freq_l']
        vline['freq_r']
        '''

        if app.desktop().screenGeometry().height() == 2160:
            matplotlib.rcParams.update({'font.size': 28})
        elif app.desktop().screenGeometry().height() == 1080:
            matplotlib.rcParams.update({'font.size': 14})
        canvas = FigureCanvas(Figure(figsize=(50, 15)))

        self.ax = {}
        self.vline = {}
        self.ax['nmr_time'] = canvas.figure.add_subplot(221)
        self.ax['nmr_freq'] = canvas.figure.add_subplot(222)
        self.ax['nsor_time'] = canvas.figure.add_subplot(223)
        self.ax['nsor_freq'] = canvas.figure.add_subplot(224)

        for axis in self.ax.values():
            if app.desktop().screenGeometry().height() == 2160:
                axis.tick_params(pad=20)
            elif app.desktop().screenGeometry().height() == 1080:
                axis.tick_params(pad=10)
        '''
        --------------------------setting widgets-------------------------------
        '''
        exitProgram = QAction(QIcon(BASE_FOLDER + r'\icons\exit_program.png'),
                              '&Exit', self)
        exitProgram.setShortcut("Ctrl+W")
        exitProgram.setStatusTip('Close the Program')
        exitProgram.triggered.connect(self.exit_program)
        fileMenu.addAction(exitProgram)

        editParameters = QAction('&Edit Parameter', self)
        editParameters.setShortcut('Ctrl+E')
        editParameters.setStatusTip('open and edit the parameter file')
        editParameters.triggered.connect(lambda: os.startfile(PARAMETER_FILE))

        saveParameters = QAction('&Save Parameter', self)
        saveParameters.setShortcut('Ctrl+S')
        saveParameters.setStatusTip('save the parameters on screen to file')
        saveParameters.triggered.connect(self.save_parameters)

        editPulse = QAction('&Edit Pulse', self)
        editPulse.setShortcut('Ctrl+P')
        editPulse.setStatusTip('open and edit the pulse file')
        editPulse.triggered.connect(lambda: os.startfile(
            BASE_FOLDER + '\pyqt_circulation_measurement\pulse_sequences\\' +
            self.parameters['pulse_file']))

        parameterMenu = mainMenu.addMenu('&Parameter')
        parameterMenu.addAction(editParameters)
        parameterMenu.addAction(saveParameters)
        parameterMenu.addAction(editPulse)

        pulseHelp = QAction('&Pulse Example', self)
        pulseHelp.setStatusTip('check the example pulse file')
        pulseHelp.triggered.connect(lambda: os.startfile(
            BASE_FOLDER +
            r'\pyqt_circulation_measurement\pulse_sequences\model_sequence.txt'
        ))

        helpMenu = mainMenu.addMenu('&Help')
        helpMenu.addAction(pulseHelp)

        startExpBtn = QPushButton('START', self)
        startExpBtn.clicked.connect(self.start_experiment)
        self.stopBtn = QPushButton('STOP', self)
        self.stopBtn.setCheckable(True)
        updateParamBtn = QPushButton('Update Parameter', self)
        updateParamBtn.clicked.connect(self.update_parameter)
        '''
        --------------------------setting layout/mix widget set-----------------
        '''
        tabs = QTabWidget()
        tabs.setDocumentMode(True)
        tabs.setTabPosition(QTabWidget.North)
        tabs.setMovable(True)

        tab = {'parameter': QWidget(), 'data': QWidget()}
        tab_layout = {'parameter': QVBoxLayout(), 'data': QHBoxLayout()}
        parameter_tab_layout = QFormLayout()
        sub_tab_layout = {'time': QVBoxLayout(), 'freq': QVBoxLayout()}
        '''
        importing edits from paramter
        '''
        self.edits = {}

        for key, value in self.parameters.items():
            if type(value) == list:
                value = str(value[0]) + ' ' + str(value[1])
            self.edits[key] = MyLineEdit(key, value, self)
            self.edits[key].setStatusTip(f'{key}')
            if 'nmr' in key:
                key_str = 'NMR Channel'
            elif 'nsor' in key:
                key_str = 'NSOR Channel'
            else:
                key_str = key.replace('_', ' ').title()

            if not ('time' in key or 'freq' in key):
                '''
                parameter tab layout:
                file_name; pulse_file; samp_rate; iteration; average; pulse_chan;
                nmr_chan; nsor_chan; laser_chan
                also add the signals to them
                '''
                self.edits[key].textModified.connect(self.parameter_change)

                layout_temp = QHBoxLayout()
                layout_temp.addWidget(self.edits[key])
                if 'file_name' in key:
                    self.edits[key].setFixedWidth(1250)
                else:
                    layout_temp.addStretch(1)

                parameter_tab_layout.addRow(key_str, layout_temp)

            else:
                '''
                data tab layout:
                time_x_limit; time_y_limit; freq_x_limit; freq_y_limit;
                time_cursor; freq_cursor
                also add the signals
                '''
                self.edits[key].textModified.connect(self.limit_and_cursor)

                sub_tab_layout[key[0:4]].addWidget(QLabel(key_str, self))
                sub_tab_layout[key[0:4]].addWidget(self.edits[key])
                if 'freq' in key:
                    self.edits[key].setFixedWidth(250)

        for key in sub_tab_layout.keys():
            sub_tab_layout[key].addStretch(1)

        tab_layout['parameter'].addLayout(parameter_tab_layout)
        tab_layout['parameter'].addWidget(updateParamBtn)
        tab_layout['parameter'].addStretch(1)
        button_layout = QHBoxLayout()
        button_layout.addWidget(startExpBtn)
        button_layout.addWidget(self.stopBtn)
        button_layout.addStretch(1)
        tab_layout['parameter'].addLayout(button_layout)

        tab_layout['data'].addLayout(sub_tab_layout['time'])
        tab_layout['data'].addWidget(canvas)
        tab_layout['data'].addLayout(sub_tab_layout['freq'])
        for key in tab.keys():
            tabs.addTab(tab[key], key)
            tab[key].setLayout(tab_layout[key])

        _main = QWidget()
        self.setCentralWidget(_main)
        layout1 = QVBoxLayout(_main)
        layout1.addWidget(tabs)
        '''
        --------------------------Multithreading preparation--------------------
        '''
        self.threadpool = QThreadPool()  #Multithreading
        '''
        --------------------------Daqmx Task initialization---------------------
        '''
        self.sig_task = Task('signal_task')
        self.pulse_task = Task('pulse task')
        self.update_parameter()
        '''
class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__()

        self.parameters = read_parameter(PARAMETER_FILE)

        self.setWindowTitle('Circulation Measurement (NSOR project)')
        self.setWindowIcon(QIcon(BASE_FOLDER + r'\icons\window_icon.png'))
        '''
        --------------------------setting menubar-------------------------------
        '''
        mainMenu = self.menuBar()  #create a menuBar
        fileMenu = mainMenu.addMenu('&File')  #add a submenu to the menu bar
        '''
        --------------------------setting toolbar-------------------------------
        '''
        self.toolbar = self.addToolBar(
            'nsor_toolbar')  #add a tool bar to the window
        self.toolbar.setIconSize(QSize(100, 100))

        self.statusBar()  #create a status bar
        '''
        --------------------------setting matplotlib----------------------------
        axes are contained in one dictionary
        ax['nmr_time']
        ax['nmr_freq']
        ax['nsor_time']
        ax['nsor_freq']
        also initiate the vertical lines
        vline['time_l']
        vline['time_r']
        vline['freq_l']
        vline['freq_r']
        '''

        if app.desktop().screenGeometry().height() == 2160:
            matplotlib.rcParams.update({'font.size': 28})
        elif app.desktop().screenGeometry().height() == 1080:
            matplotlib.rcParams.update({'font.size': 14})
        canvas = FigureCanvas(Figure(figsize=(50, 15)))

        self.ax = {}
        self.vline = {}
        self.ax['nmr_time'] = canvas.figure.add_subplot(221)
        self.ax['nmr_freq'] = canvas.figure.add_subplot(222)
        self.ax['nsor_time'] = canvas.figure.add_subplot(223)
        self.ax['nsor_freq'] = canvas.figure.add_subplot(224)

        for axis in self.ax.values():
            if app.desktop().screenGeometry().height() == 2160:
                axis.tick_params(pad=20)
            elif app.desktop().screenGeometry().height() == 1080:
                axis.tick_params(pad=10)
        '''
        --------------------------setting widgets-------------------------------
        '''
        exitProgram = QAction(QIcon(BASE_FOLDER + r'\icons\exit_program.png'),
                              '&Exit', self)
        exitProgram.setShortcut("Ctrl+W")
        exitProgram.setStatusTip('Close the Program')
        exitProgram.triggered.connect(self.exit_program)
        fileMenu.addAction(exitProgram)

        editParameters = QAction('&Edit Parameter', self)
        editParameters.setShortcut('Ctrl+E')
        editParameters.setStatusTip('open and edit the parameter file')
        editParameters.triggered.connect(lambda: os.startfile(PARAMETER_FILE))

        saveParameters = QAction('&Save Parameter', self)
        saveParameters.setShortcut('Ctrl+S')
        saveParameters.setStatusTip('save the parameters on screen to file')
        saveParameters.triggered.connect(self.save_parameters)

        editPulse = QAction('&Edit Pulse', self)
        editPulse.setShortcut('Ctrl+P')
        editPulse.setStatusTip('open and edit the pulse file')
        editPulse.triggered.connect(lambda: os.startfile(
            BASE_FOLDER + '\pyqt_circulation_measurement\pulse_sequences\\' +
            self.parameters['pulse_file']))

        parameterMenu = mainMenu.addMenu('&Parameter')
        parameterMenu.addAction(editParameters)
        parameterMenu.addAction(saveParameters)
        parameterMenu.addAction(editPulse)

        pulseHelp = QAction('&Pulse Example', self)
        pulseHelp.setStatusTip('check the example pulse file')
        pulseHelp.triggered.connect(lambda: os.startfile(
            BASE_FOLDER +
            r'\pyqt_circulation_measurement\pulse_sequences\model_sequence.txt'
        ))

        helpMenu = mainMenu.addMenu('&Help')
        helpMenu.addAction(pulseHelp)

        startExpBtn = QPushButton('START', self)
        startExpBtn.clicked.connect(self.start_experiment)
        self.stopBtn = QPushButton('STOP', self)
        self.stopBtn.setCheckable(True)
        updateParamBtn = QPushButton('Update Parameter', self)
        updateParamBtn.clicked.connect(self.update_parameter)
        '''
        --------------------------setting layout/mix widget set-----------------
        '''
        tabs = QTabWidget()
        tabs.setDocumentMode(True)
        tabs.setTabPosition(QTabWidget.North)
        tabs.setMovable(True)

        tab = {'parameter': QWidget(), 'data': QWidget()}
        tab_layout = {'parameter': QVBoxLayout(), 'data': QHBoxLayout()}
        parameter_tab_layout = QFormLayout()
        sub_tab_layout = {'time': QVBoxLayout(), 'freq': QVBoxLayout()}
        '''
        importing edits from paramter
        '''
        self.edits = {}

        for key, value in self.parameters.items():
            if type(value) == list:
                value = str(value[0]) + ' ' + str(value[1])
            self.edits[key] = MyLineEdit(key, value, self)
            self.edits[key].setStatusTip(f'{key}')
            if 'nmr' in key:
                key_str = 'NMR Channel'
            elif 'nsor' in key:
                key_str = 'NSOR Channel'
            else:
                key_str = key.replace('_', ' ').title()

            if not ('time' in key or 'freq' in key):
                '''
                parameter tab layout:
                file_name; pulse_file; samp_rate; iteration; average; pulse_chan;
                nmr_chan; nsor_chan; laser_chan
                also add the signals to them
                '''
                self.edits[key].textModified.connect(self.parameter_change)

                layout_temp = QHBoxLayout()
                layout_temp.addWidget(self.edits[key])
                if 'file_name' in key:
                    self.edits[key].setFixedWidth(1250)
                else:
                    layout_temp.addStretch(1)

                parameter_tab_layout.addRow(key_str, layout_temp)

            else:
                '''
                data tab layout:
                time_x_limit; time_y_limit; freq_x_limit; freq_y_limit;
                time_cursor; freq_cursor
                also add the signals
                '''
                self.edits[key].textModified.connect(self.limit_and_cursor)

                sub_tab_layout[key[0:4]].addWidget(QLabel(key_str, self))
                sub_tab_layout[key[0:4]].addWidget(self.edits[key])
                if 'freq' in key:
                    self.edits[key].setFixedWidth(250)

        for key in sub_tab_layout.keys():
            sub_tab_layout[key].addStretch(1)

        tab_layout['parameter'].addLayout(parameter_tab_layout)
        tab_layout['parameter'].addWidget(updateParamBtn)
        tab_layout['parameter'].addStretch(1)
        button_layout = QHBoxLayout()
        button_layout.addWidget(startExpBtn)
        button_layout.addWidget(self.stopBtn)
        button_layout.addStretch(1)
        tab_layout['parameter'].addLayout(button_layout)

        tab_layout['data'].addLayout(sub_tab_layout['time'])
        tab_layout['data'].addWidget(canvas)
        tab_layout['data'].addLayout(sub_tab_layout['freq'])
        for key in tab.keys():
            tabs.addTab(tab[key], key)
            tab[key].setLayout(tab_layout[key])

        _main = QWidget()
        self.setCentralWidget(_main)
        layout1 = QVBoxLayout(_main)
        layout1.addWidget(tabs)
        '''
        --------------------------Multithreading preparation--------------------
        '''
        self.threadpool = QThreadPool()  #Multithreading
        '''
        --------------------------Daqmx Task initialization---------------------
        '''
        self.sig_task = Task('signal_task')
        self.pulse_task = Task('pulse task')
        self.update_parameter()
        '''
        -------------------------Menu bar slot----------------------------------
        '''

    # def edit_parameters(self):
    #     os.startfile(PARAMETER_FILE)

    def save_parameters(self):
        for key in self.parameters.keys():
            str = self.edits[key].text()
            if 'freq' in key or 'time' in key:
                self.parameters[key] = str.split(' ')
            else:
                self.parameters[key] = str

        save_parameter(PARAMETER_FILE, **self.parameters)

    def exit_program(self):
        choice = QMessageBox.question(
            self, 'Exiting', 'Are you sure about exit?',
            QMessageBox.Yes | QMessageBox.No)  #Set a QMessageBox when called
        if choice == QMessageBox.Yes:  # give actions when answered the question
            sys.exit()

    '''
    --------------------------parameter update slots----------------------------
    '''

    def limit_and_cursor(self, key, text):
        pass

    def parameter_change(self, key, text):
        self.parameters[key] = text

    def update_parameter(self):
        self.sig_task.close()
        self.pulse_task.close()
        samp_rate = int(self.parameters['sampling_rate'])
        pulse_data = pulse_interpreter(
            BASE_FOLDER + '\pyqt_circulation_measurement\pulse_sequences\\' +
            self.parameters['pulse_file'], samp_rate,
            int(self.parameters['iteration']))
        self.samp_num = len(pulse_data)
        self.sig_task = Task('signal_task')
        self.pulse_task = Task('pulse task')
        for key, item in self.parameters.items():
            if 'channel' in key:
                if 'pulse' in key:
                    self.pulse_task.ao_channels.add_ao_voltage_chan(item)
                else:
                    self.sig_task.ai_channels.add_ai_voltage_chan(
                        physical_channel=item,
                        terminal_config=constants.TerminalConfiguration.
                        DIFFERENTIAL)

        self.pulse_task.timing.cfg_samp_clk_timing(
            rate=samp_rate,
            samps_per_chan=self.samp_num,
            sample_mode=constants.AcquisitionType.FINITE)
        self.sig_task.timing.cfg_samp_clk_timing(
            rate=samp_rate,
            source='/Dev1/ao/SampleClock',
            samps_per_chan=self.samp_num,
            sample_mode=constants.AcquisitionType.FINITE)
        self.pulse_task.write(pulse_data)
        self.time_data = np.linspace(0, (self.samp_num / samp_rate),
                                     self.samp_num)
        self.time_data = np.reshape(self.time_data, (1, self.samp_num))

    '''
    --------------------------Multithreading slots------------------------------
    '''

    def start_experiment(self):
        worker = ReadDataWorker(self.pulse_task, self.sig_task, self.stopBtn,
                                self.parameters, self.samp_num)
        worker.signals.data_measured.connect(self.store_plot_data)
        self.threadpool.start(worker)

    def store_plot_data(self, data):
        if self.stopBtn.isChecked():
            self.stopBtn.toggle()
        np.save(self.parameters['file_name'],
                np.concatenate((self.time_data, data)))
        self.ax['nmr_time'].clear()
        self.ax['nmr_time'].plot(self.time_data[0, :], data[0, :])
        self.ax['nsor_time'].clear()
        self.ax['nsor_time'].plot(self.time_data[0, :], data[1, :])

        f_max = int(self.parameters['sampling_rate']) / 2
        fourier_worker_nmr = FourierWorker(data[0, :], f_max, 'nmr_freq')
        fourier_worker_nmr.signals.data.connect(self.set_fourier)
        self.threadpool.start(fourier_worker_nmr)

        fourier_worker_nsor = FourierWorker(data[1, :], f_max, 'nsor_freq')
        fourier_worker_nsor.signals.data.connect(self.set_fourier)
        self.threadpool.start(fourier_worker_nsor)

    def set_fourier(self, data):
        key = data[2]
        self.ax[key].clear()
        self.ax[key].plot(data[0], np.abs(data[1]))
class read_writer():
    def __init__(self, freq, write_data, sample_rate, number_of_samples):
        """Function to read and write with the MyDAQ. Write data should be array with length equal to number_of_samples
       Make sure array does not exceed limits of MyDAQ as no safeguards are built into this function"""
        #if len(write_data) != number_of_samples:
        #    print("Wrong number of samples passed. Breaking now")
        #    return 0
        self.freq = freq
        self.__define_tasks__(write_data, sample_rate, number_of_samples)
        self.Nsamples = number_of_samples
        self.rate = sample_rate

    def __define_tasks__(self, write_data, sample_rate, number_of_samples):
        """Here we define the read and write tasks, including their timing"""
        self.readTask = Task()
        # Set channel to read from
        self.readTask.ai_channels.add_ai_voltage_chan(
            physical_channel='myDAQ1/ai0')
        self.readTask.ai_channels.add_ai_voltage_chan(
            physical_channel='myDAQ1/ai1')

        # Configure timing
        self.readTask.timing.cfg_samp_clk_timing(
            rate=sample_rate,
            samps_per_chan=number_of_samples,
            sample_mode=constants.AcquisitionType.FINITE)

        # We define and configure the write task
        self.writeTask = Task()
        # Set channel
        self.writeTask.ao_channels.add_ao_voltage_chan('myDAQ1/ao0')
        self.writeTask.ao_channels.add_ao_voltage_chan('myDAQ1/ao1')
        # Set timing
        self.writeTask.timing.cfg_samp_clk_timing(
            rate=sample_rate,
            samps_per_chan=number_of_samples,
            sample_mode=constants.AcquisitionType.FINITE)

        self.xarr_fit = np.linspace(0, number_of_samples / sample_rate,
                                    number_of_samples)
        self.yarr_fit = np.sin(2 * np.pi * self.freq * self.xarr_fit)
        #self.fitfreq = (number_of_samples / sample_rate)/5.
        #self.fit_data = 3*np.sin(2*np.pi*self.fitfreq*self.xarr_fit)
        self.writeTask.write([list(self.yarr_fit), list(write_data)])

    def __start__(self):
        """Here we start the writing and reading. We wait until reading is finished and then read the buffer from the DAQ"""
        self.readTask.start()
        self.writeTask.start()

        self.readTask.wait_until_done()
        self.writeTask.wait_until_done()
        # Acquire data
        self.__acquire__()
        self.__close__()
        self.__find_phi__()

    def __close__(self):
        """Here we shut the tasks explicitly. This function is called from the __start__ function"""
        # Close connection
        self.readTask.close()
        self.writeTask.close()

    def __acquire__(self):
        """Read the buffer into attribute self.data"""
        # Retrieve data
        self.input = self.readTask.read(
            number_of_samples_per_channel=self.Nsamples)

        self.data = self.input[1]
        self.fit_in = self.input[0]

    def __fit_call__(self, x, t0):
        return np.sin(2 * np.pi * self.freq * (x - t0))

    def __find_phi__(self):
        popt, pcov = curve_fit(self.__fit_call__,
                               self.xarr_fit[1000:],
                               self.fit_in[1000:],
                               p0=0,
                               maxfev=int(1e6))
        self.t0 = popt[0]

    def __output__(self):
        """Return a time array and the data"""
        # Prepare return data
        #time_arr = np.linspace(0, self.Nsamples/self.rate, self.Nsamples)
        t_arr = np.linspace(0, self.Nsamples / self.rate,
                            self.Nsamples) - self.t0
        return t_arr, np.array(self.data), self.t0

    freqarr = np.logspace(0, 3, 10)