diff --git a/Main.py b/Main.py old mode 100644 new mode 100755 index 0d20f9b..4aca5d0 --- a/Main.py +++ b/Main.py @@ -1,5 +1,5 @@ """ - PythonForPicam is a Python ctypes interface to the Princeton Instruments PICAM Library +PythonForPicam is a Python ctypes interface to the Princeton Instruments PICAM Library Copyright (C) 2013 Joe Lowney. The copyright holder can be reached at joelowney@gmail.com This program is free software: you can redistribute it and/or modify @@ -20,20 +20,14 @@ """Test for talking to Picam""" import ctypes as ctypes -""" Import standard type definitions from PiTypes.py """ -from PiTypes import * +from PiParameterLookup import * -""" Import non-standard type definitions from PiTypesMore.py """ -from PiTypesMore import * +from PythonForPicam import * -""" Import function definitions from PiFunctions.py """ -""" This should contian all of the function from picam.h """ -from PiFunctions import * +import numpy as np +import matplotlib.pyplot as plt -""" Import parameter lookup from PiParameterLookup.py """ -""" This file includes a function PI_V and a lookup table to return the code - for different Picam Parameters described in chapter 4 """ -from PiParameterLookup import * +import sys ############################ ##### Custom Functions ##### @@ -50,7 +44,6 @@ def load(x): x = ctypes.cdll.LoadLibrary(x) return x - ######################### ##### Main Routine ##### ######################### @@ -58,8 +51,10 @@ def load(x): if __name__ == '__main__': """ Load the picam.dll """ - # picamDll = 'C:/Users/becgroup/Documents/Python/DriverTest/Princeton Instruments/Picam/Runtime/Picam.dll' - picamDll = 'DLLs/Picam.dll' + #picamDll = 'C:/Users/becgroup/Documents/Python/DriverTest/Princeton Instruments/Picam/Runtime/Picam.dll' + #picamDll = 'DLLs/Picam.dll' + picamDll = 'C:/Program Files/Common Files/Princeton Instruments/Picam/Runtime/Picam.dll' + picam = load(picamDll) print 'Initialize Camera.',Picam_InitializeLibrary() @@ -76,24 +71,24 @@ def load(x): ## Test Routine to connect a demo camera ## p23 - print 'Preparing to connect Demo Camera' - model = ctypes.c_int(10) - serial_number = ctypes.c_char_p('Demo Cam 1') - PicamID = PicamCameraID() - """ - PICAM_API Picam_ConnectDemoCamera( - PicamModel model, - const pichar* serial_number, - PicamCameraID* id ); - """ - print 'Demo camera connetcted with return value = ',Picam_ConnectDemoCamera(model, serial_number, pointer(PicamID)) - print '\n' - - print 'Camera model is ',PicamID.model - print 'Camera computer interface is ',PicamID.computer_interface - print 'Camera sensor_name is ', PicamID.sensor_name - print 'Camera serial number is', PicamID.serial_number - print '\n' +# print 'Preparing to connect Demo Camera' +# model = ctypes.c_int(10) +# serial_number = ctypes.c_char_p('Demo Cam 1') +# PicamID = PicamCameraID() +# """ +# PICAM_API Picam_ConnectDemoCamera( +# PicamModel model, +# const pichar* serial_number, +# PicamCameraID* id ); +# """ +# print 'Demo camera connetcted with return value = ',Picam_ConnectDemoCamera(model, serial_number, pointer(PicamID)) +# print '\n' +# +# print 'Camera model is ',PicamID.model +# print 'Camera computer interface is ',PicamID.computer_interface +# print 'Camera sensor_name is ', PicamID.sensor_name +# print 'Camera serial number is', PicamID.serial_number +# print '\n' ## Test routine to open first camera ## p20 @@ -103,49 +98,20 @@ def load(x): camera = PicamHandle() print 'Opening First Camera', Picam_OpenFirstCamera(ctypes.addressof(camera)) + model = ctypes.c_int(10) + serial_number = ctypes.c_char_p('Demo Cam 1') + PicamID = PicamCameraID() - ## Test routine to acquire image - ## p73 - """ - PICAM_API Picam_Acquire( - PicamHandle camera, - pi64s readout_count, - piint readout_time_out, - PicamAvailableData* available, - PicamAcquisitionErrorsMask* errors ); - """ - readoutstride = piint(0); - print "Getting readout stride. ", Picam_GetParameterIntegerValue( camera, ctypes.c_int(PicamParameter_ReadoutStride), ctypes.byref(readoutstride) ); - - """ - Prototype - PICAM_API Picam_Acquire( - PicamHandle camera, - pi64s readout_count, - piint readout_time_out, - PicamAvailableData* available, - PicamAcquisitionErrorsMask* errors ); - """ - - """ - typedef struct PicamAvailableData - { - void* initial_readout; - pi64s readout_count; - } PicamAvailableData; - """ - readout_count = pi64s(1) - readout_time_out = piint(1000) - available = PicamAvailableData() - - """ Print Debug Information on initial readout """ + print 'Retrieving camera ID',Picam_GetCameraID(camera, pointer(PicamID)) + print 'Camera model is ',PicamID.model + print 'Camera computer interface is ',PicamID.computer_interface + print 'Camera sensor_name is ', PicamID.sensor_name + print 'Camera serial number is', PicamID.serial_number print '\n' - print "available.initial_readout: ",available.initial_readout - print "Initial readout type is", type(available.initial_readout) - errors = PicamAcquisitionErrorsMask() + ## Test routine to acquire image + ## p73 """ - Prototype PICAM_API Picam_Acquire( PicamHandle camera, pi64s readout_count, @@ -153,31 +119,154 @@ def load(x): PicamAvailableData* available, PicamAcquisitionErrorsMask* errors ); """ - Picam_Acquire.argtypes = PicamHandle, pi64s, piint, ctypes.POINTER(PicamAvailableData), ctypes.POINTER(PicamAcquisitionErrorsMask) - Picam_Acquire.restype = piint + readoutstride = piint(0) + for i in [8,5]: + print i+1 + print "Getting readout stride. ",Picam_GetParameterIntegerValue( camera, ctypes.c_int(PicamParameter_ReadoutStride), ctypes.byref(readoutstride) ); + print "The readoutstride is %d" % readoutstride.value + """ + Prototype + PICAM_API Picam_Acquire( + PicamHandle camera, + pi64s readout_count, + piint readout_time_out, + PicamAvailableData* available, + PicamAcquisitionErrorsMask* errors ); + """ - print '\nAcquiring... ',Picam_Acquire(camera, readout_count, readout_time_out, ctypes.byref(available), ctypes.byref(errors)) - print '\n' + """ + typedef struct PicamAvailableData + { + void* initial_readout; + pi64s readout_count; + } PicamAvailableData; + """ + Picam_SetParameterIntegerValue( camera, PicamParameter_TriggerResponse, PicamTriggerResponse_NoResponse) + Picam_SetParameterIntegerValue( camera, PicamParameter_TriggerDetermination, PicamTriggerDetermination_PositivePolarity ) + Picam_SetParameterIntegerValue( camera, PicamParameter_OutputSignal, i+1 ) + exposure = piflt(10.) + picam.Picam_SetParameterFloatingPointValue.argtypes=[PicamHandle, piint, piflt] + status = Picam_SetParameterFloatingPointValue(camera, PicamParameter_ExposureTime, exposure) + print " %s = Picam_SetParameterFloatingPointValue(camera, %d, "% (status,PicamParameter_ExposureTime,), exposure,")" + failCount = piint() + paramsFailed = piint() + status = Picam_CommitParameters(camera, pointer(paramsFailed), ctypes.byref(failCount)) + print "commit returned ", status, "failCount is ",failCount + readout_count = pi64s(4) + readout_time_out = piint(100000) + available = PicamAvailableData(0, 0) + + """ Print Debug Information on initial readout """ + print '\n' + print "available.initial_readout: ",available.initial_readout + print "Initial readout type is", type(available.initial_readout) + errors = PicamAcquisitionErrorsMask() + + """ + Prototype + PICAM_API Picam_Acquire( + PicamHandle camera, + pi64s readout_count, + piint readout_time_out, + PicamAvailableData* available, + PicamAcquisitionErrorsMask* errors ); + """ + # Picam_Acquire.argtypes = PicamHandle, pi64s, piint, ctypes.POINTER(PicamAvailableData), ctypes.POINTER(PicamAcquisitionErrorsMask) + Picam_Acquire.argtypes = [] + Picam_Acquire.restype = piint + + print '\nAcquiring... ',Picam_Acquire(camera, readout_count, readout_time_out, ctypes.byref(available), + ctypes.byref(errors)) + print '\n' + + print "available.initial_readout: ",available.initial_readout + print "Initial readout type is", type(available.initial_readout) + print '\n' + + + """ Test Routine to Access Data """ + + """ Create an array type to hold 1024x1024 16bit integers """ + sz = readoutstride.value/2 + DataArrayType = pi16u*sz + + """ Create pointer type for the above array type """ + DataArrayPointerType = ctypes.POINTER(pi16u*sz) + + """ Create an instance of the pointer type, and point it to initial readout contents (memory address?) """ + DataPointer = ctypes.cast(available.initial_readout,DataArrayPointerType) + + + """ Create a separate array with readout contents """ + data = DataPointer.contents + ans = np.empty(sz,np.short) + cnt = 0 + ans[:] = data + ans = ans.reshape((512,512)) + plt.figure() + plt.imshow(ans) + plt.show() + """ Write contents of Data to binary file""" + print 'readoutstride is ', readoutstride.value + + # try to do rois + rois = PicamRois(4) + rois.roi_array[0].x = 0 + rois.roi_array[0].width = 512 + rois.roi_array[0].x_binning = 1 + rois.roi_array[0].y = 76 + rois.roi_array[0].height = 60 + rois.roi_array[0].y_binning = 60 + + rois.roi_array[1].x = 0 + rois.roi_array[1].width = 512 + rois.roi_array[1].x_binning = 1 + rois.roi_array[1].y = 185 + rois.roi_array[1].height = 60 + rois.roi_array[1].y_binning = 60 + + rois.roi_array[2].x = 0 + rois.roi_array[2].width = 512 + rois.roi_array[2].x_binning = 1 + rois.roi_array[2].y = 294 + rois.roi_array[2].height = 60 + rois.roi_array[2].y_binning = 60 + + rois.roi_array[3].x = 0 + rois.roi_array[3].width = 512 + rois.roi_array[3].x_binning = 1 + rois.roi_array[3].y = 403 + rois.roi_array[3].height = 60 + rois.roi_array[3].y_binning = 60 + + Picam_SetParameterRoisValue(camera, PicamParameter_Rois, pointer(rois)) + + failCount = piint() + paramsFailed = piint() + Picam_CommitParameters(camera, pointer(paramsFailed), ctypes.byref(failCount)) + Picam_DestroyParameters(pointer(paramsFailed)) + + readoutstride = piint(0); + print "Getting readout stride. ",Picam_GetParameterIntegerValue( camera, ctypes.c_int(PicamParameter_ReadoutStride), ctypes.byref(readoutstride) ); + print "The readoutstride is %d" % readoutstride.value + readout_count = pi64s(100) + print '\nAcquiring... ',Picam_Acquire(camera, readout_count, readout_time_out, ctypes.byref(available), + ctypes.byref(errors)) print "available.initial_readout: ",available.initial_readout print "Initial readout type is", type(available.initial_readout) print '\n' - """ Close out Library Resources """ - ## Disconnected the above cameras - print 'Disconnecting demo camera', Picam_DisconnectDemoCamera(pointer(PicamID)) - ## Close down library - print 'Uninitializing',Picam_UninitializeLibrary() - - """ Test Routine to Access Data """ """ Create an array type to hold 1024x1024 16bit integers """ - DataArrayType = pi16u*1048576 + sz = readout_count.value*readoutstride.value/2 + print "sz is ", sz + DataArrayType = pi16u*sz """ Create pointer type for the above array type """ - DataArrayPointerType = ctypes.POINTER(pi16u*1048576) + DataArrayPointerType = ctypes.POINTER(pi16u*sz) """ Create an instance of the pointer type, and point it to initial readout contents (memory address?) """ DataPointer = ctypes.cast(available.initial_readout,DataArrayPointerType) @@ -185,23 +274,20 @@ def load(x): """ Create a separate array with readout contents """ data = DataPointer.contents - - + print "make the nparray" + ans = np.empty(sz,np.short) + ans[:] = data + ans = ans.reshape((readout_count.value, readoutstride.value/2/512, 512)) + print ans.flags + print ans.shape + plt.figure() + plt.plot(ans) + plt.show() """ Write contents of Data to binary file""" - libc = ctypes.cdll.msvcrt - fopen = libc.fopen - fopen.argtypes = ctypes.c_char_p, ctypes.c_char_p - fopen.restype = ctypes.c_void_p - - fwrite = libc.fwrite - fwrite.argtypes = ctypes.c_void_p, ctypes.c_size_t, ctypes.c_size_t, ctypes.c_void_p - fwrite.restype = ctypes.c_size_t - fclose = libc.fclose - fclose.argtypes = ctypes.c_void_p, - fclose.restype = ctypes.c_int + print 'readoutstride is ', readoutstride.value + print ans - fp = fopen('PythonBinOutput.raw', 'wb') - print 'fwrite returns: ',fwrite(data, readoutstride.value, 1, fp) - fclose(fp) + """ Close out Library Resources """ + print 'Uninitializing',Picam_UninitializeLibrary() diff --git a/PiFunctions.py b/PiFunctions.py index b14efc5..3e5095c 100644 --- a/PiFunctions.py +++ b/PiFunctions.py @@ -16,10 +16,11 @@ along with this program. If not, see . """ import ctypes as ctypes -picamDll = 'DLLs/Picam.dll' -picam = ctypes.cdll.LoadLibrary(picamDll) - - +picamDll = 'Picam.dll' +try: + picam = ctypes.cdll.LoadLibrary(picamDll) +except: + print "Could not load Princeton Instruments DLL. Make sure that Picam.dll is in the system path" ### Begin imported Functions diff --git a/PiParameterLookup.py b/PiParameterLookup.py old mode 100644 new mode 100755 index f43a108..d62e160 --- a/PiParameterLookup.py +++ b/PiParameterLookup.py @@ -234,4 +234,40 @@ def PI_V(PicamValueType, PicamConstraintType, n): PicamParameter_DisableCoolingFan = PI_V("Boolean", "Collection", 29) """ /*-------------------------------------------------------------------------------------*/ + * Trigger parameter values + */ """ +PicamTriggerCoupling_AC = 1 +PicamTriggerCoupling_DC = 2 +PicamTriggerDetermination_PositivePolarity = 1 +PicamTriggerDetermination_NegativePolarity = 2 +PicamTriggerDetermination_RisingEdge = 3 +PicamTriggerDetermination_FallingEdge = 4 +PicamTriggerResponse_NoResponse = 1 +PicamTriggerResponse_ReadoutPerTrigger = 2 +PicamTriggerResponse_ShiftPerTrigger = 3 +PicamTriggerResponse_ExposeDuringTriggerPulse = 4 +PicamTriggerResponse_StartOnSingleTrigger = 5 +PicamTriggerSource_External = 1 +PicamTriggerSource_Internal = 2 +PicamTriggerTermination_FiftyOhms = 1 +PicamTriggerTermination_HighImpedance = 2 + +""" +/*-------------------------------------------------------------------------------------*/ + * PicamOutputSignal parameter values + */ +""" + +PicamOutputSignal_NotReadingOut = 1 +PicamOutputSignal_ShutterOpen = 2 +PicamOutputSignal_Busy = 3 +PicamOutputSignal_AlwaysLow = 4 +PicamOutputSignal_AlwaysHigh = 5 +PicamOutputSignal_Acquiring = 6 +PicamOutputSignal_ShiftingUnderMask = 7 +PicamOutputSignal_Exposing = 8 +PicamOutputSignal_EffectivelyExposing = 9 +PicamOutputSignal_ReadingOut = 10 +PicamOutputSignal_WaitingForTrigger = 11 + diff --git a/PiTypes.py b/PiTypes.py old mode 100644 new mode 100755 index 40ef7cd..1b97026 --- a/PiTypes.py +++ b/PiTypes.py @@ -22,7 +22,7 @@ ##### Following definitions are from page 11 piint = ctypes.c_int # """Integer native to platform""" -piflt = ctypes.c_float # """Floating point native to platform""" +piflt = ctypes.c_double # """Floating point native to platform""" pibln = ctypes.c_bool # """Boolean native to platform""" pichar = ctypes.c_char # """character native to platform""" pibyte = ctypes.c_byte # """Byte native to platform""" diff --git a/PiTypesMore.py b/PiTypesMore.py index 519ad5d..3f74b56 100644 --- a/PiTypesMore.py +++ b/PiTypesMore.py @@ -86,6 +86,41 @@ class PicamAvailableData(ctypes.Structure): class PicamAvailableData2(ctypes.Structure): _fields_ = [ ( "initial_readout", ctypes.POINTER(type(ctypes.c_void_p()))), ("readout_count", pi64s)] +# PicamRoi +""" +typedef struct PicamRoi +{ + piint x; + piint width; + piint x_binning; + piint y; + piint height; + piint y_binning; +} PicamRoi; +""" +class PicamRoi(ctypes.Structure): + _fields_ = [("x", piint), + ("width", piint), + ("x_binning", piint), + ("y", piint), + ("height", piint), + ("y_binning", piint)] +# PicamRois +""" +typedef struct PicamRois +{ + PicamRoi* roi_array; + piint roi_count; +} PicamRois; +""" +class PicamRois(ctypes.Structure): + _fields_ = [("roi_array", ctypes.POINTER(PicamRoi)), + ("roi_count", piint)] + def __init__(self, num): + elems = (PicamRoi * num)() + self.roi_array = ctypes.cast(elems,ctypes.POINTER(PicamRoi)) + self.roi_count = num + # PicamAcquisitionErrorsMask """ typedef enum PicamAcquisitionErrorsMask diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..97c2732 --- /dev/null +++ b/__init__.py @@ -0,0 +1,15 @@ +""" +PythonForPicam +========== + +@authors: Joe Lowney adapted by Joshua Stillerman (MIT) +@copyright: 2016 +@license: GNU GPL + + + +""" +from PiFunctions import * +from PiParameterLookup import * +from PiTypesMore import * +from PiTypes import * diff --git a/setup.py b/setup.py new file mode 100755 index 0000000..9f508fd --- /dev/null +++ b/setup.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python + +from setuptools import setup, Extension +version='0.3' +setup(name='PythonForPicam', + version=version, + description='Setup Tools version of PythonForPicam (Joe Lowney 2013)', + long_description = """ + PythonForPicam is a Python ctypes interface to the Princeton Instruments PICAM Library + Copyright (C) 2013 Joe Lowney. The copyright holder can be reached at joelowney@gmail.com + + This program is free software: you can redistribute it and/or modify it under the terms of + the GNU General Public License as published by the Free Software Foundation, either version 3 + of the License, or any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program. + If not, see http://www.gnu.org/licenses/. + """, + author='Joe Lowney,Josh Stillerman', + author_email='jas@psfc.mit.edu', + package_dir = {'PythonForPicam':'.',}, + include_package_data = False, + packages = ['PythonForPicam',], + platforms = ('Windows'), + url = 'https://github.com/joshStillerman/PythonForPicam', + classifiers = [ 'Development Status :: 4 - Beta', + 'Programming Language :: Python', + 'Intended Audience :: Science/Research', + 'Environment :: Console', + 'Topic :: Scientific/Engineering', + ], + keywords = ['princeton instruments','camera',], + install_requires=['numpy'], + zip_safe = False, + )