mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-04-23 00:04:37 +02:00
5ec5d46c48
Build and Deploy on local RHEL9 / build (push) Successful in 2m12s
Build on RHEL9 docker image / build (push) Successful in 3m33s
Build on RHEL8 docker image / build (push) Successful in 4m54s
Build and Deploy on local RHEL8 / build (push) Successful in 4m54s
Run Simulator Tests on local RHEL9 / build (push) Successful in 14m41s
Run Simulator Tests on local RHEL8 / build (push) Successful in 17m10s
* not allowing power names for dac names to prevent duplicate names * wip * v_abcd commands should be removed to prevent unintentional usage and throw with a suggestion command for dac and power * binary in * dacs with power dac names should work and do not take in dac units to avoid ambiguity, test with 0 value for power dacs should fail, to do: implement power commands * wip: power in client, tests, and fixed server interfaces and ctb implementation, not tested * wip. client and xilinx todo * wip: ctb power works, tests left * fixed some tests * added vchip check * python cmds still left. wip * fixed xilinx. python left * wip * wip. xilinx * fixed powerchip for ctb * power all returns all * configtransceiver is removed * wip python * wip * wip * wip * wip * wip * wip * wip xilinx * wip * wip * wip * pybindings * fix getdacindex and getdacname for normal detectors to throw if random index that doesnt fit to the detector * wip * fixed tests * fixes for python api * wip * python: moved powerlist to Ctb * fixed tests to work for powelist in Ctb * moved signallist, adclist, slowadc, slowadclist to Ctb * throw approperiate error when no modules added for powers * added dac test * fix dac default names and test for dacs * ctb dacs, yet to do othe rdacs * dacs should work now even in tests * run all tests * DetectorPowers->NamedPowers in ctb * comments * removed unnecessary test code * removed hard coded dac names in python NamedDacs and NamedPowers * minor * minor * fixed error messages * changed power to be able to set DAC directly, using enable and disable methods with enabled to get
192 lines
5.7 KiB
Python
Executable File
192 lines
5.7 KiB
Python
Executable File
# SPDX-License-Identifier: LGPL-3.0-or-other
|
|
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
|
from .detector_property import DetectorProperty
|
|
from functools import partial
|
|
import numpy as np
|
|
from . import _slsdet
|
|
from .detector import freeze
|
|
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
|
class Dac(DetectorProperty):
|
|
"""
|
|
This class represents a dac on the detector. One instance handles all
|
|
dacs with the same name for a multi detector instance.
|
|
|
|
.. note ::
|
|
|
|
This class is used to build up DetectorDacs and is in general
|
|
not directly accessed to the user.
|
|
|
|
|
|
"""
|
|
def __init__(self, name, enum, low, high, default, detector):
|
|
|
|
super().__init__(partial(detector.getDAC, enum, False),
|
|
lambda x, y : detector.setDAC(enum, x, False, y),
|
|
detector.size,
|
|
name)
|
|
|
|
self.min_value = low
|
|
self.max_value = high
|
|
self.default = default
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
"""String representation for a single dac in all modules"""
|
|
dacstr = ''.join([f'{item:5d}' for item in self.get()])
|
|
return f'{self.__name__:15s}:{dacstr}'
|
|
|
|
class NamedDacs:
|
|
"""
|
|
New implementation of the detector dacs. Used at the moment for
|
|
Ctb but should replace the old one for all detectors
|
|
"""
|
|
_direct_access = ['_detector', '_current']
|
|
|
|
def __init__(self, detector):
|
|
self._frozen = False
|
|
self._detector = detector
|
|
self._current = 0
|
|
self._frozen = True
|
|
|
|
@property
|
|
def _dacnames(self):
|
|
if self._detector.size() == 0:
|
|
raise RuntimeError("No modules added")
|
|
return [n.replace(" ", "") for n in self._detector.daclist]
|
|
|
|
def __getattr__(self, name):
|
|
if name in self._dacnames:
|
|
idx = self._dacnames.index(name)
|
|
return Dac(name, dacIndex(idx), 0, 4096, -100, self._detector)
|
|
raise AttributeError(f'Dac not found: {name}')
|
|
|
|
def __setattr__(self, name, value):
|
|
if name in ('_detector', '_current', '_frozen'):
|
|
super().__setattr__(name, value)
|
|
elif name in self._dacnames:
|
|
return getattr(self, name).__setitem__(slice(None, None, None), value)
|
|
else:
|
|
raise AttributeError(f'Dac not found: {name}')
|
|
|
|
def __next__(self):
|
|
if self._current >= len(self._dacnames):
|
|
self._current = 0
|
|
raise StopIteration
|
|
else:
|
|
self._current += 1
|
|
return getattr(self, self._dacnames[self._current-1])
|
|
|
|
def __iter__(self):
|
|
self._current = 0
|
|
return self
|
|
|
|
def __repr__(self):
|
|
r_str = ['========== DACS =========']
|
|
r_str += [repr(dac) for dac in self]
|
|
return '\n'.join(r_str)
|
|
def get_asarray(self):
|
|
"""
|
|
Read the dacs into a numpy array with dimensions [ndacs, nmodules]
|
|
"""
|
|
dac_array = np.zeros((len(self._dacnames), len(self._detector)))
|
|
for i, _d in enumerate(self):
|
|
dac_array[i,:] = _d[:]
|
|
return dac_array
|
|
|
|
def to_array(self):
|
|
return self.get_asarray()
|
|
|
|
def set_from_array(self, dac_array):
|
|
"""
|
|
Set the dacs from an numpy array with dac values. [ndacs, nmodules]
|
|
"""
|
|
dac_array = dac_array.astype(np.int)
|
|
for i, _d in enumerate(self):
|
|
_d[:] = dac_array[i]
|
|
|
|
def from_array(self, dac_array):
|
|
self.set_from_array(dac_array)
|
|
|
|
class DetectorDacs:
|
|
_dacs = []
|
|
_dacnames = [_d[0] for _d in _dacs]
|
|
_allowed_attr = ['_detector', '_current']
|
|
_frozen = False
|
|
|
|
def __init__(self, detector):
|
|
# We need to at least initially know which detector we are connected to
|
|
self._detector = detector
|
|
|
|
# Index to support iteration
|
|
self._current = 0
|
|
|
|
# Name the attributes?
|
|
for _d in self._dacs:
|
|
setattr(self, '_'+_d[0], Dac(*_d, detector))
|
|
|
|
self._frozen = True
|
|
|
|
def __getattr__(self, name):
|
|
return self.__getattribute__('_' + name)
|
|
|
|
@property
|
|
def dacnames(self):
|
|
return [_d[0] for _d in _dacs]
|
|
|
|
def __setattr__(self, name, value):
|
|
if name in self._dacnames:
|
|
return self.__getattribute__('_' + name).__setitem__(slice(None, None, None), value)
|
|
else:
|
|
if self._frozen == True and name not in self._allowed_attr:
|
|
raise AttributeError(f'Dac not found: {name}')
|
|
super().__setattr__(name, value)
|
|
|
|
|
|
def __next__(self):
|
|
if self._current >= len(self._dacs):
|
|
self._current = 0
|
|
raise StopIteration
|
|
else:
|
|
self._current += 1
|
|
return self.__getattr__(self._dacnames[self._current-1])
|
|
|
|
def __iter__(self):
|
|
return self
|
|
|
|
def __repr__(self):
|
|
r_str = ['========== DACS =========']
|
|
r_str += [repr(dac) for dac in self]
|
|
return '\n'.join(r_str)
|
|
|
|
def get_asarray(self):
|
|
"""
|
|
Read the dacs into a numpy array with dimensions [ndacs, nmodules]
|
|
"""
|
|
dac_array = np.zeros((len(self._dacs), len(self._detector)))
|
|
for i, _d in enumerate(self):
|
|
dac_array[i,:] = _d[:]
|
|
return dac_array
|
|
|
|
def to_array(self):
|
|
return self.get_asarray()
|
|
|
|
def set_from_array(self, dac_array):
|
|
"""
|
|
Set the dacs from an numpy array with dac values. [ndacs, nmodules]
|
|
"""
|
|
dac_array = dac_array.astype(np.int)
|
|
for i, _d in enumerate(self):
|
|
_d[:] = dac_array[i]
|
|
|
|
def from_array(self, dac_array):
|
|
self.set_from_array(dac_array)
|
|
|
|
def set_default(self):
|
|
"""
|
|
Set all dacs to their default values
|
|
"""
|
|
for _d in self:
|
|
_d[:] = _d.default
|
|
|