Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
total_control_app
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Martin Drechsler
total_control_app
Commits
e5b1ea04
Commit
e5b1ea04
authored
Apr 18, 2019
by
Martin Drechsler
Browse files
Options
Browse Files
Download
Plain Diff
fixed merged conflict, hopefully, in zylaCameraWorker
parents
9f168d1f
595121d4
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
226 additions
and
34 deletions
+226
-34
cameraGui.py
cameraGui.py
+39
-17
cameraParameterTree.py
cameraParameterTree.py
+161
-0
andorzyla.py
drivers/andorzyla.py
+12
-6
zylaCameraWorker.py
zylaCameraWorker.py
+14
-11
No files found.
cameraGui.py
View file @
e5b1ea04
...
...
@@ -23,13 +23,13 @@ class GuiMainWindow(QMainWindow):
def
__init__
(
self
):
super
()
.
__init__
()
self
.
initUI
()
self
.
__init__
self
.
some_time
=
pg
.
time
()
#self.__init__
self
.
counter
=
0
self
.
frames_checker_timer
=
QtCore
.
QTimer
()
self
.
initUI
()
def
initUI
(
self
):
...
...
@@ -92,16 +92,30 @@ class GuiMainWindow(QMainWindow):
def
make_connections
(
self
,
backend
):
##backend connections
backend
.
imageReadySignal
.
connect
(
self
.
updateImage
)
##internal connections
self
.
frames_checker_timer
.
timeout
.
connect
(
self
.
frame_counter
)
self
.
cameraButton
.
clicked
.
connect
(
lambda
x
=
backend
.
isCameraAcquiring
:
self
.
camera_button_pressed
(
x
))
def
camera_button_pressed
(
self
,
isCameraAcquiring
):
if
isCameraAcquiring
:
self
.
frames_checker_timer
.
stop
()
else
:
self
.
frame_index
=
0
self
.
previous_frame_index
=
0
self
.
frames_checker_timer
.
start
(
1000
)
def
_initialize_image
(
self
):
## lock the aspect ratio so pixels are always square
self
.
view
.
setAspectLocked
(
True
)
self
.
view
.
addItem
(
self
.
img
)
self
.
i
=
0
self
.
frame_index
=
0
self
.
previous_frame_index
=
0
self
.
frames_checker_timer
.
start
(
1000
)
def
updateRois
(
self
):
...
...
@@ -111,20 +125,28 @@ class GuiMainWindow(QMainWindow):
roiSlice
=
roi
.
getArrayRegion
(
self
.
img
.
image
,
img
=
self
.
img
)
self
.
newData
=
np
.
mean
(
roiSlice
)
self
.
ROIdata
[
self
.
iROIdata
]
=
self
.
newData
self
.
iROIdata
=
np
.
mod
(
self
.
i
+
1
,
len
(
self
.
ROIdata
))
self
.
iROIdata
=
np
.
mod
(
self
.
frame_index
+
1
,
len
(
self
.
ROIdata
))
self
.
curve
.
setData
(
self
.
ROIdata
)
@
QtCore
.
pyqtSlot
(
np
.
ndarray
)
def
updateImage
(
self
,
image
):
@
QtCore
.
pyqtSlot
(
np
.
ndarray
,
int
)
def
updateImage
(
self
,
image
,
acq_index
):
if
self
.
frame_index
is
not
0
and
not
self
.
frame_index
==
acq_index
:
print
(
'Dephasing in camera gui has occured: while frame index is
%
i, the acq index is
%
i'
%
(
self
.
frame_index
,
acq_index
))
n
=
1024
self
.
img
.
setImage
(
image
[:
n
,
:
n
]
)
#
n = 1024
self
.
img
.
setImage
(
image
)
self
.
updateRois
()
self
.
i
=
self
.
i
+
1
if
self
.
i
%
5
==
0
:
self
.
label
.
setText
(
str
(
self
.
i
)
+
' time:'
+
str
(
pg
.
time
()
-
self
.
some_time
)
)
self
.
some_time
=
pg
.
time
()
self
.
frame_index
=
self
.
frame_index
+
1
def
frame_counter
(
self
):
self
.
counter
=
self
.
counter
+
1
self
.
label
.
setText
(
'Frames in last second: '
+
str
(
self
.
frame_index
-
self
.
previous_frame_index
)
+
' '
+
'Seconds since start: '
+
str
(
self
.
counter
))
self
.
previous_frame_index
=
self
.
frame_index
def
__del__
(
self
):
print
(
'chau gui'
)
...
...
cameraParameterTree.py
0 → 100644
View file @
e5b1ea04
# -*- coding: utf-8 -*-
"""
This example demonstrates the use of pyqtgraph's parametertree system. This provides
a simple way to generate user interfaces that control sets of parameters. The example
demonstrates a variety of different parameter types (int, float, list, etc.)
as well as some customized parameter types
"""
import
pyqtgraph
as
pg
from
pyqtgraph.Qt
import
QtCore
,
QtGui
import
pyqtgraph.parametertree.parameterTypes
as
pTypes
from
pyqtgraph.parametertree
import
Parameter
,
ParameterTree
,
ParameterItem
,
registerParameterType
app
=
QtGui
.
QApplication
([])
## test subclassing parameters
## This parameter automatically generates two child parameters which are always reciprocals of each other
class
BasicAcquisitonParameters
(
pTypes
.
GroupParameter
):
def
__init__
(
self
,
**
opts
):
pTypes
.
GroupParameter
.
__init__
(
self
,
**
opts
)
self
.
addChild
({
'name'
:
'Acquisition mode'
,
'type'
:
'list'
,
'values'
:
[
'acq1'
,
'acq2'
]})
self
.
addChild
({
'name'
:
'Pixel Binning'
,
'type'
:
'list'
,
'values'
:
[
'1x1'
,
'2x2'
,
'4x4'
,
'8x8'
]})
self
.
addChild
({
'name'
:
'Image Area'
,
'type'
:
'list'
,
'values'
:
[
'2048x2048'
,
'1024x1024'
,
'512x512'
,
'256x256'
],
'readonly'
:
True
})
self
.
addChild
({
'name'
:
'Exposure Time'
,
'type'
:
'float'
,
'value'
:
.1
,
'suffix'
:
's'
,
'siPrefix'
:
True
,
'step'
:
0.05
})
self
.
addChild
({
'name'
:
'Frame Rate'
,
'type'
:
'float'
,
'value'
:
10
})
#exposure time and frame rate connected because they are the inverse of each other
self
.
exposureTimeWidget
=
self
.
param
(
'Exposure Time'
)
self
.
frameRateWidget
=
self
.
param
(
'Frame Rate'
)
self
.
exposureTimeWidget
.
sigValueChanged
.
connect
(
self
.
expTimeChanged
)
self
.
frameRateWidget
.
sigValueChanged
.
connect
(
self
.
frameRateChanged
)
#set image area according to binning
self
.
param
(
'Pixel Binning'
)
.
sigValueChanged
.
connect
(
self
.
binningChanged
)
def
expTimeChanged
(
self
):
self
.
frameRateWidget
.
setValue
(
1.0
/
self
.
exposureTimeWidget
.
value
(),
blockSignal
=
self
.
frameRateChanged
)
def
frameRateChanged
(
self
):
self
.
exposureTimeWidget
.
setValue
(
1.0
/
self
.
frameRateWidget
.
value
(),
blockSignal
=
self
.
expTimeChanged
)
def
binningChanged
(
self
):
if
self
.
param
(
'Pixel Binning'
)
.
value
()
==
'1x1'
:
self
.
param
(
'Image Area'
)
.
setValue
(
'2048x2048'
)
if
self
.
param
(
'Pixel Binning'
)
.
value
()
==
'2x2'
:
print
(
'hola 2x2'
)
self
.
param
(
'Image Area'
)
.
setValue
(
'1024x1024'
)
if
self
.
param
(
'Pixel Binning'
)
.
value
()
==
'4x4'
:
self
.
param
(
'Image Area'
)
.
setValue
(
'512x512'
)
if
self
.
param
(
'Pixel Binning'
)
.
value
()
==
'8x8'
:
self
.
param
(
'Image Area'
)
.
setValue
(
'256x256'
)
params
=
[
BasicAcquisitonParameters
(
name
=
'Basic acq parameters'
),
{
'name'
:
'Basic parameter data types'
,
'type'
:
'group'
,
'children'
:
[
{
'name'
:
'Integer'
,
'type'
:
'int'
,
'value'
:
10
},
{
'name'
:
'Float'
,
'type'
:
'float'
,
'value'
:
10.5
,
'step'
:
0.1
},
{
'name'
:
'String'
,
'type'
:
'str'
,
'value'
:
"hi"
},
{
'name'
:
'List'
,
'type'
:
'list'
,
'values'
:
[
1
,
2
,
3
],
'value'
:
2
},
{
'name'
:
'Named List'
,
'type'
:
'list'
,
'values'
:
{
"one"
:
1
,
"two"
:
"twosies"
,
"three"
:
[
3
,
3
,
3
]},
'value'
:
2
},
{
'name'
:
'Boolean'
,
'type'
:
'bool'
,
'value'
:
True
,
'tip'
:
"This is a checkbox"
},
{
'name'
:
'Color'
,
'type'
:
'color'
,
'value'
:
"FF0"
,
'tip'
:
"This is a color button"
},
{
'name'
:
'Gradient'
,
'type'
:
'colormap'
},
{
'name'
:
'Subgroup'
,
'type'
:
'group'
,
'children'
:
[
{
'name'
:
'Sub-param 1'
,
'type'
:
'int'
,
'value'
:
10
},
{
'name'
:
'Sub-param 2'
,
'type'
:
'float'
,
'value'
:
1.2e6
},
]},
{
'name'
:
'Text Parameter'
,
'type'
:
'text'
,
'value'
:
'Some text...'
},
{
'name'
:
'Action Parameter'
,
'type'
:
'action'
},
]},
{
'name'
:
'Numerical Parameter Options'
,
'type'
:
'group'
,
'children'
:
[
{
'name'
:
'Units + SI prefix'
,
'type'
:
'float'
,
'value'
:
1.2e-6
,
'step'
:
1e-6
,
'siPrefix'
:
True
,
'suffix'
:
'V'
},
{
'name'
:
'Limits (min=7;max=15)'
,
'type'
:
'int'
,
'value'
:
11
,
'limits'
:
(
7
,
15
),
'default'
:
-
6
},
{
'name'
:
'DEC stepping'
,
'type'
:
'float'
,
'value'
:
1.2e6
,
'dec'
:
True
,
'step'
:
1
,
'siPrefix'
:
True
,
'suffix'
:
'Hz'
},
]},
{
'name'
:
'Save/Restore functionality'
,
'type'
:
'group'
,
'children'
:
[
{
'name'
:
'Save State'
,
'type'
:
'action'
},
{
'name'
:
'Restore State'
,
'type'
:
'action'
,
'children'
:
[
{
'name'
:
'Add missing items'
,
'type'
:
'bool'
,
'value'
:
True
},
{
'name'
:
'Remove extra items'
,
'type'
:
'bool'
,
'value'
:
True
},
]},
]},
{
'name'
:
'Extra Parameter Options'
,
'type'
:
'group'
,
'children'
:
[
{
'name'
:
'Read-only'
,
'type'
:
'float'
,
'value'
:
1.2e6
,
'siPrefix'
:
True
,
'suffix'
:
'Hz'
,
'readonly'
:
True
},
{
'name'
:
'Renamable'
,
'type'
:
'float'
,
'value'
:
1.2e6
,
'siPrefix'
:
True
,
'suffix'
:
'Hz'
,
'renamable'
:
True
},
{
'name'
:
'Removable'
,
'type'
:
'float'
,
'value'
:
1.2e6
,
'siPrefix'
:
True
,
'suffix'
:
'Hz'
,
'removable'
:
True
},
]}
]
## Create tree of Parameter objects
p
=
Parameter
.
create
(
name
=
'params'
,
type
=
'group'
,
children
=
params
)
## If anything changes in the tree, print a message
def
change
(
param
,
changes
):
print
(
"tree changes:"
)
for
param
,
change
,
data
in
changes
:
path
=
p
.
childPath
(
param
)
if
path
is
not
None
:
childName
=
'.'
.
join
(
path
)
else
:
childName
=
param
.
name
()
print
(
' parameter:
%
s'
%
childName
)
print
(
' change:
%
s'
%
change
)
print
(
' data:
%
s'
%
str
(
data
))
print
(
' ----------'
)
p
.
sigTreeStateChanged
.
connect
(
change
)
def
save
():
global
state
state
=
p
.
saveState
()
def
restore
():
global
state
add
=
p
[
'Save/Restore functionality'
,
'Restore State'
,
'Add missing items'
]
rem
=
p
[
'Save/Restore functionality'
,
'Restore State'
,
'Remove extra items'
]
p
.
restoreState
(
state
,
addChildren
=
add
,
removeChildren
=
rem
)
p
.
param
(
'Save/Restore functionality'
,
'Save State'
)
.
sigActivated
.
connect
(
save
)
p
.
param
(
'Save/Restore functionality'
,
'Restore State'
)
.
sigActivated
.
connect
(
restore
)
## Create two ParameterTree widgets, both accessing the same data
t
=
ParameterTree
()
t
.
setParameters
(
p
,
showTop
=
False
)
t
.
setWindowTitle
(
'Parameter Tree'
)
win
=
QtGui
.
QWidget
()
layout
=
QtGui
.
QGridLayout
()
win
.
setLayout
(
layout
)
layout
.
addWidget
(
QtGui
.
QLabel
(
"Explanation of parameter tree."
),
0
,
0
,
1
,
2
)
layout
.
addWidget
(
t
)
win
.
show
()
win
.
resize
(
400
,
800
)
## test save/restore
s
=
p
.
saveState
()
p
.
restoreState
(
s
)
## Start Qt event loop unless running in interactive mode or using pyside.
if
__name__
==
'__main__'
:
import
sys
if
(
sys
.
flags
.
interactive
!=
1
)
or
not
hasattr
(
QtCore
,
'PYQT_VERSION'
):
QtGui
.
QApplication
.
instance
()
.
exec_
()
drivers/andorzyla.py
View file @
e5b1ea04
...
...
@@ -58,7 +58,7 @@ def create_aligned_array(shape, dtype=np.typeDict['singlecomplex'], boundary=16)
class
Helper_messager
(
QtCore
.
QObject
):
imageAquiredSignal
=
QtCore
.
pyqtSignal
()
imageAquiredSignal
=
QtCore
.
pyqtSignal
(
int
)
class
AndorBase
(
SDK3Camera
):
...
...
@@ -100,13 +100,14 @@ class AndorBase(SDK3Camera):
self
.
PreAmpGain
=
ATEnum
()
self
.
PreAmpGainSelector
=
ATEnum
()
self
.
TriggerMode
=
ATEnum
()
self
.
AOIBinning
=
ATEnum
()
self
.
AOIBinning
=
ATEnum
()
self
.
AOIHeight
=
ATInt
()
self
.
AOILeft
=
ATInt
()
self
.
AOITop
=
ATInt
()
self
.
AOIWidth
=
ATInt
()
self
.
AOIStride
=
ATInt
()
self
.
FrameCount
=
ATInt
()
self
.
ImageSizeBytes
=
ATInt
()
self
.
SensorHeight
=
ATInt
()
...
...
@@ -116,6 +117,7 @@ class AndorBase(SDK3Camera):
self
.
CameraModel
=
ATString
()
self
.
SerialNumber
=
ATString
()
self
.
CameraName
=
ATString
()
self
.
ExposureTime
=
ATFloat
()
self
.
FrameRate
=
ATFloat
()
...
...
@@ -723,7 +725,7 @@ class AndorBase(SDK3Camera):
def
live_acquisition_configure
(
self
):
image_size
=
self
.
ImageSizeBytes
.
getValue
()
bufs
=
[
create_aligned_array
(
image_size
,
'uint8'
)
for
i
in
range
(
1
)]
bufs
=
[
create_aligned_array
(
image_size
,
'uint8'
)
for
i
in
range
(
1
0
)]
n_of_bufs
=
len
(
bufs
)
for
ind
in
range
(
n_of_bufs
):
...
...
@@ -743,7 +745,10 @@ class AndorBase(SDK3Camera):
while
getattr
(
t
,
"do_run"
,
True
):
a_s
,
px_encoding
,
xs
,
ys
,
bufs
=
self
.
_live_acq_auxs
try
:
pData
,
lData
=
SDK3
.
WaitBuffer
(
self
.
handle
,
1000
)
# start = time.time()
pData
,
lData
=
SDK3
.
WaitBuffer
(
self
.
handle
,
10000
)
# end = time.time()
# print(end-start)
except
:
return
img
=
create_aligned_array
(
xs
*
ys
,
'uint16'
)
...
...
@@ -754,8 +759,9 @@ class AndorBase(SDK3Camera):
img
.
shape
=
(
ys
,
xs
)
self
.
current_image
=
img
SDK3
.
QueueBuffer
(
self
.
handle
,
bufs
[
self
.
acq_index_i
%
len
(
bufs
)]
.
ctypes
.
data_as
(
SDK3
.
POINTER
(
SDK3
.
AT_U8
)),
bufs
[
self
.
acq_index_i
%
len
(
bufs
)]
.
nbytes
)
self
.
helper
.
imageAquiredSignal
.
emit
(
self
.
acq_index_i
)
self
.
acq_index_i
=
self
.
acq_index_i
+
1
self
.
helper
.
imageAquiredSignal
.
emit
()
print
(
'stopping acq loop thread'
)
...
...
zylaCameraWorker.py
View file @
e5b1ea04
...
...
@@ -10,13 +10,13 @@ Created on Thu Apr 4 11:10:20 2019
import
numpy
as
np
from
PyQt5
import
QtCore
#
from drivers.andorzyla import AndorZyla
from
dummyAndor
import
AndorZyla
from
drivers.andorzyla
import
AndorZyla
#
from dummyAndor import AndorZyla
import
threading
class
CameraWorker
(
QtCore
.
QObject
):
imageReadySignal
=
QtCore
.
pyqtSignal
(
np
.
ndarray
)
imageReadySignal
=
QtCore
.
pyqtSignal
(
np
.
ndarray
,
int
)
...
...
@@ -25,11 +25,14 @@ class CameraWorker(QtCore.QObject):
self
.
cam
=
AndorZyla
(
0
)
self
.
cam
.
Init
()
self
.
cam
.
ExposureTime
.
setValue
(
.
0
1
)
self
.
cam
.
FrameRate
.
setValue
(
20
)
self
.
cam
.
ExposureTime
.
setValue
(
.1
)
#self.cam.FrameRate.setValue(9
)
self
.
cam
.
AOIBinning
.
setIndex
(
4
)
self
.
isCameraAcquiring
=
False
print
(
'camera worker initialized'
)
...
...
@@ -50,6 +53,7 @@ class CameraWorker(QtCore.QObject):
def
run
(
self
):
if
self
.
cam
.
CameraAcquiring
.
getValue
():
self
.
_stop_acquisition_loop
()
self
.
isCameraAcquiring
=
False
print
(
'acquisition now stopping'
)
else
:
...
...
@@ -57,7 +61,7 @@ class CameraWorker(QtCore.QObject):
self
.
acq_thread
=
threading
.
Thread
(
target
=
self
.
cam
.
live_acquisition_loop
)
self
.
acq_thread
.
start
()
print
(
'acquisiting now starting'
)
self
.
isCameraAcquiring
=
True
def
_start_acquisition_loop
(
self
):
self
.
cam
.
live_acquisition_configure
()
...
...
@@ -74,8 +78,7 @@ class CameraWorker(QtCore.QObject):
@
QtCore
.
pyqtSlot
()
def
new_image_acquired
(
self
):
#print('acquiring')
self
.
imageReadySignal
.
emit
(
self
.
cam
.
current_image
)
@
QtCore
.
pyqtSlot
(
int
)
def
new_image_acquired
(
self
,
acq_index
):
self
.
imageReadySignal
.
emit
(
self
.
cam
.
current_image
,
acq_index
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment