def load(self): self.clib = CLibrary(self.library_file, self.parser, prefix='Lib_', lock_calls=False, convention='cdll', backend='ctypes')
def init_drv(self): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.sigStatusMessage.emit('Loading driver...') try: drv_path = os.environ['ANDORSDK'] except KeyError: raise Exception('Camera driver not found. Check if envionment variable ANDORSDK exist') ANDOR_HEADER = os.path.join(drv_path, 'ATMCD32D.H') ANDOR_LIB = os.path.join(drv_path, 'atmcd32d.dll') ANDOR_CACHE = os.path.join(drv_path, 'ATMCD32D.cache') self.header = CParser([ANDOR_HEADER], cache=ANDOR_CACHE, macros={'WINAPI':''}) self.camera = CLibrary(ANDOR_LIB, self.header, convention='windll') self.DRV_SUCCESS = self.camera.DRV_SUCCESS self.values = dict((v, k) for k, v in self.header.defs['values'].items()) QApplication.restoreOverrideCursor()
class CasDll(object): def __init__(self, cache_path="cache", lib_path=None, header_path=None): if not header_path: header_path = r"C:\Program Files\Instrument Systems\CAS4x64-SDK\VC2013\CAS4.h" if not lib_path: lib_path = r"C:\Windows\System32\CAS4x64.dll" lib_name = Path(lib_path).name if cache_path: cache_name = lib_name + ".cache" cache_path_ = Path(cache_path) cache_path_.mkdir(parents=True, exist_ok=True) cache_file_path = str(cache_path_ / cache_name) else: cache_file_path = None self.parser = CParser( header_path, cache=cache_file_path, replace={"#define __callconv __stdcall": "#define __callconv"}) self.clib = CLibrary(lib_path, self.parser) def new_struct(self, name): class_ = getattr(self.clib, name) return class_() def has_function(self, name): try: self.clib._get_function(name) return True except KeyError: return False def check_cas4_error_code(self, code): if (code < self.clib.ErrorNoError): p = create_string_buffer(255) self.clib.casGetErrorMessageA(code, p, 255) raise Exception("CAS Spectrometer Error: {}, {}".format( str(code), p.value.decode())) def check_cas4_device_error(self, casid): self.check_cas4_error_code(self.clib.casGetError(casid).rval) def __getattr__(self, name): return getattr(self.clib, name)
def __init__(self, cache_path="cache", lib_path=None, header_path=None): if not header_path: header_path = r"C:\Program Files\Instrument Systems\CAS4x64-SDK\VC2013\CAS4.h" if not lib_path: lib_path = r"C:\Windows\System32\CAS4x64.dll" lib_name = Path(lib_path).name if cache_path: cache_name = lib_name + ".cache" cache_path_ = Path(cache_path) cache_path_.mkdir(parents=True, exist_ok=True) cache_file_path = str(cache_path_ / cache_name) else: cache_file_path = None self.parser = CParser( header_path, cache=cache_file_path, replace={"#define __callconv __stdcall": "#define __callconv"}) self.clib = CLibrary(lib_path, self.parser)
def _setup_library(self): """Load and initialize the dll. """ cache_path = str( os.path.join(os.path.dirname(__file__), 'adq14.pycctypes.libc')) library_dir = os.path.join(self._infos.get('lib_dir', ''), 'ADQAPI.dll') header_dir = os.path.join(self._infos.get('header_dir', ''), 'ADQAPI.h') self._dll = CLibrary(library_dir, [header_dir], cache=cache_path, prefix=['ADQ', 'ADQ_'], convention='cdll')
class AndorCamera(QObject): sigStatusMessage = pyqtSignal(str) sigAcquiredData = pyqtSignal(list) SETTING_SAVE = ['frameNumberSpinBox', 'frameTransferCheckBox', 'exposureTimeSpinBox', 'shutterComboBox', 'triggerComboBox', 'hbinSpinBox', 'vbinSpinBox', 'preAmplifySlider', 'temperatureSpinBox', 'EMGainCheckBox', 'EMGainSpinBox', 'verticalVoltageSpinBox', 'verticalSpeedSpinBox', 'horizontalVoltageSpinBox'] def __init__(self): super().__init__() self.lastTemp = None self.shot_mode = None self.frames_to_shot = 0 self.frame_number = 0 self.frames = [] self.progressBar = QProgressBar() self.progressBar.setEnabled(False) self.tempLabel = QLabel('OFF') self.toolbar = QToolBar('Camera') self.connectAction = QAction('Connect', self.toolbar, triggered=self.onConnect) self.toolbar.addAction(self.connectAction) self.settingsAction = QAction('Settings', self.toolbar, triggered=self.onSettings) self.settingsAction.setEnabled(False) self.toolbar.addAction(self.settingsAction) self.startAction = QAction('Start', self.toolbar, triggered=self.onStart) self.startAction.setEnabled(False) self.toolbar.addAction(self.startAction) self.camera = None self.flowchart = None self.settingDialog = CameraSettingDialog() self.settingDialog.setModal(True) self.settingDialog.accepted.connect(self.setCamera) self.settingDialog.verticalSpeedSpinBox.valueChanged.connect(self.onVerticalSpeedChanged) self.settingDialog.horizontalVoltageSpinBox.valueChanged.connect(self.onHorizontalSpeedChanged) self.settingDialog.EMGainCheckBox.toggled.connect(self.onEMGainChecked) self.acqTimer = QTimer() self.acqTimer.setSingleShot(False) self.acqTimer.setInterval(200) self.acqTimer.timeout.connect(self.updateProgress) self.tempTimer = QTimer() self.tempTimer.setSingleShot(False) self.tempTimer.setInterval(3000) self.tempTimer.timeout.connect(self.updateTemperature) def init_drv(self): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.sigStatusMessage.emit('Loading driver...') try: drv_path = os.environ['ANDORSDK'] except KeyError: raise Exception('Camera driver not found. Check if envionment variable ANDORSDK exist') ANDOR_HEADER = os.path.join(drv_path, 'ATMCD32D.H') ANDOR_LIB = os.path.join(drv_path, 'atmcd32d.dll') ANDOR_CACHE = os.path.join(drv_path, 'ATMCD32D.cache') self.header = CParser([ANDOR_HEADER], cache=ANDOR_CACHE, macros={'WINAPI':''}) self.camera = CLibrary(ANDOR_LIB, self.header, convention='windll') self.DRV_SUCCESS = self.camera.DRV_SUCCESS self.values = dict((v, k) for k, v in self.header.defs['values'].items()) QApplication.restoreOverrideCursor() def close_drv(self): if self.camera is not None: result = self.camera.ShutDown().rval def onConnect(self): if self.connectAction.text() == 'Connect': if self.camera is None: self.init_drv() QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.sigStatusMessage.emit('Connecting camera...') result = self.camera.Initialize('.').rval QApplication.restoreOverrideCursor() if result == self.DRV_SUCCESS: self.connectAction.setText('Disconnect') self.sigStatusMessage.emit('Connected') if self.settingDialog.EMGainCheckBox.isChecked(): self.ampl_type = 0 else: self.ampl_type = 1 result = self.camera.GetTemperatureRange() self.settingDialog.temperatureSpinBox.setRange(result['mintemp'], result['maxtemp']) self.settingDialog.temperatureSpinBox.setValue(result['maxtemp']) self.settingDialog.coolerCheckBox.setChecked(False) result = self.camera.GetEMGainRange() self.settingDialog.EMGainSpinBox.setRange(result['low'], result['high']) result = self.camera.GetNumberVSAmplitudes() self.settingDialog.verticalVoltageSpinBox.setRange(0, result['number']-1) result = self.camera.GetNumberVSSpeeds() self.settingDialog.verticalSpeedSpinBox.setRange(0, result['speeds']-1) value = self.settingDialog.verticalSpeedSpinBox.value() self.onVerticalSpeedChanged(value) result = self.camera.GetNumberHSSpeeds(0, self.ampl_type) value = self.settingDialog.horizontalVoltageSpinBox.value() self.onHorizontalSpeedChanged(value) self.settingDialog.horizontalVoltageSpinBox.setRange(0, result['speeds']-1) self.settingsAction.setEnabled(True) self.startAction.setEnabled(True) self.tempTimer.start() self.setCamera() else: self.sigStatusMessage.emit('Connection Error: %s(%d)' % (self.values[result], result)) elif self.connectAction.text() == 'Disconnect': self.tempTimer.stop() self.close_drv() self.connectAction.setText('Connect') self.settingsAction.setEnabled(False) self.startAction.setEnabled(False) self.sigStatusMessage.emit('Disconnected') def onEMGainChecked(self, checked): if checked: self.ampl_type = 0 self.settingDialog.EMGainSpinBox.setEnabled(True) else: self.ampl_type = 1 self.settingDialog.EMGainSpinBox.setEnabled(False) result = self.camera.GetNumberHSSpeeds(0, self.ampl_type) self.settingDialog.horizontalVoltageSpinBox.setRange(0, result['speeds']-1) value = self.settingDialog.horizontalVoltageSpinBox.value() self.onHorizontalSpeedChanged(value) def onVerticalSpeedChanged(self, value): result = self.camera.GetVSSpeed(value) self.settingDialog.verticalSpeedLabel.setText('%fMHz' % result['speed']) def onHorizontalSpeedChanged(self, value): result = self.camera.GetHSSpeed(0, self.ampl_type, value) self.settingDialog.horizontalSpeedLabel.setText('%fMHz' % result['speed']) def onSettings(self): self.settingDialog.show() def onStart(self): if self.startAction.text() == 'Start': self.connectAction.setEnabled(False) self.settingsAction.setEnabled(False) self.camera.FreeInternalMemory() self.startAction.setText('Stop') self.progressBar.setRange(0, self.settingDialog.frameNumberSpinBox.value()) self.progressBar.setValue(0) self.progressBar.setEnabled(True) self.camera.PrepareAcquisition() self.camera.StartAcquisition() self.frames_to_shot = self.frame_number self.frames = [] self.acqTimer.start() elif self.startAction.text() == 'Stop': self.connectAction.setEnabled(True) self.settingsAction.setEnabled(True) self.acqTimer.stop() self.camera.AbortAcquisition() self.progressBar.setEnabled(False) self.startAction.setText('Start') def updateProgress(self): status = self.camera.GetStatus()['status'] if self.shot_mode == 'Kinetics': if status == self.camera.DRV_IDLE: self.acquire(self.frame_number) self.sigAcquiredData.emit(list(self.frames)) self.frames = [] self.camera.StartAcquisition() elif status == self.camera.DRV_ACQUIRING: result = self.camera.GetAcquisitionProgress() self.progressBar.setValue(result['series']) else: self.sigStatusMessage.emit('Status Error: %s(%d)' % (self.values[status], status)) elif self.shot_mode == 'FastKinetics': if status == self.camera.DRV_IDLE: self.frames_to_shot -= 2 self.acquire(2) if self.frames_to_shot == 0: self.sigAcquiredData.emit(list(self.frames)) self.frames_to_shot = self.frame_number self.frames = [] self.camera.StartAcquisition() self.progressBar.setValue(self.frame_number - self.frames_to_shot) def updateTemperature(self): temp = self.camera.GetTemperature()['temperature'] self.tempLabel.setText('%d ℃' % temp) if self.lastTemp is not None: if temp > self.lastTemp: self.tempLabel.setStyleSheet("QLabel { background-color : red;}") elif temp < self.lastTemp: self.tempLabel.setStyleSheet("QLabel { background-color : blue;}") else: self.tempLabel.setStyleSheet("QLabel { background-color : green;}") self.lastTemp = temp def acquire(self, frame_number): result = self.camera.GetNumberAvailableImages() if result['first'] == 0 and result['last'] == 0: return hbin = self.settingDialog.hbinSpinBox.value() vbin = self.settingDialog.vbinSpinBox.value() height = int(512/vbin) width = int(512/hbin) # frame_number = self.frame_number size = height * width * frame_number data = np.empty(size, dtype=np.intc) self.camera.GetImages(result['first'], result['last'], data.ctypes.data_as(POINTER(c_long)), size) self.frames.extend([arr.reshape(width, height) for arr in np.split(data, frame_number)]) # def init_settingsui(self): # QML_FILENAME = os.path.join(os.path.dirname(__file__), 'CameraSettings.qml') # self.settingDialog = QQuickView() # self.settingDialog.setSource(QUrl.fromLocalFile(QML_FILENAME)) # self.settingDialog.setResizeMode(QQuickView.SizeRootObjectToView) # self.settings = self.settingDialog.rootObject() # # self.settings.okayClicked.connect(self.output) # okaybutton = self.settings.findChild(QQuickItem, 'Button') # okaybutton.onClicked.connect(self.output) def setCamera(self): hbin = self.settingDialog.hbinSpinBox.value() vbin = self.settingDialog.vbinSpinBox.value() exposureTime = ctypes.c_float(self.settingDialog.exposureTimeSpinBox.value()/1000.0) framenumber = self.settingDialog.frameNumberSpinBox.value() self.frame_number = framenumber if self.settingDialog.frameTransferCheckBox.isChecked(): self.shot_mode = 'FastKinetics' self.camera.SetAcquisitionMode(4) self.camera.SetFastKinetics(512, 2, exposureTime, 4, hbin, vbin) else: self.shot_mode = 'Kinetics' self.camera.SetAcquisitionMode(3) self.camera.SetImage(hbin, vbin, 1, 512, 1, 512) self.camera.SetExposureTime(exposureTime) self.camera.SetNumberKinetics(framenumber) trigger = self.settingDialog.triggerComboBox.currentText() trigger_dict = { 'Internal': 0, 'External': 1 } self.camera.SetTriggerMode(trigger_dict[trigger]) shutter = self.settingDialog.shutterComboBox.currentText() shutter_dict = { 'Auto': 0, 'Open': 1, 'Close': 2 } self.camera.SetShutter(1, shutter_dict[shutter], 27, 27) preamp = self.settingDialog.preAmplifySlider.value() self.camera.SetPreAmpGain(preamp) if self.settingDialog.coolerCheckBox.isChecked(): self.camera.CoolerON() self.camera.SetTemperature(self.settingDialog.temperatureSpinBox.value()) else: self.camera.CoolerOFF() if self.settingDialog.EMGainCheckBox.isChecked(): self.camera.SetEMCCDGain(self.settingDialog.EMGainSpinBox.value()) else: self.camera.SetEMCCDGain(0) vvoltage = self.settingDialog.verticalVoltageSpinBox.value() self.camera.SetVSAmplitude(vvoltage) vspeed = self.settingDialog.verticalSpeedSpinBox.value() self.camera.SetVSSpeed(vspeed) hspeed = self.settingDialog.horizontalVoltageSpinBox.value() self.camera.SetHSSpeed(self.ampl_type, hspeed) def close(self): self.close_drv() def saveState(self): state = {} for settingName in self.SETTING_SAVE: for k in stateFunc: if settingName.endswith(k): break else: raise Exception('Unknown setting type %s' % settingName) setting = getattr(self.settingDialog, settingName) state[settingName] = getattr(setting, stateFunc[k][0])() return state def restoreState(self, state): for settingName, settingState in state.items(): for k in stateFunc: if settingName.endswith(k): break else: raise Exception('Unknown setting type %s' % settingName) setting = getattr(self.settingDialog, settingName) getattr(setting, stateFunc[k][1])(settingState)
def _load_bifrost_lib(): import os import glob library_name = "libbifrost.so" api_prefix = "bf" header_paths = ["/usr/local/include/bifrost", "../src/bifrost"] # TODO: Remove this one? include_env = 'BIFROST_INCLUDE_PATH' # PYCLIBRARY ISSUE # TODO: Would it make sense to build this into PyCLibrary? library_env = 'LD_LIBRARY_PATH' home_dir = os.path.expanduser("~") parser_cache = os.path.join(home_dir, ".cache/bifrost.parse") def _get_env_paths(env): paths = os.getenv(env) if paths is None: return [] return [p for p in paths.split(':') if len(p.strip())] import pyclibrary from pyclibrary import CParser, CLibrary import ctypes # PYCLIBRARY ISSUE Should these be built in? Optional extra? # Note: This is needed because pyclibrary starts with only # the fundamental types (short, int, float etc.). #extra_types = {} #extra_types = {'uint64_t': ctypes.c_uint64} extra_types = { 'uint8_t': ctypes.c_uint8, 'int8_t': ctypes.c_int8, 'uint16_t': ctypes.c_uint16, 'int16_t': ctypes.c_int16, 'uint32_t': ctypes.c_uint32, 'int32_t': ctypes.c_int32, 'uint64_t': ctypes.c_uint64, 'int64_t': ctypes.c_int64, 'size_t': ctypes.c_ulong } try: pyclibrary.auto_init(extra_types=extra_types) except RuntimeError: pass # WAR for annoying "Can only initialise the parser once" header_paths = _get_env_paths(include_env) + header_paths valid_header_paths = [p for p in header_paths if os.path.exists(p)] # HACK TODO: Decide on what to do here valid_header_paths = valid_header_paths[:1] if len(valid_header_paths) == 0: raise ValueError( "No valid Bifrost header paths found. Run make install or set BIFROST_INCLUDE_PATH." ) header_path = valid_header_paths[0] headers = glob.glob(os.path.join(header_path, '*.h')) pyclibrary.utils.add_header_locations(valid_header_paths) try: _parser = CParser(headers, cache=unicode(parser_cache, "utf-8")) except AttributeError: # # PYCLIBRARY ISSUE WAR for "'tuple' has no attribute 'endswith'" bug raise ValueError("Could not find Bifrost headers.\nSearch paths: " + str(header_paths)) pyclibrary.utils.add_library_locations(_get_env_paths(library_env)) lib = CLibrary(library_name, _parser, prefix=api_prefix) return lib