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)])
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
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
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()
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()
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() '''
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)
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,:])}')
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)