mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-05 17:40:40 +02:00
more tests
This commit is contained in:
parent
27d223d199
commit
af9c67539f
@ -3,31 +3,148 @@ import subprocess
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
sys.path.append(os.path.join(os.getcwd(), 'bin'))
|
import datetime as dt
|
||||||
from sls_detector import ExperimentalDetector
|
|
||||||
|
sys.path.append(os.path.join(os.getcwd(), "bin"))
|
||||||
|
from sls_detector import ExperimentalDetector, detectorSettings
|
||||||
|
|
||||||
|
n_detectors = 3
|
||||||
|
start_port = 1952
|
||||||
|
port_step = 3
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def virtual_jf_detectors(request):
|
def virtual_jf_detectors(request):
|
||||||
print('Setting up virtual detectors')
|
"""
|
||||||
|
Fixture that is run once for the module
|
||||||
|
will launch virtual servers and clean up
|
||||||
|
after
|
||||||
|
"""
|
||||||
|
print("Setting up virtual detectors")
|
||||||
|
|
||||||
|
# Ensure that no detector servers are running
|
||||||
subprocess.run(["killall", "jungfrauDetectorServer_virtual"])
|
subprocess.run(["killall", "jungfrauDetectorServer_virtual"])
|
||||||
virtual_jf_detectors = []
|
|
||||||
virtual_jf_detectors.append(subprocess.Popen('bin/jungfrauDetectorServer_virtual'))
|
# Ensure no shared memory exists before tests start
|
||||||
time.sleep(5)
|
d = ExperimentalDetector()
|
||||||
|
d.free()
|
||||||
|
|
||||||
|
# Start servers
|
||||||
|
virtual_jf_detectors = [
|
||||||
|
subprocess.Popen(
|
||||||
|
[
|
||||||
|
"bin/jungfrauDetectorServer_virtual",
|
||||||
|
"--port",
|
||||||
|
f"{start_port+port_step*i}",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
for i in range(n_detectors)
|
||||||
|
]
|
||||||
|
|
||||||
|
# Allow server startup to complete
|
||||||
|
time.sleep(3)
|
||||||
|
|
||||||
def fin():
|
def fin():
|
||||||
print("Cleaning up virtual detectors")
|
print("Cleaning up virtual detectors")
|
||||||
|
d = ExperimentalDetector()
|
||||||
|
d.free()
|
||||||
subprocess.run(["killall", "jungfrauDetectorServer_virtual"])
|
subprocess.run(["killall", "jungfrauDetectorServer_virtual"])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
request.addfinalizer(fin)
|
request.addfinalizer(fin)
|
||||||
return virtual_jf_detectors # provide the fixture value
|
return virtual_jf_detectors # provide the fixture value
|
||||||
|
|
||||||
|
|
||||||
|
def test_shmid(virtual_jf_detectors):
|
||||||
|
d = ExperimentalDetector()
|
||||||
|
assert d.getShmId() == 0
|
||||||
|
d.free()
|
||||||
|
|
||||||
|
d = ExperimentalDetector(73)
|
||||||
|
assert d.getShmId() == 73
|
||||||
|
d.free()
|
||||||
|
|
||||||
|
|
||||||
def test_hostname(virtual_jf_detectors):
|
def test_hostname(virtual_jf_detectors):
|
||||||
d = ExperimentalDetector()
|
d = ExperimentalDetector()
|
||||||
d.hostname = 'localhost'
|
d.hostname = "localhost"
|
||||||
assert d.hostname == 'localhost'
|
assert d.hostname == ["localhost"]
|
||||||
|
|
||||||
|
d.hostname = [f"localhost:{start_port+i*port_step}" for i in range(n_detectors)]
|
||||||
|
assert d.hostname == ["localhost"] * n_detectors
|
||||||
|
|
||||||
|
|
||||||
def test_fwversion(virtual_jf_detectors):
|
def test_fwversion(virtual_jf_detectors):
|
||||||
d = ExperimentalDetector()
|
d = ExperimentalDetector()
|
||||||
assert d.detectorversion == 0 #Firmware of virtual detector
|
assert d.detectorversion == 0 # Firmware of virtual detector
|
||||||
|
assert d.getFirmwareVersion() == [0] * n_detectors
|
||||||
|
|
||||||
|
|
||||||
|
def test_len(virtual_jf_detectors):
|
||||||
|
d = ExperimentalDetector()
|
||||||
|
assert len(d) == n_detectors
|
||||||
|
assert d.size() == n_detectors
|
||||||
|
|
||||||
|
|
||||||
|
def test_module_geometry(virtual_jf_detectors):
|
||||||
|
d = ExperimentalDetector()
|
||||||
|
geo = d.module_geometry
|
||||||
|
assert geo.x == 1
|
||||||
|
assert geo.y == 3
|
||||||
|
|
||||||
|
|
||||||
|
def test_module_size(virtual_jf_detectors):
|
||||||
|
d = ExperimentalDetector()
|
||||||
|
geo = d.module_size
|
||||||
|
assert geo.x == 1024
|
||||||
|
assert geo.y == 512
|
||||||
|
|
||||||
|
|
||||||
|
def test_settings(virtual_jf_detectors):
|
||||||
|
d = ExperimentalDetector()
|
||||||
|
assert d.settings == detectorSettings.DYNAMICGAIN
|
||||||
|
|
||||||
|
gain_list = [
|
||||||
|
detectorSettings.FIXGAIN1,
|
||||||
|
detectorSettings.FIXGAIN2,
|
||||||
|
detectorSettings.FORCESWITCHG1,
|
||||||
|
detectorSettings.FORCESWITCHG2,
|
||||||
|
detectorSettings.DYNAMICHG0,
|
||||||
|
detectorSettings.DYNAMICGAIN,
|
||||||
|
]
|
||||||
|
|
||||||
|
# Set all viable gain for Jungfrau to make sure nothing is crashing
|
||||||
|
for gain in gain_list:
|
||||||
|
d.settings = gain
|
||||||
|
assert d.settings == gain
|
||||||
|
|
||||||
|
d.setSettings(detectorSettings.FORCESWITCHG1, [1])
|
||||||
|
assert d.settings == [
|
||||||
|
detectorSettings.DYNAMICGAIN,
|
||||||
|
detectorSettings.FORCESWITCHG1,
|
||||||
|
detectorSettings.DYNAMICGAIN,
|
||||||
|
]
|
||||||
|
|
||||||
|
d.settings = detectorSettings.DYNAMICGAIN
|
||||||
|
assert d.settings == detectorSettings.DYNAMICGAIN
|
||||||
|
|
||||||
|
def test_frames(virtual_jf_detectors):
|
||||||
|
d = ExperimentalDetector()
|
||||||
|
d.frames = 10
|
||||||
|
assert d.frames == 10
|
||||||
|
|
||||||
|
# def test_triggers(virtual_jf_detectors):
|
||||||
|
|
||||||
|
def test_exptime(virtual_jf_detectors):
|
||||||
|
d = ExperimentalDetector()
|
||||||
|
|
||||||
|
#default value
|
||||||
|
assert d.exptime == 1e-5
|
||||||
|
|
||||||
|
d.exptime = 1.5
|
||||||
|
assert d.exptime == 1.5
|
||||||
|
|
||||||
|
t = dt.timedelta(microseconds=10)
|
||||||
|
d.exptime = t
|
||||||
|
assert d.exptime == 10e-6
|
||||||
|
|
||||||
|
|
@ -7,3 +7,5 @@ from _sls_detector import DetectorApi
|
|||||||
|
|
||||||
import _sls_detector
|
import _sls_detector
|
||||||
runStatus = _sls_detector.slsDetectorDefs.runStatus
|
runStatus = _sls_detector.slsDetectorDefs.runStatus
|
||||||
|
detectorType = _sls_detector.slsDetectorDefs.detectorType
|
||||||
|
detectorSettings = _sls_detector.slsDetectorDefs.detectorSettings
|
||||||
|
@ -3,9 +3,11 @@ from _sls_detector import slsDetectorDefs
|
|||||||
|
|
||||||
runStatus = slsDetectorDefs.runStatus
|
runStatus = slsDetectorDefs.runStatus
|
||||||
from .utils import element_if_equal, all_equal
|
from .utils import element_if_equal, all_equal
|
||||||
|
from .utils import Geometry, to_geo
|
||||||
import datetime as dt
|
import datetime as dt
|
||||||
|
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
|
|
||||||
def freeze(cls):
|
def freeze(cls):
|
||||||
@ -52,9 +54,15 @@ class ExperimentalDetector(CppDetectorApi):
|
|||||||
|
|
||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return self.size()
|
||||||
|
|
||||||
|
def free(self):
|
||||||
|
self.freeSharedMemory()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hostname(self):
|
def hostname(self):
|
||||||
return element_if_equal(self.getHostname())
|
return self.getHostname()
|
||||||
|
|
||||||
@hostname.setter
|
@hostname.setter
|
||||||
def hostname(self, hostnames):
|
def hostname(self, hostnames):
|
||||||
@ -69,6 +77,39 @@ class ExperimentalDetector(CppDetectorApi):
|
|||||||
def detectorversion(self):
|
def detectorversion(self):
|
||||||
return element_if_equal(self.getFirmwareVersion())
|
return element_if_equal(self.getFirmwareVersion())
|
||||||
|
|
||||||
|
@property
|
||||||
|
def detector_type(self):
|
||||||
|
return element_if_equal(self.getDetectorType())
|
||||||
|
|
||||||
|
@property
|
||||||
|
def module_geometry(self):
|
||||||
|
return to_geo(self.getModuleGeometry())
|
||||||
|
|
||||||
|
@property
|
||||||
|
def module_size(self):
|
||||||
|
ms = [to_geo(item) for item in self.getModuleSize()]
|
||||||
|
return element_if_equal(ms)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def detector_size(self):
|
||||||
|
return to_geo(self.getDetectorSize())
|
||||||
|
|
||||||
|
@property
|
||||||
|
def settings(self):
|
||||||
|
return element_if_equal(self.getSettings())
|
||||||
|
|
||||||
|
@settings.setter
|
||||||
|
def settings(self, value):
|
||||||
|
self.setSettings(value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def frames(self):
|
||||||
|
return element_if_equal(self.getNumberOfFrames())
|
||||||
|
|
||||||
|
@frames.setter
|
||||||
|
def frames(self, n_frames):
|
||||||
|
self.setNumberOfFrames(n_frames)
|
||||||
|
|
||||||
# Acq
|
# Acq
|
||||||
@property
|
@property
|
||||||
def rx_status(self):
|
def rx_status(self):
|
||||||
@ -178,7 +219,10 @@ class ExperimentalDetector(CppDetectorApi):
|
|||||||
|
|
||||||
@exptime.setter
|
@exptime.setter
|
||||||
def exptime(self, t):
|
def exptime(self, t):
|
||||||
self.setExptime(dt.timedelta(seconds=t))
|
if isinstance(t, dt.timedelta):
|
||||||
|
self.setExptime(t)
|
||||||
|
else:
|
||||||
|
self.setExptime(dt.timedelta(seconds=t))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def subexptime(self):
|
def subexptime(self):
|
||||||
@ -187,7 +231,10 @@ class ExperimentalDetector(CppDetectorApi):
|
|||||||
|
|
||||||
@subexptime.setter
|
@subexptime.setter
|
||||||
def subexptime(self, t):
|
def subexptime(self, t):
|
||||||
self.setSubExptime(dt.timedelta(seconds=t))
|
if isinstance(t, dt.timedelta):
|
||||||
|
self.setSubExptime(t)
|
||||||
|
else:
|
||||||
|
self.setSubExptime(dt.timedelta(seconds=t))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def period(self):
|
def period(self):
|
||||||
@ -196,5 +243,8 @@ class ExperimentalDetector(CppDetectorApi):
|
|||||||
|
|
||||||
@period.setter
|
@period.setter
|
||||||
def period(self, t):
|
def period(self, t):
|
||||||
self.setPeriod(dt.timedelta(seconds=t))
|
if isinstance(t, dt.timedelta):
|
||||||
|
self.setPeriod(t)
|
||||||
|
else:
|
||||||
|
self.setPeriod(dt.timedelta(seconds=t))
|
||||||
|
|
||||||
|
@ -2,7 +2,16 @@
|
|||||||
Utility functions that are useful for testing and troubleshooting
|
Utility functions that are useful for testing and troubleshooting
|
||||||
but not directly used in controlling the detector
|
but not directly used in controlling the detector
|
||||||
"""
|
"""
|
||||||
|
from collections import namedtuple
|
||||||
|
import _sls_detector #C++ lib
|
||||||
|
|
||||||
|
Geometry = namedtuple('Geometry', ['x', 'y'])
|
||||||
|
|
||||||
|
def to_geo(value):
|
||||||
|
if isinstance(value, _sls_detector.xy):
|
||||||
|
return Geometry(x = value.x, y = value.y)
|
||||||
|
else:
|
||||||
|
raise ValueError("Can only convert sls_detector.xy")
|
||||||
|
|
||||||
def all_equal(mylist):
|
def all_equal(mylist):
|
||||||
"""If all elements are equal return true otherwise false"""
|
"""If all elements are equal return true otherwise false"""
|
||||||
|
@ -7,6 +7,11 @@
|
|||||||
namespace py = pybind11;
|
namespace py = pybind11;
|
||||||
void init_enums(py::module &m) {
|
void init_enums(py::module &m) {
|
||||||
py::class_<slsDetectorDefs> Defs(m, "slsDetectorDefs");
|
py::class_<slsDetectorDefs> Defs(m, "slsDetectorDefs");
|
||||||
|
py::class_<slsDetectorDefs::xy> xy(m, "xy");
|
||||||
|
// xy.def(py::init())
|
||||||
|
xy.def_readwrite("x", &slsDetectorDefs::xy::x);
|
||||||
|
xy.def_readwrite("y", &slsDetectorDefs::xy::y);
|
||||||
|
|
||||||
py::enum_<slsDetectorDefs::runStatus>(Defs, "runStatus")
|
py::enum_<slsDetectorDefs::runStatus>(Defs, "runStatus")
|
||||||
.value("IDLE", slsDetectorDefs::runStatus::IDLE)
|
.value("IDLE", slsDetectorDefs::runStatus::IDLE)
|
||||||
.value("ERROR", slsDetectorDefs::runStatus::ERROR)
|
.value("ERROR", slsDetectorDefs::runStatus::ERROR)
|
||||||
@ -16,4 +21,34 @@ void init_enums(py::module &m) {
|
|||||||
.value("RUNNING", slsDetectorDefs::runStatus::RUNNING)
|
.value("RUNNING", slsDetectorDefs::runStatus::RUNNING)
|
||||||
.value("STOPPED", slsDetectorDefs::runStatus::STOPPED)
|
.value("STOPPED", slsDetectorDefs::runStatus::STOPPED)
|
||||||
.export_values();
|
.export_values();
|
||||||
|
|
||||||
|
py::enum_<slsDetectorDefs::detectorType>(Defs, "detectorType")
|
||||||
|
.value("GENERIC", slsDetectorDefs::detectorType::GENERIC)
|
||||||
|
.value("EIGER", slsDetectorDefs::detectorType::EIGER)
|
||||||
|
.value("GOTTHARD", slsDetectorDefs::detectorType::GOTTHARD)
|
||||||
|
.value("JUNGFRAU", slsDetectorDefs::detectorType::JUNGFRAU)
|
||||||
|
.value("CHIPTESTBOARD", slsDetectorDefs::detectorType::CHIPTESTBOARD)
|
||||||
|
.value("MOENCH", slsDetectorDefs::detectorType::MOENCH)
|
||||||
|
.value("MYTHEN3", slsDetectorDefs::detectorType::MYTHEN3)
|
||||||
|
.value("GOTTHARD2", slsDetectorDefs::detectorType::GOTTHARD2)
|
||||||
|
.export_values();
|
||||||
|
|
||||||
|
py::enum_<slsDetectorDefs::detectorSettings>(Defs, "detectorSettings")
|
||||||
|
.value("GET_SETTINGS", slsDetectorDefs::detectorSettings::GET_SETTINGS)
|
||||||
|
.value("STANDARD", slsDetectorDefs::detectorSettings::STANDARD)
|
||||||
|
.value("FAST", slsDetectorDefs::detectorSettings::FAST)
|
||||||
|
.value("HIGHGAIN", slsDetectorDefs::detectorSettings::HIGHGAIN)
|
||||||
|
.value("DYNAMICGAIN", slsDetectorDefs::detectorSettings::DYNAMICGAIN)
|
||||||
|
.value("LOWGAIN", slsDetectorDefs::detectorSettings::LOWGAIN)
|
||||||
|
.value("MEDIUMGAIN", slsDetectorDefs::detectorSettings::MEDIUMGAIN)
|
||||||
|
.value("VERYHIGHGAIN", slsDetectorDefs::detectorSettings::VERYHIGHGAIN)
|
||||||
|
.value("DYNAMICHG0", slsDetectorDefs::detectorSettings::DYNAMICHG0)
|
||||||
|
.value("FIXGAIN1", slsDetectorDefs::detectorSettings::FIXGAIN1)
|
||||||
|
.value("FIXGAIN2", slsDetectorDefs::detectorSettings::FIXGAIN2)
|
||||||
|
.value("FORCESWITCHG1", slsDetectorDefs::detectorSettings::FORCESWITCHG1)
|
||||||
|
.value("FORCESWITCHG2", slsDetectorDefs::detectorSettings::FORCESWITCHG2)
|
||||||
|
.value("VERYLOWGAIN", slsDetectorDefs::detectorSettings::VERYLOWGAIN)
|
||||||
|
.value("UNDEFINED", slsDetectorDefs::detectorSettings::UNDEFINED)
|
||||||
|
.value("UNINITIALIZED", slsDetectorDefs::detectorSettings::UNINITIALIZED)
|
||||||
|
.export_values();
|
||||||
}
|
}
|
||||||
|
@ -10,17 +10,17 @@ namespace py = pybind11;
|
|||||||
void init_experimental(py::module &m) {
|
void init_experimental(py::module &m) {
|
||||||
using sls::Detector;
|
using sls::Detector;
|
||||||
using sls::Positions;
|
using sls::Positions;
|
||||||
|
|
||||||
py::class_<Detector> CppDetectorApi(m, "CppDetectorApi");
|
py::class_<Detector> CppDetectorApi(m, "CppDetectorApi");
|
||||||
CppDetectorApi
|
CppDetectorApi
|
||||||
.def(py::init<int>())
|
.def(py::init<int>())
|
||||||
|
|
||||||
// Configuration
|
// Configuration
|
||||||
.def("free", &Detector::freeSharedMemory)
|
|
||||||
.def("freeSharedMemory", &Detector::freeSharedMemory)
|
.def("freeSharedMemory", &Detector::freeSharedMemory)
|
||||||
.def("loadConfig", &Detector::loadConfig)
|
.def("loadConfig", &Detector::loadConfig)
|
||||||
.def("loadParameters", &Detector::loadParameters)
|
.def("loadParameters", &Detector::loadParameters)
|
||||||
.def("getHostname", &Detector::getHostname, py::arg() = Positions{})
|
|
||||||
.def("setHostname", &Detector::setHostname)
|
.def("setHostname", &Detector::setHostname)
|
||||||
|
.def("getHostname", &Detector::getHostname, py::arg() = Positions{})
|
||||||
.def("getShmId", &Detector::getShmId)
|
.def("getShmId", &Detector::getShmId)
|
||||||
.def("getFirmwareVersion", &Detector::getFirmwareVersion,
|
.def("getFirmwareVersion", &Detector::getFirmwareVersion,
|
||||||
py::arg() = Positions{})
|
py::arg() = Positions{})
|
||||||
@ -34,7 +34,27 @@ void init_experimental(py::module &m) {
|
|||||||
.def("getDetectorType", &Detector::getDetectorType,
|
.def("getDetectorType", &Detector::getDetectorType,
|
||||||
py::arg() = Positions{})
|
py::arg() = Positions{})
|
||||||
.def("size", &Detector::size)
|
.def("size", &Detector::size)
|
||||||
|
.def("getModuleGeometry", &Detector::getModuleGeometry)
|
||||||
|
.def("getModuleSize", &Detector::getModuleSize, py::arg() = Positions{})
|
||||||
|
.def("getDetectorSize", &Detector::getDetectorSize)
|
||||||
|
.def("setDetectorSize", &Detector::setDetectorSize)
|
||||||
|
.def("getSettings", &Detector::getSettings, py::arg() = Positions{})
|
||||||
|
.def("setSettings", &Detector::setSettings, py::arg(),
|
||||||
|
py::arg() = Positions{})
|
||||||
|
|
||||||
|
// TODO! Python funcs for callbacks?
|
||||||
|
|
||||||
|
// Acquisition Parameters
|
||||||
|
.def("getNumberOfFrames", &Detector::getNumberOfFrames)
|
||||||
|
.def("setNumberOfFrames", &Detector::setNumberOfFrames)
|
||||||
|
.def("getNumberOfTriggers", &Detector::getNumberOfTriggers)
|
||||||
|
.def("setNumberOfTriggers", &Detector::setNumberOfTriggers)
|
||||||
|
.def("setExptime", &Detector::setExptime, py::arg(),
|
||||||
|
py::arg() = Positions{})
|
||||||
|
.def("getExptime", &Detector::getExptime, py::arg() = Positions{})
|
||||||
|
.def("setPeriod", &Detector::setPeriod, py::arg(),
|
||||||
|
py::arg() = Positions{})
|
||||||
|
.def("getPeriod", &Detector::getPeriod, py::arg() = Positions{})
|
||||||
|
|
||||||
// Acq related
|
// Acq related
|
||||||
.def("acquire", &Detector::acquire)
|
.def("acquire", &Detector::acquire)
|
||||||
@ -71,12 +91,7 @@ void init_experimental(py::module &m) {
|
|||||||
py::arg() = Positions{})
|
py::arg() = Positions{})
|
||||||
|
|
||||||
// Time
|
// Time
|
||||||
.def("setExptime", &Detector::setExptime, py::arg(),
|
|
||||||
py::arg() = Positions{})
|
|
||||||
.def("getExptime", &Detector::getExptime, py::arg() = Positions{})
|
|
||||||
.def("setPeriod", &Detector::setPeriod, py::arg(),
|
|
||||||
py::arg() = Positions{})
|
|
||||||
.def("getPeriod", &Detector::getPeriod, py::arg() = Positions{})
|
|
||||||
.def("setSubExptime", &Detector::setSubExptime, py::arg(),
|
.def("setSubExptime", &Detector::setSubExptime, py::arg(),
|
||||||
py::arg() = Positions{})
|
py::arg() = Positions{})
|
||||||
.def("getSubExptime", &Detector::getSubExptime,
|
.def("getSubExptime", &Detector::getSubExptime,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user