more tests

This commit is contained in:
Erik Frojdh 2019-09-20 10:46:28 +02:00
parent 27d223d199
commit af9c67539f
6 changed files with 251 additions and 23 deletions

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -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"""

View File

@ -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();
} }

View File

@ -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,