Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F65154376
Chimera.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sat, Jun 1, 06:58
Size
14 KB
Mime Type
text/x-python
Expires
Mon, Jun 3, 06:58 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
18013601
Attached To
rCHIMERAPYTHON Chimera scripts in python
Chimera.py
View Options
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}
\n
USB Read Rate
\n
{1:} kHz
\n
USB Write Rate
\n
{2}"
.
format
(
out
[
'text_time'
],
out
[
'USB_readrate'
],
out
[
'USB_writerate'
])
text2
=
"Buffer
\n
{0} kB
\n
Buffer Size
\n
{1} %
\n
Seconds 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
\n
Buffer Size
\n
{1} %
\n
Seconds buffered
\n
{2:.3f} sec"
.
format
(
out
[
'buffer'
],
out
[
'bufferPC'
],
out
[
'bufferseconds'
])
self
.
buffertext
.
set_text
(
textstr
)
Event Timeline
Log In to Comment