Page MenuHomec4science

Chimera.py
No OneTemporary

File Metadata

Created
Sat, Jun 1, 06:58

Chimera.py

import ChimeraSettings
import ok
import ChimeraControls
import os
import pickle
import datetime
import numpy as np
import time
import csv
import matplotlib.pyplot as plt
import functions
from scipy import io
from matplotlib.ticker import EngFormatter
Amp = EngFormatter(unit='A', places=2)
Time = EngFormatter(unit='s', places=2)
Volt = EngFormatter(unit='V', places=2)
Cond = EngFormatter(unit='S', places=2)
# Main Chimera Launcher
class Launcher:
def __init__(self, loadedInstance=None):
if loadedInstance is None:
self.ChimeraSettings = ChimeraSettings.ChimeraSettings()
if os.path.isfile("store.pckl"):
self.ChimeraSettings.setStoredValues()
else:
self.ChimeraSettings = loadedInstance
# Initialize Chimera
self.xem = ok.FrontPanel()
ChimeraControls.InitializeChimera(self.ChimeraSettings, self.xem)
# Control variables
self.newbiasvalue = 0
# Set saving variables
self.DataFolder = None
self.todaysfolder = None
self.experimentName = None
self.file = None
self.savename = None
self.SetSavingFolder(os.getcwd())
self.ADClogsize = 0
self.saveDownsampled = False
# Plotting Variables
self.displaysubsample = 50
self.lowpass = 10e3
self.displaySamplerate = self.lowpass*2
# IV variables
self.IVUseAlternatingV = True
self.LowerIV = -2.0
self.HigherIV = +2.0
self.StepIV = 0.2
self.timeIV = 2
# Event detection
self.Threshold = 5 # standard deviations
self.DwellTime = .5 # in ms
self.upwardevents = False
# Data variables
self.blockvalues = np.empty((1048576,), dtype=np.uint16)
self.readvalues = ChimeraControls.ConvertBlockvalues(self.ChimeraSettings, self.blockvalues)
self.displaybuffer = np.empty((65536,), dtype=np.uint16)
self.ShowSettings()
def ShowSettings(self):
print('Settings:')
print('Saving variables:')
print('savename = ' + str(self.savename))
print('saveDownsampled = ' + str(self.saveDownsampled))
print('')
print('Plotting Variables:')
print('displaysubsample = ' + str(self.displaysubsample))
print('lowpass (Hz) = ' + str(self.lowpass))
print('')
print('IV variables:')
print('IVUseAlternatingV = ' + str(self.IVUseAlternatingV))
print('LowerIV (V) = ' + str(self.LowerIV))
print('HigherIV (V) = ' + str(self.HigherIV))
print('StepIV (V) = ' + str(self.StepIV))
print('Time (s) = ' + str(self.timeIV))
print('')
print('Event Detection:')
print('Threshold (* st.dev) = ' + str(self.Threshold))
print('DwellTime (ms) = ' + str(self.DwellTime))
print('upwardevents = ' + str(self.upwardevents))
def Initialize(self):
ChimeraControls.InitializeChimera(self.ChimeraSettings, self.xem)
def ZeroCurrent(self):
measI = np.mean(self.RecordTrace())
self.ChimeraSettings.SETUP_pAoffset = self.ChimeraSettings.SETUP_pAoffset - measI * 1E-9
print('New current offset: {} '.format(Amp.format_data(self.ChimeraSettings.SETUP_pAoffset)))
self.ResetBuffer()
def EventDetection(self, useRaw=False, Threshold=None, DwellTime=None, upwardevents=None):
if Threshold is None:
Threshold = self.Threshold
if DwellTime is None:
DwellTime = self.DwellTime
if upwardevents is None:
upwardevents = self.upwardevents
if useRaw:
inputtrace = self.readvalues
DwellTimedp = DwellTime * 1e-6 * self.ChimeraSettings.ADCSAMPLERATE
else:
inputtrace = self.displaybuffer
DwellTimedp = DwellTime * 1e-6 * self.ChimeraSettings.ADCSAMPLERATE/self.displaysubsample
ndown = functions.EventDetection(inputtrace, Threshold, DwellTimedp)
if upwardevents:
nup = functions.EventDetection(inputtrace*-1, Threshold, DwellTime)
return ndown, nup
else:
return ndown
def SetSavingFolder(self, savingFolder=None, experimentName='Untitled'):
if savingFolder is not None:
self.DataFolder = savingFolder
self.todaysfolder = str(datetime.date.today())
self.experimentName = experimentName
if not os.path.exists(self.DataFolder):
os.makedirs(self.DataFolder)
if not os.path.exists(os.path.join(self.DataFolder, self.todaysfolder)):
os.makedirs(os.path.join(self.DataFolder, self.todaysfolder))
self.savename = os.path.join(self.DataFolder, self.todaysfolder, self.experimentName)
print('Files are saved in ' + self.savename)
def CreateSavename(self, IV=False):
savingFolder = os.path.join(self.DataFolder, self.todaysfolder)
now = datetime.datetime.now()
nowstr = datetime.datetime.strftime(now, '%Y%m%d_%H%M%S')
if IV:
savingName = '{}{}{}'.format('IV_', self.experimentName, nowstr)
else:
savingName = '{}{}'.format(self.experimentName, nowstr)
self.savename = os.path.join(savingFolder, savingName)
print('Savename: ' + self.savename)
def SetExperimentName(self, experimentName):
self.SetSavingFolder(self.DataFolder, experimentName=experimentName)
def SaveSettings(self, fileName):
with open(fileName, 'rb') as file:
pickle.dump(self.ChimeraSettings, file)
print('Saved as ' + fileName)
def LoadSettings(self, fileName):
with open(fileName, 'rb') as file:
self.ChimeraSettings = pickle.load(file)
print('Loaded from ' + fileName + '. Re-initializing...')
ChimeraControls.InitializeChimera(self.ChimeraSettings, self.xem)
def updateBW(self, printtext=True):
out = ChimeraControls.CHIMERA_bandwidthtimer(self.ChimeraSettings, self.xem)
if printtext:
text1 = "Time\n{0}\nUSB Read Rate\n{1:} kHz\nUSB Write Rate\n{2}".format(out['text_time'],
out['USB_readrate'],
out['USB_writerate'])
text2 = "Buffer\n{0} kB\nBuffer Size\n{1} %\nSeconds buffered\n{2:.3f} sec".format(out['buffer'],
out['bufferPC'],
out['bufferseconds'])
print(text1)
print(text2)
return out
def ResetBuffer(self):
print("Buffer is resetting...", end='')
self.xem.SetWireInValue(self.ChimeraSettings.EP_WIREIN_TEST1, self.ChimeraSettings.EPBIT_GLOBALRESET,
self.ChimeraSettings.EPBIT_GLOBALRESET)
self.xem.UpdateWireIns()
time.sleep(0.1)
self.xem.SetWireInValue(self.ChimeraSettings.EP_WIREIN_TEST1, 0, self.ChimeraSettings.EPBIT_GLOBALRESET)
self.xem.UpdateWireIns()
print('done')
def ZeroVolt(self):
Vdelta = 0.02
print('Measuring at {} ...'.format(Volt.format_data(Vdelta)), end='')
self.SetVoltage(Vdelta, write=False)
self.ResetBuffer()
time.sleep(1)
measI1 = np.mean(self.RecordTrace())
print('{}'.format(Amp.format_data(measI1)))
print('Measuring at {} ...'.format(Volt.format_data(0)), end='')
self.SetVoltage(0, write=False)
self.ResetBuffer()
time.sleep(1)
measI2 = np.mean(self.RecordTrace())
print('{}'.format(Amp.format_data(measI2)))
deltaI = measI1-measI2
if deltaI == 0:
print('Error, cannot zero voltage: deltaI = 0')
else:
measR = Vdelta / deltaI
self.ResetBuffer()
self.ChimeraSettings.voltageOffset += -measI2 * measR
print('New voltage offset: {}'.format(Volt.format_data(self.ChimeraSettings.voltageOffset)))
ChimeraControls.CHIMERA_updateDACvalues1(self.ChimeraSettings, self.xem, 0)
self.SetVoltage(self.ChimeraSettings.voltageOffset)
def SetVoltage(self, sb, write=True):
if sb is not self.newbiasvalue:
self.newbiasvalue = sb
self.file = None
# self.ChimeraSettings.RestartBuffer = True
if write:
now = datetime.datetime.now()
time_string = now.time().strftime("%H:%M:%S")
print(time_string + ', {}'.format(Volt.format_data(sb)))
self.SaveVoltage()
ChimeraControls.CHIMERA_updateDACvalues1(self.ChimeraSettings, self.xem, self.newbiasvalue)
def RecordTraceRaw(self):
self.blockvalues = ChimeraControls.CHIMERA_process_triggers(self.ChimeraSettings, self.xem)
self.readvalues = ChimeraControls.ConvertBlockvalues(self.ChimeraSettings, self.blockvalues)
return self.readvalues
def RecordTrace(self):
self.RecordTraceRaw()
# Samplerate = self.ChimeraSettings.ADCSAMPLERATE
# displaybuffer, self.displaySamplerate = functions.LowPass(readvalues, self.ChimeraSettings, self.lowpass)
# displaybuffer = ChimeraControls.lowpass(self.ChimeraSettings, readvalues, cutoff=self.lowpass)
self.displaybuffer, self.displaySamplerate = \
functions.LowPassFast(self.readvalues, self.ChimeraSettings, self.displaysubsample, self.lowpass)
return self.displaybuffer
def SaveVoltage(self):
savingFolder = os.path.join(self.DataFolder, self.todaysfolder)
savingName = self.experimentName + 'Vdata.csv'
fullpath = os.path.join(savingFolder, savingName)
if not os.path.isfile(fullpath):
csv_headers = ['Date', 'Time', 'Voltage']
with open(fullpath, 'w') as new_data_file:
datawriter = csv.writer(new_data_file)
datawriter.writerow(csv_headers)
# Create date and time string
now = datetime.datetime.now()
date_string = now.date().strftime("%Y-%m-%d")
time_string = now.time().strftime("%H:%M:%S")
# Convert to data
data = [date_string, time_string, str(self.newbiasvalue)]
with open(fullpath, 'w') as csvfile:
writeline = csv.writer(csvfile, delimiter=',')
writeline.writerows(data)
def WriteRawData(self):
if self.saveDownsampled:
self.file.write(self.displaybuffer.copy(order='C'))
self.ADClogsize += 2 * len(self.displaybuffer)
else:
self.file.write(np.uint16(self.blockvalues))
self.ADClogsize += 2 * len(self.blockvalues)
def writeSummary(self):
if self.saveDownsampled:
samplerate = self.ChimeraSettings.ADCSAMPLERATE/self.displaysubsample
else:
samplerate = self.ChimeraSettings.ADCSAMPLERATE
mdict = {'DisplayBuffer': len(self.displaybuffer),
'ADCSAMPLERATE': samplerate,
'mytimestamp': str(datetime.datetime.today()),
'bias2value': self.newbiasvalue,
'SETUP_ADCVREF': self.ChimeraSettings.ADCVREF,
'SETUP_ADCSAMPLERATE': self.ChimeraSettings.ADCSAMPLERATE,
'SETUP_displaysubsample': self.displaysubsample,
'SETUP_ADCBITS': self.ChimeraSettings.ADCBITS,
'SETUP_TIAgain': self.ChimeraSettings.SETUP_TIAgain,
'SETUP_preADCgain': self.ChimeraSettings.SETUP_preADCgain,
'SETUP_pAoffset': self.ChimeraSettings.SETUP_pAoffset,
'SETUP_mVoffset': self.ChimeraSettings.voltageOffset}
io.savemat(self.savename + '.mat', mdict, True, '5', False, False, 'row')
def SaveData(self, close=True):
if self.file is not None and self.ADClogsize < self.ChimeraSettings.MAXLOGBYTES:
if not self.file.closed:
self.WriteRawData()
else:
self.file = open(self.savename + '.log', 'ab')
self.WriteRawData()
if close:
self.file.close()
else:
if self.file is not None and not self.file.closed:
self.file.close()
# Create new filename
self.CreateSavename()
# open file and reset logsize
self.file = open(self.savename + '.log', 'ab')
self.ADClogsize = 0
# Write summary .mat file and write raw .log file
self.writeSummary()
self.WriteRawData()
if close:
self.file.close()
class ChimeraPlot:
def __init__(self, Chimera):
self.Chimera = Chimera
self.fig, self.ax = plt.subplots(figsize=(9.5, 4.5))
self.ax.set_xlabel('Time [s]')
self.ax.set_ylabel('Current [nA]')
self.ax.set_title(self.Chimera.savename)
self.buffertext = plt.figtext(0.95, 0.5, '')
self.samplerate = Chimera.ChimeraSettings.ADCSAMPLERATE/Chimera.displaysubsample
self.buffercheck = 5
def Update(self, trace):
x = np.arange(len(trace)) / self.samplerate
currentIDC = np.mean(trace)
currentRMS = np.std(trace)
if self.ax.lines:
for line in self.ax.lines:
#line.set_xdata(x)
line.set_ydata(trace)
else:
self.ax.plot(x, trace)
plt.show(block=False)
self.fig.canvas.draw()
self.ax.set_ylim([currentIDC - 10 * currentRMS, currentIDC + 10 * currentRMS])
self.ax.set_xlim([0, len(trace)/self.samplerate])
self.fig.canvas.draw()
self.fig.canvas.flush_events()
def Writebuffer(self, out):
textstr = "Buffer\n{0} kB\nBuffer Size\n{1} %\nSeconds buffered\n{2:.3f} sec".format(out['buffer'],
out['bufferPC'],
out['bufferseconds'])
self.buffertext.set_text(textstr)

Event Timeline