diff --git a/python/slsdet/ctb.py b/python/slsdet/ctb.py index f8893eb95..706060ef1 100644 --- a/python/slsdet/ctb.py +++ b/python/slsdet/ctb.py @@ -24,4 +24,13 @@ class Ctb(Detector): @property def powers(self): - return self._powers \ No newline at end of file + return self._powers + + + @property + def powerlist(self): + return self.getPowerNames() + + @powerlist.setter + def powerlist(self, value): + self.setPowerNames(value) \ No newline at end of file diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index 50d7cacea..3a0051e83 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -2044,17 +2044,6 @@ class Detector(CppDetectorApi): 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): @@ -2076,17 +2065,10 @@ 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.""" + """[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() diff --git a/python/slsdet/powers.py b/python/slsdet/powers.py index bdeacda53..b71ff655f 100755 --- a/python/slsdet/powers.py +++ b/python/slsdet/powers.py @@ -64,42 +64,39 @@ class DetectorPowers: """ List implementation of the all the power supplies with its names. """ - _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 - setattr(self, name, Power(name, powerIndex(i), 0, detector)) - self._frozen = True - def __setattr__(self, name, value): - if not getattr(self, "_frozen", False): - #durning init we need to be able to set up the class - super().__setattr__(name, value) + + @property + def _powernames(self): + # always get the latest list + if hasattr(self._detector, 'powerlist'): + return [n.replace(" ", "") for n in self._detector.powerlist] else: - #Later we restrict us to manipulate powers and a few fields - if name in self._direct_access or name == '_frozen': - super().__setattr__(name, value) - elif name in self._powernames: - raise AttributeError( - f"Cannot assign directly to power '{name}'. " - f"Use '{name}.dac = value' or '{name}.enable = value'" - ) - else: - raise AttributeError(f'Power not found: {name}') + return ["VA", "VB", "VC", "VD", "VIO"] + + 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 name in ("_detector", "_current", "_frozen"): + super().__setattr__(name, value) + elif name in self._powernames: + raise AttributeError( + f"Cannot assign directly to power '{name}'. " + f"Use '{name}.dac = value' or '{name}.enable = value'" + ) + else: + raise AttributeError(f'Power not found: {name}') def __next__(self): if self._current >= len(self._powernames): @@ -107,10 +104,11 @@ class DetectorPowers: 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): + self._current = 0 return self def __repr__(self): diff --git a/python/tests/test_det_api.py b/python/tests/test_det_api.py index c731c6d24..cbd787d41 100644 --- a/python/tests/test_det_api.py +++ b/python/tests/test_det_api.py @@ -483,12 +483,16 @@ def test_powers(session_simulator, request): prev_val_dac = d.getPowerDAC(powerIndex.V_POWER_A) prev_val = d.isPowerEnabled(powerIndex.V_POWER_A) + + from slsdet import Ctb + c = Ctb() + invalid_assignments = [ - (d.powers, "random", True), # set random power - (d.powers.VA, "random", True), # set random attribute of power - (d.powers.VA, "dac", "-100"), - (d.powers.VA, "dac", "-1"), - (d.powers.VA, "dac", "4096") + (c.powers, "random", True), # set random power + (c.powers.VA, "random", True), # set random attribute of power + (c.powers.VA, "dac", "-100"), + (c.powers.VA, "dac", "-1"), + (c.powers.VA, "dac", "4096") ] for obj, attr, value in invalid_assignments: @@ -496,32 +500,34 @@ def test_powers(session_simulator, request): setattr(obj, attr, value) with pytest.raises(Exception): - d.powers.VCHIP.dac + c.powers.VCHIP.dac - d.powers - d.powers.VA.dac = 1200 - assert d.powers.VA.dac == 1200 + c.powers + c.powers.VA.dac = 1200 + assert c.powers.VA.dac == 1200 - d.powers.VA.enable = True - assert d.powers.VA.enable == True + c.powers.VA.enable = True + assert c.powers.VA.enable == True - d.setPowerEnabled([powerIndex.V_POWER_B, powerIndex.V_POWER_C], True) - assert d.powers.VB.enable == True - assert d.powers.VC.enable == True + c.setPowerEnabled([powerIndex.V_POWER_B, powerIndex.V_POWER_C], True) + assert c.powers.VB.enable == True + assert c.powers.VC.enable == True - d.powers.VA.dac = 1500 - assert d.powers.VA.dac == 1500 + c.powers.VA.dac = 1500 + assert c.powers.VA.dac == 1500 - d.powers._powernames[1] = "v_named_b" - assert d.powers.v_named_b.enable == True + c.powerlist = ["VA", "m_VB", "VC", "VD", "VIO"] + assert c.powers.v_named_b.enable == True + + c.powerlist # restore previous value d.setPowerDAC(powerIndex.V_POWER_A, prev_val_dac) d.setPowerEnabled(powerIndex.V_POWER_A, prev_val) else: with pytest.raises(Exception) as exc_info: - d.v_limit + d.powerlist assert "not implemented" in str(exc_info.value) Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed") diff --git a/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp b/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp index 7b642d0af..fe9ee13fd 100644 --- a/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp +++ b/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp @@ -909,7 +909,7 @@ TEST_CASE("v_limit", "[.detectorintegration]") { det_type == defs::XILINX_CHIPTESTBOARD) { auto prev_val = det.getVoltageLimit(); auto prev_dac_val = det.getDAC(defs::DAC_0, false); - auto prev_power_dac_val = det.getPowerDAC(defs::V_POWER_A); + auto prev_power_dac_val = det.getPowerDAC(defs::V_POWER_A); REQUIRE_THROWS(caller.call("v_limit", {"1200", "mV"}, -1, PUT)); REQUIRE_THROWS(caller.call("v_limit", {"-100"}, -1, PUT));