def MakeSafe(self): """ Make the instruments safe, bypass the self.com command in order to pass it directly to the instruments, that way recording weather or not the making safe worked for the instruments. Reports to GUI if it is unsafe. """ sucessM,valM,stringM = self.voltmeter.make_safe() self.PrintSave("Make safe sent. status is:") self.PrintSave("Meter {}".format(sucessM)) if not all([sucessM]): wx.PostEvent(self._notify_window, stuff.ResultEvent(self.EVT, "UNSAFE")) else: wx.PostEvent(self._notify_window, stuff.ResultEvent(self.EVT, None))
def end(self): """ Function to close files and post an event to the main grid, letting it know that the thread has ended. """ self.MakeSafe() self.logfile.close() self.wb.save(filename = str(self.raw_file_name+'.xlsx')) wx.CallAfter(self.Analysis_file_name.SetValue,self.raw_file_name+'.xlsx') wx.PostEvent(self._notify_window, stuff.ResultEvent(self.EVT, 'GPIB ended'))
def run(self): """ Main thread, reads through the table and executes commands. """ self.com(self.voltmeter.create_instrument) #If the initialisations failed, stop the thread immediatly. #There is no point running make safe if the instruments arent there. if self._want_abort: #Notify the window that the thread ended, so buttons are enabled. wx.PostEvent(self._notify_window, stuff.ResultEvent(self.EVT, 'GPIB ended')) return if self.OverideSafety == False: #Then do the safety checks. state = self.SafetyCheck() if state != 'clear': self._want_abort = True self.PrintSave('safety checks failed, making safe, aborting.') self.MakeSafe() #initialise instruments self.initialise_instruments() rows = self.grid.GetNumberRows() self.set_grid_val(0, 0, 'Range (V)') self.set_grid_val(0, 1, 'Instrument Readout (V)') self.set_grid_val(0, 2, 'Standard Deviation') i = 1 empty = self.read_grid_cell(1, 1) while (i <= rows): if (i == rows): self.ranges = i if (self.read_grid_cell(i, 0) == empty): self.ranges = i i = rows print(i) i = i + 1 for row in range(1, self.ranges): if self._want_abort: print('want to abort') break #Breaks and skips to the end, where it runs "self.end()". #do the row highlighting, force a refresh. self.PrintSave("Spread sheet row " + str(int(row) + 1)) wx.CallAfter(self.grid.SelectRow, row) wx.CallAfter(self.grid.ForceRefresh) wx.CallAfter(self.grid.Update) #read errors in meters. The error string later has more warnings appended to it. error_strings = self.Error_string_maker() #need to determine maximum of DVM range to find accuracy threshold range_max = self.set_meter_range(row) delay_time = int(self.delayTime) #delay for settle time delay_time2 = 0 #delay for DVM between mesmnts nominal_reading = 0 #nominal reading for comparison to actual reading self.com(self.voltmeter.MeasureSetup) #wait desired time for instruments to settle self.wait(delay_time) these_readings = [] #array for readings from a single table row. before_msmnt_time = time.time() #start time of measuremtns. nordgs = int(self.nordgs) #Do the readings these_readings, issues = self.do_readings(delay_time2, range_max, nominal_reading, nordgs) #Update the full error string error_strings = error_strings + issues print(str(error_strings)) if len(these_readings) > 1: data_stdev = np.std(these_readings) data_mean = np.mean(these_readings) else: data_stdev = 'No readings' #avoid infinity for stdev data_mean = 'No readings' #create array to send to csv data sheet after_msmnt_time = time.time() Time = time.localtime() #time at end of msmnt row_time = str(Time[0]) + str(Time[1]) + str(Time[2]) + str( Time[3]) + str(Time[4]) #print results self.set_grid_val(row, 1, repr(data_mean)) self.set_grid_val(row, 2, repr(data_stdev)) self.print_instrument_status(row) #put csv reading at end so all values are on table. csv_line = [ self.read_grid_cell(row, i) for i in range(self.grid.GetNumberCols()) ] csv_line = csv_line + [before_msmnt_time, after_msmnt_time ] + these_readings self.sh.append(csv_line) self.end()
def run(self): """ Main thread, reads through the table and executes commands. """ self.parent.ProgressUpdate("Creating Instruments:", "In Progress", wx.Colour(0, 0, 0)) self.com(self.voltmeter.create_instrument) self.com(self.sourceX.create_instrument) self.com(self.sourceS.create_instrument) #If the initialisations failed, stop the thread immediatly. #There is no point running make safe if the instruments arent there. if self._want_abort: #Notify the window that the thread ended, so buttons are enabled. wx.PostEvent(self._notify_window, stuff.ResultEvent(self.EVT, 'GPIB ended')) self.parent.ProgressUpdate("Creating Instruments:", "Error", wx.Colour(255, 0, 0)) return else: self.parent.ProgressUpdate("Creating Instruments:", "Complete", wx.Colour(0, 255, 0)) self.parent.ProgressUpdate("Safety Checks:", "In Progress", wx.Colour(0, 0, 0)) if self.OverideSafety == False: #Then do the safety checks. state = self.SafetyCheck() if state != 'clear': self._want_abort = True self.PrintSave('safety checks failed, making safe, aborting.') self.MakeSafe() self.parent.ProgressUpdate("Safety Checks:", "Error", wx.Colour(255, 0, 0)) else: self.parent.ProgressUpdate("Safety Checks:", "Complete", wx.Colour(0, 255, 0)) #initialise instruments self.initialise_instruments() not_complete = 0 for row in range(self.start_row, self.stop_row + 1): if self._want_abort: self.parent.ProgressUpdate( "Data Collection:", "Not Complete: Step " + str(row + 1 - self.start_row) + " of " + str(self.stop_row + 1 - self.start_row) + " steps", wx.Colour(255, 0, 0)) not_complete = 1 break #Breaks and skips to the end, where it runs "self.end()". #do the row highlighting, force a refresh. self.PrintSave("Spread sheet row " + str(int(row) + 1)) self.parent.ProgressUpdate( "Data Collection:", "In Progress: " + str(row + 1 - self.start_row) + " of " + str(self.stop_row + 1 - self.start_row) + " steps", wx.Colour(0, 0, 0)) wx.CallAfter(self.grid.SelectRow, row) wx.CallAfter(self.grid.ForceRefresh) wx.CallAfter(self.grid.Update) #prepare ranges for sources self.set_source_ranges(row) #operate sources self.com(self.sourceS.Operate) self.com(self.sourceX.Operate) #read errors in meters. The error string later has more warnings appended to it. error_strings = self.Error_string_maker() #need to determine maximum of DVM range to find accuracy threshold range_max = self.set_meter_range(row) delay_time = int(float(self.read_grid_cell(row, self.delay_col))) #delay for settle time delay_time2 = float(self.read_grid_cell(row, self.delay_col + 1)) #delay for DVM between mesmnts nominal_reading = float( self.read_grid_cell(row, self.dvm_range_col + 1)) #nominal reading for comparison to actual reading self.com(self.voltmeter.MeasureSetup) #wait desired time for instruments to settle self.wait(delay_time) these_readings = [] #array for readings from a single table row. before_msmnt_time = time.time() #start time of measuremtns. nordgs = int(float(self.read_grid_cell(row, self.dvm_nordgs_col))) #Do the readings these_readings, issues = self.do_readings(delay_time2, range_max, nominal_reading, nordgs) #Update the full error string error_strings = error_strings + issues #print the error report of this data sequence to the table self.set_grid_val(row, 0, str(error_strings)) if len(these_readings) > 1: data_stdev = np.std(these_readings) data_mean = np.mean(these_readings) else: data_stdev = 'No readings' #avoid infinity for stdev data_mean = 'No readings' #create array to send to csv data sheet after_msmnt_time = time.time() Time = time.localtime() #time at end of msmnt row_time = str(Time[0]) + str(Time[1]) + str(Time[2]) + str( Time[3]) + str(Time[4]) #print results self.set_grid_val(row, self.dvm_nordgs_col + 6, repr(data_mean)) self.set_grid_val(row, self.dvm_nordgs_col + 7, repr(data_stdev)) self.print_instrument_status(row) #put csv reading at end so all values are on table. csv_line = [ self.read_grid_cell(row, i) for i in range(self.grid.GetNumberCols()) ] csv_line = csv_line + [before_msmnt_time, after_msmnt_time ] + these_readings self.sh.append(csv_line) if not_complete == 0: self.parent.ProgressUpdate("Data Collection:", "Complete", wx.Colour(0, 255, 0)) self.end()
def run(self): xmin_control = self.param[0] manual_xmin = self.param[1] xmax_control = self.param[2] manual_xmax = self.param[3] ymin_control = self.param[4] manual_ymin = self.param[5] ymax_control = self.param[6] manual_ymax = self.param[7] grid_show = self.param[8] label_show = self.param[9] panel = self.param[10] #access gui directly using wx.CallAfter to put numbers in mean and sd boxes mean_box = self.param[11] sd_box = self.param[12] text_out = self.param[13] #not useable copy = list( self.data.value) # a genuine copy, not just a pointer to same list window = 50 #default integer number of points plotted in scrolling mode if len(copy) == 0: #no data so abort the thread wx.PostEvent(self._notify_window, stuff.ResultEvent(self.EVT, None)) return if xmax_control == 'Auto': xmax = len(copy) if len(copy) > window else window else: try: xmax = int(manual_xmax) except ValueError: xmax = window #avoids rubbish in box from stopping the plot if xmin_control == 'Auto': xmin = xmax - window else: try: xmin = int(manual_xmin) except ValueError: xmin = 0 #avoids rubbish in GUI box from stopping the plot #select points based on xmin and xmax points = np.array(copy[xmin:xmax]) #also calculate mean and standard deviation of what is plotted data_mean = np.mean(points) if len(points) > 1: data_stdev = np.std(points) else: data_stdev = '-' #avoid infinity for stdev wx.CallAfter(mean_box.SetValue, repr(data_mean)) wx.CallAfter(sd_box.SetValue, repr(data_stdev)) theMin = min(points) if ymin_control == 'Auto': if data_stdev == '-': #plotting started too early, avoid error due to no stdevv ymin = theMin else: ymin = theMin - 0.1 * data_stdev else: try: ymin = float( manual_ymin) #int(self.ymin_control.manual_value()) except ValueError: ymin = 0 #avoids rubbish in box from stopping the plot theMax = max(points) if ymax_control == 'Auto': if data_stdev == '-': #plotting started too early, avoid error due to no stdevv ymax = theMax else: ymax = theMax + 0.1 * data_stdev else: try: ymax = float( manual_ymax) #int(self.ymax_control.manual_value()) except ValueError: ymax = 100 #avoids rubbish in box from stopping the plot panel.axs.plot(np.arange(xmin, xmin + len(points), 1), points, 'r') #then window in on what is required...probably inefficient panel.axs.set_xbound(lower=xmin, upper=xmax) panel.axs.set_ybound(lower=ymin, upper=ymax) if grid_show: panel.axs.grid(True, color='white') else: panel.axs.grid(False) plt.setp(panel.axs.get_xticklabels(), visible=label_show) panel.canvas.draw() if self._want_abort: #abort not useful for this single run thread wx.PostEvent(self._notify_window, stuff.ResultEvent(self.EVT, None)) return ## wx.CallAfter(text_out.AppendText,'Plotting finished\n') wx.PostEvent(self._notify_window, stuff.ResultEvent(self.EVT, '..plotted'))
def run(self): """ Main thread, reads through the table and executes commands. """ ####################INITIALISE INSTRUMENTS########################## self.com(self.lcin.reset_instrument) #reset lcin self.com(self.source.reset_instrument) self.com(self.meter.reset_instrument) time.sleep(3) self.com( self.lcin.initialise_instrument) #initialise the lcin for reading self.com(self.meter.initialise_instrument) self.com(self.source.initialise_instrument) self.PrintSave('') self.com(self.meter.query_error) self.PrintSave('meter ESR = ' + str(self.com(self.meter.read_instrument))) self.com(self.source.query_error) self.PrintSave('source ESR = ' + str(self.com(self.source.read_instrument))) self.com(self.lcin.query_error) self.PrintSave('meter ESR = ' + str(self.com(self.lcin.read_instrument))) self.PrintSave('') ######################END of INITIALISATION########################## ######################MEASUREMENT PROCESS############################ for row in range(self.start_row, self.stop_row + 1): if self._want_abort: break #read all the values in the line. self.PrintSave("Spread sheet row " + str(int(row) + 1)) wx.CallAfter(self.grid.SelectRow, row) wx.CallAfter(self.grid.ForceRefresh) wx.CallAfter(self.grid.Update) self.set_attenuation(row) self.set_voltage_phase(row) self.run_swerl(row) nordgs = self.read_grid_cell(row, self.nordgs_col) #number of readings try: nordgs = int(float(nordgs)) except TypeError: self._want_abort = 1 nordgs = 1 #so it dosent loop, but still needs an integer to play with #could also put an if statement around the for-loop self.set_up_lcin(row) self.com(self.source.MeasureSetup) self.com(self.lcin.MeasureSetup) #arrays for readings of x,y and theta. #theta used to verify the correct reading order of x and y? #lockin aparantly switches the order of (x,y) randomly. #perhaps solved by clearing the instrument bus? x_readings = [] y_readings = [] t_readings = [] before_msmnt_time = time.time() #start time of measuremtns. for i in range(nordgs): #where to add the "if not self.want_abort:"? #idea is to stop the tripple reading from attempting to break up an int, #otherwise python crashes, its not a safe stopping of the program. self.com(self.source.SingleMsmntSetup) #? self.com(self.lcin.SingleMsmntSetup) time.sleep(1) tripple_reading = str(self.com(self.lcin.read_instrument)) try: #x, y, t = tripple_reading.split(",") #this line is only used for testing with the virtual visa: x, y, t = str("{},{},{}".format( self.com(self.lcin.read_instrument), self.com(self.lcin.read_instrument), self.com(self.lcin.read_instrument))).split(",") except ValueError: selfPrintSave( "could not unpack tripple reading: {}, aborting". format(tripple_reading)) self._want_abort = 1 if self._want_abort: #break the loop if it wants to abort, speed up aborting process break x_readings.append(float(x)) y_readings.append(float(y)) t_readings.append(float(t)) printing_cols = [ self.sr_range_print, self.sr_res_mod_print, self.sr_res_mod_print, self.sr_auto_phas_print ] #post reading thing, nor normally present in dictionary. what to do about it? #can be part of the status comand, but that is not the correct repurposing. #would only work because the instrument is capable of returning a list. #This may not always be the case self.com(self.lcin.set_value, "SENS?;RMOD?;OFLT?;PHAS?\\\\n") for col in printing_cols: self.set_grid_val(row, col, str(self.com(self.lcin.read_instrument))) #the readings would be empty arrays if the program is sent to stop #so initialise the values of avg and std as strings 'failed' #then if lengths of the arrays are longer than 0, we can compute #and therefore save reasonable (calculatable) numbers x_avg, x_std, y_avg, y_std, t_avg, t_std = ['failed'] * 6 if len(x_readings) > 0: x_avg = np.average(x_readings) x_std = np.std(x_readings) if len(y_readings) > 0: y_avg = np.average(y_readings) y_std = np.std(y_readings) if len(x_readings) > 0: t_avg = np.average(t_readings) t_std = np.std(t_readings) self.set_grid_val(row, self.sr_x_print, x_avg) self.set_grid_val(row, self.sr_x_print + 1, x_std) self.set_grid_val(row, self.sr_y_print, y_avg) self.set_grid_val(row, self.sr_y_print + 1, y_std) self.set_grid_val(row, self.sr_theta_print, "{},{}".format(t_avg, t_std)) #unused columns? #self.sr_range_print = 19 #self.time_const_print = 20 wx.PostEvent(self._notify_window, stuff.ResultEvent(self.EVT, 'GPIB ended'))