mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-04-23 04:32:45 +02:00
Merge branch 'developer' into dev/ctb_clocks
This commit is contained in:
@@ -3,8 +3,8 @@
|
||||
# from .detector import Detector, DetectorError, free_shared_memory
|
||||
from .eiger import Eiger
|
||||
from .ctb import Ctb
|
||||
from .dacs import DetectorDacs, Dac
|
||||
from .powers import DetectorPowers, Power
|
||||
from .dacs import NamedDacs, DetectorDacs, Dac
|
||||
from .powers import NamedPowers, Power
|
||||
from .detector import Detector
|
||||
from .jungfrau import Jungfrau
|
||||
from .mythen3 import Mythen3
|
||||
|
||||
+68
-3
@@ -2,12 +2,15 @@
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
from .detector import Detector, freeze
|
||||
from .utils import element_if_equal
|
||||
from .dacs import DetectorDacs, NamedDacs
|
||||
from .powers import DetectorPowers, NamedPowers
|
||||
from .dacs import NamedDacs
|
||||
from .powers import NamedPowers
|
||||
from .proxy import SlowAdcProxy
|
||||
from . import _slsdet
|
||||
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
||||
from .detector_property import DetectorProperty
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
from .utils import element
|
||||
@freeze
|
||||
@@ -24,4 +27,66 @@ class Ctb(Detector):
|
||||
|
||||
@property
|
||||
def powers(self):
|
||||
return self._powers
|
||||
return self._powers
|
||||
|
||||
@property
|
||||
def powerlist(self):
|
||||
return self.getPowerNames()
|
||||
|
||||
@powerlist.setter
|
||||
def powerlist(self, value):
|
||||
self.setPowerNames(value)
|
||||
|
||||
|
||||
@property
|
||||
def adclist(self):
|
||||
return self.getAdcNames()
|
||||
|
||||
@adclist.setter
|
||||
def adclist(self, value):
|
||||
self.setAdcNames(value)
|
||||
|
||||
@property
|
||||
def signallist(self):
|
||||
return self.getSignalNames()
|
||||
|
||||
@signallist.setter
|
||||
def signallist(self, value):
|
||||
self.setSignalNames(value)
|
||||
|
||||
@property
|
||||
def slowadc(self):
|
||||
"""
|
||||
[Ctb] Slow ADC channel in uV of all channels or specific ones from 0-7.
|
||||
|
||||
Example
|
||||
-------
|
||||
>>> d.slowadc
|
||||
0: 0 uV
|
||||
1: 0 uV
|
||||
2: 0 uV
|
||||
3: 0 uV
|
||||
4: 0 uV
|
||||
5: 0 uV
|
||||
6: 0 uV
|
||||
7: 0 uV
|
||||
>>> d.slowadc[3]
|
||||
0
|
||||
"""
|
||||
return SlowAdcProxy(self)
|
||||
|
||||
@property
|
||||
def slowadclist(self):
|
||||
return self.getSlowADCNames()
|
||||
|
||||
@slowadclist.setter
|
||||
def slowadclist(self, value):
|
||||
self.setSlowADCNames(value)
|
||||
|
||||
@property
|
||||
def slowadcvalues(self):
|
||||
"""[Chiptestboard][Xilinx CTB] Gets the slow adc values for every slow adc for this detector."""
|
||||
return {
|
||||
slowadc.name.lower(): element_if_equal(np.array(self.getSlowADC(slowadc)))
|
||||
for slowadc in self.getSlowADCList()
|
||||
}
|
||||
|
||||
+20
-27
@@ -41,40 +41,33 @@ class NamedDacs:
|
||||
New implementation of the detector dacs. Used at the moment for
|
||||
Ctb but should replace the old one for all detectors
|
||||
"""
|
||||
_frozen = False
|
||||
_direct_access = ['_detector', '_current', '_dacnames']
|
||||
_direct_access = ['_detector', '_current']
|
||||
|
||||
def __init__(self, detector):
|
||||
self._frozen = False
|
||||
self._detector = detector
|
||||
self._current = 0
|
||||
|
||||
#only get the dacnames if we have modules attached
|
||||
if detector.size() == 0:
|
||||
self._dacnames = [f"dac{i}" for i in range(18)]
|
||||
else:
|
||||
self._dacnames = [n.replace(" ", "") for n in detector.getDacNames()]
|
||||
|
||||
# Populate the dacs
|
||||
for i,name in enumerate(self._dacnames):
|
||||
#name, enum, low, high, default, detector
|
||||
setattr(self, name, Dac(name, dacIndex(i), 0, 4000, 1000, detector))
|
||||
|
||||
self._frozen = True
|
||||
|
||||
# def __getattr__(self, name):
|
||||
# return self.__getattribute__('_' + name)
|
||||
@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 not self._frozen:
|
||||
#durning init we need to be able to set up the class
|
||||
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:
|
||||
#Later we restrict us to manipulate dacs and a few fields
|
||||
if name in self._direct_access:
|
||||
super().__setattr__(name, value)
|
||||
elif name in self._dacnames:
|
||||
return self.__getattribute__(name).__setitem__(slice(None, None, None), value)
|
||||
else:
|
||||
raise AttributeError(f'Dac not found: {name}')
|
||||
raise AttributeError(f'Dac not found: {name}')
|
||||
|
||||
def __next__(self):
|
||||
if self._current >= len(self._dacnames):
|
||||
@@ -82,10 +75,10 @@ class NamedDacs:
|
||||
raise StopIteration
|
||||
else:
|
||||
self._current += 1
|
||||
return self.__getattribute__(self._dacnames[self._current-1])
|
||||
# return self.__getattr__(self._dacnames[self._current-1])
|
||||
return getattr(self, self._dacnames[self._current-1])
|
||||
|
||||
def __iter__(self):
|
||||
self._current = 0
|
||||
return self
|
||||
|
||||
def __repr__(self):
|
||||
|
||||
+11
-152
@@ -10,6 +10,7 @@ runStatus = slsDetectorDefs.runStatus
|
||||
timingMode = slsDetectorDefs.timingMode
|
||||
speedLevel = slsDetectorDefs.speedLevel
|
||||
dacIndex = slsDetectorDefs.dacIndex
|
||||
powerIndex = slsDetectorDefs.powerIndex
|
||||
detectorType = slsDetectorDefs.detectorType
|
||||
streamingInterface = slsDetectorDefs.streamingInterface
|
||||
|
||||
@@ -20,7 +21,7 @@ from .utils import Geometry, to_geo, element, reduce_time, is_iterable, hostname
|
||||
from ._slsdet import xy, freeSharedMemory, getUserDetails
|
||||
from .gaincaps import Mythen3GainCapsWrapper
|
||||
from . import utils as ut
|
||||
from .proxy import JsonProxy, SlowAdcProxy, ClkDivProxy, MaxPhaseProxy, ClkFreqProxy, PatLoopProxy, PatNLoopProxy, PatWaitProxy, PatWaitTimeProxy
|
||||
from .proxy import JsonProxy, ClkDivProxy, MaxPhaseProxy, ClkFreqProxy, PatLoopProxy, PatNLoopProxy, PatWaitProxy, PatWaitTimeProxy
|
||||
from .registers import Register, Adc_register
|
||||
import datetime as dt
|
||||
|
||||
@@ -516,13 +517,12 @@ class Detector(CppDetectorApi):
|
||||
@element
|
||||
def powerchip(self):
|
||||
"""
|
||||
[Jungfrau][Moench][Mythen3][Gotthard2][Xilinx Ctb] Power the chip.
|
||||
[Jungfrau][Moench][Mythen3][Gotthard2] Power the chip.
|
||||
|
||||
Note
|
||||
----
|
||||
[Jungfrau][Moench] Default is disabled. Get will return power status. Can be off if temperature event occured (temperature over temp_threshold with temp_control enabled. Will configure chip (only chip v1.1).\n
|
||||
[Mythen3][Gotthard2] Default is 1. If module not connected or wrong module, powerchip will fail.
|
||||
[Xilinx Ctb] Default is 0. Also configures the chip if powered on.
|
||||
"""
|
||||
return self.getPowerChip()
|
||||
|
||||
@@ -1987,26 +1987,7 @@ class Detector(CppDetectorApi):
|
||||
return super().getBit(resolved)
|
||||
|
||||
|
||||
@property
|
||||
def slowadc(self):
|
||||
"""
|
||||
[Ctb] Slow ADC channel in uV of all channels or specific ones from 0-7.
|
||||
|
||||
Example
|
||||
-------
|
||||
>>> d.slowadc
|
||||
0: 0 uV
|
||||
1: 0 uV
|
||||
2: 0 uV
|
||||
3: 0 uV
|
||||
4: 0 uV
|
||||
5: 0 uV
|
||||
6: 0 uV
|
||||
7: 0 uV
|
||||
>>> d.slowadc[3]
|
||||
0
|
||||
"""
|
||||
return SlowAdcProxy(self)
|
||||
|
||||
|
||||
@property
|
||||
def daclist(self):
|
||||
@@ -2022,52 +2003,7 @@ class Detector(CppDetectorApi):
|
||||
def daclist(self, value):
|
||||
self.setDacNames(value)
|
||||
|
||||
@property
|
||||
def adclist(self):
|
||||
"""
|
||||
[Chiptestboard] List of names for every adc for this board. 32 adcs
|
||||
"""
|
||||
return self.getAdcNames()
|
||||
|
||||
@adclist.setter
|
||||
def adclist(self, value):
|
||||
self.setAdcNames(value)
|
||||
|
||||
@property
|
||||
def signallist(self):
|
||||
"""
|
||||
[Chiptestboard] List of names for every io signal for this board. 64 signals
|
||||
"""
|
||||
return self.getSignalNames()
|
||||
|
||||
@signallist.setter
|
||||
def signallist(self, value):
|
||||
self.setSignalNames(value)
|
||||
|
||||
@property
|
||||
def powerlist(self):
|
||||
"""
|
||||
[Chiptestboard] List of names for every power for this board. 5 power supply
|
||||
|
||||
"""
|
||||
return self.getPowerNames()
|
||||
|
||||
@powerlist.setter
|
||||
def powerlist(self, value):
|
||||
self.setPowerNames(value)
|
||||
|
||||
@property
|
||||
def slowadclist(self):
|
||||
"""
|
||||
[Chiptestboard] List of names for every slowadc for this board. 8 slowadc
|
||||
|
||||
"""
|
||||
return self.getSlowADCNames()
|
||||
|
||||
@slowadclist.setter
|
||||
def slowadclist(self, value):
|
||||
self.setSlowADCNames(value)
|
||||
|
||||
@property
|
||||
def dacvalues(self):
|
||||
"""Gets the dac values for every dac for this detector."""
|
||||
@@ -2076,21 +2012,6 @@ class Detector(CppDetectorApi):
|
||||
for dac in self.getDacList()
|
||||
}
|
||||
|
||||
@property
|
||||
def powervalues(self):
|
||||
"""[Chiptestboard] Gets the power values for every power for this detector."""
|
||||
return {
|
||||
power.name.lower(): element_if_equal(np.array(self.getPower(power)))
|
||||
for power in self.getPowerList()
|
||||
}
|
||||
|
||||
@property
|
||||
def slowadcvalues(self):
|
||||
"""[Chiptestboard] Gets the slow adc values for every slow adc for this detector."""
|
||||
return {
|
||||
slowadc.name.lower(): element_if_equal(np.array(self.getSlowADC(slowadc)))
|
||||
for slowadc in self.getSlowADCList()
|
||||
}
|
||||
|
||||
@property
|
||||
def timinglist(self):
|
||||
@@ -4189,77 +4110,15 @@ class Detector(CppDetectorApi):
|
||||
n = ut.merge_args(2, n)
|
||||
ut.set_using_dict(self.setPatternLoopCycles, *n)
|
||||
|
||||
@property
|
||||
@element
|
||||
def v_a(self):
|
||||
"""[Ctb][Xilinx Ctb] Power supply a in mV."""
|
||||
return self.getPower(dacIndex.V_POWER_A)
|
||||
|
||||
@v_a.setter
|
||||
def v_a(self, value):
|
||||
value = ut.merge_args(dacIndex.V_POWER_A, value)
|
||||
ut.set_using_dict(self.setPower, *value)
|
||||
|
||||
@property
|
||||
@element
|
||||
def v_b(self):
|
||||
"""[Ctb][Xilinx Ctb] Power supply b in mV."""
|
||||
return self.getPower(dacIndex.V_POWER_B)
|
||||
|
||||
@v_b.setter
|
||||
def v_b(self, value):
|
||||
value = ut.merge_args(dacIndex.V_POWER_B, value)
|
||||
ut.set_using_dict(self.setPower, *value)
|
||||
|
||||
@property
|
||||
@element
|
||||
def v_c(self):
|
||||
"""[Ctb][Xilinx Ctb] Power supply c in mV."""
|
||||
return self.getPower(dacIndex.V_POWER_C)
|
||||
|
||||
@v_c.setter
|
||||
def v_c(self, value):
|
||||
value = ut.merge_args(dacIndex.V_POWER_C, value)
|
||||
ut.set_using_dict(self.setPower, *value)
|
||||
|
||||
@property
|
||||
@element
|
||||
def v_d(self):
|
||||
"""[Ctb][Xilinx Ctb] Power supply d in mV."""
|
||||
return self.getPower(dacIndex.V_POWER_D)
|
||||
|
||||
@v_d.setter
|
||||
def v_d(self, value):
|
||||
value = ut.merge_args(dacIndex.V_POWER_D, value)
|
||||
ut.set_using_dict(self.setPower, *value)
|
||||
|
||||
@property
|
||||
@element
|
||||
def v_io(self):
|
||||
"""[Ctb][Xilinx Ctb] Power supply io in mV. Minimum 1200 mV.
|
||||
|
||||
Note
|
||||
----
|
||||
Must be the first power regulator to be set after fpga reset (on-board detector server start up).
|
||||
"""
|
||||
return self.getPower(dacIndex.V_POWER_IO)
|
||||
|
||||
@v_io.setter
|
||||
def v_io(self, value):
|
||||
value = ut.merge_args(dacIndex.V_POWER_IO, value)
|
||||
ut.set_using_dict(self.setPower, *value)
|
||||
|
||||
@property
|
||||
@element
|
||||
def v_limit(self):
|
||||
"""[Ctb][Xilinx Ctb] Soft limit for power supplies (ctb only) and DACS in mV."""
|
||||
return self.getPower(dacIndex.V_LIMIT)
|
||||
return self.getVoltageLimit()
|
||||
|
||||
@v_limit.setter
|
||||
def v_limit(self, value):
|
||||
value = ut.merge_args(dacIndex.V_LIMIT, value)
|
||||
ut.set_using_dict(self.setPower, *value)
|
||||
|
||||
ut.set_using_dict(self.setVoltageLimit, value)
|
||||
|
||||
@property
|
||||
@element
|
||||
@@ -4268,7 +4127,7 @@ class Detector(CppDetectorApi):
|
||||
|
||||
:setter: Not implemented
|
||||
"""
|
||||
return self.getMeasuredCurrent(dacIndex.I_POWER_A)
|
||||
return self.getMeasuredCurrent(powerIndex.I_POWER_A)
|
||||
|
||||
@property
|
||||
@element
|
||||
@@ -4277,7 +4136,7 @@ class Detector(CppDetectorApi):
|
||||
|
||||
:setter: Not implemented
|
||||
"""
|
||||
return self.getMeasuredCurrent(dacIndex.I_POWER_B)
|
||||
return self.getMeasuredCurrent(powerIndex.I_POWER_B)
|
||||
|
||||
@property
|
||||
@element
|
||||
@@ -4286,7 +4145,7 @@ class Detector(CppDetectorApi):
|
||||
|
||||
:setter: Not implemented
|
||||
"""
|
||||
return self.getMeasuredCurrent(dacIndex.I_POWER_C)
|
||||
return self.getMeasuredCurrent(powerIndex.I_POWER_C)
|
||||
|
||||
@property
|
||||
@element
|
||||
@@ -4295,7 +4154,7 @@ class Detector(CppDetectorApi):
|
||||
|
||||
:setter: Not implemented
|
||||
"""
|
||||
return self.getMeasuredCurrent(dacIndex.I_POWER_D)
|
||||
return self.getMeasuredCurrent(powerIndex.I_POWER_D)
|
||||
|
||||
@property
|
||||
@element
|
||||
@@ -4304,7 +4163,7 @@ class Detector(CppDetectorApi):
|
||||
|
||||
:setter: Not implemented
|
||||
"""
|
||||
return self.getMeasuredCurrent(dacIndex.I_POWER_IO)
|
||||
return self.getMeasuredCurrent(powerIndex.I_POWER_IO)
|
||||
|
||||
@property
|
||||
def clkphase(self):
|
||||
|
||||
+93
-145
@@ -1,77 +1,125 @@
|
||||
# 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 Power(DetectorProperty):
|
||||
powerIndex = _slsdet.slsDetectorDefs.powerIndex
|
||||
class Power:
|
||||
"""
|
||||
This class represents a power on the Chip Test Board. One instance handles all
|
||||
powers with the same name for a multi detector instance. (TODO: Not needed for CTB)
|
||||
This class represents a power supply on the Chip Test Board.
|
||||
|
||||
.. note ::
|
||||
|
||||
This class is used to build up DetectorPowers and is in general
|
||||
This class is used to build up NamedPowers and is in general
|
||||
not directly accessible to the user.
|
||||
|
||||
|
||||
"""
|
||||
_direct_access = ['_detector']
|
||||
|
||||
def __init__(self, name, enum, default, detector):
|
||||
|
||||
super().__init__(partial(detector.getPower, enum),
|
||||
lambda x, y : detector.setPower(enum, x, y),
|
||||
detector.size,
|
||||
name)
|
||||
|
||||
self._frozen = False
|
||||
self.__name__ = name
|
||||
self.enum = enum
|
||||
self.default = default
|
||||
self.detector = detector
|
||||
self._frozen = True
|
||||
|
||||
def enable(self):
|
||||
" Enable this power supply."
|
||||
self.detector.setPowerEnabled([self.enum], True)
|
||||
|
||||
def disable(self):
|
||||
" Disable this power supply."
|
||||
self.detector.setPowerEnabled([self.enum], False)
|
||||
|
||||
@property
|
||||
def dac(self):
|
||||
" Returns the dac value for this power supply in mV."
|
||||
return self.detector.getPowerDAC(self.enum)
|
||||
|
||||
@property
|
||||
def enabled(self):
|
||||
" Returns whether this power supply is enabled."
|
||||
return self.detector.isPowerEnabled(self.enum)
|
||||
|
||||
# prevent unknown attributes
|
||||
def __setattr__(self, name, value):
|
||||
if not getattr(self, "_frozen", False) or name in ("_frozen", "__name__", "enum", "default", "detector"):
|
||||
super().__setattr__(name, value)
|
||||
else:
|
||||
raise AttributeError(f"Cannot set attribute '{name}' on Power.")
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, Power):
|
||||
return (
|
||||
self.detector == other.detector and
|
||||
self.enum == other.enum
|
||||
)
|
||||
if isinstance(other, int):
|
||||
return self.dac == other
|
||||
return NotImplemented
|
||||
|
||||
def __repr__(self):
|
||||
"""String representation for a single power in all modules"""
|
||||
powerstr = ''.join([f'{item:5d}' for item in self.get()])
|
||||
return f'{self.__name__:15s}:{powerstr}'
|
||||
"String representation for a single power supply"
|
||||
return f'{self.__name__:15s}: {str(self.enabled):5s}, {self.dac:5d} mV'
|
||||
|
||||
|
||||
class NamedPowers:
|
||||
"""
|
||||
New implementation of the detector powers.
|
||||
List implementation of the all the power supplies with its names.
|
||||
d.powers gives you list of all powers with their DAC values and enables.
|
||||
|
||||
Example
|
||||
--------
|
||||
# print all powers with DAC and enables
|
||||
d.powers
|
||||
# set DAC or enables
|
||||
d.powers.VA = 1200
|
||||
d.powers.VA.enable()
|
||||
d.powers.VA.disable()
|
||||
# get
|
||||
d.powers.VA.enabled
|
||||
d.powers.VA.dac
|
||||
d.powers.VA # print both enabled and dac
|
||||
"""
|
||||
_frozen = False
|
||||
_direct_access = ['_detector', '_current', '_powernames']
|
||||
_direct_access = ['_detector', '_current']
|
||||
|
||||
def __init__(self, detector):
|
||||
self._frozen = False
|
||||
self._detector = detector
|
||||
self._current = 0
|
||||
|
||||
#only get the powernames if we have modules attached
|
||||
if detector.size() == 0:
|
||||
self._powernames = ["VA", "VB", "VC", "VD", "VIO"]
|
||||
else:
|
||||
self._powernames = [n.replace(" ", "") for n in detector.getPowerNames()]
|
||||
|
||||
# Populate the powers
|
||||
for i,name in enumerate(self._powernames):
|
||||
#name, enum, low, high, default, detector
|
||||
k = dacIndex(i + int(dacIndex.V_POWER_A))
|
||||
setattr(self, name, Power(name, k, 0, detector))
|
||||
|
||||
self._frozen = True
|
||||
|
||||
# def __getattr__(self, name):
|
||||
# return self.__getattribute__('_' + name)
|
||||
|
||||
@property
|
||||
def _powernames(self):
|
||||
if self._detector.size() == 0:
|
||||
raise RuntimeError("No modules added")
|
||||
# always get the latest list
|
||||
if hasattr(self._detector, 'powerlist'):
|
||||
return [n.replace(" ", "") for n in self._detector.powerlist]
|
||||
else:
|
||||
raise RuntimeError("Detector does not have powerlist attribute")
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name in self._powernames:
|
||||
idx = self._powernames.index(name)
|
||||
return Power(name, powerIndex(idx), 0, self._detector)
|
||||
raise AttributeError(f'Power not found: {name}')
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
if not self._frozen:
|
||||
#durning init we need to be able to set up the class
|
||||
if name in ("_detector", "_current", "_frozen"):
|
||||
super().__setattr__(name, value)
|
||||
else:
|
||||
#Later we restrict us to manipulate powers and a few fields
|
||||
if name in self._direct_access:
|
||||
super().__setattr__(name, value)
|
||||
elif name in self._powernames:
|
||||
return self.__getattribute__(name).__setitem__(slice(None, None), value)
|
||||
elif name in self._powernames:
|
||||
if isinstance(value, int):
|
||||
idx = self._powernames.index(name)
|
||||
self._detector.setPowerDAC(powerIndex(idx), value)
|
||||
else:
|
||||
raise AttributeError(f'Power not found: {name}')
|
||||
raise AttributeError(f"Can only set DAC (int) for '{name}' on Power.")
|
||||
else:
|
||||
raise AttributeError(f'Power not found: {name}')
|
||||
|
||||
def __next__(self):
|
||||
if self._current >= len(self._powernames):
|
||||
@@ -79,83 +127,11 @@ class NamedPowers:
|
||||
raise StopIteration
|
||||
else:
|
||||
self._current += 1
|
||||
return self.__getattribute__(self._powernames[self._current-1])
|
||||
return getattr(self, self._powernames[self._current-1])
|
||||
# return self.__getattr__(self._powernames[self._current-1])
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __repr__(self):
|
||||
r_str = ['========== POWERS =========']
|
||||
r_str += [repr(power) for power in self]
|
||||
return '\n'.join(r_str)
|
||||
def get_asarray(self):
|
||||
"""
|
||||
Read the powers into a numpy array with dimensions [npowers, nmodules]
|
||||
"""
|
||||
power_array = np.zeros((len(self._powernames), len(self._detector)))
|
||||
for i, _d in enumerate(self):
|
||||
power_array[i,:] = _d[:]
|
||||
return power_array
|
||||
|
||||
def to_array(self):
|
||||
return self.get_asarray()
|
||||
|
||||
def set_from_array(self, power_array):
|
||||
"""
|
||||
Set the power from an numpy array with power values. [npowers, nmodules]
|
||||
"""
|
||||
power_array = power_array.astype(np.int)
|
||||
for i, _d in enumerate(self):
|
||||
_d[:] = power_array[i]
|
||||
|
||||
def from_array(self, power_array):
|
||||
self.set_from_array(power_array)
|
||||
|
||||
class DetectorPowers:
|
||||
_powers = []
|
||||
_powernames = [_d[0] for _d in _powers]
|
||||
_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._powers:
|
||||
setattr(self, '_'+_d[0], Power(*_d, detector))
|
||||
|
||||
self._frozen = True
|
||||
|
||||
def __getattr__(self, name):
|
||||
return self.__getattribute__('_' + name)
|
||||
|
||||
@property
|
||||
def powernames(self):
|
||||
return [_d[0] for _d in _powers]
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
if name in self._powernames:
|
||||
return self.__getattribute__('_' + name).__setitem__(slice(None, None), value)
|
||||
else:
|
||||
if self._frozen == True and name not in self._allowed_attr:
|
||||
raise AttributeError(f'Power not found: {name}')
|
||||
super().__setattr__(name, value)
|
||||
|
||||
|
||||
def __next__(self):
|
||||
if self._current >= len(self._powers):
|
||||
self._current = 0
|
||||
raise StopIteration
|
||||
else:
|
||||
self._current += 1
|
||||
return self.__getattr__(self._powernames[self._current-1])
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __repr__(self):
|
||||
@@ -163,33 +139,5 @@ class DetectorPowers:
|
||||
r_str += [repr(power) for power in self]
|
||||
return '\n'.join(r_str)
|
||||
|
||||
def get_asarray(self):
|
||||
"""
|
||||
Read the powers into a numpy array with dimensions [npowers, nmodules]
|
||||
"""
|
||||
power_array = np.zeros((len(self._powers), len(self._detector)))
|
||||
for i, _d in enumerate(self):
|
||||
power_array[i,:] = _d[:]
|
||||
return power_array
|
||||
|
||||
def to_array(self):
|
||||
return self.get_asarray()
|
||||
|
||||
def set_from_array(self, power_array):
|
||||
"""
|
||||
Set the powers from an numpy array with power values. [npowers, nmodules]
|
||||
"""
|
||||
power_array = power_array.astype(np.int)
|
||||
for i, _d in enumerate(self):
|
||||
_d[:] = power_array[i]
|
||||
|
||||
def from_array(self, power_array):
|
||||
self.set_from_array(power_array)
|
||||
|
||||
def set_default(self):
|
||||
"""
|
||||
Set all powers to their default values
|
||||
"""
|
||||
for _d in self:
|
||||
_d[:] = _d.default
|
||||
|
||||
def __dir__(self):
|
||||
return super().__dir__() + self._powernames
|
||||
+40
-29
@@ -1549,21 +1549,46 @@ void init_det(py::module &m) {
|
||||
Detector::getSYNCClock,
|
||||
py::arg() = Positions{});
|
||||
CppDetectorApi.def("getPowerList",
|
||||
(std::vector<defs::dacIndex>(Detector::*)() const) &
|
||||
(std::vector<defs::powerIndex>(Detector::*)() const) &
|
||||
Detector::getPowerList);
|
||||
CppDetectorApi.def("getPowerDAC",
|
||||
(int (Detector::*)(defs::powerIndex) const) &
|
||||
Detector::getPowerDAC,
|
||||
py::arg());
|
||||
CppDetectorApi.def("setPowerDAC",
|
||||
(void (Detector::*)(defs::powerIndex, int)) &
|
||||
Detector::setPowerDAC,
|
||||
py::arg(), py::arg());
|
||||
CppDetectorApi.def("isPowerEnabled",
|
||||
(bool (Detector::*)(defs::powerIndex) const) &
|
||||
Detector::isPowerEnabled,
|
||||
py::arg());
|
||||
CppDetectorApi.def(
|
||||
"setPowerEnabled",
|
||||
(void (Detector::*)(const std::vector<defs::powerIndex> &, bool)) &
|
||||
Detector::setPowerEnabled,
|
||||
py::arg(), py::arg());
|
||||
CppDetectorApi.def("getMeasuredPower",
|
||||
(int (Detector::*)(defs::powerIndex) const) &
|
||||
Detector::getMeasuredPower,
|
||||
py::arg());
|
||||
CppDetectorApi.def("getMeasuredCurrent",
|
||||
(int (Detector::*)(defs::powerIndex) const) &
|
||||
Detector::getMeasuredCurrent,
|
||||
py::arg());
|
||||
CppDetectorApi.def("getVoltageLimit",
|
||||
(int (Detector::*)() const) & Detector::getVoltageLimit);
|
||||
CppDetectorApi.def(
|
||||
"setVoltageLimit",
|
||||
(void (Detector::*)(const int)) & Detector::setVoltageLimit, py::arg());
|
||||
CppDetectorApi.def("getSlowADCList",
|
||||
(std::vector<defs::dacIndex>(Detector::*)() const) &
|
||||
Detector::getSlowADCList);
|
||||
CppDetectorApi.def(
|
||||
"getPower",
|
||||
"getSlowADC",
|
||||
(Result<int>(Detector::*)(defs::dacIndex, sls::Positions) const) &
|
||||
Detector::getPower,
|
||||
Detector::getSlowADC,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def(
|
||||
"setPower",
|
||||
(void (Detector::*)(defs::dacIndex, int, sls::Positions)) &
|
||||
Detector::setPower,
|
||||
py::arg(), py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def("getADCVpp",
|
||||
(Result<int>(Detector::*)(bool, sls::Positions) const) &
|
||||
Detector::getADCVpp,
|
||||
@@ -1629,21 +1654,6 @@ void init_det(py::module &m) {
|
||||
(void (Detector::*)(int, sls::Positions)) &
|
||||
Detector::setDBITClock,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def(
|
||||
"getMeasuredPower",
|
||||
(Result<int>(Detector::*)(defs::dacIndex, sls::Positions) const) &
|
||||
Detector::getMeasuredPower,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def(
|
||||
"getMeasuredCurrent",
|
||||
(Result<int>(Detector::*)(defs::dacIndex, sls::Positions) const) &
|
||||
Detector::getMeasuredCurrent,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def(
|
||||
"getSlowADC",
|
||||
(Result<int>(Detector::*)(defs::dacIndex, sls::Positions) const) &
|
||||
Detector::getSlowADC,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def("getExternalSamplingSource",
|
||||
(Result<int>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getExternalSamplingSource,
|
||||
@@ -1766,18 +1776,19 @@ void init_det(py::module &m) {
|
||||
Detector::getPowerNames);
|
||||
CppDetectorApi.def(
|
||||
"getPowerIndex",
|
||||
(defs::dacIndex(Detector::*)(const std::string &) const) &
|
||||
(defs::powerIndex(Detector::*)(const std::string &) const) &
|
||||
Detector::getPowerIndex,
|
||||
py::arg());
|
||||
CppDetectorApi.def(
|
||||
"setPowerName",
|
||||
(void (Detector::*)(const defs::dacIndex, const std::string &)) &
|
||||
(void (Detector::*)(const defs::powerIndex, const std::string &)) &
|
||||
Detector::setPowerName,
|
||||
py::arg(), py::arg());
|
||||
CppDetectorApi.def("getPowerName",
|
||||
(std::string(Detector::*)(const defs::dacIndex) const) &
|
||||
Detector::getPowerName,
|
||||
py::arg());
|
||||
CppDetectorApi.def(
|
||||
"getPowerName",
|
||||
(std::string(Detector::*)(const defs::powerIndex) const) &
|
||||
Detector::getPowerName,
|
||||
py::arg());
|
||||
CppDetectorApi.def("setSlowADCNames",
|
||||
(void (Detector::*)(const std::vector<std::string>)) &
|
||||
Detector::setSlowADCNames,
|
||||
|
||||
+20
-12
@@ -29,6 +29,12 @@ void init_enums(py::module &m) {
|
||||
slsDetectorDefs::detectorType::XILINX_CHIPTESTBOARD)
|
||||
.export_values();
|
||||
|
||||
py::enum_<slsDetectorDefs::boolFormat>(Defs, "boolFormat")
|
||||
.value("TrueFalse", slsDetectorDefs::boolFormat::TrueFalse)
|
||||
.value("OnOff", slsDetectorDefs::boolFormat::OnOff)
|
||||
.value("OneZero", slsDetectorDefs::boolFormat::OneZero)
|
||||
.export_values();
|
||||
|
||||
py::enum_<slsDetectorDefs::runStatus>(Defs, "runStatus")
|
||||
.value("IDLE", slsDetectorDefs::runStatus::IDLE)
|
||||
.value("ERROR", slsDetectorDefs::runStatus::ERROR)
|
||||
@@ -175,18 +181,6 @@ void init_enums(py::module &m) {
|
||||
.value("TEMPERATURE_FPGA3",
|
||||
slsDetectorDefs::dacIndex::TEMPERATURE_FPGA3)
|
||||
.value("TRIMBIT_SCAN", slsDetectorDefs::dacIndex::TRIMBIT_SCAN)
|
||||
.value("V_POWER_A", slsDetectorDefs::dacIndex::V_POWER_A)
|
||||
.value("V_POWER_B", slsDetectorDefs::dacIndex::V_POWER_B)
|
||||
.value("V_POWER_C", slsDetectorDefs::dacIndex::V_POWER_C)
|
||||
.value("V_POWER_D", slsDetectorDefs::dacIndex::V_POWER_D)
|
||||
.value("V_POWER_IO", slsDetectorDefs::dacIndex::V_POWER_IO)
|
||||
.value("V_POWER_CHIP", slsDetectorDefs::dacIndex::V_POWER_CHIP)
|
||||
.value("I_POWER_A", slsDetectorDefs::dacIndex::I_POWER_A)
|
||||
.value("I_POWER_B", slsDetectorDefs::dacIndex::I_POWER_B)
|
||||
.value("I_POWER_C", slsDetectorDefs::dacIndex::I_POWER_C)
|
||||
.value("I_POWER_D", slsDetectorDefs::dacIndex::I_POWER_D)
|
||||
.value("I_POWER_IO", slsDetectorDefs::dacIndex::I_POWER_IO)
|
||||
.value("V_LIMIT", slsDetectorDefs::dacIndex::V_LIMIT)
|
||||
.value("SLOW_ADC0", slsDetectorDefs::dacIndex::SLOW_ADC0)
|
||||
.value("SLOW_ADC1", slsDetectorDefs::dacIndex::SLOW_ADC1)
|
||||
.value("SLOW_ADC2", slsDetectorDefs::dacIndex::SLOW_ADC2)
|
||||
@@ -198,6 +192,20 @@ void init_enums(py::module &m) {
|
||||
.value("SLOW_ADC_TEMP", slsDetectorDefs::dacIndex::SLOW_ADC_TEMP)
|
||||
.export_values();
|
||||
|
||||
py::enum_<slsDetectorDefs::powerIndex>(Defs, "powerIndex")
|
||||
.value("V_POWER_A", slsDetectorDefs::powerIndex::V_POWER_A)
|
||||
.value("V_POWER_B", slsDetectorDefs::powerIndex::V_POWER_B)
|
||||
.value("V_POWER_C", slsDetectorDefs::powerIndex::V_POWER_C)
|
||||
.value("V_POWER_D", slsDetectorDefs::powerIndex::V_POWER_D)
|
||||
.value("V_POWER_IO", slsDetectorDefs::powerIndex::V_POWER_IO)
|
||||
.value("V_POWER_CHIP", slsDetectorDefs::powerIndex::V_POWER_CHIP)
|
||||
.value("I_POWER_A", slsDetectorDefs::powerIndex::I_POWER_A)
|
||||
.value("I_POWER_B", slsDetectorDefs::powerIndex::I_POWER_B)
|
||||
.value("I_POWER_C", slsDetectorDefs::powerIndex::I_POWER_C)
|
||||
.value("I_POWER_D", slsDetectorDefs::powerIndex::I_POWER_D)
|
||||
.value("I_POWER_IO", slsDetectorDefs::powerIndex::I_POWER_IO)
|
||||
.export_values();
|
||||
|
||||
py::enum_<slsDetectorDefs::detectorSettings>(Defs, "detectorSettings")
|
||||
.value("STANDARD", slsDetectorDefs::detectorSettings::STANDARD)
|
||||
.value("FAST", slsDetectorDefs::detectorSettings::FAST)
|
||||
|
||||
@@ -394,3 +394,324 @@ def test_patternstart(session_simulator, request):
|
||||
assert "not implemented" in str(exc_info.value)
|
||||
|
||||
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
||||
|
||||
|
||||
@pytest.mark.detectorintegration
|
||||
def test_v_limit(session_simulator, request):
|
||||
"""Test v_limit."""
|
||||
det_type, num_interfaces, num_mods, d = session_simulator
|
||||
assert d is not None
|
||||
|
||||
if det_type in ['ctb', 'xilinx_ctb']:
|
||||
|
||||
# save previous value
|
||||
prev_val = d.getVoltageLimit()
|
||||
from slsdet import dacIndex, powerIndex
|
||||
prev_dac_val = d.getDAC(dacIndex.DAC_0, False)
|
||||
prev_power_dac_val = d.getPowerDAC(powerIndex.V_POWER_A)
|
||||
|
||||
with pytest.raises(Exception):
|
||||
d.v_limit = (1200, 'mV') #mV unit not supported, should be 'no unit'
|
||||
|
||||
with pytest.raises(Exception):
|
||||
d.v_limit = -100 # previously worked but not allowing now
|
||||
|
||||
# setting dac and power dac with no vlimit should work
|
||||
d.v_limit = 0
|
||||
assert d.v_limit == 0
|
||||
d.setDAC(dacIndex.DAC_0, 1200, True, [0])
|
||||
d.setPowerDAC(powerIndex.V_POWER_A, 1200)
|
||||
|
||||
# setting vlimit should throw setting values above vlimit
|
||||
d.v_limit = 1500
|
||||
assert d.v_limit == 1500
|
||||
|
||||
with pytest.raises(Exception):
|
||||
d.setDAC(dacIndex.DAC_0, 1501, True, [0])
|
||||
|
||||
with pytest.raises(Exception):
|
||||
d.setPowerDAC(powerIndex.V_POWER_A, 1501)
|
||||
|
||||
# setting dac and power dac below vlimit should still work
|
||||
d.setDAC(dacIndex.DAC_0, 1210, True, [0])
|
||||
d.setPowerDAC(powerIndex.V_POWER_A, 1210)
|
||||
|
||||
# restore previous value
|
||||
d.setVoltageLimit(prev_val)
|
||||
d.setPowerDAC(powerIndex.V_POWER_A, prev_power_dac_val)
|
||||
for i in range(len(d)):
|
||||
d.setDAC(dacIndex.DAC_0, prev_dac_val[i], False, [i])
|
||||
|
||||
else:
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
d.v_limit
|
||||
assert "not implemented" in str(exc_info.value)
|
||||
|
||||
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
||||
|
||||
|
||||
@pytest.mark.detectorintegration
|
||||
def test_v_abcd(session_simulator, request):
|
||||
"""Test v_a, v_b, v_c, v_d, v_io are deprecated comands."""
|
||||
det_type, num_interfaces, num_mods, d = session_simulator
|
||||
assert d is not None
|
||||
|
||||
|
||||
with pytest.raises(Exception):
|
||||
d.v_a
|
||||
|
||||
with pytest.raises(Exception):
|
||||
d.v_b
|
||||
|
||||
with pytest.raises(Exception):
|
||||
d.v_c
|
||||
|
||||
with pytest.raises(Exception):
|
||||
d.v_d
|
||||
|
||||
with pytest.raises(Exception):
|
||||
d.v_io
|
||||
|
||||
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
||||
|
||||
|
||||
|
||||
@pytest.mark.detectorintegration
|
||||
def test_powers(session_simulator, request):
|
||||
"""Test powers and powerlist."""
|
||||
det_type, num_interfaces, num_mods, d = session_simulator
|
||||
assert d is not None
|
||||
|
||||
from slsdet import Ctb
|
||||
c = Ctb()
|
||||
|
||||
if det_type in ['ctb', 'xilinx_ctb']:
|
||||
|
||||
c.powerlist
|
||||
|
||||
# save previous value
|
||||
from slsdet import powerIndex
|
||||
prev_val_dac = {power: c.getPowerDAC(power) for power in c.getPowerList()}
|
||||
prev_val = {power: c.isPowerEnabled(power) for power in c.getPowerList()}
|
||||
|
||||
# invalid
|
||||
invalid_assignments = [
|
||||
(c.powers, "random", True), # set random power
|
||||
(c.powers, "random", True), # set random attribute of power
|
||||
(c.powers.VA, "dac", "1200"),
|
||||
(c.powers.VA, "enabled", "True"),
|
||||
(c.powers, "VA", "-100"),
|
||||
(c.powers, "VA", "-1"),
|
||||
(c.powers, "VA", "4096")
|
||||
]
|
||||
for obj, attr, value in invalid_assignments:
|
||||
with pytest.raises(Exception):
|
||||
setattr(obj, attr, value)
|
||||
# vchip power can only be accessed via pybindings because it cannot be enabled/disabled
|
||||
with pytest.raises(Exception):
|
||||
c.powers.VCHIP
|
||||
|
||||
# valid
|
||||
c.powers
|
||||
c.powers.VA = 1200
|
||||
assert c.powers.VA == 1200
|
||||
assert c.powers.VA.dac == 1200
|
||||
|
||||
c.powers.VA.enable()
|
||||
assert c.powers.VA.enabled == True
|
||||
|
||||
c.setPowerEnabled([powerIndex.V_POWER_B, powerIndex.V_POWER_C], True)
|
||||
assert c.powers.VB.enabled == True
|
||||
assert c.powers.VC.enabled == True
|
||||
|
||||
c.powers.VA = 1500
|
||||
assert c.powers.VA == 1500
|
||||
assert c.powers.VA.dac == 1500
|
||||
|
||||
# change power name and test same value
|
||||
temp = c.powers.VB
|
||||
c.powerlist = ["VA", "m_VB", "VC", "VD", "VIO"]
|
||||
assert c.powers.m_VB.enabled == True
|
||||
assert c.powers.m_VB == temp
|
||||
|
||||
# restore previous value
|
||||
for power in c.getPowerList():
|
||||
c.setPowerDAC(power, prev_val_dac[power])
|
||||
c.setPowerEnabled([power], prev_val[power])
|
||||
else:
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
c.powerlist
|
||||
assert "only for CTB" in str(exc_info.value)
|
||||
|
||||
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
||||
|
||||
|
||||
@pytest.mark.detectorintegration
|
||||
def test_adclist(session_simulator, request):
|
||||
"""Test ADC list."""
|
||||
det_type, num_interfaces, num_mods, d = session_simulator
|
||||
assert d is not None
|
||||
|
||||
from slsdet import Ctb
|
||||
c = Ctb()
|
||||
|
||||
if det_type in ['ctb', 'xilinx_ctb']:
|
||||
c.adclist
|
||||
c.adclist = ["1", "2", "3", "test", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32"]
|
||||
c.adclist
|
||||
|
||||
else:
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
c.adclist
|
||||
assert "only for CTB" in str(exc_info.value)
|
||||
|
||||
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
||||
|
||||
|
||||
@pytest.mark.detectorintegration
|
||||
def test_signallist(session_simulator, request):
|
||||
"""Test signal list."""
|
||||
det_type, num_interfaces, num_mods, d = session_simulator
|
||||
assert d is not None
|
||||
|
||||
from slsdet import Ctb
|
||||
c = Ctb()
|
||||
|
||||
if det_type in ['ctb', 'xilinx_ctb']:
|
||||
c.signallist
|
||||
c.signallist = ["1", "2", "3", "test", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64"]
|
||||
c.signallist
|
||||
|
||||
else:
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
c.signallist
|
||||
assert "only for CTB" in str(exc_info.value)
|
||||
|
||||
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
||||
|
||||
|
||||
@pytest.mark.detectorintegration
|
||||
def test_slowadc(session_simulator, request):
|
||||
"""Test slow ADC and slow adc list."""
|
||||
det_type, num_interfaces, num_mods, d = session_simulator
|
||||
assert d is not None
|
||||
|
||||
from slsdet import Ctb
|
||||
c = Ctb()
|
||||
|
||||
if det_type in ['ctb', 'xilinx_ctb']:
|
||||
c.slowadc
|
||||
c.slowadc.SLOWADC5
|
||||
c.slowadclist = ["1", "2", "3", "test", "5", "6", "7", "8"]
|
||||
c.slowadc.test
|
||||
|
||||
else:
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
c.signallist
|
||||
assert "only for CTB" in str(exc_info.value)
|
||||
|
||||
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
||||
|
||||
|
||||
|
||||
|
||||
@pytest.mark.detectorintegration
|
||||
def test_dac(session_simulator, request):
|
||||
"""Test dac."""
|
||||
det_type, num_interfaces, num_mods, d = session_simulator
|
||||
assert d is not None
|
||||
from slsdet import dacIndex
|
||||
|
||||
if det_type in ['ctb', 'xilinx_ctb']:
|
||||
|
||||
from slsdet import Ctb
|
||||
c = Ctb()
|
||||
|
||||
# valid
|
||||
c.daclist
|
||||
c.dacvalues
|
||||
|
||||
# save previous value
|
||||
prev_val = {dac: c.getDAC(dac, False) for dac in c.getDacList()}
|
||||
prev_dac_list = c.daclist
|
||||
|
||||
# invalid
|
||||
invalid_assignments = [
|
||||
(c.dacs, "vb_comp", "1200"), # set random dac
|
||||
(c.dacs, "DAC18", "1200"), # set dac 18
|
||||
(c.dacs, "DAC0", "-1"),
|
||||
(c.dacs, "DAC0", "4096")
|
||||
]
|
||||
for obj, attr, value in invalid_assignments:
|
||||
with pytest.raises(Exception):
|
||||
setattr(obj, attr, value)
|
||||
|
||||
# valid
|
||||
c.dacs.DAC0 = 1200
|
||||
assert c.getDAC(dacIndex.DAC_0, False)[0] == 1200
|
||||
|
||||
c.dacs.DAC0 = 0
|
||||
assert c.dacs.DAC0[0] == 0
|
||||
|
||||
# restore previous value
|
||||
for dac in c.getDacList():
|
||||
c.setDAC(dac, prev_val[dac][0], False)
|
||||
c.daclist = prev_dac_list
|
||||
|
||||
else:
|
||||
with pytest.raises(Exception):
|
||||
d.dacs.DAC0
|
||||
|
||||
# valid
|
||||
d.daclist
|
||||
d.dacvalues
|
||||
|
||||
# remember first dac name and index to test later
|
||||
dacname = d.daclist[0]
|
||||
assert dacname
|
||||
dacIndex = d.getDacList()[0]
|
||||
|
||||
# save previous value
|
||||
prev_val = d.getDAC(dacIndex, False)
|
||||
|
||||
if det_type == 'eiger':
|
||||
from slsdet import Eiger
|
||||
c = Eiger()
|
||||
elif det_type == 'jungfrau':
|
||||
from slsdet import Jungfrau
|
||||
c = Jungfrau()
|
||||
elif det_type == 'gotthard2':
|
||||
from slsdet import Gotthard2
|
||||
c = Gotthard2()
|
||||
elif det_type == 'mythen3':
|
||||
from slsdet import Mythen3
|
||||
c = Mythen3()
|
||||
elif det_type == 'moench':
|
||||
from slsdet import Moench
|
||||
c = Moench()
|
||||
else:
|
||||
raise RuntimeError("Unknown detector type to test dac: " + det_type)
|
||||
# invalid checks
|
||||
invalid_assignments = [
|
||||
(c.dacs, "random", "1200"), # set random dac
|
||||
(c.dacs, "DAC0", "1200"), # set random dac
|
||||
(c.dacs, dacname, "-1"),
|
||||
(c.dacs, dacname, "4096")
|
||||
]
|
||||
for obj, attr, value in invalid_assignments:
|
||||
with pytest.raises(Exception):
|
||||
setattr(obj, attr, value)
|
||||
|
||||
# valid, have to use setattr because c is different for each detector
|
||||
# and we cannot hardcode the dac name
|
||||
setattr(c.dacs, dacname, 1200)
|
||||
assert c.getDAC(dacIndex, False)[0] == 1200
|
||||
setattr(c.dacs, dacname, 0)
|
||||
assert getattr(c.dacs, dacname)[0] == 0
|
||||
|
||||
# restore previous value
|
||||
for i in range(len(d)):
|
||||
d.setDAC(dacIndex, prev_val[i], False, [i])
|
||||
|
||||
|
||||
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
||||
|
||||
Reference in New Issue
Block a user