mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-05-08 07:32:04 +02:00
0837de2a5a
* round CTB clocks to next closest possible value, added freq measurement * added time for firmware to measrue actual value after frequency change * add check for backwards compatibility * change CTB and XCTB clock values to MHz, TODO: units and validation errors * changed runclk command to use units and float, TODO: dbit, adcclk, why is everything called StringTo ? * do the same for dbit and adcclk * added tolerance to exptime, fixed test * update default values in server defs * added virtual check in Altera_PLL, update testcases * change python and pyctbgui to accept and return floating point MHz * update help and comments * Dev/ctb clocks fix (#1434) * introduced new type Hz, typetraits, String conversions, command generation (not yet generated) * incorrect unit typo * cmd generation and compiles * default to MHz, removed space between units for consistency with timers, min and max checks for clks * in python, but need to change the default to Hz again for clean code and intuition * allow ints, doubles, implicit conversions * dont allow raw ints, doubles and implicit conversions * fixed tests * added operators for Hz in python * fix test for min clk for xilinx ctb * fix test * fix python tests * fixed xilinx period and default clks * test fix * removed the 3 clock cycle check for ctb and implemented properly the max adc clk frq for altera ctb * removing 3 clock cycle code from xilinx as well * formatting * loadpattern before 3 clk cycles code * actualtime and measurement time to be implemented in 100ns already in fw * fix tests * pyzmq dependency forthe tests * fixed pyctbgui for freq * insert tolerance check again * also added tolerance check for patwaittime * formatting * minor: rounding test * removed Rep redundant in ToString for freq * intro frequency unit enums, removed unnecessary template behavior for ToString with freq unit, switching from parsing string unit argument to the enum argument for ToString, adding parsing string to unit at CLI boundary * minor, and binaries * minor, default clk vals are 0 but set up at detector setup * get frequency only for that unit * tolerance process * missed in previous commit * some more changes to exptime and validations * ctb is probably done * periodleft and delayleft * fixed xilinx freq conv as well * fixed m3 bug, binaries * xilinx: setup also done in stop server so that the clk is not 0 * missed a test marker * binaries in * review fixes, simpler validation of timers in ctb and xilinx ctb * typo fix * format * fix tests --------- Co-authored-by: Martin Mueller <martin.mueller@psi.ch> Co-authored-by: Dhanya Thattil <dhanya.thattil@psi.ch>
906 lines
29 KiB
Python
906 lines
29 KiB
Python
import pytest, sys, traceback
|
|
|
|
from pathlib import Path
|
|
current_dir = Path(__file__).resolve().parents[2]
|
|
scripts_dir = current_dir / "tests" / "scripts"
|
|
sys.path.append(str(scripts_dir))
|
|
print(sys.path)
|
|
|
|
from utils_for_test import (
|
|
Log,
|
|
LogLevel,
|
|
)
|
|
from slsdet import Detector
|
|
|
|
|
|
|
|
@pytest.mark.detectorintegration
|
|
def test_define_reg(session_simulator, request):
|
|
""" Test setting define_reg for ctb and xilinx_ctb."""
|
|
det_type, num_interfaces, num_mods, d = session_simulator
|
|
assert d is not None
|
|
|
|
from slsdet import RegisterAddress
|
|
|
|
if det_type in ['ctb', 'xilinx_ctb']:
|
|
prev_reg_defs = d.getRegisterDefinitions()
|
|
prev_bit_defs = d.getBitDefinitions()
|
|
d.clearRegisterDefinitions()
|
|
d.clearBitDefinitions()
|
|
|
|
addr1 = RegisterAddress(0x201)
|
|
addr2 = RegisterAddress(0x202)
|
|
d.define_reg(name="test_reg", addr=RegisterAddress(0x200)) # valid
|
|
d.define_reg(name="test_reg", addr=addr1) # takes a register address
|
|
d.define_reg(name="test_reg2", addr=0x202) # takes an int
|
|
|
|
# not using keyword arguments
|
|
with pytest.raises(TypeError) as exc_info:
|
|
d.define_reg("randomreg", 0x203)
|
|
|
|
# invalid value type
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.define_reg(name="test_reg3", addr='0x203')
|
|
assert "addr must int or RegisterAddress" in str(exc_info.value)
|
|
|
|
# defining with duplicate value
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.define_reg(name="test_reg3", addr=addr1)
|
|
assert "Value already assigned" in str(exc_info.value)
|
|
|
|
assert(d.getRegisterAddress("test_reg") == addr1)
|
|
assert(d.getRegisterName(addr1) == "test_reg")
|
|
|
|
# accessing non existent reg name
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.reg['random_reg']
|
|
assert "No entry found for key" in str(exc_info.value)
|
|
|
|
# get non existing reg address
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.getRegisterName(RegisterAddress(0x300))
|
|
assert "No entry found for value" in str(exc_info.value)
|
|
|
|
d.clearRegisterDefinitions()
|
|
|
|
d.setRegisterDefinitions(prev_reg_defs)
|
|
d.setBitDefinitions(prev_bit_defs)
|
|
|
|
else:
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.define_reg(name="test_reg", addr=0x201)
|
|
assert "Register Definitions only for CTB" in str(exc_info.value)
|
|
|
|
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
|
|
|
|
|
@pytest.mark.detectorintegration
|
|
def test_define_bit(session_simulator, request):
|
|
""" Test setting define_bit for ctb and xilinx_ctb."""
|
|
det_type, num_interfaces, num_mods, d = session_simulator
|
|
assert d is not None
|
|
|
|
from slsdet import RegisterAddress, BitAddress
|
|
|
|
if det_type in ['ctb', 'xilinx_ctb']:
|
|
prev_reg_defs = d.getRegisterDefinitions()
|
|
prev_bit_defs = d.getBitDefinitions()
|
|
d.clearRegisterDefinitions()
|
|
d.clearBitDefinitions()
|
|
|
|
addr1 = RegisterAddress(0x201)
|
|
addr2 = RegisterAddress(0x202)
|
|
d.define_reg(name="test_reg1", addr=addr1)
|
|
d.define_reg(name="test_reg2", addr=addr2)
|
|
|
|
# not using keyword arguments
|
|
with pytest.raises(TypeError) as exc_info:
|
|
d.define_bit("randombit", 0x203, 1)
|
|
|
|
# invalid value type (bit=string)
|
|
with pytest.raises(ValueError) as exc_info:
|
|
d.define_bit(name="test_bit1", addr='test_reg1', bit_position='1')
|
|
|
|
# invalid bit_position
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.define_bit(name="test_bit1", addr='test_reg1', bit_position=32)
|
|
assert "Bit position must be between 0 and 31" in str(exc_info.value)
|
|
|
|
# defining with random reg value
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.define_bit(name='test_bit1', addr='random_reg', bit_position=1)
|
|
assert "No entry found for key" in str(exc_info.value)
|
|
|
|
bit1 = BitAddress(addr1, 2)
|
|
bit2 = BitAddress(addr1, 4)
|
|
bit3 = BitAddress(addr2, 3)
|
|
|
|
# defining bit address with bit_position as well
|
|
with pytest.raises(ValueError) as exc_info:
|
|
d.define_bit(name='test_bit1', addr=bit1, bit_position=1)
|
|
assert "bit_position must be None" in str(exc_info.value)
|
|
|
|
|
|
d.define_bit(name="test_bit1", addr='test_reg2', bit_position=1)
|
|
d.define_bit(name="test_bit1", addr='test_reg1', bit_position=1) # modify reg
|
|
d.define_bit(name='test_bit1', addr=bit1) # modify pos
|
|
d.define_bit(name="test_bit2", addr=0x201, bit_position=4) # int addr
|
|
d.define_bit(name="test_bit3", addr=addr2, bit_position=3) # RegisterAddress addr
|
|
|
|
|
|
assert(d.getBitAddress('test_bit1') == bit1)
|
|
assert(d.getBitAddress('test_bit2') == bit2)
|
|
assert(d.getBitAddress('test_bit3') == bit3)
|
|
assert(d.getBitAddress('test_bit1').address() == addr1)
|
|
assert(d.getBitAddress('test_bit1').bitPosition() == 2)
|
|
assert(d.getBitAddress('test_bit2') == BitAddress(addr1, 4))
|
|
|
|
assert(d.getBitName(bit1) == 'test_bit1')
|
|
assert(d.getBitName(bit2) == 'test_bit2')
|
|
assert(d.getBitName(bit3) == 'test_bit3')
|
|
assert(d.getBitName(BitAddress(addr2,3)) == 'test_bit3')
|
|
|
|
# bit doesnt exist for that reg
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.getBitName(BitAddress(addr1, 5))
|
|
assert "No entry found for value" in str(exc_info.value)
|
|
|
|
# addr doesnt exist for that reg
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.getBitName(BitAddress(RegisterAddress(0x300), 5))
|
|
assert "No entry found for value" in str(exc_info.value)
|
|
|
|
d.clearRegisterDefinitions()
|
|
d.clearBitDefinitions()
|
|
|
|
d.setRegisterDefinitions(prev_reg_defs)
|
|
d.setBitDefinitions(prev_bit_defs)
|
|
else:
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.define_bit(name="test_bit", addr=0x300, bit_position=1)
|
|
assert "Bit Definitions only for CTB" in str(exc_info.value)
|
|
|
|
|
|
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
|
|
|
|
|
@pytest.mark.detectorintegration
|
|
def test_using_defined_reg_and_bit(session_simulator, request):
|
|
""" Test using defined reg and bit define_bit for ctb and xilinx_ctb."""
|
|
det_type, num_interfaces, num_mods, d = session_simulator
|
|
assert d is not None
|
|
|
|
from slsdet import RegisterAddress, BitAddress, RegisterValue
|
|
|
|
if det_type in ['ctb', 'xilinx_ctb']:
|
|
prev_reg_defs = d.getRegisterDefinitions()
|
|
prev_bit_defs = d.getBitDefinitions()
|
|
d.clearRegisterDefinitions()
|
|
d.clearBitDefinitions()
|
|
|
|
addr1 = RegisterAddress(0x201)
|
|
addr2 = RegisterAddress(0x202)
|
|
d.setRegisterDefinition('test_reg1', addr1)
|
|
d.setRegisterDefinition('test_reg2', addr2)
|
|
bit1 = BitAddress(addr1, 2)
|
|
bit2 = BitAddress(addr1, 4)
|
|
bit3 = BitAddress(addr2, 3)
|
|
d.setBitDefinition('test_bit1', bit1)
|
|
d.setBitDefinition('test_bit2', bit2)
|
|
d.setBitDefinition('test_bit3', bit3)
|
|
|
|
prev_val_addr1 = d.reg[addr1]
|
|
prev_val_addr2 = d.reg[addr2]
|
|
|
|
# reg name doesnt exist
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.reg['random_reg']
|
|
assert "No entry found for key" in str(exc_info.value)
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.setBit('random_reg')
|
|
assert "No entry found for key" in str(exc_info.value)
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.clearBit('random_reg')
|
|
assert "No entry found for key" in str(exc_info.value)
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.getBit('random_reg')
|
|
assert "No entry found for key" in str(exc_info.value)
|
|
|
|
# bit name doesnt exist
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.setBit('test_bit1', bit_position=5)
|
|
assert "bit_position must be None" in str(exc_info.value)
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.clearBit('test_bit1', bit_position=5)
|
|
assert "bit_position must be None" in str(exc_info.value)
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.getBit('test_bit1', bit_position=5)
|
|
assert "bit_position must be None" in str(exc_info.value)
|
|
|
|
d.reg['test_reg1'] = RegisterValue(0x0)
|
|
assert(d.reg['test_reg1'].value() == 0x0)
|
|
|
|
d.reg['test_reg1'] = RegisterValue(0x10)
|
|
assert(d.reg['test_reg1'].value() == 0x10)
|
|
|
|
d.setBit('test_bit1')
|
|
assert(d.reg['test_reg1'].value() == 0x14) # 0x10 | (1 << 2)
|
|
|
|
d.clearBit('test_bit1')
|
|
assert(d.reg['test_reg1'].value() == 0x10)
|
|
|
|
assert(d.getBit('test_bit1') == 0)
|
|
|
|
# restore previous values
|
|
d.reg[addr1] = prev_val_addr1
|
|
d.reg[addr2] = prev_val_addr2
|
|
|
|
d.clearRegisterDefinitions()
|
|
d.clearBitDefinitions()
|
|
|
|
d.setRegisterDefinitions(prev_reg_defs)
|
|
d.setBitDefinitions(prev_bit_defs)
|
|
else:
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.define_bit(name="test_bit", addr=0x300, bit_position=1)
|
|
assert "Bit Definitions only for CTB" in str(exc_info.value)
|
|
|
|
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
|
|
|
|
|
@pytest.mark.detectorintegration
|
|
def test_definelist_reg(session_simulator, request):
|
|
""" Test using definelist_reg for ctb and xilinx_ctb."""
|
|
det_type, num_interfaces, num_mods, d = session_simulator
|
|
assert d is not None
|
|
|
|
from slsdet import RegisterAddress, BitAddress, RegisterValue
|
|
|
|
if det_type in ['ctb', 'xilinx_ctb']:
|
|
prev_reg_defs = d.getRegisterDefinitions()
|
|
prev_bit_defs = d.getBitDefinitions()
|
|
d.clearRegisterDefinitions()
|
|
d.clearBitDefinitions()
|
|
|
|
addr1 = RegisterAddress(0x201)
|
|
addr2 = RegisterAddress(0x202)
|
|
bit1 = BitAddress(addr1, 2)
|
|
bit2 = BitAddress(addr1, 4)
|
|
bit3 = BitAddress(addr2, 3)
|
|
|
|
d.setRegisterDefinitions({
|
|
'test_reg1': RegisterAddress(0x201),
|
|
'test_reg2': RegisterAddress(0x202)
|
|
})
|
|
|
|
res = d.getRegisterDefinitions()
|
|
assert(res['test_reg1'] == addr1)
|
|
assert(res['test_reg2'] == addr2)
|
|
assert(len(res) == 2)
|
|
|
|
d.clearRegisterDefinitions()
|
|
d.clearBitDefinitions()
|
|
|
|
d.setRegisterDefinitions(prev_reg_defs)
|
|
d.setBitDefinitions(prev_bit_defs)
|
|
else:
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.define_bit(name="test_bit", addr=0x300, bit_position=1)
|
|
assert "Bit Definitions only for CTB" in str(exc_info.value)
|
|
|
|
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
|
|
|
|
|
@pytest.mark.detectorintegration
|
|
def test_definelist_bit(session_simulator, request):
|
|
""" Test using definelist_bit for ctb and xilinx_ctb."""
|
|
det_type, num_interfaces, num_mods, d = session_simulator
|
|
assert d is not None
|
|
|
|
from slsdet import RegisterAddress, BitAddress, RegisterValue
|
|
|
|
if det_type in ['ctb', 'xilinx_ctb']:
|
|
prev_reg_defs = d.getRegisterDefinitions()
|
|
prev_bit_defs = d.getBitDefinitions()
|
|
d.clearRegisterDefinitions()
|
|
d.clearBitDefinitions()
|
|
|
|
addr1 = RegisterAddress(0x201)
|
|
addr2 = RegisterAddress(0x202)
|
|
bit1 = BitAddress(addr1, 2)
|
|
bit2 = BitAddress(addr1, 4)
|
|
bit3 = BitAddress(addr2, 3)
|
|
|
|
d.setRegisterDefinitions({
|
|
'test_reg1': RegisterAddress(0x201),
|
|
'test_reg2': RegisterAddress(0x202)
|
|
})
|
|
d.setBitDefinitions({
|
|
'test_bit1': BitAddress(addr1, 2),
|
|
'test_bit2': BitAddress(addr1, 4),
|
|
'test_bit3': BitAddress(addr2, 3)
|
|
})
|
|
|
|
res = d.getBitDefinitions()
|
|
assert(len(res) == 3)
|
|
assert(res['test_bit1'] == bit1)
|
|
assert(res['test_bit2'] == bit2)
|
|
assert(res['test_bit3'] == bit3)
|
|
assert(res['test_bit2'].address() == addr1)
|
|
assert(res['test_bit2'].bitPosition() == 4)
|
|
|
|
d.clearRegisterDefinitions()
|
|
d.clearBitDefinitions()
|
|
|
|
d.setRegisterDefinitions(prev_reg_defs)
|
|
d.setBitDefinitions(prev_bit_defs)
|
|
else:
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.define_bit(name="test_bit", addr=0x300, bit_position=1)
|
|
assert "Bit Definitions only for CTB" in str(exc_info.value)
|
|
|
|
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
|
|
|
|
|
@pytest.mark.detectorintegration
|
|
def test_parameters_file(session_simulator, request):
|
|
""" Test using test_parameters_file."""
|
|
det_type, num_interfaces, num_mods, d = session_simulator
|
|
assert d is not None
|
|
|
|
with open("/tmp/params.det", "w") as f:
|
|
f.write("frames 2\n")
|
|
f.write("fwrite 1\n")
|
|
|
|
# this should not throw
|
|
d.parameters = "/tmp/params.det"
|
|
|
|
assert d.frames == 2
|
|
assert d.fwrite == 1
|
|
|
|
Log(LogLevel.INFOGREEN, f"✅ Test passed. Command: parameters")
|
|
|
|
|
|
@pytest.mark.detectorintegration
|
|
def test_include_file(session_simulator, request):
|
|
""" Test using test_include_file."""
|
|
det_type, num_interfaces, num_mods, d = session_simulator
|
|
assert d is not None
|
|
|
|
with open("/tmp/params.det", "w") as f:
|
|
f.write("frames 3\n")
|
|
f.write("fwrite 0\n")
|
|
|
|
# this should not throw
|
|
d.include = "/tmp/params.det"
|
|
|
|
assert d.frames == 3
|
|
assert d.fwrite == 0
|
|
|
|
Log(LogLevel.INFOGREEN, f"✅ Test passed. Command: include")
|
|
|
|
|
|
@pytest.mark.detectorintegration
|
|
def test_patternstart(session_simulator, request):
|
|
""" Test using patternstart for ctb, xilinx_ctb and mythen3."""
|
|
det_type, num_interfaces, num_mods, d = session_simulator
|
|
assert d is not None
|
|
|
|
if det_type in ['ctb', 'xilinx_ctb', 'mythen3']:
|
|
d.patternstart()
|
|
else:
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.patternstart()
|
|
assert "not implemented" in str(exc_info.value)
|
|
|
|
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
|
|
|
|
|
|
|
@pytest.mark.detectorintegration
|
|
def test_runclk(session_simulator, request):
|
|
""" Test using runclk for ctb and xilinx_ctb."""
|
|
det_type, num_interfaces, num_mods, d = session_simulator
|
|
assert d is not None
|
|
|
|
from slsdet import Hz, MHz, kHz
|
|
|
|
if det_type in ['ctb', 'xilinx_ctb']:
|
|
prev_runclk = d.getRUNClock()
|
|
|
|
d.runclk
|
|
|
|
# invalid value type
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.runclk = 5e6
|
|
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.runclk = 5 * 1000 * 1000
|
|
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.runclk = Hz(5e6)
|
|
|
|
d.runclk = MHz(15)
|
|
assert d.runclk.value == 15_000_000
|
|
|
|
d.runclk = MHz(14.5)
|
|
assert d.runclk.value == 14_500_000
|
|
|
|
d.runclk = kHz(15000.5)
|
|
assert d.runclk.value == 15_000_500
|
|
|
|
# invalid values from server
|
|
# max is 300MHz
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.runclk = MHz(301)
|
|
|
|
# min is 2MHz for ctb and 10MHz for xilinx_ctb
|
|
if det_type == 'ctb':
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.runclk = MHz(1)
|
|
else:
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.runclk = MHz(9)
|
|
|
|
c = MHz(2)
|
|
for rc in [5, 10, 15, 20]:
|
|
d.runclk = rc * c
|
|
assert d.runclk.value == 40_000_000
|
|
|
|
for i in range(len(d)):
|
|
d.setRUNClock(prev_runclk[i], [i])
|
|
|
|
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
|
|
|
|
|
@pytest.mark.detectorintegration
|
|
def test_adcclk(session_simulator, request):
|
|
""" Test using adcclk for ctb and xilinx_ctb."""
|
|
det_type, num_interfaces, num_mods, d = session_simulator
|
|
assert d is not None
|
|
|
|
from slsdet import Hz, MHz, kHz
|
|
|
|
if det_type in ['ctb', 'xilinx_ctb']:
|
|
prev_adcclk = d.getADCClock()
|
|
|
|
d.adcclk
|
|
|
|
# invalid value type
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.adcclk = 5e6
|
|
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.adcclk = 5 * 1000 * 1000
|
|
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.adcclk = Hz(5e6)
|
|
|
|
d.adcclk = MHz(15)
|
|
assert d.adcclk.value == 15_000_000
|
|
|
|
d.adcclk = MHz(14.5)
|
|
assert d.adcclk.value == 14_500_000
|
|
|
|
d.adcclk = kHz(15000.5)
|
|
assert d.adcclk.value == 15_000_500
|
|
|
|
# invalid values from server
|
|
# max is 300MHz for xilinx and 54 MHz for ctb
|
|
if det_type == 'ctb':
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.adcclk = MHz(66)
|
|
else:
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.adcclk = MHz(301)
|
|
|
|
# min is 2MHz for ctb and 10MHz for xilinx_ctb
|
|
if det_type == 'ctb':
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.adcclk = MHz(1)
|
|
else:
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.adcclk = MHz(9)
|
|
|
|
c = MHz(2)
|
|
for rc in [5, 10, 15, 20]:
|
|
d.adcclk = rc * c
|
|
assert d.adcclk.value == 40_000_000
|
|
|
|
for i in range(len(d)):
|
|
d.setADCClock(prev_adcclk[i], [i])
|
|
|
|
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
|
|
|
|
|
@pytest.mark.detectorintegration
|
|
def test_dbitclk(session_simulator, request):
|
|
""" Test using dbitclk for ctb and xilinx_ctb."""
|
|
det_type, num_interfaces, num_mods, d = session_simulator
|
|
assert d is not None
|
|
|
|
from slsdet import Hz, MHz, kHz
|
|
|
|
if det_type in ['ctb', 'xilinx_ctb']:
|
|
prev_dbitclk = d.getDBITClock()
|
|
|
|
d.dbitclk
|
|
|
|
# invalid value type
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.dbitclk = 5e6
|
|
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.dbitclk = 5 * 1000 * 1000
|
|
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.dbitclk = Hz(5e6)
|
|
|
|
d.dbitclk = MHz(15)
|
|
assert d.dbitclk.value == 15_000_000
|
|
|
|
d.dbitclk = MHz(14.5)
|
|
assert d.dbitclk.value == 14_500_000
|
|
|
|
d.dbitclk = kHz(15000.5)
|
|
assert d.dbitclk.value == 15_000_500
|
|
|
|
# invalid values from server
|
|
# max is 300MHz
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.dbitclk = MHz(301)
|
|
|
|
# min is 2MHz for ctb and 10MHz for xilinx_ctb
|
|
if det_type == 'ctb':
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.dbitclk = MHz(1)
|
|
else:
|
|
with pytest.raises(Exception) as exc_info:
|
|
d.dbitclk = MHz(9)
|
|
|
|
c = MHz(2)
|
|
for rc in [5, 10, 15, 20]:
|
|
d.dbitclk = rc * c
|
|
assert d.dbitclk.value == 40_000_000
|
|
|
|
for i in range(len(d)):
|
|
d.setDBITClock(prev_dbitclk[i], [i])
|
|
|
|
Log(LogLevel.INFOGREEN, f"✅ {request.node.name} passed")
|
|
|
|
|
|
|
|
@pytest.mark.detectorintegration
|
|
def test_syncclk(session_simulator, request):
|
|
""" Test using syncclk for ctb."""
|
|
det_type, num_interfaces, num_mods, d = session_simulator
|
|
assert d is not None
|
|
|
|
if det_type in ['ctb']:
|
|
d.syncclk
|
|
|
|
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")
|
|
|