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 sys
import time
sys.path.append(os.path.join(os.getcwd(), 'bin'))
from sls_detector import ExperimentalDetector
import datetime as dt
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")
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"])
virtual_jf_detectors = []
virtual_jf_detectors.append(subprocess.Popen('bin/jungfrauDetectorServer_virtual'))
time.sleep(5)
# Ensure no shared memory exists before tests start
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():
print("Cleaning up virtual detectors")
d = ExperimentalDetector()
d.free()
subprocess.run(["killall", "jungfrauDetectorServer_virtual"])
request.addfinalizer(fin)
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):
d = ExperimentalDetector()
d.hostname = 'localhost'
assert d.hostname == 'localhost'
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):
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
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
from .utils import element_if_equal, all_equal
from .utils import Geometry, to_geo
import datetime as dt
from functools import wraps
from collections import namedtuple
def freeze(cls):
@ -52,9 +54,15 @@ class ExperimentalDetector(CppDetectorApi):
# CONFIGURATION
def __len__(self):
return self.size()
def free(self):
self.freeSharedMemory()
@property
def hostname(self):
return element_if_equal(self.getHostname())
return self.getHostname()
@hostname.setter
def hostname(self, hostnames):
@ -69,6 +77,39 @@ class ExperimentalDetector(CppDetectorApi):
def detectorversion(self):
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
@property
def rx_status(self):
@ -178,7 +219,10 @@ class ExperimentalDetector(CppDetectorApi):
@exptime.setter
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
def subexptime(self):
@ -187,7 +231,10 @@ class ExperimentalDetector(CppDetectorApi):
@subexptime.setter
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
def period(self):
@ -196,5 +243,8 @@ class ExperimentalDetector(CppDetectorApi):
@period.setter
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
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):
"""If all elements are equal return true otherwise false"""

View File

@ -7,6 +7,11 @@
namespace py = pybind11;
void init_enums(py::module &m) {
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")
.value("IDLE", slsDetectorDefs::runStatus::IDLE)
.value("ERROR", slsDetectorDefs::runStatus::ERROR)
@ -16,4 +21,34 @@ void init_enums(py::module &m) {
.value("RUNNING", slsDetectorDefs::runStatus::RUNNING)
.value("STOPPED", slsDetectorDefs::runStatus::STOPPED)
.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) {
using sls::Detector;
using sls::Positions;
py::class_<Detector> CppDetectorApi(m, "CppDetectorApi");
CppDetectorApi
.def(py::init<int>())
// Configuration
.def("free", &Detector::freeSharedMemory)
.def("freeSharedMemory", &Detector::freeSharedMemory)
.def("loadConfig", &Detector::loadConfig)
.def("loadParameters", &Detector::loadParameters)
.def("getHostname", &Detector::getHostname, py::arg() = Positions{})
.def("setHostname", &Detector::setHostname)
.def("getHostname", &Detector::getHostname, py::arg() = Positions{})
.def("getShmId", &Detector::getShmId)
.def("getFirmwareVersion", &Detector::getFirmwareVersion,
py::arg() = Positions{})
@ -34,7 +34,27 @@ void init_experimental(py::module &m) {
.def("getDetectorType", &Detector::getDetectorType,
py::arg() = Positions{})
.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
.def("acquire", &Detector::acquire)
@ -71,12 +91,7 @@ void init_experimental(py::module &m) {
py::arg() = Positions{})
// 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(),
py::arg() = Positions{})
.def("getSubExptime", &Detector::getSubExptime,