def initLogFiles(self): startDatetime = self.ADRSettings['Start Compressor Datetime'] self.tempDataChest = dataChest(self.ADRSettings['Log Path']) dts = dateStamp() iso = startDatetime.isoformat().split('+')[ 0] # strip timezone (or dateStamp will fail) dtstamp = dts.dateStamp(iso) try: self.tempDataChest.openDataset(dtstamp + '_temperatures', modify=True) except Exception as e: self.tempDataChest.createDataset( "temperatures", [('time', [1], 'utc_datetime', '')], [('temp60K', [1], 'float16', 'Kelvin'), ('temp03K', [1], 'float16', 'Kelvin'), ('tempGGG', [1], 'float16', 'Kelvin'), ('tempFAA', [1], 'float16', 'Kelvin')], dateStamp=dtstamp) self.tempDataChest.addParameter("X Label", "Time") self.tempDataChest.addParameter("Y Label", "Temperature") self.tempDataChest.addParameter( "Plot Title", startDatetime.strftime("ADR temperature history " "for run starting on %y/%m/%d %H:%M")) self.logMessages = []
def selectFile(self): fileDialog = QtGui.QFileDialog() fileDialog.setNameFilters( [self.tr('HDF5 Files (*.hdf5)'), self.tr('All Files (*)')]) fileDialog.setDefaultSuffix('.hdf5') baseDirList = ['Z:', 'mcdermott-group', 'data'] baseDir = os.path.join(*(baseDirList + self.fileDir)) fileDialog.setDirectory(baseDir) filePath = str( fileDialog.getSaveFileName( self, 'Save File', options=QtGui.QFileDialog.DontConfirmOverwrite)) print('save file: ' + filePath) if filePath is not '': filePath = filePath.replace(baseDir, '') # remove base path if filePath[-5:] == '.hdf5': filePath = filePath[:-5] fileArray = filePath.split('/') for elem in baseDirList: if fileArray[0] == elem: fileArray.remove(elem) self.fileDir = fileArray[:-1] fileName = fileArray[-1] self.resDataChest = dataChest(self.fileDir) try: self.resDataChest.openDataset(fileName, modify=True) self.setOdd(self.resDataChest.getParameter("Odd")) self.setPitchX(self.resDataChest.getParameter("Pitch X")) self.setPitchY(self.resDataChest.getParameter("Pitch Y")) self.setInnerDiameter( self.resDataChest.getParameter("Inner Diameter")) oldData = self.resDataChest.getData() for die, index, _, __, resistance in oldData: if die not in self.measurements: self.measurements[die] = {} if index not in self.measurements[die]: self.measurements[die][index] = [] self.measurements[die][index].append(resistance) print('opened old dataset') except Exception: self.resDataChest.createDataset( fileName, [('die', [1], 'string', ''), ('index', [1], 'uint8', ''), ('area', [1], 'float64', 'um**2'), ('DMM range', [1], 'float64', 'Ohm')], [('resistance', [1], 'float64', 'Ohms')]) self.resDataChest.addParameter("Odd", self.odd) self.resDataChest.addParameter("Pitch X", self.pitchX) self.resDataChest.addParameter("Pitch Y", self.pitchY) self.resDataChest.addParameter("Inner Diameter", self.innerDiameter) self.resDataChest.addParameter("Date Measured", str(datetime.datetime.utcnow())) self.waferMap.initGrid() self.areaView.setAreasIndex(0) self.fileButton.setText('End Measurement') self.fileButton.clicked.disconnect(self.selectFile) self.fileButton.clicked.connect(self.endMeasurement)
def addSubstrateCalibration(self, path): """This should be a path to a normal probe file that only has a single die with a measurement at each index.""" chest = dataChest(path[:-1]) chest.openDataset(path[-1]) dataOrder = ('die', 'index', 'area', 'range', 'resistance') self.calibration_data = [dict(zip(dataOrder,row)) for row in chest.getData()] cal_dict = {row['index']:row['resistance'] for row in self.calibration_data} for row in self.data: row['resistance_cal_file'] = 1./( 1./row['resistance'] - 1./cal_dict[row['index']] )
def __init__(self, path, bounds={}): """bounds should be in the form {area: (lower,upper)}""" chest = dataChest(path[:-1]) chest.openDataset(path[-1]) dataOrder = ('die', 'index', 'area', 'range', 'resistance') self.data = [dict(zip(dataOrder,row)) for row in chest.getData() if not np.isnan(row[2]) \ and (row[2] not in bounds \ or (row[4]>bounds[row[2]][0] \ and row[4]<bounds[row[2]][1]))] # data in format (resistance, area, die, range) self.odd = False self.inner_diameter = 65 self.pitchX = 6.25 self.pitchY = 6.25 try: self.odd = chest.getParameter('Odd') self.inner_diameter = chest.getParameter('Inner Diameter') self.pitchX = chest.getParameter('Pitch X') self.pitchY = chest.getParameter('Pitch Y') except: pass
def changeFridge(self,*args): """Select which ADR you want to operate on. Called when select ADR menu is changed.""" self.selectedADR = self.adrSelect.get() # clear temps plot self.stage60K.set_xdata([]) self.stage60K.set_ydata([]) self.stage03K.set_xdata([]) self.stage03K.set_ydata([]) self.stageGGG.set_xdata([]) self.stageGGG.set_ydata([]) self.stageFAA.set_xdata([]) self.stageFAA.set_ydata([]) # load saved temp data # We have to sleep for 0.5s here because it seems like it takes # a moment for the connected server to register in self.cxn, even # though all this starts because a message is received saying it # is connected :\ time.sleep(0.5) startDateTime = yield self.cxn[self.selectedADR].get_start_datetime() try: reg = self.cxn.registry yield reg.cd(ADR_SETTINGS_BASE_PATH + [self.selectedADR]) logPath = yield reg.get('Log Path') tempDataChest = dataChest(logPath) ds = dateStamp() dset = '%s_temperatures'%ds.dateStamp(startDateTime.isoformat()) tempDataChest.openDataset(dset) n = tempDataChest.getNumRows() # load approximately the last 6 hours of data pastTempData = tempDataChest.getData(max(0,n-6*60*60),None ) for newRow in pastTempData: # change utc time to local utc = newRow[0] # (float) utc = datetime.datetime.utcfromtimestamp(utc) utc = utc.replace(tzinfo=tz.tzutc()) newRow[0] = mpl.dates.date2num(utc) # add old data from file into plot self.stage60K.set_xdata(numpy.append(self.stage60K.get_xdata(),newRow[0])) self.stage60K.set_ydata(numpy.append(self.stage60K.get_ydata(),newRow[1])) self.stage03K.set_xdata(numpy.append(self.stage03K.get_xdata(),newRow[0])) self.stage03K.set_ydata(numpy.append(self.stage03K.get_ydata(),newRow[2])) self.stageGGG.set_xdata(numpy.append(self.stageGGG.get_xdata(),newRow[0])) self.stageGGG.set_ydata(numpy.append(self.stageGGG.get_ydata(),newRow[3])) self.stageFAA.set_xdata(numpy.append(self.stageFAA.get_xdata(),newRow[0])) self.stageFAA.set_ydata(numpy.append(self.stageFAA.get_ydata(),newRow[4])) except IOError: # file not created yet if adr server just opened print( 'temp file not created yet?' ) self.updatePlot() # clear and reload last 20 messages of log self.log.clear() logMessages = yield self.cxn[self.selectedADR].get_log(20) for (t,m,a) in logMessages: self.updateLog(t,m,a) # update instrument status stuff: delete old, create new for widget in self.instrumentStatusFrame.winfo_children(): widget.destroy() returnStatus = yield self.cxn[self.selectedADR].get_instrument_state() self.instrumentStatuses = {} for name,status in returnStatus: self.instrumentStatuses[name] = Tkinter.Label(self.instrumentStatusFrame, text=name, relief=Tkinter.RIDGE, bg='gray70') self.instrumentStatuses[name].pack(side=Tkinter.LEFT, expand=True, fill=Tkinter.X) # update field limits and button statuses self.setFieldLimits() self.magUpButton.configure(state=Tkinter.NORMAL) self.regulateButton.configure(state=Tkinter.NORMAL) self.compressorButton.configure(state=Tkinter.DISABLED) mUp = yield self.cxn[self.selectedADR].get_state_var('maggingUp') reg = yield self.cxn[self.selectedADR].get_state_var('regulating') if mUp: self.magUpButton.configure(text='Stop Magging Up', command=self.cancelMagUp) self.regulateButton.configure(state=Tkinter.DISABLED) if reg: self.regulateButton.configure(text='Stop Regulating', command=self.cancelRegulate) self.magUpButton.configure(state=Tkinter.DISABLED) # update heat switch buttons HSAvailable = yield self.cxn[self.selectedADR].get_instrument_state(['Heat Switch']) if HSAvailable[0][1][0]: self.HSCloseButton.configure(state=Tkinter.NORMAL) self.HSOpenButton.configure(state=Tkinter.NORMAL) else: self.HSCloseButton.configure(state=Tkinter.DISABLED) self.HSOpenButton.configure(state=Tkinter.DISABLED) # refresh interface self.updateInterface()
import numpy as np from dataChest import dataChest import time def gaussian(x, mu, sig): # with noise return np.exp(-np.power(x - mu, 2.) / (2 * np.power(sig, 2.))) + np.random.rand()/5. d = dataChest(['testProject','Test Datasets']) # 1D: Arbitrary Type 1 plot over time if False: d.createDataset("1D_ArbType1_MyFavoriteTimeSeries", [("indepName1", [1], "float64", "s")], [("depName1", [1], "float64", "V")] ) d.addParameter("X Label", "Time") d.addParameter("Y Label", "Digitizer Noise") d.addParameter("Plot Title", "Random Number Generator") for ii in range(0, 1000): d.addData([[float(ii),np.random.rand()]]) time.sleep(.2) # 1D: Arbitrary Type 1 if True: d.createDataset("1D_ArbType1_MyFavoriteTimeSeries", [("indepName1", [1], "float64", "s")], [("depName1", [1], "float64", "V")] ) d.addParameter("X Label", "Time") d.addParameter("Y Label", "Digitizer Noise")
def __init__(self, args): DeviceServer.__init__(self) self.ADRSettingsPath = ADR_SETTINGS_BASE_PATH selectedADR = DEFAULT_ADR if '-a' in args: # Use -a to specify ADR index = args.index('-a') args.pop(index) # If we do not pop these off, twisted will complain because # this is not an allowed argument. selection = str( args.pop(index) ) if selection in AVAILABLE_ADRS: selectedADR = selection else: print('%s is not a valid ADR selection.' %selection) self.ADRSettingsPath.append(selectedADR) self.name = selectedADR self.deviceName = selectedADR print('%s selected.' %selectedADR) self.alive = True # to turn off the update state look when server is closed self.state = { 'T_FAA': numpy.NaN * units.K, 'T_GGG': numpy.NaN * units.K, 'T_3K' : numpy.NaN * units.K, 'T_60K': numpy.NaN * units.K, 'datetime' : datetime.datetime.utcnow(), 'cycle': 0, 'magnetV': numpy.NaN * units.V, 'RuOxChan': 'FAA', 'RuOxChanSetTime': datetime.datetime.utcnow(), 'PSCurrent': numpy.NaN * units.A, 'PSVoltage': numpy.NaN * units.V, 'maggingUp': False, 'regulating': False, 'regulationTemp': 0.1, 'PID_cumulativeError': 0 } self.lastState = self.state.copy() # These are defaults. They can be overridden in the registry by # including a setting with the same name. self.ADRSettings = { 'PID_KP': 0.75, 'PID_KI': 0, 'PID_KD': 15, 'PID_MaxI': 1, 'magup_dV': 0.003, #[V/step] How much do we increase the voltage by every second when maggin up? HPD Manual uses 10mV=0.01V, 2.5V/30min=1.4mV/s ==> Let's use a middle rate of 3mV/step. (1 step is about 1s) 'magnet_voltage_limit': 0.1, #Back EMF limit in Volts 'current_limit': 9, #Max Current in Amps 'voltage_limit': 2, #Max Voltage in Volts. At 9A, we usually get about 2.5-2.7V or 1.69V (with or without the external diode protection box), so this shouldn't need to be more than 3 or 2 'dVdT_limit': 0.008, #Keep dV/dt to under this value [V/s] 'dIdt_magup_limit': 9. / (30*60), #limit on the rate at which we allow current to increase in amps/s (we want 9A over 30 min) 'dIdt_regulate_limit': 9./(40*60),#limit on the rate at which we allow current to change in amps/s (we want 9A over 40 min) 'step_length': 1.0, #How long is each regulation/mag up cycle in seconds. **Never set this less than 1.0sec.** The SRS SIM922 only measures once a second and this would cause runaway voltages/currents. 'magnet_max_temp': 5, 'FAA MP Chan': 2, 'GGG MP Chan': 1, 'Power Supply':['Agilent 6641A PS','addr'], 'Ruox Temperature Monitor':['SIM921','addr'], #['AC Bridge with Multiplexer',[['SIM921 Server','addr'],['SIM925 Server','addr']]], 'Diode Temperature Monitor':['SIM922','addr'], 'Magnet Voltage Monitor':['SIM922','addr'], 'Heat Switch':['Heat Switch','addr'], 'Compressor':['CP2800 Compressor','addr'] } self.instruments = {'Power Supply':'None', 'Ruox Temperature Monitor':'None', 'Diode Temperature Monitor':'None', 'Magnet Voltage Monitor':'None', 'Heat Switch':'None', 'Compressor':'None'} self.startDatetime = datetime.datetime.utcnow() self.tempDataChest = dataChest(['ADR Logs',self.name]) dts = dateStamp() iso = self.startDatetime.isoformat().split('+')[0] # strip timezone (or dateStamp will fail) dtstamp = dts.dateStamp(iso) self.tempDataChest.createDataset("temperatures", [('time',[1],'utc_datetime','')], [('temp60K',[1],'float64','Kelvin'),('temp03K',[1],'float64','Kelvin'), ('tempGGG',[1],'float64','Kelvin'),('tempFAA',[1],'float64','Kelvin')], dateStamp=dtstamp) self.tempDataChest.addParameter("X Label", "Time") self.tempDataChest.addParameter("Y Label", "Temperature") self.tempDataChest.addParameter("Plot Title", self.startDatetime.strftime("ADR temperature history " "for run starting on %y/%m/%d %H:%M")) self.logMessages = []
def changeFridge(self,*args): """Select which ADR you want to operate on. Called when select ADR menu is changed.""" self.selectedADR = self.adrSelect.get() # clear temps plot self.stage60K.set_xdata([]) self.stage60K.set_ydata([]) self.stage03K.set_xdata([]) self.stage03K.set_ydata([]) self.stageGGG.set_xdata([]) self.stageGGG.set_ydata([]) self.stageFAA.set_xdata([]) self.stageFAA.set_ydata([]) # load saved temp data # We have to sleep for 0.5s here because it seems like it takes # a moment for the connected server to register in self.cxn, even # though all this starts because a message is received saying it # is connected :\ time.sleep(0.5) startDateTime = yield self.cxn[self.selectedADR].get_start_datetime() try: tempDataChest = dataChest(['ADR Logs']) tempDataChest.cd(self.selectedADR) ds = dateStamp() dset = '%s_temperatures'%ds.dateStamp(startDateTime.isoformat()) tempDataChest.openDataset(dset) n = tempDataChest.getNumRows() # load approximately the last 6 hours of data pastTempData = tempDataChest.getData(max(0,n-6*60*60),None ) for newRow in pastTempData: # change utc time to local utc = newRow[0] # (float) utc = datetime.datetime.utcfromtimestamp(utc) utc = utc.replace(tzinfo=tz.tzutc()) newRow[0] = mpl.dates.date2num(utc) # add old data from file into plot self.stage60K.set_xdata(numpy.append(self.stage60K.get_xdata(),newRow[0])) self.stage60K.set_ydata(numpy.append(self.stage60K.get_ydata(),newRow[1])) self.stage03K.set_xdata(numpy.append(self.stage03K.get_xdata(),newRow[0])) self.stage03K.set_ydata(numpy.append(self.stage03K.get_ydata(),newRow[2])) self.stageGGG.set_xdata(numpy.append(self.stageGGG.get_xdata(),newRow[0])) self.stageGGG.set_ydata(numpy.append(self.stageGGG.get_ydata(),newRow[3])) self.stageFAA.set_xdata(numpy.append(self.stageFAA.get_xdata(),newRow[0])) self.stageFAA.set_ydata(numpy.append(self.stageFAA.get_ydata(),newRow[4])) except IOError: # file not created yet if adr server just opened print( 'temp file not created yet?' ) self.updatePlot() # clear and reload last 20 messages of log self.log.clear() logMessages = yield self.cxn[self.selectedADR].get_log(20) for (t,m,a) in logMessages: self.updateLog(t,m,a) # update instrument status stuff: delete old, create new for widget in self.instrumentStatusFrame.winfo_children(): widget.destroy() returnStatus = yield self.cxn[self.selectedADR].get_instrument_state() self.instrumentStatuses = {} for name,status in returnStatus: self.instrumentStatuses[name] = Tkinter.Label(self.instrumentStatusFrame, text=name, relief=Tkinter.RIDGE, bg='gray70') self.instrumentStatuses[name].pack(side=Tkinter.LEFT, expand=True, fill=Tkinter.X) # update field limits and button statuses self.setFieldLimits() self.magUpButton.configure(state=Tkinter.NORMAL) self.regulateButton.configure(state=Tkinter.NORMAL) self.compressorButton.configure(state=Tkinter.DISABLED) mUp = yield self.cxn[self.selectedADR].get_state_var('maggingUp') reg = yield self.cxn[self.selectedADR].get_state_var('regulating') if mUp: self.magUpButton.configure(text='Stop Magging Up', command=self.cancelMagUp) self.regulateButton.configure(state=Tkinter.DISABLED) if reg: self.regulateButton.configure(text='Stop Regulating', command=self.cancelRegulate) self.magUpButton.configure(state=Tkinter.DISABLED) # update heat switch buttons HSAvailable = yield self.cxn[self.selectedADR].get_instrument_state(['Heat Switch']) if HSAvailable[0][1][0]: self.HSCloseButton.configure(state=Tkinter.NORMAL) self.HSOpenButton.configure(state=Tkinter.NORMAL) else: self.HSCloseButton.configure(state=Tkinter.DISABLED) self.HSOpenButton.configure(state=Tkinter.DISABLED) # refresh interface self.updateInterface()