Source code for qcodes_contrib_drivers.drivers.Horiba.private.fhr_server

from __future__ import annotations

import logging
from pathlib import Path
from typing import Tuple

from msl.loadlib import Server32

try:
    import ctypes.wintypes
except ImportError:
    import ctypes
    from types import ModuleType

    ctypes.wintypes = ModuleType('wintypes')
    ctypes.wintypes.DWORD = ctypes.c_ulong

LOG = logging.getLogger(__name__)


# Uncomment the line below to log (cannot control the logger from the
# client since the server runs on a different executable).
# logging.basicConfig(filename='path/to/log', level=logging.DEBUG)


[docs] class FHRServer(Server32): class _SpeSetup(ctypes.Structure): _fields_ = [('Size', ctypes.wintypes.DWORD), ('MinSpeed', ctypes.c_int), ('MaxSpeed', ctypes.c_int), ('Ramp', ctypes.c_int), ('Backlash', ctypes.c_int), ('Step', ctypes.c_int), ('Revers', ctypes.c_int)] class _SpeIniParams(ctypes.Structure): _fields_ = [('Size', ctypes.wintypes.DWORD), ('Phase', ctypes.c_int), ('MinSpeed', ctypes.c_int), ('MaxSpeed', ctypes.c_int), ('Ramp', ctypes.c_int)] def __init__(self, host, port, dll_dir='', filename='SpeControl'): path = str(Path(dll_dir, filename).with_suffix('.dll')) LOG.info('Initializing FHRServer.') LOG.debug(f'host = {host}') LOG.debug(f'port = {port}') LOG.debug(f'path = {path}') super().__init__(path, 'cdll', host, port)
[docs] def CreateSpe(self) -> int: """Create new spectrometer handle.""" LOG.info('Creating spe handle.') return self.lib.CreateSpe()
[docs] def DeleteSpe(self, h_spe: int): """Delete spectrometer handle h_spe.""" hSpe = ctypes.c_int(h_spe) LOG.info(f'Deleting spe handle {hSpe}.') self.lib.DeleteSpe(hSpe)
[docs] def SpeCommand( self, h_spe: int, a_dsp: str, a_fun: str, aPar: _SpeSetup | _SpeIniParams | ctypes.c_int | None = None ) -> Tuple[int, int | None]: """Send command (execute a function) named "a_fun" for the function dispatcher named "a_dsp" for the spectrometer handled "h_spe". "a_par" is a pointer to the function parameters.""" hSpe = ctypes.c_int(h_spe) aDsp = ctypes.c_char_p(a_dsp.encode()) aFun = ctypes.c_char_p(a_fun.encode()) LOG.info('Calling SpeCommand.') LOG.debug(f'hSpe = {hSpe}') LOG.debug(f'aDsp = {aDsp}') LOG.debug(f'aFun = {aFun}') LOG.debug(f'aPar = {aPar}') code = self.lib.SpeCommand( hSpe, aDsp, aFun, ctypes.byref(aPar) if aPar is not None else None ) if isinstance(aPar, ctypes._SimpleCData): return code, aPar.value return code, None
[docs] def SpeCommandSetup(self, h_spe: int, a_dsp: str, fields: Tuple[int, ...]) -> Tuple[int, int | None]: """Send command to set up a motor. Need to treat this separately since the SpeSetup structure must be defined in the 32-bit module. Otherwise, the 32-bit executable would need to know about qcodes_contrib_drivers. """ setup = self._SpeSetup(28, *fields) return self.SpeCommand(h_spe, a_dsp, 'SetSetup', setup)
[docs] def SpeCommandIniParams(self, h_spe: int, a_dsp: str, fields: Tuple[int, ...]) -> Tuple[int, int | None]: """Send command to initialize a grating motor. Need to treat this separately since the SpeIniParams structure must be defined in the 32-bit module. Otherwise, the 32-bit executable would need to know about qcodes_contrib_drivers. """ iniParams = self._SpeIniParams(20, *fields) return self.SpeCommand(h_spe, a_dsp, 'SetIniParams', iniParams)