from PyQt4 import QtCore from PyQt4 import QtGui import sys from THz_GUI_test import Ui_MainWindow import matplotlib.pyplot as plt from motor_controller_test import sixpack2 from motor_controller_test import smc100 import serial import io import time import os import csv import numpy as np import thread from bitlib import * class AppForm(QtGui.QMainWindow, Ui_MainWindow, sixpack2, smc100): def __init__(self, parent = None): super(AppForm, self).__init__(parent) self.setupUi(self) self.smc100_ctr = smc100() self.sixpack2_ctr = sixpack2() self.trig_lvl_input.setText('0') self.acq_time_input.setText('0.0001') self.rate_input.setText('100000') self.ctr1_is_enabled = True self.ctr2_is_enabled = True scan_axes = ['INT_MIR', 'VAC_MIR', 'VAC_HOR'] self.scan_type_selector.addItems(scan_axes) # ---> Default values for serial ports self.serial_port_name_input_int.setText("/dev/ttyAMA0") self.serial_port_name_input_vac.setText("/dev/ttyUSB0") # ---> Signals # open serial ports (check the ports first) self.open_port_button.clicked.connect( lambda: self.open_serial_port()) # move the mirror to absolute position self.move_mirror_button.clicked.connect( lambda: self.smc100_ctr.move_to_pos(1, self.move_mirror_to_pos.text(),self.sio)) # find home position for INT_LIN_MIR stage self.home_mirror_button.clicked.connect( lambda: self.smc100_ctr.find_home(1, self.sio)) # stop INT_LIN_MIR motor self.move_mirror_stop_button.clicked.connect( lambda: self.smc100_ctr.stop(1, self.sio)) # disable INT_LIN_MIR stage self.disable_mirror_button.clicked.connect( lambda: self.endis_mirror()) # disable INT_LIN_DET stage self.disable_detector_button.clicked.connect( lambda: self.endis_detector()) # move detector to absolute position self.move_detector_button.clicked.connect( lambda: self.smc100_ctr.move_to_pos(2, self.move_detector_to_pos.text(), self.sio)) # find home position for INT_LIN_DET stage self.home_detector_button.clicked.connect( lambda: self.smc100_ctr.find_home(2, self.sio)) # stop INT_LIN_DET motor self.move_detector_stop_button.clicked.connect( lambda: self.smc100_ctr.stop(2, self.sio)) # home vac_lin_hor self.lin_hor_home_button.clicked.connect( lambda: self.sixpack2_ctr.find_home(self.port_2, 0)) # move vac_lin_hor to absolute position self.lin_hor_move_button.clicked.connect( lambda: self.sixpack2_ctr.move_to_pos(self.port_2, 0, self.lin_hor_pos_input.text(), "lin")) # stop val_lin_hor motor self.lin_hor_stop_button.clicked.connect( lambda: self.sixpack2_ctr.stop(self.port_2, 0)) # open bitscope self.open_scope_button.clicked.connect(self.open_scope) # close bitscope self.close_scope_button.clicked.connect(self.close_scope) # start scan self.scan_button.clicked.connect( lambda: self.scan(float(self.scan_start.text()), float(self.scan_stop.text()), float(self.scan_step.text()), int(self.scan_rep.text()))) # acquire trace from the scope self.acquire_trace_button.clicked.connect(self.scope_acquire) # save single shot data self.save_single_shot_button.clicked.connect(lambda: self.save_single_shot(self.scope_acquire())) return # ---> Functions def open_scope(self): # When called it is doing something with other ports. Better to call it before opening ports for novers. # ---> Scope inputs self.rate = float((self.rate_input.text())) # Hz self.trig_lvl = float(self.trig_lvl_input.text()) # V self.acq_time = float(self.acq_time_input.text()) # s print "Attempting to open the BitScope" if BL_Open("", 1): print "Bitscope is opened" # setup channel 4 (logic) for trigger BL_Select(BL_SELECT_DEVICE, 0) BL_Mode(BL_MODE_MIXED) BL_Select(BL_SELECT_CHANNEL, 4) BL_Trigger(self.trig_lvl, BL_TRIG_RISE) BL_Intro(0) BL_Delay(0) BL_Rate(self.rate) BL_Time(self.acq_time) BL_Select(BL_SELECT_SOURCE, BL_SOURCE_POD) BL_Range(BL_Count(BL_COUNT_RANGE)) BL_Offset(BL_ZERO) BL_Enable(1) # setup channel 0 (analog) BL_Select(BL_SELECT_CHANNEL, 0) BL_Intro(0) BL_Delay(0) BL_Rate(self.rate) BL_Time(self.acq_time) BL_Select(BL_SELECT_SOURCE, BL_SOURCE_POD) BL_Range(BL_Count(BL_COUNT_RANGE)) BL_Offset(BL_ZERO) BL_Enable(1) # setup channel 1 (analog) BL_Select(BL_SELECT_CHANNEL, 1) BL_Intro(0) BL_Delay(0) BL_Rate(self.rate) BL_Time(self.acq_time) BL_Select(BL_SELECT_SOURCE, BL_SOURCE_POD) BL_Range(BL_Count(BL_COUNT_RANGE)) BL_Offset(BL_ZERO) BL_Enable(1) #print BL_State() return def close_scope(self): BL_Close() print "Bitscope is closed" return def scope_acquire(self): BL_Trace(BL_TRACE_FOREVER) BL_Select(BL_SELECT_CHANNEL, 0) ch1_data = BL_Acquire() BL_Select(BL_SELECT_CHANNEL, 1) ch2_data = BL_Acquire() BL_Select(BL_SELECT_CHANNEL, 4) trg_data = BL_Acquire() # plot acquired data x = np.arange(len(ch1_data))/float(self.rate) self.mpl.canvas.ax1.clear() self.mpl.canvas.ax1.plot(x, ch1_data, c='m', lw=1.5, label='CH1') self.mpl.canvas.ax1.plot(x, ch2_data, c='y', lw=1.5, label='CH2') self.mpl.canvas.ax1.plot(x, trg_data, c='r', lw=1.5, label='TRG') self.mpl.canvas.ax1.set_xlabel('Time (s)') self.mpl.canvas.ax1.set_ylabel('Signal (V)') self.mpl.canvas.ax1.grid(True) self.mpl.canvas.ax1.legend(loc='upper center', bbox_to_anchor=(0.5,1.1), ncol=3) self.mpl.canvas.draw() return ch1_data,ch2_data, trg_data def save_single_shot(self, data): self.current_data = [] # define filepath, foldername and filename filepath = '/home/pi/rhul_thz/data/' foldername = time.strftime('%Y_%m_%d', time.localtime())+'/' filename = time.strftime('%Y%m%d_%H%M%S', time.localtime()) if not os.path.isdir(filepath+foldername): os.makedirs(filepath+foldername) print 'folder %s has been created at %s' %(foldername, filepath) # form a header for the file self.current_data.append( ['INT_MIR', self.smc100_ctr.current_position(1, self.sio)] ) self.current_data.append( ['INT_DET', self.smc100_ctr.current_position(2, self.sio)] ) self.current_data.append( ['VAC_VER', 0.00] ) self.current_data.append( ['VAC_HOR', self.sixpack2_ctr.current_position(self.port_2, 0,'lin')] ) self.current_data.append( ['VAC_MIR', 0.00] ) self.current_data.append( ['VAC_TAR', 0.00] ) self.current_data.append( ['TRG_LVL', self.trig_lvl] ) self.current_data.append( ['ACQ_TME', self.acq_time] ) self.current_data.append( ['ACQ_RTE', self.rate] ) # data from the scope self.current_data.append( ['CH1_DAT', data[0]] ) self.current_data.append( ['CH2_DAT', data[1]] ) self.current_data.append( ['TRG_DAT', data[2]] ) # open file and write data with open(filepath+foldername+filename+'_single.csv', 'w') as csvfile: writer = csv.writer(csvfile, delimiter='\t') for item in self.current_data: writer.writerow(item) print 'Data has been written to %s' % filepath+foldername+filename+'_single.csv' def update_serial_port(self, port1): while 1: if port1.isOpen() == True: self.interferometer_mirror_pos.setText( str(self.smc100_ctr.current_position(1, self.sio))) time.sleep(0.025) self.interferometer_mirror_sts.setText( self.smc100_ctr.status(1, self.sio)) time.sleep(0.025) self.detector_pos.setText( str(self.smc100_ctr.current_position(2, self.sio))) time.sleep(0.025) self.detector_sts.setText( self.smc100_ctr.status(2, self.sio)) time.sleep(0.025) self.lin_hor_pos.setText( str(self.sixpack2_ctr.current_position(self.port_2, 0, "lin"))) time.sleep(0.05) self.lin_hor_sts.setText(self.sixpack2_ctr.status(self.port_2, 0)) return def open_serial_port(self): port_1 = serial.Serial(port=str(self.serial_port_name_input_int.text()), baudrate=57600, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=0.1) self.sio = io.TextIOWrapper(io.BufferedRWPair(port_1, port_1)) self.port_2 = serial.Serial(port=str(self.serial_port_name_input_vac.text()), baudrate=19200, timeout=0.1) self.sixpack2_ctr.set_initial_parameters(self.port_2) thread.start_new_thread(self.update_serial_port, (port_1,)) print("Ports are OPEN") return def endis_mirror(self): if self.ctr1_is_enabled: self.smc100_ctr.disable(1, self.sio) self.disable_mirror_button.setText("ENABLE") else: self.smc100_ctr.enable(1, self.sio) self.disable_mirror_button.setText("DISABLE") self.ctr1_is_enabled = not self.ctr1_is_enabled return def endis_detector(self): if self.ctr2_is_enabled: self.smc100_ctr.disable(2, self.sio) self.disable_detector_button.setText("ENABLE") else: self.smc100_ctr.enable(2, self.sio) self.disable_detector_button.setText("DISABLE") self.ctr2_is_enabled = not self.ctr2_is_enabled return def scan(self, start, stop, step, rep): self.scan_pos = [] self.scan_dat = [] self.scan_dat_avg = [] self.scan_dat_std = [] print("Scan initiated") # define filepath, foldername and filename filepath = '/home/pi/rhul_thz/data/' foldername = time.strftime('%Y_%m_%d', time.localtime())+'/' filename = time.strftime('%Y%m%d_%H%M%S', time.localtime()) if not os.path.isdir(filepath+foldername): os.makedirs(filepath+foldername) print 'folder %s has been created at %s' %(foldername, filepath) # form a header and write it to the file with open(filepath+foldername+filename+'_scan.csv', 'w') as csvfile: writer = csv.writer(csvfile, delimiter='\t') writer.writerow( ['SCN_AXS', str(self.scan_type_selector.currentText())] ) writer.writerow( ['INT_MIR', self.smc100_ctr.current_position(1, self.sio)] ) writer.writerow( ['INT_DET', self.smc100_ctr.current_position(2, self.sio)] ) writer.writerow( ['VAC_VER', 0.00] ) writer.writerow( ['VAC_HOR', self.sixpack2_ctr.current_position(self.port_2, 0,'lin')] ) writer.writerow( ['VAC_MIR', 0.00] ) writer.writerow( ['VAC_TAR', 0.00] ) writer.writerow( ['TRG_LVL', self.trig_lvl] ) writer.writerow( ['ACQ_TME', self.acq_time] ) writer.writerow( ['ACQ_RTE', self.rate] ) writer.writerow( ['SCN_SRT', start] ) writer.writerow( ['SCN_END', stop] ) writer.writerow( ['SCN_STP', step] ) writer.writerow( ['SCN_REP', rep] ) scan_positions = np.arange(start, stop+step, step) for position in scan_positions: QtCore.QCoreApplication.processEvents() # With this line the GUI will not freeze while in the loop. # Not the best solution but it works. if self.scan_type_selector.currentText() == 'INT_MIR': self.smc100_ctr.move_to_pos(1, position, self.sio) while 1: time.sleep(0.1) if self.smc100_ctr.status(1, self.sio) != "MOVING": break else: time.sleep(0.1) with open(filepath+foldername+filename+'_scan.csv', 'a') as csvfile: writer = csv.writer(csvfile, delimiter='\t') writer.writerow( ['INT_MIR', self.smc100_ctr.current_position(1, self.sio)] ) elif self.scan_type_selector.currentText() == 'VAC_HOR': self.sixpack2_ctr.move_to_pos(self.port_2, 0, position, "lin") while 1: time.sleep(0.1) if self.sixpack2_ctr.status(self.port_2, 0) != "MOVING": break else: time.sleep(0.1) with open(filepath+foldername+filename+'_scan.csv', 'a') as csvfile: writer = csv.writer(csvfile, delimiter='\t') writer.writerow( ['VAC_HOR', self.sixpack2_ctr.current_position(self.port_2, 0, 'lin')] ) else: print 'something wrong' print 'position %f' %position temp_data = [] # temporary list with data for avg and std for i in range(rep): area = 0 print 'sample %i' %i QtCore.QCoreApplication.processEvents() # acquire the data data = self.scope_acquire() # append current data to the file with open(filepath+foldername+filename+'_scan.csv', 'a') as csvfile: writer = csv.writer(csvfile, delimiter='\t') writer.writerow( ['CH1_DAT', data[0]] ) writer.writerow( ['CH2_DAT', data[1]] ) writer.writerow( ['TRG_DAT', data[2]] ) # plot results #calculate the area of the signal (normalized) area = np.trapz(data[0], dx=1.0/len(data[0])/np.trapz(data[1], dx=1.0/len(data[1]))) self.scan_pos.append(position) self.scan_dat.append(area) temp_data.append(area) self.mpl.canvas.ax2.clear() self.mpl.canvas.ax2.plot(self.scan_pos, self.scan_dat,'o-', c='k', label='') self.mpl.canvas.ax2.set_xlabel('Position (mm)') self.mpl.canvas.ax2.set_ylabel('Amplitude (arb. units)') self.mpl.canvas.ax2.grid(True) self.mpl.canvas.ax2.set_xlim(min(self.scan_pos)-step/2, max(self.scan_pos)+step/2) self.mpl.canvas.ax2.set_ylim(0, 2*max(self.scan_dat)) self.mpl.canvas.draw() self.scan_dat_avg.append(np.array(temp_data).mean()) self.scan_dat_std.append(np.array(temp_data).std()) print "----------" print("Scan finished") # save a pdf with the resultant image plt.figure() plt.errorbar(scan_positions, self.scan_dat_avg, self.scan_dat_std, fmt='ro-') plt.xlabel('Position (mm)') plt.ylabel('Amplitude (arb. units)') plt.xlim(min(scan_positions)-step/2, max(scan_positions)+step/2) plt.ylim(0, 2*max(self.scan_dat)) plt.savefig(filepath+foldername+filename+'_scan.pdf') return def main(): app = QtGui.QApplication(sys.argv) form = AppForm() form.show() sys.exit(app.exec_()) if __name__ == "__main__": main()