Commit 6027e85f authored by Martin Drechsler's avatar Martin Drechsler

Initial commit of the camera GUI and camera worker scripts

parents
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Apr 4 10:35:32 2019
@author: martindrech
"""
from PyQt5.QtWidgets import QMainWindow, QPushButton, QLabel
from pyqtgraph.Qt import QtGui, QtCore
from pyqtgraph import dockarea
import pyqtgraph as pg
from zylaCameraWorker import CameraWorker
import sys
import numpy as np
class GuiMainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
self.__init__
self.some_time = pg.time()
def initUI(self):
self.win = QtGui.QMainWindow()
self.win.setWindowTitle('Toy GUI')
self.win.resize(1000,500)
self.area = dockarea.DockArea()
self.win.setCentralWidget(self.area)
self.cw = QtGui.QWidget()
self.win.show()
self.d1 = dockarea.Dock("Zyla Camera Control")
self.d2 = dockarea.Dock("Zyla Camera Analysis")
self.area.addDock(self.d1)
self.area.addDock(self.d2, 'left', self.d1)
## button spinbox and label
self.cameraButton = QPushButton('Acquisition')
self.d1.addWidget(self.cameraButton)
self.sb = pg.SpinBox(min = 0)
self.d1.addWidget(self.sb)
self.label = QLabel('nada')
self.d1.addWidget(self.label)
#layouts and viewboxes
self.ImageLayout = pg.GraphicsLayoutWidget()
self.view = self.ImageLayout.addViewBox()
self.AnalysisLayout = pg.GraphicsLayoutWidget()
#image layout
self.img = pg.ImageItem(border='w')
self.imv = pg.ImageView(imageItem = self.img, view = self.view)
self.d1.addWidget(self.imv)
#analysis layout
self.d2.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)
#self.p.setRange(xRange = (0, 10), yRange = (0, 255))
self.curve = self.p.plot(pen='y')
## rOI
self.rois = []
self.rois.append(pg.TestROI([0, 0], [10, 10], pen=(0,9)))
for r in self.rois:
self.view.addItem(r)
#r.sigRegionChanged.connect(self.updateRoi)
self.ROIdata = np.zeros(100)
self.iROIdata = 0
self._initialize_image()
def make_connections(self, backend):
backend.imageReadySignal.connect(self.updateImage)
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
def updateRois(self):
for roi in self.rois:
self.lastRoi = roi
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.curve.setData(self.ROIdata)
@QtCore.pyqtSlot(np.ndarray)
def updateImage(self, image):
n = 1024
self.img.setImage(image[:n, :n])
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()
def __del__(self):
print('chau gui')
###############################################################################
if __name__ == '__main__':
app = QtGui.QApplication([])
myGuiMainWIndow = GuiMainWindow()
cameraWorker = CameraWorker()
cameraWorker.make_connections(myGuiMainWIndow)
myGuiMainWIndow.make_connections(cameraWorker)
cameraThread = QtCore.QThread()
cameraWorker.moveToThread(cameraThread)
cameraThread.start()
sys.exit(app.exec_())
\ No newline at end of file
# -*- coding: utf-8 -*-
"""
Andor Zyla 5.5 Camera Driver. Adapted from the PYME driver.
"""
import sys
sys.path.append(r'C:\Users\Usuario\Anaconda3\Lib\site-packages')
import time
import numpy as np
import threading
import ctypes
from datetime import datetime
import pylab as plt
from PyQt5 import QtCore
def _add_path_to_os_path():
# This makes sure that SDK3 finds the DLLs
import os
p = os.environ['PATH'].split(';')
from drivers.PYME.Acquire.Hardware import AndorNeo
loc, _ = os.path.split(AndorNeo.__file__)
if loc in p:
return
p.append(loc)
os.environ['path'] = ';'.join(p)
_add_path_to_os_path()
#%%
from drivers.PYME.Acquire.Hardware.AndorNeo import SDK3
from drivers.PYME.Acquire.Hardware.AndorNeo.SDK3Cam import SDK3Camera
from drivers.PYME.Acquire.Hardware.AndorNeo.SDK3Cam import ATBool, ATCommand, ATEnum, ATInt, ATString, ATFloat, camReg
try:
import Queue
except ImportError:
import queue as Queue
from drivers.PYME.Acquire import MetaDataHandler
def create_aligned_array(shape, dtype=np.typeDict['singlecomplex'], boundary=16):
array = np.zeros(shape, dtype=dtype)
if (array.ctypes.data % boundary) == 0:
return array
extra = boundary / array.itemsize
buf = np.empty(array.size + extra, dtype=array.dtype)
ofs = (-buf.ctypes.data % boundary) / array.itemsize
aligned_array = buf[ofs:ofs+array.size].reshape(array.shape)
np.copyto(aligned_array, array)
assert (aligned_array.ctypes.data % boundary) == 0
return aligned_array
class Helper_messager(QtCore.QObject):
imageAquiredSignal = QtCore.pyqtSignal()
class AndorBase(SDK3Camera):
numpy_frames=1
MODE_CONTINUOUS = 1
MODE_SINGLE_SHOT = 0
# validROIS = [(2592, 2160,1, 1),
# (2544,2160,1,25),
# (2064,2048,57,265),
# (1776,1760,201,409),
# (1920,1080,537,337),
# (1392,1040,561,601),
# (528,512,825,1033),
# (240,256,953,1177),
# (144,128,1017,1225)]
def __init__(self, camNum):
self.helper = Helper_messager()
self.current_image = None
#define properties
self.CameraAcquiring = ATBool()
self.SensorCooling = ATBool()
self.AcquisitionStart = ATCommand()
self.AcquisitionStop = ATCommand()
self.CycleMode = ATEnum()
self.ElectronicShutteringMode = ATEnum()
self.FanSpeed = ATEnum()
self.PreAmpGainChannel = ATEnum()
self.PixelEncoding = ATEnum()
self.PixelReadoutRate = ATEnum()
self.PreAmpGain = ATEnum()
self.PreAmpGainSelector = ATEnum()
self.TriggerMode = 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()
self.SensorWidth = ATInt()
self.BufferOverflowEvent = ATInt()
self.Baseline = ATInt()
self.CameraModel = ATString()
self.SerialNumber = ATString()
self.ExposureTime = ATFloat()
self.FrameRate = ATFloat()
self.SensorTemperature = ATFloat()
self.TargetSensorTemperature = ATFloat()
SDK3Camera.__init__(self,camNum)
#end auto properties
self.camLock = threading.Lock()
self.buffersToQueue = Queue.Queue()
self.queuedBuffers = Queue.Queue()
self.fullBuffers = Queue.Queue()
self.nQueued = 0
self.nFull = 0
self.nBuffers = 100
self.defBuffers = 100
self.contMode = True
self.burstMode = False
self._temp = 0
self._frameRate = 0
self.active = True
#register as a provider of metadata
MetaDataHandler.provideStartMetadata.append(self.GenStartMetadata)
# def Init(self):
# SDK3Camera.Init(self)
#
# #set some intial parameters
# #self.FrameCount.setValue(1)
# self.CycleMode.setString(u'Continuous')
# px_encoding = self.PixelEncoding.getString()
# print(px_encoding)
# self.PixelEncoding.setString(px_encoding)
# self.SensorCooling.setValue(True)
# #self.TemperatureControl.setString('-30.00')
# #self.PixelReadoutRate.setIndex(1)
#
# #set up polling thread
# self.doPoll = False
# self.pollLoopActive = True
# self.pollThread = threading.Thread(target = self._pollLoop)
# self.pollThread.start()
#
#
# def Init2(self):
# SDK3Camera.Init(self)
#
# #set some intial parameters
# self.CycleMode.setString(u'Fixed')
# self.FrameCount.setValue(1)
# px_encoding = self.PixelEncoding.getString()
# print(px_encoding)
# self.SensorCooling.setValue(True)
# #self.TemperatureControl.setString('-30.00')
# #self.PixelReadoutRate.setIndex(1)
#
# #set up polling thread
# self.doPoll = False
# self.pollLoopActive = True
# self.pollThread = threading.Thread(target = self._pollLoop)
# self.pollThread.start()
#Neo buffer helper functions
def InitBuffers(self):
self._flush()
bufSize = self.ImageSizeBytes.getValue()
vRed = int(self.SensorHeight.getValue()/self.AOIHeight.getValue())
self.nBuffers = vRed*self.defBuffers
#print bufSize
for i in range(self.nBuffers):
#buf = np.empty(bufSize, 'uint8')
buf = create_aligned_array(bufSize, 'uint8')
self._queueBuffer(buf)
self.doPoll = True
def _flush(self):
self.doPoll = False
#purge camera buffers
SDK3.Flush(self.handle)
#purge our local queues
while not self.queuedBuffers.empty():
self.queuedBuffers.get()
while not self.buffersToQueue.empty():
self.buffersToQueue.get()
self.nQueued = 0
while not self.fullBuffers.empty():
self.fullBuffers.get()
self.nFull = 0
#purge camera buffers
SDK3.Flush(self.handle)
def _queueBuffer(self, buf):
#self.queuedBuffers.put(buf)
#print np.base_repr(buf.ctypes.data, 16)
#SDK3.QueueBuffer(self.handle, buf.ctypes.data_as(SDK3.POINTER(SDK3.AT_U8)), buf.nbytes)
#self.nQueued += 1
self.buffersToQueue.put(buf)
def _queueBuffers(self):
#self.camLock.acquire()
while not self.buffersToQueue.empty():
buf = self.buffersToQueue.get(block=False)
self.queuedBuffers.put(buf)
#print np.base_repr(buf.ctypes.data, 16)
SDK3.QueueBuffer(self.handle, buf.ctypes.data_as(SDK3.POINTER(SDK3.AT_U8)), buf.nbytes)
#self.fLog.write('%f\tq\n' % time.time())
self.nQueued += 1
#self.camLock.release()
def _pollBuffer(self):
try:
#self.fLog.write('%f\tp\n' % time.time())
pData, lData = SDK3.WaitBuffer(self.handle, 100)
#self.fLog.write('%f\tb\n' % time.time())
except SDK3.TimeoutError as e:
#Both AT_ERR_TIMEDOUT and AT_ERR_NODATA
#get caught as TimeoutErrors
#if e.errNo == SDK3.AT_ERR_TIMEDOUT:
# self.fLog.write('%f\tt\n' % time.time())
#else:
# self.fLog.write('%f\tn\n' % time.time())
return
#except SDK3.CameraError as e:
# if not e.errNo == SDK3.AT_ERR_NODATA:
# traceback.print_exc()
# return
#self.camLock.acquire()
buf = self.queuedBuffers.get()
self.nQueued -= 1
if not buf.ctypes.data == ctypes.addressof(pData.contents):
print((ctypes.addressof(pData.contents), buf.ctypes.data))
#self.camLock.release()
raise RuntimeError('Returned buffer not equal to expected buffer')
#print 'Returned buffer not equal to expected buffer'
self.fullBuffers.put(buf)
self.nFull += 1
#self.camLock.release()
def _pollLoop(self):
#self.fLog = open('poll.txt', 'w')
while self.pollLoopActive:
self._queueBuffers()
if self.doPoll: #only poll if an acquisition is running
self._pollBuffer()
else:
#print 'w',
time.sleep(.05)
time.sleep(.0005)
#self.fLog.flush()
#self.fLog.close()
#PYME Camera interface functions - make this look like the other cameras
def ExpReady(self):
#self._pollBuffer()
return not self.fullBuffers.empty()
def ExtractColor(self, chSlice, mode):
#grab our buffer from the full buffers list
buf = self.fullBuffers.get()
self.nFull -= 1
#copy to the current 'active frame'
#print chSlice.shape, buf.view(chSlice.dtype).shape
#bv = buf.view(chSlice.dtype).reshape(chSlice.shape)
xs, ys = chSlice.shape[:2]
a_s = self.AOIStride.getValue()
#print buf.nbytes
#bv = buf.view(chSlice.dtype).reshape([-1, ys], order='F')
# bv = np.ndarray(shape=[xs,ys], dtype='uint16', strides=[2, a_s], buffer=buf)
# chSlice[:] = bv
#chSlice[:,:] = bv
#ctypes.cdll.msvcrt.memcpy(chSlice.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8)), buf.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8)), chSlice.nbytes)
#ctypes.cdll.msvcrt.memcpy(chSlice.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8)), buf.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8)), chSlice.nbytes)
#print 'f'
dt = self.PixelEncoding.getString()
SDK3.ConvertBuffer(buf.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8)), chSlice.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8)), xs, ys, a_s, dt, 'Mono16')
#SDK3.ConvertBuffer(buf.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8)), chSlice.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8)), xs, ys, a_s, dt, dt)
#recycle buffer
self._queueBuffer(buf)
def GetSerialNumber(self):
return self.SerialNumber.getValue()
def SetIntegTime(self, iTime):
self.ExposureTime.setValue(iTime*1e-3)
self.FrameRate.setValue(self.FrameRate.max())
def GetIntegTime(self):
return self.ExposureTime.getValue()
def GetCCDWidth(self):
return self.SensorHeight.getValue()
def GetCCDHeight(self):
return self.SensorWidth.getValue()
def SetHorizBin(*args):
raise Exception('Not implemented yet!!')
def GetHorizBin(*args):
return 0
#raise Exception, 'Not implemented yet!!'
def GetHorzBinValue(*args):
raise Exception('Not implemented yet!!')
def SetVertBin(*args):
raise Exception('Not implemented yet!!')
def GetVertBin(*args):
return 0
#raise Exception, 'Not implemented yet!!'
def GetNumberChannels(*args):
raise Exception('Not implemented yet!!')
def GetElectrTemp(*args):
return 25
def GetCCDTemp(self):
#for some reason querying the temperature takes a lot of time - do it less often
#return self.SensorTemperature.getValue()
return self._temp
def GetCCDTemp2(self):
#for some reason querying the temperature takes a lot of time - do it less often
return self.SensorTemperature.getValue()
#return self._temp
def CamReady(*args):
return True
def GetPicWidth(self):
return self.AOIWidth.getValue()
def GetPicHeight(self):
return self.AOIHeight.getValue()
def SetROIIndex(self, index):
width, height, top, left = self.validROIS[index]
self.AOIWidth.setValue(width)
self.AOILeft.setValue(left)
self.AOIHeight.setValue(height)
self.AOITop.setValue(top)
def SetROI(self, x1, y1, x2, y2):
#shouldn't do GUI stuff here, but quick way of making it work
#print('Setting ROI')
#import wx
#dlg = wx.SingleChoiceDialog(None, 'Please select the ROI size', 'Camera ROI', ['%dx%d at (%d, %d)' % roi for roi in self.validROIS])
#dlg.ShowModal()
#self.SetROIIndex(dlg.GetSelection())
#dlg.Destroy()
print(x1, y1, x2-x1, y2-y1)
#pass #silently fail
#have to set width before x, height before y
self.AOIWidth.setValue(x2-x1)
self.AOIHeight.setValue(y2 - y1)
self.AOILeft.setValue(x1+1)
self.AOITop.setValue(y1+1)
def GetROIX1(self):
return self.AOILeft.getValue()
def GetROIX2(self):
return self.AOILeft.getValue() + self.AOIWidth.getValue()
def GetROIY1(self):
return self.AOITop.getValue()
def GetROIY2(self):
return self.AOITop.getValue() + self.AOIHeight.getValue()
def DisplayError(*args):
pass
#def Init(*args):
# pass
def Shutdown(self):
print('Shutting down sCMOS camera')
self.pollLoopActive = False
self.shutdown()
#pass
def GetStatus(*args):
pass
def SetCOC(*args):
pass
def StartExposure(self):
#make sure no acquisiton is running
self.StopAq()
self._temp = self.SensorTemperature.getValue()
self._frameRate = self.FrameRate.getValue()
self._flush()
self.InitBuffers()
self.AcquisitionStart()
return 0
def StopAq(self):
if self.CameraAcquiring.getValue():
self.AcquisitionStop()
def StartLifePreview(*args):
raise Exception('Not implemented yet!!')
def StopLifePreview(*args):
raise Exception('Not implemented yet!!')
def GetBWPicture(*args):
raise Exception('Not implemented yet!!')
def CheckCoordinates(*args):
raise Exception('Not implemented yet!!')
#new fcns for Andor compatibility
def GetNumImsBuffered(self):
return self.nFull
def GetBufferSize(self):
return self.nBuffers
def SetActive(self, active=True):
'''flag the camera as active (or inactive) to dictate whether it writes it's metadata or not'''
self.active = active
def GenStartMetadata(self, mdh):
if self.active:
self.GetStatus()
mdh.setEntry('Camera.Name', 'Andor Zyla')
mdh.setEntry('Camera.IntegrationTime', self.GetIntegTime())
mdh.setEntry('Camera.CycleTime', self.GetIntegTime())
mdh.setEntry('Camera.EMGain', 1)
mdh.setEntry('Camera.ROIPosX', self.GetROIX1())
mdh.setEntry('Camera.ROIPosY', self.GetROIY1())
mdh.setEntry('Camera.ROIWidth', self.GetROIX2() - self.GetROIX1())
mdh.setEntry('Camera.ROIHeight', self.GetROIY2() - self.GetROIY1())
#mdh.setEntry('Camera.StartCCDTemp', self.GetCCDTemp())
mdh.setEntry('Camera.ReadNoise', 1)
mdh.setEntry('Camera.NoiseFactor', 1)
mdh.setEntry('Camera.ElectronsPerCount', .28)
mdh.setEntry('Camera.ADOffset', self.Baseline.getValue())
#mdh.setEntry('Simulation.Fluorophores', self.fluors.fl)
#mdh.setEntry('Simulation.LaserPowers', self.laserPowers)
#realEMGain = ccdCalibrator.CalibratedCCDGain(self.GetEMGain(), self.GetCCDTempSetPoint())
#if not realEMGain == None:
mdh.setEntry('Camera.TrueEMGain', 1)
#functions to make us look more like andor camera
def GetEMGain(self):
return 1
def GetCCDTempSetPoint(self):
return self.TargetSensorTemperature.getValue()
def SetCCDTemp(self, temp):
self.TargetSensorTemperature.setValue(temp)
#pass
def SetEMGain(self, gain):
pass
def SetAcquisitionMode(self, aqMode):
self.CycleMode.setIndex(aqMode)
self.contMode = aqMode == self.MODE_CONTINUOUS
def SetBurst(self, burstSize):
if burstSize > 1:
self.SetAcquisitionMode(self.MODE_SINGLE_SHOT)
self.FrameCount.setValue(burstSize)
self.contMode = True
self.burstMode = True
else:
self.FrameCount.setValue(1)
self.SetAcquisitionMode(self.MODE_CONTINUOUS)
self.burstMode = False
def SetShutter(self, mode):
pass
def SetBaselineClamp(self, mode):
pass
def GetFPS(self):
#return self.FrameRate.getValue()
return self._frameRate
def __del__(self):
self.Shutdown()
#self.compT.kill = True
def GetCameraModel(self):
return self.CameraModel.getValue()
def GetShutteringMode(self):
return self.ElectronicShutteringMode.getString()
def GetFanSpeed(self):
return self.FanSpeed.getString()
def GetCycleMode(self):
return self.CycleMode.getString()
def GetPixelReadoutRate(self):
return self.PixelReadoutRate.getString()
def GetSimplePreAmpGainControl(self):
return self.SimplePreAmpGainControl.getString()
def GetImageSizeBytes(self):
return self.ImageSizeBytes.getValue()
def GetBufferOverflowEvent(self):
return self.BufferOverflowEvent.getValue()
def GetMetaData(self):
metadata = dict()
metadata["BufferOverflowEvent"] = self.GetBufferOverflowEvent()
metadata["CameraModel"] = self.GetCameraModel()
metadata["PixelEncoding"] = self.PixelEncoding.getString()
metadata["SerialNumber"] = self.GetSerialNumber()
metadata["IntegTime"] = self.GetIntegTime()
metadata["CCDWidth"] = self.GetCCDWidth()
metadata["CCDHeight"] = self.GetCCDHeight()
metadata["PicWidth"] = self.GetPicWidth()
metadata["PicHeight"] = self.GetPicHeight()
metadata["CCDTemp"] = self.GetCCDTemp2()
metadata["NumImsBuffered"] = self.GetNumImsBuffered()
metadata["BufferSize"] = self.GetBufferSize()
metadata["FPS"] = self.GetFPS()
metadata["CCDTempSetPoint"] = self.GetCCDTempSetPoint()
metadata["ShutteringMode"] = self.GetShutteringMode()
metadata["FanSpeed"] = self.GetFanSpeed()
metadata["CycleMode"] = self.GetCycleMode()
metadata["PixelReadoutRate"] = self.GetPixelReadoutRate()
metadata["SimplePreAmpGainControl"] = self.GetSimplePreAmpGainControl()
metadata["SpuriousNoiseFilter"] = self.SpuriousNoiseFilter.getValue()
metadata["TemperatureStatus"] = self.TemperatureStatus.getString()
metadata["ImageSizeBytes"] = self.GetImageSizeBytes()
metadata["Date"] = datetime.now().strftime("%Y-%m-%d")
metadata["Time"] = datetime.now().strftime("%H:%M:%S")
metadata["TimeAbsolute"] = time.time()
return metadata
def GetInt(self, name):
return SDK3.GetInt(self.handle, name).value
def acquireOne(self):
image_size = self.ImageSizeBytes.getValue()
buf = create_aligned_array(image_size, 'uint8')
SDK3.QueueBuffer(self.handle, buf.ctypes.data_as(SDK3.POINTER(SDK3.AT_U8)), buf.nbytes)
self.AcquisitionStart()
pData, lData = SDK3.WaitBuffer(self.handle, SDK3.AT_INFINITE)
self.AcquisitionStop()
xs, ys = self.GetPicWidth(), self.GetPicHeight()
img = create_aligned_array(xs*ys, 'uint16')
a_s = self.AOIStride.getValue()
px_encoding = self.PixelEncoding.getString()
SDK3.ConvertBuffer(buf.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8)),
img.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8)),
xs, ys, a_s,
px_encoding, 'Mono16')
self._flush()
img.shape = (ys, xs)
return img
def live_preview_plot(self):
fig, ax = plt.subplots(1, 1 )
ax.set_title(str(0))
myPlot = plt.imshow(self.acquireOne())
image_size = self.ImageSizeBytes.getValue()
buf = create_aligned_array(image_size, 'uint8')
self.CycleMode.setString('Continuous')
a_s = self.AOIStride.getValue()
px_encoding = self.PixelEncoding.getString()
self.AcquisitionStart()
xs, ys = self.GetPicWidth(), self.GetPicHeight()
i = 1
while plt.fignum_exists(fig.number):
SDK3.QueueBuffer(self.handle, buf.ctypes.data_as(SDK3.POINTER(SDK3.AT_U8)), buf.nbytes)
pData, lData = SDK3.WaitBuffer(self.handle, 1000)
img = create_aligned_array(xs*ys, 'uint16')
SDK3.ConvertBuffer(buf.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8)),
img.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8)),
xs, ys, a_s,
px_encoding, 'Mono16')
img.shape = (ys, xs)
myPlot.set_data(img)
fig.canvas.draw()
fig.canvas.flush_events()
ax.set_title(str(i))
plt.pause(0.01)
i = i + 1
self.AcquisitionStop()
self._flush()
def live_preview_plot_circular(self):
image_size = self.ImageSizeBytes.getValue()
bufs = [create_aligned_array(image_size, 'uint8') for i in range(1)]
n_of_bufs = len(bufs)
for i in range(n_of_bufs):
SDK3.QueueBuffer(self.handle, bufs[i].ctypes.data_as(SDK3.POINTER(SDK3.AT_U8)), bufs[i].nbytes)
self.CycleMode.setString('Continuous')
a_s = self.AOIStride.getValue()
px_encoding = self.PixelEncoding.getString()
self.AcquisitionStart()
xs, ys = self.GetPicWidth(), self.GetPicHeight()
#start_t = time.time()
i = 0
while True:
pData, lData = SDK3.WaitBuffer(self.handle, 1000)
img = create_aligned_array(xs*ys, 'uint16')
SDK3.ConvertBuffer(bufs[i%n_of_bufs].ctypes.data_as(ctypes.POINTER(ctypes.c_uint8)),
img.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8)),
xs, ys, a_s,
px_encoding, 'Mono16')
img.shape = (ys, xs)
self.current_image = img
self.helper.imageAquiredSignal.emit()
#if i%self.FrameRate.getValue() == 0:
# print(i, 'time = : ', '%.2f' % (time.time()-start_t))
SDK3.QueueBuffer(self.handle, bufs[i%n_of_bufs].ctypes.data_as(SDK3.POINTER(SDK3.AT_U8)), bufs[i%n_of_bufs].nbytes)
i = i + 1
self.AcquisitionStop()
self._flush()
def live_acquisition_configure(self):
image_size = self.ImageSizeBytes.getValue()
bufs = [create_aligned_array(image_size, 'uint8') for i in range(1)]
n_of_bufs = len(bufs)
for ind in range(n_of_bufs):
SDK3.QueueBuffer(self.handle, bufs[ind].ctypes.data_as(SDK3.POINTER(SDK3.AT_U8)), bufs[ind].nbytes)
self.CycleMode.setString('Continuous')
a_s = self.AOIStride.getValue()
px_encoding = self.PixelEncoding.getString()
xs, ys = self.GetPicWidth(), self.GetPicHeight()
self.acq_index_i = 0
self._live_acq_auxs = a_s, px_encoding, xs, ys, bufs
def live_acquisition_loop(self):
t = threading.currentThread()
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)
except:
return
img = create_aligned_array(xs*ys, 'uint16')
SDK3.ConvertBuffer(bufs[self.acq_index_i%len(bufs)].ctypes.data_as(ctypes.POINTER(ctypes.c_uint8)),
img.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8)),
xs, ys, a_s,
px_encoding, 'Mono16')
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.acq_index_i = self.acq_index_i + 1
self.helper.imageAquiredSignal.emit()
print('stopping acq loop thread')
def _convert_buffer_12(self, buf):
import itertools
xs, ys = self.GetPicWidth(), self.GetPicHeight()
a_s = self.AOIStride.getValue()
img = np.empty((xs, ys), 'uint16')
for m, n in itertools.product(range(xs), range(ys)):
try:
img[m, n] = buf[n*a_s + 2 * m + 1] *256 + buf[n*a_s + 2 * m]
except:
print('!!',xs, ys, a_s, buf.size, buf.shape)
print(m, n,n*a_s + 2 * m + 1, n*a_s + 2 * m)
break
return img
class AndorZyla(AndorBase):
def __init__(self, camNum):
#define properties
self.Overlap = ATBool()
self.SpuriousNoiseFilter = ATBool()
self.StaticBlemishCorrection = ATBool()
self.VerticallyCentreAOI = ATBool()
self.CameraDump = ATCommand()
self.SoftwareTrigger = ATCommand()
self.TemperatureControl = ATEnum()
self.TemperatureStatus = ATEnum()
self.SimplePreAmpGainControl = ATEnum()
self.BitDepth = ATEnum()
self.ActualExposureTime = ATFloat()
self.BurstRate = ATFloat()
self.ReadoutTime = ATFloat()
self.TimestampClock = ATInt()
self.TimestampClockFrequency = ATInt()
self.AccumulateCount = ATInt()
self.BaselineLevel = ATInt()
self.BurstCount = ATInt()
self.LUTIndex = ATInt()
self.LUTValue = ATInt()
self.ControllerID = ATString()
self.FirmwareVersion = ATString()
AndorBase.__init__(self,camNum)
class AndorSim(AndorBase):
def __init__(self, camNum):
#define properties
self.SynchronousTriggering = ATBool()
self.PixelCorrection = ATEnum()
self.TriggerSelector = ATEnum()
self.TriggerSource = ATEnum()
self.PixelHeight = ATFloat()
self.PixelWidth = ATFloat()
self.AOIHBin = ATInt()
self.AOIVbin = ATInt()
AndorBase.__init__(self,camNum)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Apr 6 22:17:00 2019
@author: martindrech
"""
import numpy as np
from PyQt5 import QtCore
import time
import threading
class Helper_messager(QtCore.QObject):
imageAquiredSignal = QtCore.pyqtSignal()
class AndorZyla():
def __init__(self, num):
self.ExposureTime = AndorFeats()
self.FrameRate = AndorFeats()
self.CameraAcquiring = AndorFeats()
self.helper = Helper_messager()
self.current_image = None
self.CameraAcquiring.setValue(False)
def Init(self):
print('Dummy camera initialized')
def live_acquisition_loop(self):
t = threading.currentThread()
while getattr(t, "do_run", True):
time.sleep(self.ExposureTime.getValue())
self.current_image = self._twoD_gaussian()
self.helper.imageAquiredSignal.emit()
print('stopping acq loop thread')
def live_acquisition_configure(self):
pass
def AcquisitionStart(self):
self.CameraAcquiring.setValue(True)
def AcquisitionStop(self):
self.CameraAcquiring.setValue(False)
def _flush(self):
pass
def _twoD_gaussian(self, lim = 10, N = 100, sigma = 1, x0 = 0, y0 = 0):
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)
return(g+noise)
class AndorFeats():
def __init__(self):
self.value = None
def getValue(self):
return self.value
def setValue(self, val):
self.value = val
def _twoD_gaussian(self, lim = 10, N = 100, sigma = 1, x0 = 0, y0 = 0):
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)
return(g+noise)
\ No newline at end of file
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Apr 4 11:10:20 2019
@author: martindrech
Por ahora, aca se va a crear una imagen cada cierto tiempo y eso se va a mandar a toy_gui para plotearse ahi
"""
import numpy as np
from PyQt5 import QtCore
#from drivers.andorzyla import AndorZyla
from dummyAndor import AndorZyla
import threading
class CameraWorker(QtCore.QObject):
imageReadySignal = QtCore.pyqtSignal(np.ndarray)
def __init__(self):
super(CameraWorker, self).__init__()
self.cam = AndorZyla(0)
self.cam.Init()
self.cam.ExposureTime.setValue(.01)
self.cam.FrameRate.setValue(20)
print('camera worker initialized')
def make_connections(self, frontend):
#frontend connections
frontend.cameraButton.clicked.connect(self.run)
frontend.sb.valueChanged.connect(lambda x = frontend.sb.value(): self.cam.ExposureTime.setValue(x))
#internal connections
self.cam.helper.imageAquiredSignal.connect(self.acquire)
def __del__(self):
print('adios camera worker')
@QtCore.pyqtSlot()
def run(self):
if self.cam.CameraAcquiring.getValue():
self._stop_acquisition_loop()
print('acquisition now stopping')
else:
self._start_acquisition_loop()
self.acq_thread = threading.Thread(target= self.cam.live_acquisition_loop)
self.acq_thread.start()
print('acquisiting now starting')
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
self.acq_thread.join()
self.cam.AcquisitionStop()
self.cam._flush()
@QtCore.pyqtSlot()
def acquire(self):
#print('acquiring')
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