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 __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: 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()
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()