Commit 13b3044f authored by Martin Drechsler's avatar Martin Drechsler

Agregada carpeta de ejemplos de cosas utiles. Ademas, ahora la gui puede (con...

Agregada carpeta de ejemplos de cosas utiles. Ademas, ahora la gui puede (con la dummyandor), hacer una medicion, que no guarda datos ni nada por ahora, pero escanea un analog output
parent da12b4f6
...@@ -16,7 +16,7 @@ from subclasses.pyqtgraph_subclasses import CustomRectangularROI ...@@ -16,7 +16,7 @@ from subclasses.pyqtgraph_subclasses import CustomRectangularROI
from zylaCameraWorker import CameraWorker from zylaCameraWorker import CameraWorker
from subclasses.cameraParameterTree import CameraParameterTree from subclasses.cameraParameterTree import CameraParameterTree
from subclasses.controllayouts import LaserControlLayout, LaserScanLayout from subclasses.controllayouts import LaserControlLayout, LaserScanLayout
from resources.scanFunctions import create_measurement_array
#from drivers.andorzyla import AndorZyla #from drivers.andorzyla import AndorZyla
...@@ -81,32 +81,44 @@ class CameraGuiMainWindow(QMainWindow): ...@@ -81,32 +81,44 @@ class CameraGuiMainWindow(QMainWindow):
# layouts and viewboxes # layouts and viewboxes
self.ImageLayout = pg.GraphicsLayoutWidget() self.ImageLayout = pg.GraphicsLayoutWidget()
self.view = self.ImageLayout.addViewBox() self.imageView = self.ImageLayout.addViewBox()
self.AnalysisLayout = pg.GraphicsLayoutWidget() self.timeAnalysisLayout = pg.GraphicsLayoutWidget()
self.scanAnalysisLayout = pg.GraphicsLayoutWidget()
# image layout # image layout
self.img = pg.ImageItem(border="w") self.img = pg.ImageItem(border="w")
self.imv = pg.ImageView(imageItem=self.img, view=self.view) self.imv = pg.ImageView(imageItem=self.img, view=self.imageView)
self.imv.ui.roiBtn.setText('Useless') self.imv.ui.roiBtn.setText('Useless')
self.dCameraView.addWidget(self.imv) self.dCameraView.addWidget(self.imv)
# analysis layout # time analysis layout
self.dCameraTimeAnal.addWidget(self.AnalysisLayout) self.dCameraTimeAnal.addWidget(self.timeAnalysisLayout)
self.p = self.AnalysisLayout.addPlot(row=0, col=0, title="Time plot") self.timePlot = self.timeAnalysisLayout.addPlot(row=0, col=0, title="Time plot")
self.p.setRange(QtCore.QRectF(0, 0, 50, 255)) self.timePlot.setRange(QtCore.QRectF(0, 0, 50, 255))
self.p.setAutoPan(y=True) self.timePlot.setAutoPan(y=True)
# self.p.setRange(xRange = (0, 10), yRange = (0, 255)) # self.p.setRange(xRange = (0, 10), yRange = (0, 255))
self.curve = self.p.plot(pen="y") self.timeCurve = self.timePlot.plot(pen="y")
# scan analysis layout
self.dCameraScanAnal.addWidget(self.scanAnalysisLayout)
self.scanPlot = self.scanAnalysisLayout.addPlot(row=0, col=0, title="Scan plot")
self.scanPlot.setRange(QtCore.QRectF(0, 0, 50, 255))
self.scanPlot.setAutoPan(y=True)
# self.p.setRange(xRange = (0, 10), yRange = (0, 255))
self.scanCurve = self.scanPlot.plot(pen="y")
# rOI # rOI
self.rois = [] self.rois = []
self.rois.append(CustomRectangularROI([0, 0])) self.rois.append(CustomRectangularROI([0, 0]))
for r in self.rois: for r in self.rois:
self.view.addItem(r) self.imageView.addItem(r)
# r.sigRegionChanged.connect(self.updateRoi)
self.ROIdata = np.zeros(1000) self.timeROIdataY = np.zeros(2000)
self.scanROIdataX = np.linspace(0, 1, 2000)
self.scanROIdataY = np.zeros(2000)
self.iROIdata = 0 self.iROIdata = 0
self.current_image_size = 2048 self.current_image_size = 2048
self._initialize_image() self._initialize_image()
...@@ -126,7 +138,7 @@ class CameraGuiMainWindow(QMainWindow): ...@@ -126,7 +138,7 @@ class CameraGuiMainWindow(QMainWindow):
) )
self.dConsole.addWidget(self.console) self.dConsole.addWidget(self.console)
self.measurementFrame.startMeasureButton.clicked.connect(self.emit_measurement_parameters) self.measurementFrame.startMeasureButton.clicked.connect(self.emit_measurement_parameters_and_start)
self.measurementFrame.folderButton.clicked.connect(self.measurementFrame.select_folder) self.measurementFrame.folderButton.clicked.connect(self.measurementFrame.select_folder)
self.measurementFrame.selectScanSignal.activated[str].connect(self.measurementFrame.configure_spinBoxes) self.measurementFrame.selectScanSignal.activated[str].connect(self.measurementFrame.configure_spinBoxes)
self.measurementFrame.startValue.valueChanged.connect(self.measurementFrame.update_tree) self.measurementFrame.startValue.valueChanged.connect(self.measurementFrame.update_tree)
...@@ -145,6 +157,10 @@ class CameraGuiMainWindow(QMainWindow): ...@@ -145,6 +157,10 @@ class CameraGuiMainWindow(QMainWindow):
else: else:
self.repositionRoi() self.repositionRoi()
self.scanROIdataX = np.linspace(0, 1, 2000)
self.scanROIdataY = np.zeros(2000)
self.timeROIdataY = np.zeros(2000)
self.iROIdata = 0
self.cameraButton.setText('Stop Acquisition') self.cameraButton.setText('Stop Acquisition')
self.measurementFrame.startMeasureButton.setEnabled(False) self.measurementFrame.startMeasureButton.setEnabled(False)
self.frame_index = 0 self.frame_index = 0
...@@ -154,22 +170,25 @@ class CameraGuiMainWindow(QMainWindow): ...@@ -154,22 +170,25 @@ class CameraGuiMainWindow(QMainWindow):
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.imageView.setAspectLocked(True)
self.view.addItem(self.img) self.imageView.addItem(self.img)
self.frame_index = 0 self.frame_index = 0
self.previous_frame_index = 0 self.previous_frame_index = 0
self.frames_checker_timer.start(1000) self.frames_checker_timer.start(1000)
def updateRois(self): def updatePlots(self):
for roi in self.rois: for roi in self.rois:
roiSlice = roi.getArrayRegion(self.img.image, img=self.img) roiSlice = roi.getArrayRegion(self.img.image, img=self.img)
self.newData = roiSlice.sum() self.newData = roiSlice.sum()
self.ROIdata[self.iROIdata] = self.newData
self.iROIdata = np.mod(self.frame_index + 1, len(self.ROIdata)) self.scanROIdataY[self.iROIdata] = self.newData
self.curve.setData(self.ROIdata) self.timeROIdataY[self.iROIdata] = self.newData
self.iROIdata = np.mod(self.frame_index + 1, len(self.timeROIdataY))
self.timeCurve.setData(self.timeROIdataY)
self.scanCurve.setData(self.scanROIdataX, self.scanROIdataY)
def repositionRoi(self): def repositionRoi(self):
old_size = self.current_image_size old_size = self.current_image_size
...@@ -188,16 +207,14 @@ class CameraGuiMainWindow(QMainWindow): ...@@ -188,16 +207,14 @@ class CameraGuiMainWindow(QMainWindow):
@QtCore.pyqtSlot(np.ndarray, int) @QtCore.pyqtSlot(np.ndarray, int)
def updateImage(self, image, acq_index): def updateImage(self, image, acq_index):
if self.frame_index is not 0 and not self.frame_index == acq_index: if self.frame_index is not 0 and not self.frame_index == acq_index:
print( print(
"Dephasing in camera gui has occured: while frame index is %i, the acq index is %i" "Dephasing in camera gui has occured: while frame index is %i, the acq index is %i"
% (self.frame_index, acq_index) % (self.frame_index, acq_index)
) )
# n = 1024
self.img.setImage(image, autoDownsample=True) self.img.setImage(image, autoDownsample=True)
self.updateRois() self.updatePlots()
self.frame_index = self.frame_index + 1 self.frame_index = self.frame_index + 1
self.current_image_size = image.shape[0] self.current_image_size = image.shape[0]
...@@ -216,10 +233,23 @@ class CameraGuiMainWindow(QMainWindow): ...@@ -216,10 +233,23 @@ class CameraGuiMainWindow(QMainWindow):
def measurement_starting(self): def measurement_starting(self):
self.cameraButton.setEnabled(False) self.cameraButton.setEnabled(False)
self.measurementFrame.startMeasureButton.setEnabled(False) self.measurementFrame.startMeasureButton.setEnabled(False)
start = self.measurementFrame.startValue.value()
end = self.measurementFrame.endValue.value()
steps = self.measurementFrame.stepsNum.value()
self.frame_index = 0
self.iROIdata = 0
self.scanROIdataX = create_measurement_array(start, end, steps)
self.scanROIdataY = np.zeros(steps)
self.timeROIdataY = np.zeros(steps)
for l in LaserControlLayout._registry + LaserScanLayout._registry : for l in LaserControlLayout._registry + LaserScanLayout._registry :
l.freeze() l.freeze()
print('gui meas start') print('gui meas start')
#@QtCore.pyqtSlot() #@QtCore.pyqtSlot()
def measurement_ending(self): def measurement_ending(self):
self.cameraButton.setEnabled(True) self.cameraButton.setEnabled(True)
...@@ -227,10 +257,11 @@ class CameraGuiMainWindow(QMainWindow): ...@@ -227,10 +257,11 @@ class CameraGuiMainWindow(QMainWindow):
for l in LaserControlLayout._registry + LaserScanLayout._registry : for l in LaserControlLayout._registry + LaserScanLayout._registry :
l.unfreeze() l.unfreeze()
print('gui meas end') print('gui meas end')
def __del__(self): def __del__(self):
print("chau gui") print("chau gui")
def emit_measurement_parameters(self): def emit_measurement_parameters_and_start(self):
measure_params = dict() measure_params = dict()
measure_params['signal_to_scan'] = self.measurementFrame.selectScanSignal.currentText() measure_params['signal_to_scan'] = self.measurementFrame.selectScanSignal.currentText()
measure_params['start'] = self.measurementFrame.startValue.value() measure_params['start'] = self.measurementFrame.startValue.value()
......
...@@ -44,7 +44,9 @@ class AndorZyla: ...@@ -44,7 +44,9 @@ class AndorZyla:
self.AOIBinning.setValue('1x1') self.AOIBinning.setValue('1x1')
self.ImageArea.setValue(2048) self.ImageArea.setValue(2048)
self.CameraModel.setValue('dummy') self.CameraModel.setValue('dummy')
self.TriggerMode.setString('Internal')
self.triggerEventHappened = False
self.images_array = [] self.images_array = []
def Init(self): def Init(self):
...@@ -52,18 +54,26 @@ class AndorZyla: ...@@ -52,18 +54,26 @@ class AndorZyla:
def live_acquisition_loop(self): def live_acquisition_loop(self):
t = threading.currentThread()
for i in range(10):
self.images_array.append(self._twoD_gaussian())
while getattr(t, "do_run", True):
self.current_image = self.images_array[self.acq_index_i%10]
time.sleep(self.ExposureTime.getValue())
self.acq_queue.put(self.current_image)
self.helper.imageAquiredSignal.emit(self.acq_index_i)
self.acq_index_i = self.acq_index_i + 1
print("stopping acq loop thread")
if self.TriggerMode.getString() == 'Software':
pass
else:
t = threading.currentThread()
for i in range(10):
self.images_array.append(self._twoD_gaussian())
while getattr(t, "do_run", True):
self.current_image = self.images_array[self.acq_index_i%10]
self.wait_for_image()
self.acq_queue.put(self.current_image)
self.helper.imageAquiredSignal.emit(self.acq_index_i)
self.acq_index_i = self.acq_index_i + 1
print("stopping acq loop thread")
def wait_for_image(self):
time.sleep(self.ExposureTime.getValue())
def live_acquisition_configure(self): def live_acquisition_configure(self):
self.acq_index_i = 0 self.acq_index_i = 0
...@@ -81,18 +91,22 @@ class AndorZyla: ...@@ -81,18 +91,22 @@ class AndorZyla:
d = {'1x1': 2048, '2x2': 1024, '4x4': 512, '8x8': 256} d = {'1x1': 2048, '2x2': 1024, '4x4': 512, '8x8': 256}
self.ImageArea.setValue(d[self.AOIBinning.getValue()]) self.ImageArea.setValue(d[self.AOIBinning.getValue()])
def _twoD_gaussian(self, lim=10, sigma=1, x0=0, y0=0): def _twoD_gaussian(self, lim=10, sigma=1, x0=0, y0=0):
start = time.time()
N = self.ImageArea.getValue() N = self.ImageArea.getValue()
x, y = np.meshgrid(np.linspace(-lim, lim, N), np.linspace(-lim, lim, N)) x, y = np.meshgrid(np.linspace(-lim, lim, N), np.linspace(-lim, lim, N))
d = np.sqrt((x - x0) ** 2 + (y - y0) ** 2) d = np.sqrt((x - x0) ** 2 + (y - y0) ** 2)
g = np.exp(-((d) ** 2 / (2.0 * sigma ** 2))) g = np.exp(-((d) ** 2 / (2.0 * sigma ** 2)))
noise = np.random.rand(N, N) noise = np.random.rand(N, N)
end = time.time()
return np.int8(g + noise) return np.int8(g + noise)
def trigger(self):
self.current_image = self.images_array[self.acq_index_i%10]
time.sleep(self.ExposureTime.getValue())
self.acq_queue.put(self.current_image)
self.acq_index_i = self.acq_index_i + 1
self.helper.imageAquiredSignal.emit(self.acq_index_i-1)
class AndorFeats: class AndorFeats:
def __init__(self): def __init__(self):
self.value = None self.value = None
...@@ -118,5 +132,5 @@ class AndorFeats: ...@@ -118,5 +132,5 @@ class AndorFeats:
print(s) print(s)
def getString(self): def getString(self):
return "" return str(self.value)
\ No newline at end of file
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat May 4 11:43:50 2019
Here an example of a correct way of creating a thread that executes a loop,
which can be ended safely.
@author: martindrech
"""
import threading
import time
def do_something():
print('do something')
def loop_function():
t = threading.currentThread()
while getattr(t, "do_run", True):
do_something()
time.sleep(1)
def stop_loop_thread(some_thread):
some_thread.do_run = False
some_thread.join()
#%%
#deine a thread where target function will be executed
some_thread = threading.Thread(
target=loop_function
)
# start thread, wait 5 seconds, and then stop the thread
some_thread.start()
time.sleep(5)
stop_loop_thread(some_thread)
#%%
from PyQt5 import QtCore
def block_until_emit(signal, timeout=10000):
"""Block loop until signal emitted, or timeout (ms) elapses."""
loop = QtCore.QEventLoop()
signal.connect(loop.quit)
yield
if timeout is not None:
QtCore.QTimer.singleShot(timeout, loop.quit)
loop.exec_()
#%%
def loop_function(trigger_signal):
while True:
do_something()
block_until_emit(trigger_signal)
class Emitter(QtCore.QObject):
signal = QtCore.pyqtSignal()
def __init__(self):
super().__init__()
#%%
emitter = Emitter()
some_thread = threading.Thread(
target=lambda :loop_function(emitter.signal)
)
# start thread, wait 5 seconds, and then stop the thread
some_thread.start()
...@@ -12,9 +12,6 @@ from MCDAQcontrolsignals import digital_control_signal ...@@ -12,9 +12,6 @@ from MCDAQcontrolsignals import digital_control_signal
from controlGui import ControlGui from controlGui import ControlGui
if __name__ == "__main__": if __name__ == "__main__":
import sys import sys
app = QtGui.QApplication([]) app = QtGui.QApplication([])
...@@ -57,23 +54,13 @@ if __name__ == "__main__": ...@@ -57,23 +54,13 @@ if __name__ == "__main__":
myGuiMainWindow = CameraGuiMainWindow() myGuiMainWindow = CameraGuiMainWindow()
cameraWorker = CameraWorker(camera) cameraWorker = CameraWorker(camera)
cameraWorker.make_connections(myGuiMainWindow)
myGuiMainWindow.make_connections(cameraWorker)
cameraThread = QtCore.QThread() cameraThread = QtCore.QThread()
cameraWorker.moveToThread(cameraThread) cameraWorker.moveToThread(cameraThread)
# measurementGui = MeasurementGui() cameraWorker.make_connections(myGuiMainWindow)
# measurementWorker = MeasurementWorker() myGuiMainWindow.make_connections(cameraWorker)
# myGuiMainWindow.dMeasurement.addWidget(measurementGui)
# measurementThread = QtCore.QThread()
# measurementWorker.moveToThread(measurementThread)
# measurementGui.make_connections(measurementWorker)
# measurementWorker.make_connections(measurementGui, camera)
cameraThread.start() cameraThread.start()
mcDAQthread.start() mcDAQthread.start()
# measurementThread.start()
sys.exit(app.exec_()) sys.exit(app.exec_())
...@@ -29,6 +29,10 @@ Work flow: ...@@ -29,6 +29,10 @@ Work flow:
Cosas a arreglar:
- Cuando pongo start measurement, no usa los parametros del arbol de la camara sino los parametros del arbol que cargaron la live acq anterior.
Cosas de andor zyla a pensar y/o consultar: Cosas de andor zyla a pensar y/o consultar:
......
...@@ -51,6 +51,9 @@ def create_measurement_array(start, stop, steps, back_and_forth=False): ...@@ -51,6 +51,9 @@ def create_measurement_array(start, stop, steps, back_and_forth=False):
def yield_array(arr): def yield_array(arr):
"""
Returns array generator
"""
larr = len(arr) larr = len(arr)
cursor = 0 cursor = 0
while cursor < larr: while cursor < larr:
......
...@@ -32,13 +32,13 @@ class CameraWorker(QtCore.QObject): ...@@ -32,13 +32,13 @@ class CameraWorker(QtCore.QObject):
print("camera worker initialized") print("camera worker initialized")
self.ao_to_scan = None self.ao_to_scan = None
self.scan_array_gen = None
def make_connections(self, frontend): def make_connections(self, frontend):
# frontend connections # frontend connections
live_acq_params = frontend.param_tree.p live_acq_params = frontend.param_tree.p
frontend.cameraButton.clicked.connect(lambda: self.run(live_acq_params)) frontend.cameraButton.clicked.connect(lambda: self.run(live_acq_params))
frontend.signalWithMeasurementParameters.connect(self.simple_scan_measurement) frontend.signalWithMeasurementParameters.connect(self.simple_scan_measurement_start)
# internal connections # internal connections
self.cam.helper.imageAquiredSignal.connect(self.new_image_acquired) self.cam.helper.imageAquiredSignal.connect(self.new_image_acquired)
...@@ -63,8 +63,7 @@ class CameraWorker(QtCore.QObject): ...@@ -63,8 +63,7 @@ class CameraWorker(QtCore.QObject):
def _start_acquisition_loop(self): def _start_acquisition_loop(self):
self.cam.live_acquisition_configure() self.cam.live_acquisition_configure()
self.cam.AcquisitionStart() self.cam.AcquisitionStart()
print("frame rate: ", self.cam.FrameRate.getValue())
print("Exp time: ", self.cam.ExposureTime.getValue())
def _stop_acquisition_loop(self): def _stop_acquisition_loop(self):
self.acq_thread.do_run = False self.acq_thread.do_run = False
...@@ -114,26 +113,56 @@ class CameraWorker(QtCore.QObject): ...@@ -114,26 +113,56 @@ class CameraWorker(QtCore.QObject):
@QtCore.pyqtSlot(int) @QtCore.pyqtSlot(int)
def new_image_acquired(self, acq_index): def new_image_acquired(self, acq_index):
self.imageReadySignal.emit(self.cam.acq_queue.get(), acq_index) self.imageReadySignal.emit(self.cam.acq_queue.get(), acq_index)
@QtCore.pyqtSlot(int)
def new_image_acquired_with_trigger(self, acq_index):
self.imageReadySignal.emit(self.cam.acq_queue.get(), acq_index)
self.simple_scan_measurement_step()
def simple_scan_measurement(self, measure_params): def simple_scan_measurement_start(self, measure_params):
if self.cam.CameraAcquiring.getValue(): if self.cam.CameraAcquiring.getValue():
show_warning('Can not start measurement if camera is acquiring') show_warning('Can not start measurement if camera is acquiring')
return 0 return 0
self.measurementStartingSignal.emit() self.measurementStartingSignal.emit()
signal_to_scan = self.get_scan_signal(measure_params['signal_to_scan']) self.ao_to_scan = self.get_scan_signal(measure_params['signal_to_scan'])
start = measure_params['start'] start = measure_params['start']
end = measure_params['end'] end = measure_params['end']
step_num = measure_params['steps'] step_num = measure_params['steps']
directory = measure_params['directory'] directory = measure_params['directory']
scan_array = create_measurement_array(start, end, step_num) self.scan_array_gen = yield_array(create_measurement_array(start, end, step_num))
storage = Storage(directory) storage = Storage(directory)
self.cam.TriggerMode.setString('Software') self.cam.TriggerMode.setString('Software')
self.cam.helper.imageAquiredSignal.disconnect(self.new_image_acquired)
self.cam.helper.imageAquiredSignal.connect(self.new_image_acquired_with_trigger)
self._start_acquisition_loop()
self.acq_thread = threading.Thread(
target=self.cam.live_acquisition_loop
)
self.acq_thread.start()
self.simple_scan_measurement_step()
for value in scan_array:
signal_to_scan.AO.set_out(value) def simple_scan_measurement_end(self):
self._stop_acquisition_loop()
self.cam.TriggerMode.setString('Internal')
self.cam.helper.imageAquiredSignal.disconnect(self.new_image_acquired_with_trigger)
self.cam.helper.imageAquiredSignal.connect(self.new_image_acquired)
self.measurementEndingSignal.emit()
def simple_scan_measurement_step(self):
try:
value = next(self.scan_array_gen)
self.ao_to_scan.AO.set_out(value)
#aca puede esperar o chequear algo, por ahora nada
self.cam.trigger()
except StopIteration:
self.simple_scan_measurement_end()
def get_scan_signal(self, ao_name): def get_scan_signal(self, ao_name):
return [ao for ao in anal_control_signal._registry if ao.name == ao_name][0] return [ao for ao in anal_control_signal._registry if ao.name == ao_name][0]
...@@ -157,5 +186,3 @@ class CameraWorker(QtCore.QObject): ...@@ -157,5 +186,3 @@ class CameraWorker(QtCore.QObject):
""" """
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