Files
maliakal_d 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
Dev/ctb separate dac and power (#1420)
* 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
2026-04-15 10:33:01 +02:00

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