Skip to content
GitLab
Explore
Sign in
Register
Expand all
Show whitespace changes
Inline
Side-by-side
dstat_interface/core/experiments/experiment_loops.py
0 → 100644
View file @
86048afb
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# DStat Interface - An interface for the open hardware DStat potentiostat
# Copyright (C) 2014 Michael D. M. Dryden -
# Wheeler Microfluidics Laboratory <http://microfluidics.utoronto.ca>
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from
__future__
import
division
,
absolute_import
,
print_function
,
unicode_literals
from
..dstat
import
state
import
logging
try
:
import
gi
gi
.
require_version
(
'
Gtk
'
,
'
3.0
'
)
from
gi.repository
import
Gtk
,
GObject
except
ImportError
:
print
(
"
ERR: GTK not available
"
)
sys
.
exit
(
1
)
logger
=
logging
.
getLogger
(
__name__
)
class
BaseLoop
(
GObject
.
GObject
):
__gsignals__
=
{
b
'
experiment_done
'
:
(
GObject
.
SIGNAL_RUN_FIRST
,
None
,
tuple
()),
b
'
progress_update
'
:
(
GObject
.
SIGNAL_RUN_FIRST
,
None
,
(
float
,))
}
def
__init__
(
self
,
experiment
,
callbacks
=
None
):
GObject
.
GObject
.
__init__
(
self
)
self
.
line
=
None
self
.
lastdataline
=
0
self
.
current_exp
=
experiment
self
.
experiment_proc
=
None
for
signal
,
cb
in
callbacks
.
items
():
try
:
self
.
connect
(
signal
,
cb
)
except
TypeError
:
logger
.
warning
(
"
Invalid signal %s
"
,
signal
)
def
run
(
self
):
self
.
experiment_proc
=
[
GObject
.
idle_add
(
self
.
experiment_running_data
),
GObject
.
idle_add
(
self
.
experiment_running_proc
),
GObject
.
timeout_add
(
100
,
self
.
update_progress
)
]
def
experiment_running_data
(
self
):
"""
Receive data from experiment process and add to
current_exp.data[
'
data].
Run in GTK main loop.
Returns:
True -- when experiment is continuing to keep function in GTK
'
s queue.
False -- when experiment process signals EOFError or IOError to remove
function from GTK
'
s queue.
"""
try
:
incoming
=
state
.
ser
.
get_data
()
while
incoming
is
not
None
:
try
:
self
.
line
=
incoming
[
0
]
if
self
.
line
>
self
.
lastdataline
:
newline
=
True
try
:
logger
.
info
(
"
running scan_process()
"
)
self
.
current_exp
.
scan_process
(
self
.
lastdataline
)
except
AttributeError
:
pass
self
.
lastdataline
=
self
.
line
else
:
newline
=
False
self
.
current_exp
.
store_data
(
incoming
,
newline
)
except
TypeError
:
pass
incoming
=
state
.
ser
.
get_data
()
return
True
except
EOFError
as
err
:
logger
.
error
(
err
)
self
.
experiment_done
()
return
False
except
IOError
as
err
:
logger
.
error
(
err
)
self
.
experiment_done
()
return
False
def
experiment_running_proc
(
self
):
"""
Receive proc signals from experiment process.
Run in GTK main loop.
Returns:
True -- when experiment is continuing to keep function in GTK
'
s queue.
False -- when experiment process signals EOFError or IOError to remove
function from GTK
'
s queue.
"""
try
:
ctrl_buffer
=
state
.
ser
.
get_ctrl
()
try
:
if
ctrl_buffer
is
not
None
:
self
.
current_exp
.
ctrl_loop
(
ctrl_buffer
)
except
AttributeError
:
pass
proc_buffer
=
state
.
ser
.
get_proc
()
if
proc_buffer
is
not
None
:
if
proc_buffer
in
[
"
DONE
"
,
"
SERIAL_ERROR
"
,
"
ABORT
"
]:
self
.
experiment_done
()
if
proc_buffer
==
"
SERIAL_ERROR
"
:
self
.
on_serial_disconnect_clicked
()
else
:
logger
.
warning
(
"
Unrecognized experiment return code: %s
"
,
proc_buffer
)
return
False
return
True
except
EOFError
as
err
:
logger
.
warning
(
"
EOFError: %s
"
,
err
)
self
.
experiment_done
()
return
False
except
IOError
as
err
:
logger
.
warning
(
"
IOError: %s
"
,
err
)
self
.
experiment_done
()
return
False
def
experiment_done
(
self
):
logger
.
info
(
"
Experiment done
"
)
for
proc
in
self
.
experiment_proc
:
GObject
.
source_remove
(
proc
)
self
.
current_exp
.
scan_process
(
self
.
lastdataline
)
self
.
current_exp
.
experiment_done
()
self
.
emit
(
"
experiment_done
"
)
def
update_progress
(
self
):
try
:
progress
=
self
.
current_exp
.
get_progress
()
except
AttributeError
:
progress
=
-
1
self
.
emit
(
"
progress_update
"
,
progress
)
return
True
class
PlotLoop
(
BaseLoop
):
def
experiment_running_plot
(
self
,
force_refresh
=
False
):
"""
Plot all data in current_exp.data.
Run in GTK main loop. Always returns True so must be manually
removed from GTK
'
s queue.
"""
if
self
.
line
is
None
:
return
True
for
plot
in
self
.
current_exp
.
plots
:
if
(
plot
.
scan_refresh
and
self
.
line
>
self
.
lastdataline
):
while
self
.
line
>
self
.
lastline
:
# make sure all of last line is added
plot
.
updateline
(
self
.
current_exp
,
self
.
lastdataline
)
self
.
lastdataline
+=
1
plot
.
updateline
(
self
.
current_exp
,
self
.
line
)
plot
.
redraw
()
else
:
while
self
.
line
>
self
.
lastdataline
:
# make sure all of last line is added
plot
.
updateline
(
self
.
current_exp
,
self
.
lastdataline
)
self
.
lastdataline
+=
1
plot
.
updateline
(
self
.
current_exp
,
self
.
line
)
if
plot
.
continuous_refresh
is
True
or
force_refresh
is
True
:
plot
.
redraw
()
return
True
def
run
(
self
):
super
(
PlotLoop
,
self
).
run
()
self
.
experiment_proc
.
append
(
GObject
.
timeout_add
(
200
,
self
.
experiment_running_plot
)
)
def
experiment_done
(
self
):
logger
.
info
(
"
Experiment done
"
)
for
proc
in
self
.
experiment_proc
:
GObject
.
source_remove
(
proc
)
self
.
current_exp
.
scan_process
(
self
.
lastdataline
)
self
.
current_exp
.
experiment_done
()
self
.
experiment_running_plot
(
force_refresh
=
True
)
self
.
emit
(
"
experiment_done
"
)
\ No newline at end of file
dstat_interface/experiments/experiment_template.py
→
dstat_interface/
core/
experiments/experiment_template.py
View file @
86048afb
...
@@ -19,11 +19,11 @@
...
@@ -19,11 +19,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import
logging
import
logging
import
struct
import
struct
from
datetime
import
date
time
import
time
from
collections
import
OrderedDict
from
collections
import
OrderedDict
from
copy
import
deepcopy
from
copy
import
deepcopy
from
datetime
import
datetime
from
math
import
ceil
from
math
import
ceil
import
time
try
:
try
:
import
gi
import
gi
...
@@ -33,39 +33,45 @@ except ImportError:
...
@@ -33,39 +33,45 @@ except ImportError:
print
"
ERR: GTK not available
"
print
"
ERR: GTK not available
"
sys
.
exit
(
1
)
sys
.
exit
(
1
)
from
matplotlib.figure
import
Figure
from
matplotlib.figure
import
Figure
import
matplotlib.gridspec
as
gridspec
import
matplotlib.gridspec
as
gridspec
import
matplotlib.pyplot
as
plt
from
matplotlib.backends.backend_gtk3agg
\
from
matplotlib.backends.backend_gtk3agg
\
import
FigureCanvasGTK3Agg
as
FigureCanvas
import
FigureCanvasGTK3Agg
as
FigureCanvas
from
pandas
import
DataFrame
from
pandas
import
DataFrame
try
:
import
seaborn
as
sns
import
seaborn
as
sns
sns
.
set
(
context
=
'
paper
'
,
style
=
'
darkgrid
'
)
sns
.
set
(
context
=
'
paper
'
,
style
=
'
darkgrid
'
)
except
ImportError
:
pass
import
serial
import
serial
logger
=
logging
.
getLogger
(
"
dstat.comm
"
)
from
..dstat
import
state
,
comm
dstat_logger
=
logging
.
getLogger
(
"
dstat.comm.DSTAT
"
)
from
..dstat.comm
import
TransmitError
exp_logger
=
logging
.
getLogger
(
"
dstat.comm.Experiment
"
)
from
.
import
experiment_loops
logger
=
logging
.
getLogger
(
__name__
)
dstat_logger
=
logging
.
getLogger
(
"
{}.DSTAT
"
.
format
(
comm
.
__name__
))
exp_logger
=
logging
.
getLogger
(
"
{}.Experiment
"
.
format
(
__name__
))
from
errors
import
InputError
,
VarError
import
state
class
Experiment
(
o
bject
):
class
Experiment
(
GObject
.
O
bject
):
"""
Store and acquire a potentiostat experiment. Meant to be subclassed
"""
Store and acquire a potentiostat experiment. Meant to be subclassed
to by different experiment types and not used instanced directly. Subclass
to by different experiment types and not used instanced directly. Subclass
must instantiate self.plotbox as the PlotBox class to use and define id as
must instantiate self.plotbox as the PlotBox class to use and define id as
a class attribute.
a class attribute.
"""
"""
id
=
None
id
=
None
Loops
=
experiment_loops
.
PlotLoop
__gsignals__
=
{
b
'
exp_ready
'
:
(
GObject
.
SIGNAL_RUN_FIRST
,
None
,
()),
b
'
exp_done
'
:
(
GObject
.
SIGNAL_RUN_FIRST
,
None
,
()),
}
def
__init__
(
self
,
parameters
):
def
__init__
(
self
,
parameters
):
"""
Adds commands for gain and ADC.
"""
"""
Adds commands for gain and ADC.
"""
super
(
Experiment
,
self
).
__init__
()
self
.
current_command
=
None
self
.
parameters
=
parameters
self
.
parameters
=
parameters
self
.
databytes
=
8
self
.
databytes
=
8
self
.
datapoint
=
0
self
.
datapoint
=
0
...
@@ -73,25 +79,18 @@ class Experiment(object):
...
@@ -73,25 +79,18 @@ class Experiment(object):
self
.
time
=
0
self
.
time
=
0
self
.
plots
=
[]
self
.
plots
=
[]
major
,
minor
=
state
.
dstat_version
self
.
re_voltage_scale
=
state
.
board_instance
.
re_voltage_scale
if
major
>=
1
:
self
.
gain
=
state
.
board_instance
.
gain
[
int
(
self
.
parameters
[
'
gain
'
])]
if
minor
==
1
:
self
.
__gaintable
=
[
1e2
,
3e2
,
3e3
,
3e4
,
3e5
,
3e6
,
3e7
,
5e8
]
elif
minor
>=
2
:
self
.
__gaintable
=
[
1
,
1e2
,
3e3
,
3e4
,
3e5
,
3e6
,
3e7
,
1e8
]
self
.
__gain_trim_table
=
[
'
r100_trim
'
,
'
r100_trim
'
,
'
r3k_trim
'
,
'
r30k_trim
'
,
'
r300k_trim
'
,
'
r3M_trim
'
,
'
r30M_trim
'
,
'
r100M_trim
'
]
else
:
raise
VarError
(
parameters
[
'
version
'
],
"
Invalid version parameter.
"
)
self
.
gain
=
self
.
__gaintable
[
int
(
self
.
parameters
[
'
gain
'
])]
try
:
self
.
gain_trim
=
int
(
self
.
gain_trim
=
int
(
state
.
settings
[
state
.
settings
[
self
.
__
gain_trim
_table
[
int
(
self
.
parameters
[
'
gain
'
])]
state
.
board_instance
.
gain_trim
[
int
(
self
.
parameters
[
'
gain
'
])]
][
1
]
][
1
]
)
)
except
AttributeError
:
logger
.
debug
(
"
No gain trim table.
"
)
self
.
commands
=
[
"
EA
"
,
"
EG
"
]
self
.
commands
=
[
"
EA
"
,
"
EG
"
]
...
@@ -104,30 +103,40 @@ class Experiment(object):
...
@@ -104,30 +103,40 @@ class Experiment(object):
self
.
commands
[
1
]
+=
"
{p[gain]} {p[short_true]:d}
"
.
format
(
self
.
commands
[
1
]
+=
"
{p[gain]} {p[short_true]:d}
"
.
format
(
p
=
self
.
parameters
)
p
=
self
.
parameters
)
self
.
plotlims
=
{
'
current_voltage
'
:
{
'
xlims
'
:
(
0
,
1
)}
}
self
.
setup
()
self
.
setup
()
self
.
time
=
[
datetime
.
utcnow
()]
self
.
time
=
[
datetime
.
utcnow
()]
def
setup_loops
(
self
,
callbacks
):
self
.
loops
=
self
.
__class__
.
Loops
(
self
,
callbacks
)
self
.
loops
.
run
()
def
setup
(
self
):
def
setup
(
self
):
self
.
data
=
OrderedDict
(
current_voltage
=
[([],
[])])
self
.
data
=
OrderedDict
(
current_voltage
=
[([],
[])])
self
.
columns
=
[
'
Voltage (mV)
'
,
'
Current (A)
'
]
self
.
columns
=
[
'
Voltage (mV)
'
,
'
Current (A)
'
]
self
.
plot_format
=
{
'
current_voltage
'
:
{
'
labels
'
:
self
.
columns
,
'
xlims
'
:
(
0
,
1
)
}
}
# list of scans, tuple of dimensions, list of data
# list of scans, tuple of dimensions, list of data
self
.
line_data
=
([],
[])
self
.
line_data
=
([],
[])
self
.
plots
.
append
(
PlotBox
([
'
current_voltage
'
]))
plot
=
PlotBox
([
'
current_voltage
'
])
plot
.
setlims
(
'
current_voltage
'
,
**
self
.
plotlims
[
'
current_voltage
'
])
self
.
plots
.
append
(
plot
)
def
write_command
(
self
,
cmd
,
params
=
None
,
retry
=
10
):
def
write_command
(
self
,
cmd
,
params
=
None
,
retry
=
5
):
"""
Write command to serial with optional number of retries.
"""
"""
Write command to serial with optional number of retries.
"""
def
get_reply
():
def
get_reply
(
retries
=
3
):
while
True
:
reply
=
self
.
serial
.
readline
().
rstrip
()
reply
=
self
.
serial
.
readline
().
rstrip
()
if
reply
.
startswith
(
'
#
'
):
if
reply
.
startswith
(
'
#
'
):
dstat_logger
.
info
(
reply
)
dstat_logger
.
info
(
reply
)
return
get_reply
()
elif
reply
==
""
:
retries
-=
1
if
retries
<=
0
:
raise
TransmitError
else
:
return
reply
return
reply
n
=
len
(
cmd
)
n
=
len
(
cmd
)
...
@@ -135,50 +144,87 @@ class Experiment(object):
...
@@ -135,50 +144,87 @@ class Experiment(object):
n_params
=
len
(
params
)
n_params
=
len
(
params
)
for
_
in
range
(
retry
):
for
_
in
range
(
retry
):
tries
=
5
while
True
:
time
.
sleep
(
0.2
)
time
.
sleep
(
0.2
)
self
.
serial
.
reset_input_buffer
()
self
.
serial
.
reset_input_buffer
()
self
.
serial
.
write
(
'
!{}
\n
'
.
format
(
n
))
self
.
serial
.
write
(
'
!{}
\n
'
.
format
(
n
))
time
.
sleep
(.
1
)
time
.
sleep
(.
1
)
try
:
reply
=
get_reply
()
reply
=
get_reply
()
except
TransmitError
:
if
tries
<=
0
:
continue
tries
-=
1
pass
else
:
break
if
reply
!=
"
@ACK {}
"
.
format
(
n
):
if
reply
!=
"
@ACK {}
"
.
format
(
n
):
logger
.
warning
(
"
Invalid response
: {}
"
.
format
(
reply
))
logger
.
warning
(
"
Expected ACK got
: {}
"
.
format
(
reply
))
continue
continue
self
.
serial
.
write
(
'
{}
\n
'
.
format
(
cmd
))
tries
=
5
while
True
:
self
.
serial
.
write
(
'
{}
\n
'
.
format
(
cmd
))
try
:
reply
=
get_reply
()
reply
=
get_reply
()
except
TransmitError
:
if
tries
<=
0
:
continue
tries
-=
1
pass
else
:
break
if
reply
!=
"
@RCV {}
"
.
format
(
n
):
if
reply
!=
"
@RCV {}
"
.
format
(
n
):
logger
.
warning
(
"
Invalid response
: {}
"
.
format
(
reply
))
logger
.
warning
(
"
Expected RCV got
: {}
"
.
format
(
reply
))
continue
continue
if
params
is
None
:
if
params
is
None
:
return
True
return
True
tries
=
5
while
True
:
try
:
reply
=
get_reply
()
reply
=
get_reply
()
except
TransmitError
:
if
tries
<=
0
:
break
tries
-=
1
pass
else
:
break
if
reply
!=
"
@RQP {}
"
.
format
(
n_params
):
if
reply
!=
"
@RQP {}
"
.
format
(
n_params
):
logger
.
warning
(
"
Invalid response
: {}
"
.
format
(
reply
))
logger
.
warning
(
"
Expected RQP got
: {}
"
.
format
(
reply
))
continue
continue
self
.
serial
.
write
(
"
"
.
join
(
params
)
+
"
"
)
tries
=
5
for
i
in
params
:
while
True
:
self
.
serial
.
write
(
i
+
"
"
)
try
:
reply
=
get_reply
()
reply
=
get_reply
()
if
reply
==
"
@RCVC {}
"
.
format
(
i
):
if
reply
!=
"
@RCP {}
"
.
format
(
n_params
):
break
logger
.
warning
(
"
Invalid response: {}
"
.
format
(
reply
))
except
TransmitError
:
if
tries
<=
0
:
continue
continue
tries
-=
1
pass
else
:
break
return
True
return
True
return
False
return
False
def
run
(
self
,
ser
,
ctrl_pipe
,
data_pipe
):
def
run
(
self
,
ser
,
ctrl_pipe
,
data_pipe
):
"""
Execute experiment. Connects and sends handshake signal to DStat
"""
Execute experiment. Connects and sends handshake signal to DStat
then sends self.commands. Don
'
t call directly as a process in Windows,
then sends self.commands.
use run_wrapper instead.
"""
"""
self
.
serial
=
ser
self
.
serial
=
ser
self
.
ctrl_pipe
=
ctrl_pipe
self
.
ctrl_pipe
=
ctrl_pipe
...
@@ -188,6 +234,7 @@ class Experiment(object):
...
@@ -188,6 +234,7 @@ class Experiment(object):
try
:
try
:
for
i
in
self
.
commands
:
for
i
in
self
.
commands
:
self
.
current_command
=
i
status
=
"
DONE
"
status
=
"
DONE
"
if
isinstance
(
i
,
(
str
,
unicode
)):
if
isinstance
(
i
,
(
str
,
unicode
)):
logger
.
info
(
"
Command: %s
"
,
i
)
logger
.
info
(
"
Command: %s
"
,
i
)
...
@@ -225,11 +272,11 @@ class Experiment(object):
...
@@ -225,11 +272,11 @@ class Experiment(object):
data to self.data_pipe as result of self.data_handler).
data to self.data_pipe as result of self.data_handler).
"""
"""
scan
=
0
scan
=
0
try
:
while
True
:
def
check_ctrl
()
:
if
self
.
ctrl_pipe
.
poll
():
if
self
.
ctrl_pipe
.
poll
():
input
=
self
.
ctrl_pipe
.
recv
()
input
=
self
.
ctrl_pipe
.
recv
()
logger
.
debug
(
"
serial_handler: %s
"
,
input
)
logger
.
info
(
"
serial_handler: %s
"
,
input
)
if
input
==
"
DISCONNECT
"
:
if
input
==
"
DISCONNECT
"
:
self
.
serial
.
write
(
'
a
'
)
self
.
serial
.
write
(
'
a
'
)
self
.
serial
.
reset_input_buffer
()
self
.
serial
.
reset_input_buffer
()
...
@@ -238,11 +285,14 @@ class Experiment(object):
...
@@ -238,11 +285,14 @@ class Experiment(object):
return
False
return
False
elif
input
==
'
a
'
:
elif
input
==
'
a
'
:
self
.
serial
.
write
(
'
a
'
)
self
.
serial
.
write
(
'
a
'
)
else
:
self
.
serial
.
write
(
input
)
try
:
while
True
:
check_ctrl
()
for
line
in
self
.
serial
:
for
line
in
self
.
serial
:
if
self
.
ctrl_pipe
.
poll
():
check_ctrl
()
if
self
.
ctrl_pipe
.
recv
()
==
'
a
'
:
self
.
serial
.
write
(
'
a
'
)
if
line
.
startswith
(
'
B
'
):
if
line
.
startswith
(
'
B
'
):
data
=
self
.
data_handler
(
data
=
self
.
data_handler
(
...
@@ -269,7 +319,6 @@ class Experiment(object):
...
@@ -269,7 +319,6 @@ class Experiment(object):
except
serial
.
SerialException
:
except
serial
.
SerialException
:
return
False
return
False
def
data_handler
(
self
,
data_input
):
def
data_handler
(
self
,
data_input
):
"""
Takes data_input as tuple -- (scan, data).
"""
Takes data_input as tuple -- (scan, data).
Returns:
Returns:
...
@@ -278,8 +327,8 @@ class Experiment(object):
...
@@ -278,8 +327,8 @@ class Experiment(object):
scan
,
data
=
data_input
scan
,
data
=
data_input
voltage
,
current
=
struct
.
unpack
(
'
<Hl
'
,
data
)
#uint16 + int32
voltage
,
current
=
struct
.
unpack
(
'
<Hl
'
,
data
)
#uint16 + int32
return
(
scan
,
(
return
(
scan
,
(
(
voltage
-
32768
)
*
3000.
/
65536
,
(
voltage
-
32768
)
*
(
3000.
/
65536
)
*
self
.
re_voltage_scale
,
(
current
+
self
.
gain_trim
)
*
(
1.5
/
self
.
gain
/
8388607
)
(
current
+
self
.
gain_trim
)
*
(
1.5
/
8388607
)
/
self
.
gain
)
)
)
)
...
@@ -299,13 +348,16 @@ class Experiment(object):
...
@@ -299,13 +348,16 @@ class Experiment(object):
in subclass.
in subclass.
"""
"""
try
:
try
:
if
self
.
datapoint
=
=
0
:
if
self
.
datapoint
<
=
1
:
return
None
return
None
except
AttributeError
:
# Datapoint counting is optional
except
AttributeError
:
# Datapoint counting is optional
pass
pass
return
data
return
data
def
scan_process
(
self
,
line
):
pass
def
experiment_done
(
self
):
def
experiment_done
(
self
):
"""
Runs when experiment is finished (all data acquired)
"""
"""
Runs when experiment is finished (all data acquired)
"""
self
.
data_to_pandas
()
self
.
data_to_pandas
()
...
@@ -332,11 +384,45 @@ class Experiment(object):
...
@@ -332,11 +384,45 @@ class Experiment(object):
self
.
df
=
OrderedDict
()
self
.
df
=
OrderedDict
()
for
name
,
data
in
self
.
data
.
items
():
for
name
,
data
in
self
.
data
.
items
():
df
=
DataFrame
(
columns
=
[
'
Scan
'
]
+
self
.
columns
)
try
:
df
=
DataFrame
(
columns
=
[
'
Scan
'
]
+
list
(
self
.
plot_format
[
name
][
'
labels
'
]))
for
n
,
line
in
enumerate
(
data
):
# Each scan
df
=
df
.
append
(
DataFrame
(
OrderedDict
(
zip
(
[
'
Scan
'
]
+
list
(
self
.
plot_format
[
name
][
'
labels
'
]),
[
n
]
+
list
(
line
))
)
),
ignore_index
=
True
)
except
(
AttributeError
,
KeyError
):
try
:
df
=
DataFrame
(
columns
=
[
'
Scan
'
]
+
list
(
self
.
columns
))
for
n
,
line
in
enumerate
(
data
):
# Each scan
df
=
df
.
append
(
DataFrame
(
OrderedDict
(
zip
(
[
'
Scan
'
]
+
list
(
self
.
columns
),
[
n
]
+
list
(
line
))
)
),
ignore_index
=
True
)
except
AttributeError
as
e
:
# Fallback if no self.columns
df
=
DataFrame
(
columns
=
[
'
Scan
'
]
+
[
"
{}{}
"
.
format
(
name
,
n
)
for
n
in
range
(
len
(
data
))]
)
for
n
,
line
in
enumerate
(
data
):
for
n
,
line
in
enumerate
(
data
):
df
=
df
.
append
(
DataFrame
(
df
=
df
.
append
(
OrderedDict
(
zip
([
'
Scan
'
]
+
self
.
columns
,
DataFrame
(
OrderedDict
(
zip
(
[
'
Scan
'
]
+
[
"
{}{}
"
.
format
(
name
,
n
)
for
n
in
range
(
len
(
data
))],
[
n
]
+
list
(
line
))
[
n
]
+
list
(
line
))
)
)
),
ignore_index
=
True
),
ignore_index
=
True
...
@@ -365,20 +451,26 @@ class Experiment(object):
...
@@ -365,20 +451,26 @@ class Experiment(object):
return
buf
return
buf
class
PlotBox
(
object
):
class
PlotBox
(
object
):
"""
Contains data plot and associated methods.
"""
"""
Contains data plot and associated methods.
"""
def
__init__
(
self
,
plots
):
def
__init__
(
self
,
plots
=
None
):
"""
Initializes plots. self.box should be reparented.
"""
"""
Initializes plots. self.box should be reparented.
"""
self
.
name
=
"
Main
"
self
.
name
=
"
Main
"
self
.
continuous_refresh
=
True
self
.
continuous_refresh
=
True
self
.
scan_refresh
=
False
if
plots
is
not
None
:
self
.
plotnames
=
plots
self
.
plotnames
=
plots
else
:
self
.
plotnames
=
[]
self
.
subplots
=
{}
self
.
subplots
=
{}
self
.
figure
=
Figure
()
self
.
figure
=
Figure
()
# self.figure.subplots_adjust(left=0.07, bottom=0.07,
# self.figure.subplots_adjust(left=0.07, bottom=0.07,
# right=0.96, top=0.96)
# right=0.96, top=0.96)
self
.
setup
()
self
.
format_plots
()
# Should be overriden by subclass
self
.
format_plots
()
# Should be overriden by subclass
self
.
figure
.
set_tight_layout
(
True
)
self
.
figure
.
set_tight_layout
(
True
)
...
@@ -389,6 +481,13 @@ class PlotBox(object):
...
@@ -389,6 +481,13 @@ class PlotBox(object):
self
.
box
=
Gtk
.
Box
(
orientation
=
Gtk
.
Orientation
.
VERTICAL
)
self
.
box
=
Gtk
.
Box
(
orientation
=
Gtk
.
Orientation
.
VERTICAL
)
self
.
box
.
pack_start
(
self
.
canvas
,
expand
=
True
,
fill
=
True
,
padding
=
0
)
self
.
box
.
pack_start
(
self
.
canvas
,
expand
=
True
,
fill
=
True
,
padding
=
0
)
def
setup
(
self
):
self
.
plot_format
=
{
'
current_voltage
'
:
{
'
xlabel
'
:
"
Voltage (mV)
"
,
'
ylabel
'
:
"
Current (A)
"
}
}
def
format_plots
(
self
):
def
format_plots
(
self
):
"""
"""
Creates and formats subplots needed. Should be overriden by subclass
Creates and formats subplots needed. Should be overriden by subclass
...
@@ -402,10 +501,12 @@ class PlotBox(object):
...
@@ -402,10 +501,12 @@ class PlotBox(object):
for
n
,
i
in
enumerate
(
self
.
plotnames
):
for
n
,
i
in
enumerate
(
self
.
plotnames
):
self
.
subplots
[
i
]
=
self
.
figure
.
add_subplot
(
gs
[
n
])
self
.
subplots
[
i
]
=
self
.
figure
.
add_subplot
(
gs
[
n
])
for
subplot
in
self
.
subplots
.
value
s
():
for
key
,
subplot
in
self
.
subplots
.
item
s
():
subplot
.
ticklabel_format
(
style
=
'
sci
'
,
scilimits
=
(
0
,
3
),
subplot
.
ticklabel_format
(
style
=
'
sci
'
,
scilimits
=
(
0
,
3
),
useOffset
=
False
,
axis
=
'
y
'
)
useOffset
=
False
,
axis
=
'
y
'
)
subplot
.
plot
([],
[])
subplot
.
plot
([],
[])
subplot
.
set_xlabel
(
self
.
plot_format
[
key
][
'
xlabel
'
])
subplot
.
set_ylabel
(
self
.
plot_format
[
key
][
'
ylabel
'
])
def
clearall
(
self
):
def
clearall
(
self
):
"""
Remove all lines on plot.
"""
"""
Remove all lines on plot.
"""
...
@@ -436,25 +537,27 @@ class PlotBox(object):
...
@@ -436,25 +537,27 @@ class PlotBox(object):
line_number -- line number to update
line_number -- line number to update
"""
"""
for
subplot
in
Experiment
.
data
:
for
subplot
in
Experiment
.
data
:
while
True
:
try
:
self
.
subplots
[
subplot
].
lines
[
line_number
].
set_xdata
(
self
.
subplots
[
subplot
].
lines
[
line_number
].
set_xdata
(
Experiment
.
data
[
subplot
][
line_number
][
0
])
Experiment
.
data
[
subplot
][
line_number
][
0
])
self
.
subplots
[
subplot
].
lines
[
line_number
].
set_ydata
(
self
.
subplots
[
subplot
].
lines
[
line_number
].
set_ydata
(
Experiment
.
data
[
subplot
][
line_number
][
1
])
Experiment
.
data
[
subplot
][
line_number
][
1
])
except
IndexError
:
self
.
addline
()
except
KeyError
:
pass
else
:
break
# logger.warning("Tried to set line %s that doesn't exist.", line_number)
def
changetype
(
self
,
Experiment
):
def
setlims
(
self
,
plot
,
xlims
=
None
,
ylims
=
None
):
"""
Change plot type. Set axis labels and x bounds to those stored
"""
Sets x and y limits.
in the Experiment instance. Stores class instance in Experiment.
"""
"""
if
xlims
is
not
None
:
for
name
,
subplot
in
self
.
subplots
.
items
():
self
.
subplots
[
plot
].
set_xlim
(
xlims
)
subplot
.
set_xlabel
(
Experiment
.
plot_format
[
name
][
'
labels
'
][
0
])
if
ylims
is
not
None
:
subplot
.
set_ylabel
(
Experiment
.
plot_format
[
name
][
'
labels
'
][
1
])
self
.
subplots
[
plot
].
set_ylim
(
ylims
)
subplot
.
set_xlim
(
Experiment
.
plot_format
[
name
][
'
xlims
'
])
for
name
,
subplot
in
Experiment
.
plot_format
.
items
():
self
.
subplots
[
name
].
set_xlabel
(
subplot
[
'
labels
'
][
0
])
self
.
subplots
[
name
].
set_ylabel
(
subplot
[
'
labels
'
][
1
])
self
.
subplots
[
name
].
set_xlim
(
subplot
[
'
xlims
'
])
self
.
figure
.
canvas
.
draw
()
self
.
figure
.
canvas
.
draw
()
...
...
dstat_interface/experiments/idle.py
→
dstat_interface/
core/
experiments/idle.py
View file @
86048afb
import
time
import
time
import
struct
import
struct
from
experiments.experiment_template
import
Experiment
from
.experiment_template
import
Experiment
from
..dstat
import
state
class
OCPExp
(
Experiment
):
class
OCPExp
(
Experiment
):
"""
Open circuit potential measumement in statusbar.
"""
"""
Open circuit potential measumement in statusbar.
"""
id
=
'
ocp
'
id
=
'
ocp
'
def
__init__
(
self
):
def
__init__
(
self
):
self
.
re_voltage_scale
=
state
.
board_instance
.
re_voltage_scale
self
.
databytes
=
8
self
.
databytes
=
8
self
.
commands
=
[
"
EA
"
,
"
EP0 0
"
]
self
.
commands
=
[
"
EA
"
,
"
EP0 0
"
]
...
@@ -15,17 +18,18 @@ class OCPExp(Experiment):
...
@@ -15,17 +18,18 @@ class OCPExp(Experiment):
self
.
commands
[
0
]
+=
"
3
"
# 2.5 Hz sample rate
self
.
commands
[
0
]
+=
"
3
"
# 2.5 Hz sample rate
self
.
commands
[
0
]
+=
"
1
"
# 2x PGA
self
.
commands
[
0
]
+=
"
1
"
# 2x PGA
def
data_handler
(
self
,
data_input
):
def
data_handler
(
self
,
data_input
):
"""
Overrides Experiment method to only send ADC values.
"""
"""
Overrides Experiment method to only send ADC values.
"""
scan
,
data
=
data_input
scan
,
data
=
data_input
# 2*uint16 + int32
# 2*uint16 + int32
seconds
,
milliseconds
,
voltage
=
struct
.
unpack
(
'
<HHl
'
,
data
)
seconds
,
milliseconds
,
voltage
=
struct
.
unpack
(
'
<HHl
'
,
data
)
return
(
voltage
/
5.592405e6
)
return
voltage
/
5.592405e6
*
self
.
re_voltage_scale
class
PMTIdle
(
Experiment
):
class
PMTIdle
(
Experiment
):
"""
Open circuit potential measumement in statusbar
.
"""
"""
PMT idle mode
.
"""
id
=
"
pmt_idle
"
id
=
"
pmt_idle
"
def
__init__
(
self
):
def
__init__
(
self
):
self
.
databytes
=
8
self
.
databytes
=
8
...
...
dstat_interface/core/experiments/lsv.py
0 → 100644
View file @
86048afb
import
time
import
struct
from
.experiment_template
import
PlotBox
,
Experiment
class
LSVExp
(
Experiment
):
"""
Linear Scan Voltammetry experiment
"""
id
=
'
lsv
'
def
setup
(
self
):
self
.
plotlims
[
'
current_voltage
'
][
'
xlims
'
]
=
tuple
(
sorted
(
(
int
(
self
.
parameters
[
'
start
'
]),
int
(
self
.
parameters
[
'
stop
'
]))
)
)
super
(
LSVExp
,
self
).
setup
()
self
.
datatype
=
"
linearData
"
self
.
datalength
=
2
self
.
databytes
=
6
# uint16 + int32
self
.
stop_mv
=
int
(
self
.
parameters
[
'
stop
'
])
self
.
max_mv
=
abs
(
int
(
self
.
parameters
[
'
start
'
])
-
int
(
self
.
parameters
[
'
stop
'
]))
self
.
commands
+=
"
E
"
self
.
commands
[
2
]
+=
"
L
"
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
clean_s
'
])
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
dep_s
'
])
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
int
(
int
(
self
.
parameters
[
'
clean_mV
'
])
/
self
.
re_voltage_scale
*
(
65536.
/
3000
)
+
32768
))
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
int
(
int
(
self
.
parameters
[
'
dep_mV
'
])
/
self
.
re_voltage_scale
*
(
65536.
/
3000
)
+
32768
))
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
int
(
int
(
self
.
parameters
[
'
start
'
])
/
self
.
re_voltage_scale
*
(
65536.
/
3000
)
+
32768
))
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
int
(
int
(
self
.
parameters
[
'
stop
'
])
/
self
.
re_voltage_scale
*
(
65536.
/
3000
)
+
32768
))
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
int
(
int
(
self
.
parameters
[
'
slope
'
])
/
self
.
re_voltage_scale
*
(
65536.
/
3000
)
))
self
.
commands
[
2
]
+=
"
"
def
get_progress
(
self
):
try
:
return
1
-
(
abs
(
self
.
stop_mv
-
self
.
data
[
'
current_voltage
'
][
-
1
][
0
][
-
1
])
/
self
.
max_mv
)
except
IndexError
:
return
0
\ No newline at end of file
dstat_interface/experiments/pot.py
→
dstat_interface/
core/
experiments/pot.py
View file @
86048afb
import
time
import
time
import
struct
import
struct
from
experiments.experiment_template
import
PlotBox
,
Experiment
from
.experiment_template
import
PlotBox
,
Experiment
class
PotBox
(
PlotBox
):
class
PotBox
(
PlotBox
):
def
setup
(
self
):
self
.
plot_format
=
{
'
voltage_time
'
:
{
'
xlabel
'
:
"
Time (s)
"
,
'
ylabel
'
:
"
Voltage (V)
"
}
}
def
format_plots
(
self
):
def
format_plots
(
self
):
"""
"""
Creates and formats subplots needed. Overrides superclass.
Creates and formats subplots needed. Overrides superclass.
...
@@ -14,6 +22,9 @@ class PotBox(PlotBox):
...
@@ -14,6 +22,9 @@ class PotBox(PlotBox):
subplot
.
ticklabel_format
(
style
=
'
sci
'
,
scilimits
=
(
0
,
3
),
subplot
.
ticklabel_format
(
style
=
'
sci
'
,
scilimits
=
(
0
,
3
),
useOffset
=
False
,
axis
=
'
y
'
)
useOffset
=
False
,
axis
=
'
y
'
)
subplot
.
plot
([],[])
subplot
.
plot
([],[])
subplot
.
set_xlabel
(
self
.
plot_format
[
key
][
'
xlabel
'
])
subplot
.
set_ylabel
(
self
.
plot_format
[
key
][
'
ylabel
'
])
class
PotExp
(
Experiment
):
class
PotExp
(
Experiment
):
id
=
'
pot
'
id
=
'
pot
'
...
@@ -26,12 +37,14 @@ class PotExp(Experiment):
...
@@ -26,12 +37,14 @@ class PotExp(Experiment):
self
.
databytes
=
8
self
.
databytes
=
8
self
.
data
=
{
'
voltage_time
'
:
[([],[])]}
self
.
data
=
{
'
voltage_time
'
:
[([],[])]}
self
.
columns
=
[
'
Time (s)
'
,
'
Voltage (V)
'
]
self
.
columns
=
[
'
Time (s)
'
,
'
Voltage (V)
'
]
self
.
plot
_format
=
{
self
.
plot
lims
=
{
'
voltage_time
'
:
{
'
voltage_time
'
:
{
'
labels
'
:
self
.
columns
,
'
xlims
'
:
(
0
,
int
(
self
.
parameters
[
'
time
'
]))
'
xlims
'
:
(
0
,
int
(
self
.
parameters
[
'
time
'
]))
}
}
}
}
self
.
plots
[
-
1
].
setlims
(
'
voltage_time
'
,
**
self
.
plotlims
[
'
voltage_time
'
])
self
.
total_time
=
int
(
self
.
parameters
[
'
time
'
])
self
.
commands
+=
"
E
"
self
.
commands
+=
"
E
"
self
.
commands
[
2
]
+=
"
P
"
self
.
commands
[
2
]
+=
"
P
"
...
@@ -44,7 +57,8 @@ class PotExp(Experiment):
...
@@ -44,7 +57,8 @@ class PotExp(Experiment):
# 2*uint16 + int32
# 2*uint16 + int32
seconds
,
milliseconds
,
voltage
=
struct
.
unpack
(
'
<HHl
'
,
data
)
seconds
,
milliseconds
,
voltage
=
struct
.
unpack
(
'
<HHl
'
,
data
)
return
(
scan
,
(
return
(
scan
,
(
seconds
+
milliseconds
/
1000.
,
voltage
*
(
1.5
/
8388607.
)
seconds
+
milliseconds
/
1000.
,
voltage
*
self
.
re_voltage_scale
*
(
1.5
/
8388607.
)
)
)
)
)
...
@@ -58,3 +72,9 @@ class PotExp(Experiment):
...
@@ -58,3 +72,9 @@ class PotExp(Experiment):
for
i
,
item
in
enumerate
(
self
.
data
[
'
voltage_time
'
][
line
]):
for
i
,
item
in
enumerate
(
self
.
data
[
'
voltage_time
'
][
line
]):
item
.
append
(
data
[
i
])
item
.
append
(
data
[
i
])
def
get_progress
(
self
):
try
:
return
self
.
data
[
'
voltage_time
'
][
-
1
][
0
][
-
1
]
/
self
.
total_time
except
IndexError
:
return
0
\ No newline at end of file
dstat_interface/experiments/swv.py
→
dstat_interface/
core/
experiments/swv.py
View file @
86048afb
...
@@ -2,27 +2,35 @@ import time
...
@@ -2,27 +2,35 @@ import time
import
struct
import
struct
from
copy
import
deepcopy
from
copy
import
deepcopy
from
experiments.experiment_template
import
PlotBox
,
Experiment
from
.experiment_template
import
PlotBox
,
Experiment
class
SWVBox
(
PlotBox
):
class
SWVBox
(
PlotBox
):
def
setup
(
self
):
self
.
plot_format
=
{
'
swv
'
:
{
'
xlabel
'
:
"
Voltage (mV)
"
,
'
ylabel
'
:
"
Current (A)
"
}
}
def
format_plots
(
self
):
def
format_plots
(
self
):
"""
"""
Creates and formats subplots needed. Overrides superclass.
Creates and formats subplots needed. Overrides superclass.
"""
"""
self
.
subplots
=
{
'
swv
'
:
self
.
figure
.
add_subplot
(
111
)}
self
.
subplots
=
{
'
swv
'
:
self
.
figure
.
add_subplot
(
111
)}
for
key
,
subplot
in
self
.
subplots
.
items
():
for
key
,
subplot
in
self
.
subplots
.
items
():
subplot
.
ticklabel_format
(
style
=
'
sci
'
,
scilimits
=
(
0
,
3
),
subplot
.
ticklabel_format
(
style
=
'
sci
'
,
scilimits
=
(
0
,
3
),
useOffset
=
False
,
axis
=
'
y
'
)
useOffset
=
False
,
axis
=
'
y
'
)
subplot
.
plot
([],[])
subplot
.
plot
([],[])
subplot
.
set_xlabel
(
self
.
plot_format
[
key
][
'
xlabel
'
])
subplot
.
set_ylabel
(
self
.
plot_format
[
key
][
'
ylabel
'
])
class
SWVExp
(
Experiment
):
class
SWVExp
(
Experiment
):
"""
Square Wave Voltammetry experiment
"""
"""
Square Wave Voltammetry experiment
"""
id
=
'
swv
'
id
=
'
swv
'
def
setup
(
self
):
self
.
plots
.
append
(
SWVBox
([
'
swv
'
]))
def
setup
(
self
):
self
.
datatype
=
"
SWVData
"
self
.
datatype
=
"
SWVData
"
self
.
xlabel
=
"
Voltage (mV)
"
self
.
xlabel
=
"
Voltage (mV)
"
self
.
ylabel
=
"
Current (A)
"
self
.
ylabel
=
"
Current (A)
"
...
@@ -34,34 +42,65 @@ class SWVExp(Experiment):
...
@@ -34,34 +42,65 @@ class SWVExp(Experiment):
self
.
databytes
=
10
self
.
databytes
=
10
self
.
columns
=
[
'
Voltage (mV)
'
,
'
Net Current (A)
'
,
self
.
columns
=
[
'
Voltage (mV)
'
,
'
Net Current (A)
'
,
'
Forward Current (A)
'
,
'
Reverse Current (A)
'
]
'
Forward Current (A)
'
,
'
Reverse Current (A)
'
]
self
.
plot_format
=
{
self
.
plotlims
=
{
'
swv
'
:
{
'
labels
'
:
(
'
Voltage (mV)
'
,
'
swv
'
:
{
'
Current (A)
'
'
xlims
'
:
tuple
(
sorted
(
),
(
int
(
self
.
parameters
[
'
start
'
]),
'
xlims
'
:
(
int
(
self
.
parameters
[
'
start
'
]),
int
(
self
.
parameters
[
'
stop
'
]))
int
(
self
.
parameters
[
'
stop
'
]))
)
)
}
}
}
}
plot
=
SWVBox
()
plot
.
setlims
(
'
swv
'
,
**
self
.
plotlims
[
'
swv
'
])
self
.
plots
.
append
(
plot
)
self
.
stop_mv
=
int
(
self
.
parameters
[
'
stop
'
])
self
.
max_mv
=
abs
(
int
(
self
.
parameters
[
'
start
'
])
-
int
(
self
.
parameters
[
'
stop
'
]))
self
.
scan_points
=
self
.
max_mv
*
2
/
float
(
self
.
parameters
[
'
step
'
])
self
.
commands
+=
"
E
"
self
.
commands
+=
"
E
"
self
.
commands
[
2
]
+=
"
S
"
self
.
commands
[
2
]
+=
"
S
"
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
clean_s
'
])
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
clean_s
'
])
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
dep_s
'
])
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
dep_s
'
])
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
int
(
int
(
self
.
parameters
[
'
clean_mV
'
])
*
self
.
commands
[
2
]
+=
str
(
int
(
(
65536.
/
3000
)
+
32768
))
int
(
self
.
parameters
[
'
clean_mV
'
])
/
self
.
commands
[
2
]
+=
"
"
self
.
re_voltage_scale
*
self
.
commands
[
2
]
+=
str
(
int
(
int
(
self
.
parameters
[
'
dep_mV
'
])
*
(
65536.
/
3000
)
+
32768
(
65536.
/
3000
)
+
32768
))
))
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
start
'
])
self
.
commands
[
2
]
+=
str
(
int
(
self
.
commands
[
2
]
+=
"
"
int
(
self
.
parameters
[
'
dep_mV
'
])
/
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
stop
'
])
self
.
re_voltage_scale
*
self
.
commands
[
2
]
+=
"
"
(
65536.
/
3000
)
+
32768
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
step
'
])
))
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
pulse
'
])
self
.
commands
[
2
]
+=
str
(
int
(
int
(
self
.
parameters
[
'
start
'
])
/
self
.
re_voltage_scale
*
(
65536.
/
3000
)
+
32768
))
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
int
(
int
(
self
.
parameters
[
'
stop
'
])
/
self
.
re_voltage_scale
*
(
65536.
/
3000
)
+
32768
))
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
int
(
int
(
self
.
parameters
[
'
step
'
])
/
self
.
re_voltage_scale
*
(
65536.
/
3000
)
))
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
int
(
int
(
self
.
parameters
[
'
pulse
'
])
/
self
.
re_voltage_scale
*
(
65536.
/
3000
)
))
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
freq
'
])
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
freq
'
])
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
"
"
...
@@ -77,7 +116,7 @@ class SWVExp(Experiment):
...
@@ -77,7 +116,7 @@ class SWVExp(Experiment):
r_trim
=
reverse
+
self
.
gain_trim
r_trim
=
reverse
+
self
.
gain_trim
return
(
scan
,
(
return
(
scan
,
(
(
voltage
-
32768
)
*
3000.
/
65536
,
(
voltage
-
32768
)
*
3000.
/
65536
*
self
.
re_voltage_scale
,
(
f_trim
-
r_trim
)
*
(
1.5
/
self
.
gain
/
8388607
),
(
f_trim
-
r_trim
)
*
(
1.5
/
self
.
gain
/
8388607
),
f_trim
*
(
1.5
/
self
.
gain
/
8388607
),
f_trim
*
(
1.5
/
self
.
gain
/
8388607
),
r_trim
*
(
1.5
/
self
.
gain
/
8388607
)
r_trim
*
(
1.5
/
self
.
gain
/
8388607
)
...
@@ -95,12 +134,25 @@ class SWVExp(Experiment):
...
@@ -95,12 +134,25 @@ class SWVExp(Experiment):
for
i
,
item
in
enumerate
(
self
.
data
[
'
swv
'
][
line
]):
for
i
,
item
in
enumerate
(
self
.
data
[
'
swv
'
][
line
]):
item
.
append
(
data
[
i
])
item
.
append
(
data
[
i
])
def
get_progress
(
self
):
try
:
if
int
(
self
.
parameters
[
'
scans
'
])
!=
0
:
scans_prog
=
(
len
(
self
.
data
[
'
swv
'
])
-
1
)
/
float
(
self
.
parameters
[
'
scans
'
])
scan_prog
=
(
len
(
self
.
data
[
'
swv
'
][
-
1
][
0
])
-
1
)
/
self
.
scan_points
/
float
(
self
.
parameters
[
'
scans
'
])
prog
=
scans_prog
+
scan_prog
if
prog
>
1
:
prog
=
1
return
prog
else
:
return
1
-
(
abs
(
self
.
stop_mv
-
self
.
data
[
'
swv
'
][
-
1
][
0
][
-
1
])
/
self
.
max_mv
)
except
IndexError
:
return
0
class
DPVExp
(
SWVExp
):
class
DPVExp
(
SWVExp
):
"""
Diffential Pulse Voltammetry experiment.
"""
"""
Diffential Pulse Voltammetry experiment.
"""
id
=
'
dpv
'
id
=
'
dpv
'
def
setup
(
self
):
def
setup
(
self
):
self
.
plots
.
append
(
SWVBox
([
'
swv
'
]))
self
.
datatype
=
"
SWVData
"
self
.
datatype
=
"
SWVData
"
self
.
xlabel
=
"
Voltage (mV)
"
self
.
xlabel
=
"
Voltage (mV)
"
self
.
ylabel
=
"
Current (A)
"
self
.
ylabel
=
"
Current (A)
"
...
@@ -112,36 +164,73 @@ class DPVExp(SWVExp):
...
@@ -112,36 +164,73 @@ class DPVExp(SWVExp):
self
.
databytes
=
10
self
.
databytes
=
10
self
.
columns
=
[
'
Voltage (mV)
'
,
'
Net Current (A)
'
,
self
.
columns
=
[
'
Voltage (mV)
'
,
'
Net Current (A)
'
,
'
Forward Current (A)
'
,
'
Reverse Current (A)
'
]
'
Forward Current (A)
'
,
'
Reverse Current (A)
'
]
self
.
plot_format
=
{
'
swv
'
:
{
'
labels
'
:
(
'
Voltage (mV)
'
,
self
.
plotlims
=
{
'
Current (A)
'
'
swv
'
:
{
),
'
xlims
'
:
tuple
(
sorted
(
'
xlims
'
:
(
int
(
self
.
parameters
[
'
start
'
]),
(
int
(
self
.
parameters
[
'
start
'
]),
int
(
self
.
parameters
[
'
stop
'
]))
int
(
self
.
parameters
[
'
stop
'
]))
)
)
}
}
}
}
plot
=
SWVBox
()
plot
.
setlims
(
'
swv
'
,
**
self
.
plotlims
[
'
swv
'
])
self
.
plots
.
append
(
plot
)
self
.
stop_mv
=
int
(
self
.
parameters
[
'
stop
'
])
self
.
max_mv
=
abs
(
int
(
self
.
parameters
[
'
start
'
])
-
int
(
self
.
parameters
[
'
stop
'
]))
self
.
commands
+=
"
E
"
self
.
commands
+=
"
E
"
self
.
commands
[
2
]
+=
"
D
"
self
.
commands
[
2
]
+=
"
D
"
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
clean_s
'
])
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
clean_s
'
])
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
dep_s
'
])
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
dep_s
'
])
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
int
(
int
(
self
.
parameters
[
'
clean_mV
'
])
*
self
.
commands
[
2
]
+=
str
(
int
(
(
65536.
/
3000
)
+
32768
))
int
(
self
.
parameters
[
'
clean_mV
'
])
/
self
.
commands
[
2
]
+=
"
"
self
.
re_voltage_scale
*
self
.
commands
[
2
]
+=
str
(
int
(
int
(
self
.
parameters
[
'
dep_mV
'
])
*
(
65536.
/
3000
)
+
32768
(
65536.
/
3000
)
+
32768
))
))
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
start
'
])
self
.
commands
[
2
]
+=
str
(
int
(
self
.
commands
[
2
]
+=
"
"
int
(
self
.
parameters
[
'
dep_mV
'
])
/
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
stop
'
])
self
.
re_voltage_scale
*
self
.
commands
[
2
]
+=
"
"
(
65536.
/
3000
)
+
32768
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
step
'
])
))
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
pulse
'
])
self
.
commands
[
2
]
+=
str
(
int
(
int
(
self
.
parameters
[
'
start
'
])
/
self
.
re_voltage_scale
*
(
65536.
/
3000
)
+
32768
))
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
int
(
int
(
self
.
parameters
[
'
stop
'
])
/
self
.
re_voltage_scale
*
(
65536.
/
3000
)
+
32768
))
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
int
(
int
(
self
.
parameters
[
'
step
'
])
/
self
.
re_voltage_scale
*
(
65536.
/
3000
)
))
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
int
(
int
(
self
.
parameters
[
'
pulse
'
])
/
self
.
re_voltage_scale
*
(
65536.
/
3000
)
))
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
period
'
])
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
period
'
])
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
width
'
])
self
.
commands
[
2
]
+=
str
(
self
.
parameters
[
'
width
'
])
self
.
commands
[
2
]
+=
"
"
self
.
commands
[
2
]
+=
"
"
def
get_progress
(
self
):
try
:
return
1
-
(
abs
(
self
.
stop_mv
-
self
.
data
[
'
swv
'
][
-
1
][
0
][
-
1
])
/
self
.
max_mv
)
except
IndexError
:
return
0
\ No newline at end of file
dstat_interface/core/interface/__init__.py
0 → 100644
View file @
86048afb
dstat_interface/interface/acv.glade
→
dstat_interface/
core/
interface/acv.glade
View file @
86048afb
File moved
dstat_interface/interface/adc_pot.glade
→
dstat_interface/
core/
interface/adc_pot.glade
View file @
86048afb
File moved
dstat_interface/interface/adc_pot.py
→
dstat_interface/
core/
interface/adc_pot.py
View file @
86048afb
...
@@ -17,6 +17,8 @@
...
@@ -17,6 +17,8 @@
#
#
# You should have received a copy of the GNU General Public License
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import
os.path
from
pkg_resources
import
parse_version
try
:
try
:
import
gi
import
gi
...
@@ -26,31 +28,15 @@ except ImportError:
...
@@ -26,31 +28,15 @@ except ImportError:
print
"
ERR: GTK not available
"
print
"
ERR: GTK not available
"
sys
.
exit
(
1
)
sys
.
exit
(
1
)
from
errors
import
InputError
,
VarError
from
..errors
import
InputError
,
VarError
from
..dstat
import
state
v1_1_gain
=
[(
0
,
"
100 Ω (15 mA FS)
"
,
"
0
"
),
(
1
,
"
300 Ω (5 mA FS)
"
,
"
1
"
),
(
2
,
"
3 kΩ (500 µA FS)
"
,
"
2
"
),
(
3
,
"
30 kΩ (50 µA FS)
"
,
"
3
"
),
(
4
,
"
300 kΩ (5 µA FS)
"
,
"
4
"
),
(
5
,
"
3 MΩ (500 nA FS)
"
,
"
5
"
),
(
6
,
"
30 MΩ (50 nA FS)
"
,
"
6
"
),
(
7
,
"
500 MΩ (3 nA FS)
"
,
"
7
"
)]
v1_2_gain
=
[(
0
,
"
Bypass
"
,
"
0
"
),
(
1
,
"
100 Ω (15 mA FS)
"
,
"
1
"
),
(
2
,
"
3 kΩ (500 µA FS)
"
,
"
2
"
),
(
3
,
"
30 kΩ (50 µA FS)
"
,
"
3
"
),
(
4
,
"
300 kΩ (5 µA FS)
"
,
"
4
"
),
(
5
,
"
3 MΩ (500 nA FS)
"
,
"
5
"
),
(
6
,
"
30 MΩ (50 nA FS)
"
,
"
6
"
),
(
7
,
"
100 MΩ (15 nA FS)
"
,
"
7
"
)]
mod_dir
=
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
))
class
adc_pot
(
object
):
class
adc_pot
(
object
):
def
__init__
(
self
):
def
__init__
(
self
):
self
.
builder
=
Gtk
.
Builder
()
self
.
builder
=
Gtk
.
Builder
()
self
.
builder
.
add_from_file
(
'
interface/
adc_pot.glade
'
)
self
.
builder
.
add_from_file
(
os
.
path
.
join
(
mod_dir
,
'
adc_pot.glade
'
)
)
self
.
builder
.
connect_signals
(
self
)
self
.
builder
.
connect_signals
(
self
)
self
.
cell
=
Gtk
.
CellRendererText
()
self
.
cell
=
Gtk
.
CellRendererText
()
...
@@ -81,7 +67,7 @@ class adc_pot(object):
...
@@ -81,7 +67,7 @@ class adc_pot(object):
self
.
gain_liststore
=
self
.
builder
.
get_object
(
'
gain_liststore
'
)
self
.
gain_liststore
=
self
.
builder
.
get_object
(
'
gain_liststore
'
)
self
.
ui
[
'
gain_index
'
].
pack_start
(
self
.
cell
,
True
)
self
.
ui
[
'
gain_index
'
].
pack_start
(
self
.
cell
,
True
)
self
.
ui
[
'
gain_index
'
].
add_attribute
(
self
.
cell
,
'
text
'
,
1
)
self
.
ui
[
'
gain_index
'
].
add_attribute
(
self
.
cell
,
'
text
'
,
1
)
self
.
ui
[
'
gain_index
'
].
set_active
(
2
)
#
self.ui['gain_index'].set_active(2)
self
.
_params
=
{}
self
.
_params
=
{}
...
@@ -135,15 +121,19 @@ class adc_pot(object):
...
@@ -135,15 +121,19 @@ class adc_pot(object):
for
i
in
self
.
ui
:
for
i
in
self
.
ui
:
self
.
ui
[
i
].
set_active
(
self
.
_params
[
i
])
self
.
ui
[
i
].
set_active
(
self
.
_params
[
i
])
def
set_version
(
self
,
versi
on
):
def
set_version
(
self
,
boost
=
N
on
e
):
"""
Sets menus for DStat version.
"""
"""
Sets menus for DStat version.
"""
try
:
if
self
.
version
==
state
.
board_instance
:
return
except
AttributeError
:
pass
self
.
version
=
state
.
board_instance
self
.
gain_liststore
.
clear
()
self
.
gain_liststore
.
clear
()
if
version
[
0
]
==
1
:
if
version
[
1
]
==
1
:
for
i
in
v1_1_gain
:
self
.
gain_liststore
.
append
(
str
(
i
))
elif
version
[
1
]
>=
2
:
for
i
in
v1_2_gain
:
self
.
gain_liststore
.
append
(
i
)
for
n
,
i
in
enumerate
(
self
.
version
.
gain_labels
):
self
.
gain_liststore
.
append
((
n
,
i
,
str
(
n
)))
self
.
ui
[
'
gain_index
'
].
set_active
(
self
.
version
.
gain_default_index
)
\ No newline at end of file
dstat_interface/interface/analysis_options.glade
→
dstat_interface/
core/
interface/analysis_options.glade
View file @
86048afb
File moved
dstat_interface/interface/calib.glade
→
dstat_interface/
core/
interface/calib.glade
View file @
86048afb
File moved
dstat_interface/interface/chronoamp.glade
→
dstat_interface/
core/
interface/chronoamp.glade
View file @
86048afb
File moved
dstat_interface/interface/cv.glade
→
dstat_interface/
core/
interface/cv.glade
View file @
86048afb
File moved
dstat_interface/interface/data_view.py
→
dstat_interface/
core/
interface/data_view.py
View file @
86048afb
from
__future__
import
division
,
absolute_import
,
print_function
,
unicode_literals
from
__future__
import
division
,
absolute_import
,
print_function
,
unicode_literals
import
logging
import
logging
logger
=
logging
.
getLogger
(
"
dstat.interface.data_view
"
)
logger
=
logging
.
getLogger
(
__name__
)
from
collections
import
OrderedDict
from
collections
import
OrderedDict
...
...
dstat_interface/interface/db.glade
→
dstat_interface/
core/
interface/db.glade
View file @
86048afb
File moved
dstat_interface/interface/db.py
→
dstat_interface/
core/
interface/db.py
View file @
86048afb
...
@@ -30,7 +30,7 @@ except ImportError:
...
@@ -30,7 +30,7 @@ except ImportError:
print
"
ERR: GTK not available
"
print
"
ERR: GTK not available
"
sys
.
exit
(
1
)
sys
.
exit
(
1
)
logger
=
logging
.
getLogger
(
'
dstat.interface.db
'
)
logger
=
logging
.
getLogger
(
__name__
)
class
DB_Window
(
GObject
.
GObject
):
class
DB_Window
(
GObject
.
GObject
):
__gsignals__
=
{
__gsignals__
=
{
...
...
dstat_interface/interface/dpv.glade
→
dstat_interface/
core/
interface/dpv.glade
View file @
86048afb
File moved
dstat_interface/interface/dstatinterface.glade
→
dstat_interface/
core/
interface/dstatinterface.glade
View file @
86048afb
This diff is collapsed.
Click to expand it.
dstat_interface/interface/exp_int.py
→
dstat_interface/
core/
interface/exp_int.py
View file @
86048afb
...
@@ -30,13 +30,16 @@ except ImportError:
...
@@ -30,13 +30,16 @@ except ImportError:
print
(
"
ERR: GTK not available
"
)
print
(
"
ERR: GTK not available
"
)
sys
.
exit
(
1
)
sys
.
exit
(
1
)
import
dstat_comm
from
..dstat
import
comm
,
state
import
state
from
..experiments
import
(
cal
,
chronoamp
,
cv
,
experiment_template
,
import
experiments
as
exp
idle
,
lsv
,
pot
,
swv
)
import
experiments.cal
as
cal
import
__main__
import
__main__
from
errors
import
InputError
,
VarError
from
..errors
import
InputError
,
VarError
logger
=
logging
.
getLogger
(
"
dstat.interface.exp_int
"
)
logger
=
logging
.
getLogger
(
__name__
)
mod_dir
=
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
))
class
ExpInterface
(
GObject
.
Object
):
class
ExpInterface
(
GObject
.
Object
):
"""
Generic experiment interface class. Should be subclassed to implement
"""
Generic experiment interface class. Should be subclassed to implement
...
@@ -59,13 +62,16 @@ class ExpInterface(GObject.Object):
...
@@ -59,13 +62,16 @@ class ExpInterface(GObject.Object):
self
.
entry
=
{}
# to be used only for str parameters
self
.
entry
=
{}
# to be used only for str parameters
self
.
_params
=
None
self
.
_params
=
None
def
get_experiment
(
self
,
parameters
):
return
self
.
__class__
.
experiment
(
parameters
)
def
_fill_params
(
self
):
def
_fill_params
(
self
):
self
.
_params
=
dict
.
fromkeys
(
self
.
entry
.
keys
())
self
.
_params
=
dict
.
fromkeys
(
self
.
entry
.
keys
())
@property
@property
def
params
(
self
):
def
params
(
self
):
"""
Dict of parameters
"""
"""
Dict of parameters
"""
if
self
.
_params
==
None
:
if
self
.
_params
is
None
:
self
.
_fill_params
()
self
.
_fill_params
()
self
.
_get_params
()
self
.
_get_params
()
return
self
.
_params
return
self
.
_params
...
@@ -77,7 +83,7 @@ class ExpInterface(GObject.Object):
...
@@ -77,7 +83,7 @@ class ExpInterface(GObject.Object):
@params.setter
@params.setter
def
params
(
self
,
params
):
def
params
(
self
,
params
):
if
self
.
_params
==
None
:
if
self
.
_params
is
None
:
self
.
_fill_params
()
self
.
_fill_params
()
for
i
in
self
.
_params
:
for
i
in
self
.
_params
:
try
:
try
:
...
@@ -98,6 +104,7 @@ class ExpInterface(GObject.Object):
...
@@ -98,6 +104,7 @@ class ExpInterface(GObject.Object):
def
on_done_utility
(
self
,
data
=
None
):
def
on_done_utility
(
self
,
data
=
None
):
self
.
emit
(
'
done_utility
'
)
self
.
emit
(
'
done_utility
'
)
class
Chronoamp
(
ExpInterface
):
class
Chronoamp
(
ExpInterface
):
"""
Experiment class for chronoamperometry. Extends ExpInterface class to
"""
Experiment class for chronoamperometry. Extends ExpInterface class to
support treeview neeeded for CA.
support treeview neeeded for CA.
...
@@ -108,10 +115,10 @@ class Chronoamp(ExpInterface):
...
@@ -108,10 +115,10 @@ class Chronoamp(ExpInterface):
get_params(self)
get_params(self)
"""
"""
id
=
'
cae
'
id
=
'
cae
'
experiment
=
ex
p
.
Chronoamp
experiment
=
chronoam
p
.
Chronoamp
def
__init__
(
self
):
def
__init__
(
self
):
"""
Extends superclass method to support treeview.
"""
"""
Extends superclass method to support treeview.
"""
super
(
Chronoamp
,
self
).
__init__
(
'
interface/
chronoamp.glade
'
)
super
(
Chronoamp
,
self
).
__init__
(
os
.
path
.
join
(
mod_dir
,
'
chronoamp.glade
'
)
)
self
.
name
=
"
Chronoamperometry
"
self
.
name
=
"
Chronoamperometry
"
...
@@ -144,9 +151,9 @@ class Chronoamp(ExpInterface):
...
@@ -144,9 +151,9 @@ class Chronoamp(ExpInterface):
self
.
builder
.
get_object
(
'
potential_entry
'
).
get_text
())
self
.
builder
.
get_object
(
'
potential_entry
'
).
get_text
())
time
=
int
(
self
.
builder
.
get_object
(
'
time_entry
'
).
get_text
())
time
=
int
(
self
.
builder
.
get_object
(
'
time_entry
'
).
get_text
())
if
(
potential
>
1499
or
potential
<
-
1500
):
if
not
state
.
board_instance
.
test_mv
(
potential
):
raise
ValueError
(
"
Potential out of range
"
)
raise
ValueError
(
"
Potential out of range
"
)
if
(
time
<
1
or
time
>
65535
):
if
not
state
.
board_instance
.
test_s
(
time
):
raise
ValueError
(
"
Time out of range
"
)
raise
ValueError
(
"
Time out of range
"
)
self
.
model
.
append
([
potential
,
time
])
self
.
model
.
append
([
potential
,
time
])
...
@@ -187,10 +194,10 @@ class Chronoamp(ExpInterface):
...
@@ -187,10 +194,10 @@ class Chronoamp(ExpInterface):
class
LSV
(
ExpInterface
):
class
LSV
(
ExpInterface
):
"""
Experiment class for LSV.
"""
"""
Experiment class for LSV.
"""
id
=
'
lsv
'
id
=
'
lsv
'
experiment
=
exp
.
LSVExp
experiment
=
lsv
.
LSVExp
def
__init__
(
self
):
def
__init__
(
self
):
"""
Adds entry listings to superclass
'
s self.entry dict
"""
"""
Adds entry listings to superclass
'
s self.entry dict
"""
super
(
LSV
,
self
).
__init__
(
'
interface/
lsv.glade
'
)
super
(
LSV
,
self
).
__init__
(
os
.
path
.
join
(
mod_dir
,
'
lsv.glade
'
)
)
self
.
name
=
"
Linear Sweep Voltammetry
"
self
.
name
=
"
Linear Sweep Voltammetry
"
self
.
entry
[
'
clean_mV
'
]
=
self
.
builder
.
get_object
(
'
clean_mV
'
)
self
.
entry
[
'
clean_mV
'
]
=
self
.
builder
.
get_object
(
'
clean_mV
'
)
...
@@ -204,10 +211,10 @@ class LSV(ExpInterface):
...
@@ -204,10 +211,10 @@ class LSV(ExpInterface):
class
CV
(
ExpInterface
):
class
CV
(
ExpInterface
):
"""
Experiment class for CV.
"""
"""
Experiment class for CV.
"""
id
=
'
cve
'
id
=
'
cve
'
experiment
=
exp
.
CVExp
experiment
=
cv
.
CVExp
def
__init__
(
self
):
def
__init__
(
self
):
"""
Adds entry listings to superclass
'
s self.entry dict
"""
"""
Adds entry listings to superclass
'
s self.entry dict
"""
super
(
CV
,
self
).
__init__
(
'
interface/
cv.glade
'
)
super
(
CV
,
self
).
__init__
(
os
.
path
.
join
(
mod_dir
,
'
cv.glade
'
)
)
self
.
name
=
"
Cyclic Voltammetry
"
self
.
name
=
"
Cyclic Voltammetry
"
self
.
entry
[
'
clean_mV
'
]
=
self
.
builder
.
get_object
(
'
clean_mV
'
)
self
.
entry
[
'
clean_mV
'
]
=
self
.
builder
.
get_object
(
'
clean_mV
'
)
...
@@ -223,10 +230,10 @@ class CV(ExpInterface):
...
@@ -223,10 +230,10 @@ class CV(ExpInterface):
class
SWV
(
ExpInterface
):
class
SWV
(
ExpInterface
):
"""
Experiment class for SWV.
"""
"""
Experiment class for SWV.
"""
id
=
'
swv
'
id
=
'
swv
'
experiment
=
exp
.
SWVExp
experiment
=
swv
.
SWVExp
def
__init__
(
self
):
def
__init__
(
self
):
"""
Adds entry listings to superclass
'
s self.entry dict
"""
"""
Adds entry listings to superclass
'
s self.entry dict
"""
super
(
SWV
,
self
).
__init__
(
'
interface/
swv.glade
'
)
super
(
SWV
,
self
).
__init__
(
os
.
path
.
join
(
mod_dir
,
'
swv.glade
'
)
)
self
.
name
=
"
Square Wave Voltammetry
"
self
.
name
=
"
Square Wave Voltammetry
"
self
.
entry
[
'
clean_mV
'
]
=
self
.
builder
.
get_object
(
'
clean_mV
'
)
self
.
entry
[
'
clean_mV
'
]
=
self
.
builder
.
get_object
(
'
clean_mV
'
)
...
@@ -262,10 +269,10 @@ class SWV(ExpInterface):
...
@@ -262,10 +269,10 @@ class SWV(ExpInterface):
class
DPV
(
ExpInterface
):
class
DPV
(
ExpInterface
):
"""
Experiment class for DPV.
"""
"""
Experiment class for DPV.
"""
id
=
'
dpv
'
id
=
'
dpv
'
experiment
=
exp
.
DPVExp
experiment
=
swv
.
DPVExp
def
__init__
(
self
):
def
__init__
(
self
):
"""
Adds entry listings to superclass
'
s self.entry dict
"""
"""
Adds entry listings to superclass
'
s self.entry dict
"""
super
(
DPV
,
self
).
__init__
(
'
interface/
dpv.glade
'
)
super
(
DPV
,
self
).
__init__
(
os
.
path
.
join
(
mod_dir
,
'
dpv.glade
'
)
)
self
.
name
=
"
Differential Pulse Voltammetry
"
self
.
name
=
"
Differential Pulse Voltammetry
"
...
@@ -297,10 +304,10 @@ class DPV(ExpInterface):
...
@@ -297,10 +304,10 @@ class DPV(ExpInterface):
class
PD
(
ExpInterface
):
class
PD
(
ExpInterface
):
"""
Experiment class for PD.
"""
"""
Experiment class for PD.
"""
id
=
'
pde
'
id
=
'
pde
'
experiment
=
ex
p
.
PDExp
experiment
=
chronoam
p
.
PDExp
def
__init__
(
self
):
def
__init__
(
self
):
"""
Adds entry listings to superclass
'
s self.entry dict
"""
"""
Adds entry listings to superclass
'
s self.entry dict
"""
super
(
PD
,
self
).
__init__
(
'
interface/
pd.glade
'
)
super
(
PD
,
self
).
__init__
(
os
.
path
.
join
(
mod_dir
,
'
pd.glade
'
)
)
self
.
name
=
"
Photodiode/PMT
"
self
.
name
=
"
Photodiode/PMT
"
...
@@ -363,9 +370,9 @@ class PD(ExpInterface):
...
@@ -363,9 +370,9 @@ class PD(ExpInterface):
try
:
try
:
self
.
builder
.
get_object
(
'
light_label
'
).
set_text
(
str
(
self
.
builder
.
get_object
(
'
light_label
'
).
set_text
(
str
(
dstat_comm
.
read_light_sensor
()))
dstat_comm
.
read_light_sensor
()))
dstat_
comm
.
read_settings
()
comm
.
read_settings
()
state
.
settings
[
'
tcs_enabled
'
][
1
]
=
'
1
'
# Make sure TCS enabled
state
.
settings
[
'
tcs_enabled
'
][
1
]
=
'
1
'
# Make sure TCS enabled
dstat_
comm
.
write_settings
()
comm
.
write_settings
()
self
.
builder
.
get_object
(
'
threshold_entry
'
).
set_text
(
str
(
self
.
builder
.
get_object
(
'
threshold_entry
'
).
set_text
(
str
(
state
.
settings
[
'
tcs_clear_threshold
'
][
1
]))
state
.
settings
[
'
tcs_clear_threshold
'
][
1
]))
...
@@ -384,8 +391,8 @@ class PD(ExpInterface):
...
@@ -384,8 +391,8 @@ class PD(ExpInterface):
try
:
try
:
state
.
settings
[
'
tcs_clear_threshold
'
][
1
]
=
self
.
builder
.
get_object
(
state
.
settings
[
'
tcs_clear_threshold
'
][
1
]
=
self
.
builder
.
get_object
(
'
threshold_entry
'
).
get_text
()
'
threshold_entry
'
).
get_text
()
dstat_
comm
.
write_settings
()
comm
.
write_settings
()
dstat_
comm
.
read_settings
()
comm
.
read_settings
()
self
.
builder
.
get_object
(
'
threshold_entry
'
).
set_text
(
self
.
builder
.
get_object
(
'
threshold_entry
'
).
set_text
(
str
(
state
.
settings
[
'
tcs_clear_threshold
'
][
1
]))
str
(
state
.
settings
[
'
tcs_clear_threshold
'
][
1
]))
__main__
.
MAIN
.
start_ocp
()
__main__
.
MAIN
.
start_ocp
()
...
@@ -405,10 +412,10 @@ class PD(ExpInterface):
...
@@ -405,10 +412,10 @@ class PD(ExpInterface):
class
POT
(
ExpInterface
):
class
POT
(
ExpInterface
):
"""
Experiment class for Potentiometry.
"""
"""
Experiment class for Potentiometry.
"""
id
=
'
pot
'
id
=
'
pot
'
experiment
=
exp
.
PotExp
experiment
=
pot
.
PotExp
def
__init__
(
self
):
def
__init__
(
self
):
"""
Adds entry listings to superclass
'
s self.entry dict
"""
"""
Adds entry listings to superclass
'
s self.entry dict
"""
super
(
POT
,
self
).
__init__
(
'
interface/
potexp.glade
'
)
super
(
POT
,
self
).
__init__
(
os
.
path
.
join
(
mod_dir
,
'
potexp.glade
'
)
)
self
.
name
=
"
Potentiometry
"
self
.
name
=
"
Potentiometry
"
self
.
entry
[
'
time
'
]
=
self
.
builder
.
get_object
(
'
time_entry
'
)
self
.
entry
[
'
time
'
]
=
self
.
builder
.
get_object
(
'
time_entry
'
)
...
@@ -416,10 +423,10 @@ class POT(ExpInterface):
...
@@ -416,10 +423,10 @@ class POT(ExpInterface):
class
CAL
(
ExpInterface
):
class
CAL
(
ExpInterface
):
"""
Experiment class for Calibrating gain.
"""
"""
Experiment class for Calibrating gain.
"""
id
=
'
cal
'
id
=
'
cal
'
experiment
=
exp
.
CALExp
experiment
=
cal
.
CALExp
def
__init__
(
self
):
def
__init__
(
self
):
"""
Adds entry listings to superclass
'
s self.entry dict
"""
"""
Adds entry listings to superclass
'
s self.entry dict
"""
super
(
CAL
,
self
).
__init__
(
'
interface/
calib.glade
'
)
super
(
CAL
,
self
).
__init__
(
os
.
path
.
join
(
mod_dir
,
'
calib.glade
'
)
)
self
.
name
=
"
Calilbration
"
self
.
name
=
"
Calilbration
"
self
.
entry
[
'
time
'
]
=
self
.
builder
.
get_object
(
'
time_entry
'
)
self
.
entry
[
'
time
'
]
=
self
.
builder
.
get_object
(
'
time_entry
'
)
...
@@ -442,7 +449,7 @@ class CAL(ExpInterface):
...
@@ -442,7 +449,7 @@ class CAL(ExpInterface):
try
:
try
:
__main__
.
MAIN
.
on_pot_stop_clicked
()
__main__
.
MAIN
.
on_pot_stop_clicked
()
__main__
.
MAIN
.
stop_ocp
()
__main__
.
MAIN
.
stop_ocp
()
dstat_
comm
.
read_settings
()
comm
.
read_settings
()
self
.
entry
[
'
R100
'
].
set_text
(
str
(
self
.
entry
[
'
R100
'
].
set_text
(
str
(
state
.
settings
[
'
r100_trim
'
][
1
]))
state
.
settings
[
'
r100_trim
'
][
1
]))
...
@@ -479,7 +486,7 @@ class CAL(ExpInterface):
...
@@ -479,7 +486,7 @@ class CAL(ExpInterface):
state
.
settings
[
'
r3M_trim
'
][
1
]
=
self
.
entry
[
'
R3M
'
].
get_text
()
state
.
settings
[
'
r3M_trim
'
][
1
]
=
self
.
entry
[
'
R3M
'
].
get_text
()
state
.
settings
[
'
r30M_trim
'
][
1
]
=
self
.
entry
[
'
R30M
'
].
get_text
()
state
.
settings
[
'
r30M_trim
'
][
1
]
=
self
.
entry
[
'
R30M
'
].
get_text
()
state
.
settings
[
'
r100M_trim
'
][
1
]
=
self
.
entry
[
'
R100M
'
].
get_text
()
state
.
settings
[
'
r100M_trim
'
][
1
]
=
self
.
entry
[
'
R100M
'
].
get_text
()
dstat_
comm
.
write_settings
()
comm
.
write_settings
()
__main__
.
MAIN
.
start_ocp
()
__main__
.
MAIN
.
start_ocp
()
...
@@ -487,7 +494,7 @@ class CAL(ExpInterface):
...
@@ -487,7 +494,7 @@ class CAL(ExpInterface):
GObject
.
timeout_add
(
700
,
restore_buttons
,
self
.
buttons
)
GObject
.
timeout_add
(
700
,
restore_buttons
,
self
.
buttons
)
def
on_measure_button_clicked
(
self
,
data
=
None
):
def
on_measure_button_clicked
(
self
,
data
=
None
):
if
(
int
(
self
.
entry
[
'
time
'
].
get_text
())
<=
0
or
int
(
self
.
entry
[
'
time
'
].
get_text
())
>
65535
)
:
if
int
(
self
.
entry
[
'
time
'
].
get_text
())
<=
0
or
int
(
self
.
entry
[
'
time
'
].
get_text
())
>
65535
:
logger
.
error
(
"
ERR: Time out of range
"
)
logger
.
error
(
"
ERR: Time out of range
"
)
return
return
...
@@ -524,6 +531,7 @@ class CAL(ExpInterface):
...
@@ -524,6 +531,7 @@ class CAL(ExpInterface):
GObject
.
timeout_add
(
700
,
restore_buttons
,
self
.
buttons
)
GObject
.
timeout_add
(
700
,
restore_buttons
,
self
.
buttons
)
__main__
.
MAIN
.
spinner
.
stop
()
__main__
.
MAIN
.
spinner
.
stop
()
def
restore_buttons
(
buttons
):
def
restore_buttons
(
buttons
):
"""
Should be called with GObject callback
"""
"""
Should be called with GObject callback
"""
for
i
in
buttons
:
for
i
in
buttons
:
...
...
Prev
1
2
3
4
Next