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
from zylaCameraWorker import CameraWorker
from subclasses.cameraParameterTree import CameraParameterTree
from subclasses.controllayouts import LaserControlLayout, LaserScanLayout
from resources.scanFunctions import create_measurement_array
#from drivers.andorzyla import AndorZyla
......@@ -81,32 +81,44 @@ class CameraGuiMainWindow(QMainWindow):
# layouts and viewboxes
self.ImageLayout = pg.GraphicsLayoutWidget()
self.view = self.ImageLayout.addViewBox()
self.AnalysisLayout = pg.GraphicsLayoutWidget()
self.imageView = self.ImageLayout.addViewBox()
self.timeAnalysisLayout = pg.GraphicsLayoutWidget()
self.scanAnalysisLayout = pg.GraphicsLayoutWidget()
# image layout
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.dCameraView.addWidget(self.imv)
# analysis layout
self.dCameraTimeAnal.addWidget(self.AnalysisLayout)
self.p = self.AnalysisLayout.addPlot(row=0, col=0, title="Time plot")
self.p.setRange(QtCore.QRectF(0, 0, 50, 255))
self.p.setAutoPan(y=True)
# time analysis layout
self.dCameraTimeAnal.addWidget(self.timeAnalysisLayout)
self.timePlot = self.timeAnalysisLayout.addPlot(row=0, col=0, title="Time plot")
self.timePlot.setRange(QtCore.QRectF(0, 0, 50, 255))
self.timePlot.setAutoPan(y=True)
# 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
self.rois = []
self.rois.append(CustomRectangularROI([0, 0]))
for r in self.rois:
self.view.addItem(r)
# r.sigRegionChanged.connect(self.updateRoi)
self.imageView.addItem(r)
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.current_image_size = 2048
self._initialize_image()
......@@ -126,7 +138,7 @@ class CameraGuiMainWindow(QMainWindow):
)
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.selectScanSignal.activated[str].connect(self.measurementFrame.configure_spinBoxes)
self.measurementFrame.startValue.valueChanged.connect(self.measurementFrame.update_tree)
......@@ -145,6 +157,10 @@ class CameraGuiMainWindow(QMainWindow):
else:
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.measurementFrame.startMeasureButton.setEnabled(False)
self.frame_index = 0
......@@ -154,22 +170,25 @@ class CameraGuiMainWindow(QMainWindow):
def _initialize_image(self):
# lock the aspect ratio so pixels are always square
self.view.setAspectLocked(True)
self.view.addItem(self.img)
self.imageView.setAspectLocked(True)
self.imageView.addItem(self.img)
self.frame_index = 0
self.previous_frame_index = 0
self.frames_checker_timer.start(1000)
def updateRois(self):
def updatePlots(self):
for roi in self.rois:
roiSlice = roi.getArrayRegion(self.img.image, img=self.img)
self.newData = roiSlice.sum()
self.ROIdata[self.iROIdata] = self.newData
self.iROIdata = np.mod(self.frame_index + 1, len(self.ROIdata))
self.curve.setData(self.ROIdata)
self.scanROIdataY[self.iROIdata] = self.newData
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):
old_size = self.current_image_size
......@@ -188,16 +207,14 @@ class CameraGuiMainWindow(QMainWindow):
@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, autoDownsample=True)
self.updateRois()
self.updatePlots()
self.frame_index = self.frame_index + 1
self.current_image_size = image.shape[0]
......@@ -216,10 +233,23 @@ class CameraGuiMainWindow(QMainWindow):
def measurement_starting(self):
self.cameraButton.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 :
l.freeze()
print('gui meas start')
#@QtCore.pyqtSlot()
def measurement_ending(self):
self.cameraButton.setEnabled(True)
......@@ -227,10 +257,11 @@ class CameraGuiMainWindow(QMainWindow):
for l in LaserControlLayout._registry + LaserScanLayout._registry :
l.unfreeze()
print('gui meas end')
def __del__(self):
print("chau gui")
def emit_measurement_parameters(self):
def emit_measurement_parameters_and_start(self):
measure_params = dict()
measure_params['signal_to_scan'] = self.measurementFrame.selectScanSignal.currentText()
measure_params['start'] = self.measurementFrame.startValue.value()
......
......@@ -44,7 +44,9 @@ class AndorZyla:
self.AOIBinning.setValue('1x1')
self.ImageArea.setValue(2048)
self.CameraModel.setValue('dummy')
self.TriggerMode.setString('Internal')
self.triggerEventHappened = False
self.images_array = []
def Init(self):
......@@ -52,18 +54,26 @@ class AndorZyla:
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):
self.acq_index_i = 0
......@@ -81,18 +91,22 @@ class AndorZyla:
d = {'1x1': 2048, '2x2': 1024, '4x4': 512, '8x8': 256}
self.ImageArea.setValue(d[self.AOIBinning.getValue()])
def _twoD_gaussian(self, lim=10, sigma=1, x0=0, y0=0):
start = time.time()
N = self.ImageArea.getValue()
x, y = np.meshgrid(np.linspace(-lim, lim, N), np.linspace(-lim, lim, N))
d = np.sqrt((x - x0) ** 2 + (y - y0) ** 2)
g = np.exp(-((d) ** 2 / (2.0 * sigma ** 2)))
noise = np.random.rand(N, N)
end = time.time()
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:
def __init__(self):
self.value = None
......@@ -118,5 +132,5 @@ class AndorFeats:
print(s)
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
from controlGui import ControlGui
if __name__ == "__main__":
import sys
app = QtGui.QApplication([])
......@@ -57,23 +54,13 @@ if __name__ == "__main__":
myGuiMainWindow = CameraGuiMainWindow()
cameraWorker = CameraWorker(camera)
cameraWorker.make_connections(myGuiMainWindow)
myGuiMainWindow.make_connections(cameraWorker)
cameraThread = QtCore.QThread()
cameraWorker.moveToThread(cameraThread)
# measurementGui = MeasurementGui()
# measurementWorker = MeasurementWorker()
# myGuiMainWindow.dMeasurement.addWidget(measurementGui)
# measurementThread = QtCore.QThread()
# measurementWorker.moveToThread(measurementThread)
# measurementGui.make_connections(measurementWorker)
# measurementWorker.make_connections(measurementGui, camera)
cameraWorker.make_connections(myGuiMainWindow)
myGuiMainWindow.make_connections(cameraWorker)
cameraThread.start()
mcDAQthread.start()
# measurementThread.start()
sys.exit(app.exec_())
......@@ -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:
......
......@@ -51,6 +51,9 @@ def create_measurement_array(start, stop, steps, back_and_forth=False):
def yield_array(arr):
"""
Returns array generator
"""
larr = len(arr)
cursor = 0
while cursor < larr:
......
......@@ -32,13 +32,13 @@ class CameraWorker(QtCore.QObject):
print("camera worker initialized")
self.ao_to_scan = None
self.scan_array_gen = None
def make_connections(self, frontend):
# frontend connections
live_acq_params = frontend.param_tree.p
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
self.cam.helper.imageAquiredSignal.connect(self.new_image_acquired)
......@@ -63,8 +63,7 @@ class CameraWorker(QtCore.QObject):
def _start_acquisition_loop(self):
self.cam.live_acquisition_configure()
self.cam.AcquisitionStart()
print("frame rate: ", self.cam.FrameRate.getValue())
print("Exp time: ", self.cam.ExposureTime.getValue())
def _stop_acquisition_loop(self):
self.acq_thread.do_run = False
......@@ -114,26 +113,56 @@ class CameraWorker(QtCore.QObject):
@QtCore.pyqtSlot(int)
def new_image_acquired(self, 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():
show_warning('Can not start measurement if camera is acquiring')
return 0
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']
end = measure_params['end']
step_num = measure_params['steps']
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)
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):
return [ao for ao in anal_control_signal._registry if ao.name == ao_name][0]
......@@ -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