Commit 595121d4 authored by Martin Drechsler's avatar Martin Drechsler

added parameter tree file

parent d9ca3b4a
...@@ -23,13 +23,13 @@ class GuiMainWindow(QMainWindow): ...@@ -23,13 +23,13 @@ class GuiMainWindow(QMainWindow):
def __init__(self): def __init__(self):
super().__init__() 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): def initUI(self):
...@@ -92,16 +92,30 @@ class GuiMainWindow(QMainWindow): ...@@ -92,16 +92,30 @@ class GuiMainWindow(QMainWindow):
def make_connections(self, backend): def make_connections(self, backend):
##backend connections
backend.imageReadySignal.connect(self.updateImage) 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): def _initialize_image(self):
## lock the aspect ratio so pixels are always square ## lock the aspect ratio so pixels are always square
self.view.setAspectLocked(True) self.view.setAspectLocked(True)
self.view.addItem(self.img) 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): def updateRois(self):
...@@ -111,20 +125,28 @@ class GuiMainWindow(QMainWindow): ...@@ -111,20 +125,28 @@ class GuiMainWindow(QMainWindow):
roiSlice = roi.getArrayRegion(self.img.image, img=self.img) roiSlice = roi.getArrayRegion(self.img.image, img=self.img)
self.newData = np.mean(roiSlice) self.newData = np.mean(roiSlice)
self.ROIdata[self.iROIdata] = self.newData 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) self.curve.setData(self.ROIdata)
@QtCore.pyqtSlot(np.ndarray) @QtCore.pyqtSlot(np.ndarray, int)
def updateImage(self, image): 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 #n = 1024
self.img.setImage(image[:n, :n]) self.img.setImage(image)
self.updateRois() self.updateRois()
self.i = self.i + 1 self.frame_index = self.frame_index + 1
if self.i%5 ==0:
self.label.setText(str(self.i) + ' time:' + str(pg.time()-self.some_time) )
self.some_time = pg.time()
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): def __del__(self):
print('chau gui') print('chau gui')
......
# -*- 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_()
...@@ -58,7 +58,7 @@ def create_aligned_array(shape, dtype=np.typeDict['singlecomplex'], boundary=16) ...@@ -58,7 +58,7 @@ def create_aligned_array(shape, dtype=np.typeDict['singlecomplex'], boundary=16)
class Helper_messager(QtCore.QObject): class Helper_messager(QtCore.QObject):
imageAquiredSignal = QtCore.pyqtSignal() imageAquiredSignal = QtCore.pyqtSignal(int)
class AndorBase(SDK3Camera): class AndorBase(SDK3Camera):
...@@ -100,13 +100,14 @@ class AndorBase(SDK3Camera): ...@@ -100,13 +100,14 @@ class AndorBase(SDK3Camera):
self.PreAmpGain = ATEnum() self.PreAmpGain = ATEnum()
self.PreAmpGainSelector = ATEnum() self.PreAmpGainSelector = ATEnum()
self.TriggerMode = ATEnum() self.TriggerMode = ATEnum()
self.AOIBinning = ATEnum()
self.AOIBinning = ATEnum()
self.AOIHeight = ATInt() self.AOIHeight = ATInt()
self.AOILeft = ATInt() self.AOILeft = ATInt()
self.AOITop = ATInt() self.AOITop = ATInt()
self.AOIWidth = ATInt() self.AOIWidth = ATInt()
self.AOIStride = ATInt() self.AOIStride = ATInt()
self.FrameCount = ATInt() self.FrameCount = ATInt()
self.ImageSizeBytes = ATInt() self.ImageSizeBytes = ATInt()
self.SensorHeight = ATInt() self.SensorHeight = ATInt()
...@@ -116,6 +117,7 @@ class AndorBase(SDK3Camera): ...@@ -116,6 +117,7 @@ class AndorBase(SDK3Camera):
self.CameraModel = ATString() self.CameraModel = ATString()
self.SerialNumber = ATString() self.SerialNumber = ATString()
self.CameraName = ATString()
self.ExposureTime = ATFloat() self.ExposureTime = ATFloat()
self.FrameRate = ATFloat() self.FrameRate = ATFloat()
...@@ -723,7 +725,7 @@ class AndorBase(SDK3Camera): ...@@ -723,7 +725,7 @@ class AndorBase(SDK3Camera):
def live_acquisition_configure(self): def live_acquisition_configure(self):
image_size = self.ImageSizeBytes.getValue() 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(10)]
n_of_bufs = len(bufs) n_of_bufs = len(bufs)
for ind in range(n_of_bufs): for ind in range(n_of_bufs):
...@@ -745,7 +747,10 @@ class AndorBase(SDK3Camera): ...@@ -745,7 +747,10 @@ class AndorBase(SDK3Camera):
while getattr(t, "do_run", True): while getattr(t, "do_run", True):
a_s, px_encoding, xs, ys, bufs = self._live_acq_auxs a_s, px_encoding, xs, ys, bufs = self._live_acq_auxs
try: 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: except:
return return
img = create_aligned_array(xs*ys, 'uint16') img = create_aligned_array(xs*ys, 'uint16')
...@@ -756,8 +761,9 @@ class AndorBase(SDK3Camera): ...@@ -756,8 +761,9 @@ class AndorBase(SDK3Camera):
img.shape = (ys, xs) img.shape = (ys, xs)
self.current_image = img 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) 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.acq_index_i = self.acq_index_i + 1
self.helper.imageAquiredSignal.emit()
print('stopping acq loop thread') print('stopping acq loop thread')
......
...@@ -10,13 +10,13 @@ Por ahora, aca se va a crear una imagen cada cierto tiempo y eso se va a mandar ...@@ -10,13 +10,13 @@ Por ahora, aca se va a crear una imagen cada cierto tiempo y eso se va a mandar
import numpy as np import numpy as np
from PyQt5 import QtCore from PyQt5 import QtCore
#from drivers.andorzyla import AndorZyla from drivers.andorzyla import AndorZyla
from dummyAndor import AndorZyla #from dummyAndor import AndorZyla
import threading import threading
class CameraWorker(QtCore.QObject): class CameraWorker(QtCore.QObject):
imageReadySignal = QtCore.pyqtSignal(np.ndarray) imageReadySignal = QtCore.pyqtSignal(np.ndarray, int)
...@@ -25,11 +25,14 @@ class CameraWorker(QtCore.QObject): ...@@ -25,11 +25,14 @@ class CameraWorker(QtCore.QObject):
self.cam = AndorZyla(0) self.cam = AndorZyla(0)
self.cam.Init() self.cam.Init()
self.cam.ExposureTime.setValue(.01) self.cam.ExposureTime.setValue(.1)
self.cam.FrameRate.setValue(20) #self.cam.FrameRate.setValue(9)
self.cam.AOIBinning.setIndex(4)
self.isCameraAcquiring = False
print('camera worker initialized') print('camera worker initialized')
...@@ -39,7 +42,7 @@ class CameraWorker(QtCore.QObject): ...@@ -39,7 +42,7 @@ class CameraWorker(QtCore.QObject):
frontend.sb.valueChanged.connect(lambda x = frontend.sb.value(): self.cam.ExposureTime.setValue(x)) frontend.sb.valueChanged.connect(lambda x = frontend.sb.value(): self.cam.ExposureTime.setValue(x))
#internal connections #internal connections
self.cam.helper.imageAquiredSignal.connect(self.acquire) self.cam.helper.imageAquiredSignal.connect(self.update_acquire)
def __del__(self): def __del__(self):
...@@ -50,6 +53,7 @@ class CameraWorker(QtCore.QObject): ...@@ -50,6 +53,7 @@ class CameraWorker(QtCore.QObject):
def run(self): def run(self):
if self.cam.CameraAcquiring.getValue(): if self.cam.CameraAcquiring.getValue():
self._stop_acquisition_loop() self._stop_acquisition_loop()
self.isCameraAcquiring = False
print('acquisition now stopping') print('acquisition now stopping')
else: else:
...@@ -57,7 +61,7 @@ class CameraWorker(QtCore.QObject): ...@@ -57,7 +61,7 @@ class CameraWorker(QtCore.QObject):
self.acq_thread = threading.Thread(target= self.cam.live_acquisition_loop) self.acq_thread = threading.Thread(target= self.cam.live_acquisition_loop)
self.acq_thread.start() self.acq_thread.start()
print('acquisiting now starting') print('acquisiting now starting')
self.isCameraAcquiring = True
def _start_acquisition_loop(self): def _start_acquisition_loop(self):
self.cam.live_acquisition_configure() self.cam.live_acquisition_configure()
...@@ -74,8 +78,7 @@ class CameraWorker(QtCore.QObject): ...@@ -74,8 +78,7 @@ class CameraWorker(QtCore.QObject):
@QtCore.pyqtSlot() @QtCore.pyqtSlot(int)
def acquire(self): def update_acquire(self, acq_index):
#print('acquiring') self.imageReadySignal.emit(self.cam.current_image, acq_index)
self.imageReadySignal.emit(self.cam.current_image)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment