* WIP

* WIP

* WIP

* cleaned up multi

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* split up python module

* WIP

* WIP

* WIP

* WIP

* WIP

* ok

* fixed bugs from rebase

* WIP

* fixed broken test

* WIP

* fixed python

* WIP

* sphinx help

* including new commands

* docs

* WIP

* WIP

* more tests

* added missing public header

* WIP
This commit is contained in:
Dhanya Thattil
2019-08-07 11:21:07 +02:00
committed by GitHub
parent 98ddf154b2
commit 4ceee97c03
58 changed files with 2317 additions and 571 deletions

View File

@ -1,11 +1,13 @@
pybind11_add_module(_sls_detector src/main.cpp)
pybind11_add_module(_sls_detector
src/main.cpp
src/enums.cpp
src/experimental.cpp
)
target_link_libraries(_sls_detector PUBLIC
slsProjectOptions
slsProjectWarnings
slsDetectorShared
slsReceiverShared
slsSupportLib

View File

@ -36,7 +36,9 @@ class get_pybind_include(object):
ext_modules = [
Extension(
'_sls_detector',
['src/main.cpp'],
['src/main.cpp',
'src/enums.cpp',
'src/experimental.cpp'],
include_dirs=[
# Path to pybind11 headers
get_pybind_include(),

View File

@ -4,3 +4,6 @@ from .experimental import ExperimentalDetector
from .jungfrau import Jungfrau
from .jungfrau_ctb import JungfrauCTB
from _sls_detector import DetectorApi
import _sls_detector
runStatus = _sls_detector.slsDetectorDefs.runStatus

View File

@ -1,9 +1,180 @@
from _sls_detector import multiDetectorApi
from _sls_detector import slsDetectorDefs
runStatus = slsDetectorDefs.runStatus
from .utils import element_if_equal, all_equal
import datetime as dt
from functools import wraps
def freeze(cls):
cls.__frozen = False
def frozensetattr(self, key, value):
if self.__frozen and not hasattr(self, key):
raise AttributeError(
"Class {} is frozen. Cannot set {} = {}".format(
cls.__name__, key, value
)
)
else:
object.__setattr__(self, key, value)
def init_decorator(func):
@wraps(func)
def wrapper(self, *args, **kwargs):
func(self, *args, **kwargs)
self.__frozen = True
return wrapper
cls.__setattr__ = frozensetattr
cls.__init__ = init_decorator(cls.__init__)
return cls
@freeze
class ExperimentalDetector(multiDetectorApi):
def __init__(self):
super().__init__(0)
self.online = True
"""
This class is the base for detector specific
interfaces. Most functions exists in two versions
like the getExptime() function that uses the
C++ API directly and the simplified exptime property.
"""
def __init__(self, multi_id = 0):
"""
multi_id refers to the shared memory id of the
slsDetectorPackage. Default value is 0.
"""
super().__init__(multi_id)
# Acq
@property
def rx_status(self):
"""
Read the status of the receiver
"""
return element_if_equal(self.getReceiverStatus())
@rx_status.setter
def rx_status(self, status_str):
if status_str == "start":
self.startReceiver()
elif status_str == "stop":
self.stopReceiver()
else:
raise NotImplementedError("Unknown argument to rx_status")
@property
def busy(self):
"""
Checks if the detector is acquiring. Can also be set but should only be used if the acquire fails and
leaves the detector with busy == True
.. note ::
Only works when the measurement is launched using acquire, not with status start!
Returns
--------
bool
:py:obj:`True` if the detector is acquiring otherwise :py:obj:`False`
Examples
----------
::
d.busy
>> True
#If the detector is stuck reset by:
d.busy = False
"""
return self.getAcquiringFlag()
@busy.setter
def busy(self, value):
self.setAcquiringFlag(value)
# Configuration
@property
def startingfnum(self):
return element_if_equal(self.getStartingFrameNumber())
@startingfnum.setter
def startingfnum(self, value):
self.setStartingFrameNumber(value)
@property
def config(self):
return NotImplementedError("config is set only")
@config.setter
def config(self, fname):
self.setConfig(fname)
# File
@property
def fname(self):
return element_if_equal(self.getFileName())
@fname.setter
def fname(self, file_name):
self.setFileName(file_name)
@property
def fpath(self):
return element_if_equal(self.getFilePath())
@fpath.setter
def fpath(self, path):
self.setFilePath(path)
@property
def fwrite(self):
return element_if_equal(self.getFileWrite())
@fwrite.setter
def fwrite(self, value):
self.setFileWrite(value)
@property
def foverwrite(self):
return element_if_equal(self.getFileOverWrite())
@foverwrite.setter
def foverwrite(self, value):
self.setFileOverWrite(value)
# Time
@property
def exptime(self):
res = self.getExptime()
return element_if_equal([it.total_seconds() for it in res])
@exptime.setter
def exptime(self, t):
self.setExptime(dt.timedelta(seconds=t))
@property
def subexptime(self):
res = self.getSubExptime()
return element_if_equal([it.total_seconds() for it in res])
@subexptime.setter
def subexptime(self, t):
self.setSubExptime(dt.timedelta(seconds=t))
@property
def period(self):
res = self.getPeriod()
return element_if_equal([it.total_seconds() for it in res])
@period.setter
def period(self, t):
self.setPeriod(dt.timedelta(seconds=t))

View File

@ -1,143 +0,0 @@
Examples
================
Some short hints on how to use the detector
------------------------
Simple threshold scan
------------------------
Assuming you have set up your detector with exposure time, period, enabled
file writing etc.
.. code-block:: python
from sls_detector import Eiger
d = Eiger()
threshold = range(0, 2000, 200)
for th in threshold:
d.vthreshold = th
d.acq()
If we want to control the shutter of for example, the big X-ray box we can add
this line in our code. It then opens the shutter just before the measurement
and closes is afterwards.
::
with xrf_shutter_open(box, 'Fe'):
for th in threshold:
d.vthreshold = th
d.acq()
-----------------------
Reading temperatures
-----------------------
::
d.temp
>>
temp_fpga : 43.19°C, 51.83°C
temp_fpgaext : 38.50°C, 38.50°C
temp_10ge : 39.50°C, 39.50°C
temp_dcdc : 42.50°C, 42.50°C
temp_sodl : 39.50°C, 40.50°C
temp_sodr : 39.50°C, 40.50°C
temp_fpgafl : 40.87°C, 37.61°C
temp_fpgafr : 34.51°C, 35.63°C
d.temp.fpga
>> temp_fpga : 40.84°C, 39.31°C
t = d.temp.fpga[0]
t
>> 40.551
t = d.temp.fpga[:]
t
>> [40.566, 39.128]
-----------------------
Non blocking acquire
-----------------------
There are mainly two ways to achieve a non blocking acquire when calling from the Python API. One is to manually start
the detector and the second one is to launch the normal acquire from a different process. Depending on your measurement
it might also be better to run the other task in a seperate process and use acq in the main thread.
But lets start looking at the at the manual way:
::
import time
from sls_detector import Eiger
d = Eiger()
n = 10
t = 1
d.exposure_time = t
d.n_frames = n
d.reset_frames_caught()
#Start the measurement
t0 = time.time()
d.start_receiver()
d.start_detector()
#Wait for the detector to be ready or do other important stuff
time.sleep(t*n)
#check if the detector is ready otherwise wait a bit longer
while d.status != 'idle':
time.sleep(0.1)
#Stop the receiver after we got the frames
#Detector is already idle so we don't need to stop it
d.stop_receiver()
lost = d.frames_caught - n
print(f'{n} frames of {t}s took {time.time()-t0:{.3}}s with {lost} frames lost ')
#Reset to not interfere with a potential next measurement
d.reset_frames_caught()
Instead launching d.acq() from a different process is a bit easier since the control of receiver and detector
is handled in the acq call. However, you need to join the process used otherwise a lot of zombie processes would
hang around until the main process exits.
::
import time
from multiprocessing import Process
from sls_detector import Eiger
def acquire():
"""
Create a new Eiger object that still referes to the same actual detector
and same shared memory. Then launch acq.
"""
detector = Eiger()
detector.acq()
#This is the detector we use throughout the session
d = Eiger()
#Process to run acquire
p = Process(target=acquire)
#Start the thread and short sleep to allow the acq to start
p.start()
time.sleep(0.01)
#Do some other work
while d.busy is True:
print(d.busy)
time.sleep(0.1)
#Join the process
p.join()

View File

@ -11,9 +11,9 @@
#include "slsDetector.h"
#include "sls_detector_defs.h"
class Detector {
class DetectorPythonInterface {
public:
Detector(int i) : det(i), multi_detector_id(i) {
DetectorPythonInterface(int i) : det(i), multi_detector_id(i) {
// Disable output from std::cout
// std::cout.setstate(std::ios_base::failbit);
}
@ -352,7 +352,7 @@ class Detector {
void checkDetectorVersionCompatibility() {
det.checkDetectorVersionCompatibility();
}
bool checkReceiverVersionCompatibility() {
void checkReceiverVersionCompatibility() {
det.checkReceiverVersionCompatibility();
}
@ -695,7 +695,7 @@ class Detector {
int multi_detector_id = 0;
};
void Detector::setFileFormat(const std::string &format) {
void DetectorPythonInterface::setFileFormat(const std::string &format) {
if (format == "binary") {
det.setFileFormat(slsDetectorDefs::fileFormat::BINARY);
} else if (format == "hdf5") {
@ -703,7 +703,7 @@ void Detector::setFileFormat(const std::string &format) {
}
}
std::string Detector::getFileFormat() {
std::string DetectorPythonInterface::getFileFormat() {
auto format =
det.setFileFormat(slsDetectorDefs::fileFormat::GET_FILE_FORMAT, -1);
switch (format) {
@ -717,7 +717,7 @@ std::string Detector::getFileFormat() {
}
slsDetectorDefs::networkParameter
Detector::networkNameToEnum(std::string par_name) {
DetectorPythonInterface::networkNameToEnum(std::string par_name) {
if (par_name == "detectormac") {
return slsDetectorDefs::networkParameter::DETECTOR_MAC;
@ -761,9 +761,9 @@ Detector::networkNameToEnum(std::string par_name) {
throw std::runtime_error("Could not decode network parameter");
};
// slsDetectorDefs::fileFormat Detector::file///
// slsDetectorDefs::fileFormat DetectorPythonInterface::file///
slsDetectorDefs::dacIndex Detector::dacNameToEnum(std::string dac_name) {
slsDetectorDefs::dacIndex DetectorPythonInterface::dacNameToEnum(std::string dac_name) {
// to avoid uninitialised
slsDetectorDefs::dacIndex dac = slsDetectorDefs::dacIndex::E_SvP;
@ -918,7 +918,7 @@ slsDetectorDefs::dacIndex Detector::dacNameToEnum(std::string dac_name) {
// overflow of single subframes */
// };
std::vector<std::string> Detector::getReadoutFlags() {
std::vector<std::string> DetectorPythonInterface::getReadoutFlags() {
std::vector<std::string> flags;
auto r = det.setReadOutFlags();
if (r & slsDetectorDefs::readOutFlags::STORE_IN_RAM)
@ -953,7 +953,7 @@ std::vector<std::string> Detector::getReadoutFlags() {
}
// note singular
void Detector::setReadoutFlag(const std::string flag_name) {
void DetectorPythonInterface::setReadoutFlag(const std::string flag_name) {
if (flag_name == "none")
det.setReadOutFlags(slsDetectorDefs::readOutFlags::NORMAL_READOUT);
else if (flag_name == "storeinram")
@ -988,7 +988,7 @@ void Detector::setReadoutFlag(const std::string flag_name) {
throw std::runtime_error("Flag name not recognized");
}
std::vector<double> Detector::getRateCorrection() {
std::vector<double> DetectorPythonInterface::getRateCorrection() {
std::vector<double> rate_corr;
for (int i = 0; i < det.getNumberOfDetectors(); ++i) {
rate_corr.push_back(det.getRateCorrection(i));
@ -996,7 +996,7 @@ std::vector<double> Detector::getRateCorrection() {
return rate_corr;
}
void Detector::pulseAllPixels(int n) {
void DetectorPythonInterface::pulseAllPixels(int n) {
// int pulsePixelNMove(int n=0,int x=0,int y=0);
// int pulsePixel(int n=0,int x=0,int y=0);
@ -1008,7 +1008,7 @@ void Detector::pulseAllPixels(int n) {
}
return;
}
void Detector::pulseDiagonal(int n) {
void DetectorPythonInterface::pulseDiagonal(int n) {
// int pulsePixelNMove(int n=0,int x=0,int y=0);
// int pulsePixel(int n=0,int x=0,int y=0);

19
python/src/enums.cpp Normal file
View File

@ -0,0 +1,19 @@
#include <pybind11/chrono.h>
#include <pybind11/operators.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "sls_detector_defs.h"
namespace py = pybind11;
void init_enums(py::module &m) {
py::class_<slsDetectorDefs> Defs(m, "slsDetectorDefs");
py::enum_<slsDetectorDefs::runStatus>(Defs, "runStatus")
.value("IDLE", slsDetectorDefs::runStatus::IDLE)
.value("ERROR", slsDetectorDefs::runStatus::ERROR)
.value("WAITING", slsDetectorDefs::runStatus::WAITING)
.value("RUN_FINISHED", slsDetectorDefs::runStatus::RUN_FINISHED)
.value("TRANSMITTING", slsDetectorDefs::runStatus::TRANSMITTING)
.value("RUNNING", slsDetectorDefs::runStatus::RUNNING)
.value("STOPPED", slsDetectorDefs::runStatus::STOPPED)
.export_values();
}

View File

@ -0,0 +1,70 @@
#include <pybind11/chrono.h>
#include <pybind11/operators.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "Detector.h"
#include "sls_detector_defs.h"
#include "typecaster.h"
namespace py = pybind11;
void init_experimental(py::module &m) {
// Experimental API to use the multi directly and inherit from to reduce
// code duplication need to investigate how to handle documentation
using sls::Detector;
using sls::Positions;
py::class_<Detector> multiDetectorApi(m, "multiDetectorApi");
multiDetectorApi
.def(py::init<int>())
// Acq related
.def("acquire", &Detector::acquire)
.def("startReceiver", &Detector::startReceiver, py::arg() = Positions{})
.def("stopReceiver", &Detector::stopReceiver, py::arg() = Positions{})
.def("getAcquiringFlag", &Detector::getAcquiringFlag)
.def("setAcquiringFlag", &Detector::setAcquiringFlag)
.def("getReceiverStatus", &Detector::getReceiverStatus,
py::arg() = Positions{})
// Configuration
.def("free", &Detector::freeSharedMemory)
.def("setConfig", &Detector::setConfig)
.def("getHostname", &Detector::getHostname, py::arg() = Positions{})
// Bits and registers
.def("setBit", &Detector::setBit, py::arg(), py::arg(),
py::arg() = Positions{})
.def("clearBit", &Detector::clearBit, py::arg(), py::arg(),
py::arg() = Positions{})
.def("getRegister", &Detector::getRegister, py::arg(),
py::arg() = Positions{})
.def("getStartingFrameNumber", &Detector::getStartingFrameNumber,
py::arg() = Positions{})
.def("setStartingFrameNumber", &Detector::setStartingFrameNumber,
py::arg(), py::arg() = Positions{})
// File
.def("getFileName", &Detector::getFileName)
.def("setFileName", &Detector::setFileName, py::arg())
.def("getFilePath", &Detector::getFilePath)
.def("setFilePath", &Detector::setFilePath, py::arg())
.def("setFileWrite", &Detector::setFileWrite, py::arg(),
py::arg() = Positions{})
.def("getFileWrite", &Detector::getFileWrite, py::arg() = Positions{})
.def("setFileOverWrite", &Detector::setFileOverWrite, py::arg(),
py::arg() = Positions{})
.def("getFileOverWrite", &Detector::getFileOverWrite,
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,
py::arg() = Positions{});
}

View File

@ -1,12 +1,31 @@
#include <pybind11/chrono.h>
#include <pybind11/operators.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "Detector.h"
#include "DetectorPythonInterface.h"
#include "Result.h"
#include "mythenFileIO.h"
#include <chrono>
#include <vector>
#include "typecaster.h"
// // Add type_typecaster to pybind for our wrapper type
// namespace pybind11 {
// namespace detail {
// template <typename Type, typename Alloc>
// struct type_caster<sls::Result<Type, Alloc>>
// : list_caster<sls::Result<Type, Alloc>, Type> {};
// } // namespace detail
// } // namespace pybind11
using ds = std::chrono::duration<double>;
namespace py = pybind11;
void init_enums(py::module &);
void init_experimental(py::module &);
PYBIND11_MODULE(_sls_detector, m) {
m.doc() = R"pbdoc(
C/C++ API
@ -18,7 +37,10 @@ PYBIND11_MODULE(_sls_detector, m) {
)pbdoc";
py::class_<Detector> DetectorApi(m, "DetectorApi", R"pbdoc(
init_enums(m);
init_experimental(m);
py::class_<DetectorPythonInterface> DetectorApi(m, "DetectorApi", R"pbdoc(
Interface to the multiSlsDetector class through Detector.h These functions
are used by the python classes Eiger and Jungfrau and normally it is better
to use them than to directly access functions here.
@ -43,298 +65,283 @@ PYBIND11_MODULE(_sls_detector, m) {
)pbdoc");
DetectorApi.def(py::init<int>())
.def("freeSharedMemory", &Detector::freeSharedMemory)
.def("getMultiDetectorId", &Detector::getMultiDetectorId)
.def("acq", &Detector::acquire)
.def("getAcquiringFlag", &Detector::getAcquiringFlag)
.def("setAcquiringFlag", &Detector::setAcquiringFlag)
.def("freeSharedMemory", &DetectorPythonInterface::freeSharedMemory)
.def("getMultiDetectorId", &DetectorPythonInterface::getMultiDetectorId)
.def("acq", &DetectorPythonInterface::acquire)
.def("getAcquiringFlag", &DetectorPythonInterface::getAcquiringFlag)
.def("setAcquiringFlag", &DetectorPythonInterface::setAcquiringFlag)
.def("setAllTrimbits", &Detector::setAllTrimbits)
.def("getAllTrimbits", &Detector::getAllTrimbits)
.def("setCounterBit", &Detector::setCounterBit)
.def("getCounterBit", &Detector::getCounterBit)
.def("setAllTrimbits", &DetectorPythonInterface::setAllTrimbits)
.def("getAllTrimbits", &DetectorPythonInterface::getAllTrimbits)
.def("setCounterBit", &DetectorPythonInterface::setCounterBit)
.def("getCounterBit", &DetectorPythonInterface::getCounterBit)
.def("getAdc", &Detector::getAdc)
.def("getDac", &Detector::getDac)
.def("getDac_mV", &Detector::getDac_mV)
.def("setDac", &Detector::setDac)
.def("setDac_mV", &Detector::setDac_mV)
.def("getDacFromIndex", &Detector::getDacFromIndex)
.def("setDacFromIndex", &Detector::setDacFromIndex)
.def("getAdc", &DetectorPythonInterface::getAdc)
.def("getDac", &DetectorPythonInterface::getDac)
.def("getDac_mV", &DetectorPythonInterface::getDac_mV)
.def("setDac", &DetectorPythonInterface::setDac)
.def("setDac_mV", &DetectorPythonInterface::setDac_mV)
.def("getDacFromIndex", &DetectorPythonInterface::getDacFromIndex)
.def("setDacFromIndex", &DetectorPythonInterface::setDacFromIndex)
.def("getDbitPipeline", &Detector::getDbitPipeline)
.def("setDbitPipeline", &Detector::setDbitPipeline)
.def("getDbitPhase", &Detector::getDbitPhase)
.def("setDbitPhase", &Detector::setDbitPhase)
.def("getDbitClock", &Detector::getDbitClock)
.def("setDbitClock", &Detector::setDbitClock)
.def("getDbitPipeline", &DetectorPythonInterface::getDbitPipeline)
.def("setDbitPipeline", &DetectorPythonInterface::setDbitPipeline)
.def("getDbitPhase", &DetectorPythonInterface::getDbitPhase)
.def("setDbitPhase", &DetectorPythonInterface::setDbitPhase)
.def("getDbitClock", &DetectorPythonInterface::getDbitClock)
.def("setDbitClock", &DetectorPythonInterface::setDbitClock)
.def("setThresholdEnergy", &Detector::setThresholdEnergy)
.def("getThresholdEnergy", &Detector::getThresholdEnergy)
.def("setThresholdEnergy", &DetectorPythonInterface::setThresholdEnergy)
.def("getThresholdEnergy", &DetectorPythonInterface::getThresholdEnergy)
.def("getSettings", &Detector::getSettings)
.def("setSettings", &Detector::setSettings)
.def("getSettingsDir", &Detector::getSettingsDir)
.def("setSettingsDir", &Detector::setSettingsDir)
.def("getSettings", &DetectorPythonInterface::getSettings)
.def("setSettings", &DetectorPythonInterface::setSettings)
.def("getSettingsDir", &DetectorPythonInterface::getSettingsDir)
.def("setSettingsDir", &DetectorPythonInterface::setSettingsDir)
.def("loadTrimbitFile", &Detector::loadTrimbitFile)
.def("setTrimEnergies", &Detector::setTrimEnergies)
.def("getTrimEnergies", &Detector::getTrimEnergies)
.def("loadTrimbitFile", &DetectorPythonInterface::loadTrimbitFile)
.def("setTrimEnergies", &DetectorPythonInterface::setTrimEnergies)
.def("getTrimEnergies", &DetectorPythonInterface::getTrimEnergies)
.def("pulseChip", &Detector::pulseChip)
.def("pulseAllPixels", &Detector::pulseAllPixels)
.def("pulseDiagonal", &Detector::pulseDiagonal)
.def("getRunStatus", &Detector::getRunStatus)
.def("readConfigurationFile", &Detector::readConfigurationFile)
.def("readParametersFile", &Detector::readParametersFile)
.def("checkOnline", &Detector::checkOnline)
.def("setReadoutClockSpeed", &Detector::setReadoutClockSpeed)
.def("getReadoutClockSpeed", &Detector::getReadoutClockSpeed)
.def("getSyncClkSpeed", &Detector::getSyncClkSpeed)
.def("getHostname", &Detector::getHostname)
.def("setHostname", &Detector::setHostname)
.def("pulseChip", &DetectorPythonInterface::pulseChip)
.def("pulseAllPixels", &DetectorPythonInterface::pulseAllPixels)
.def("pulseDiagonal", &DetectorPythonInterface::pulseDiagonal)
.def("getRunStatus", &DetectorPythonInterface::getRunStatus)
.def("readConfigurationFile",
&DetectorPythonInterface::readConfigurationFile)
.def("readParametersFile", &DetectorPythonInterface::readParametersFile)
.def("checkOnline", &DetectorPythonInterface::checkOnline)
.def("setReadoutClockSpeed",
&DetectorPythonInterface::setReadoutClockSpeed)
.def("getReadoutClockSpeed",
&DetectorPythonInterface::getReadoutClockSpeed)
.def("getSyncClkSpeed", &DetectorPythonInterface::getSyncClkSpeed)
.def("getHostname", &DetectorPythonInterface::getHostname)
.def("setHostname", &DetectorPythonInterface::setHostname)
.def("getReceiverPort", &Detector::getReceiverPort)
.def("setReceiverPort", &Detector::setReceiverPort)
.def("getReceiverPort", &DetectorPythonInterface::getReceiverPort)
.def("setReceiverPort", &DetectorPythonInterface::setReceiverPort)
.def("isChipPowered", &Detector::isChipPowered)
.def("powerChip", &Detector::powerChip)
.def("isChipPowered", &DetectorPythonInterface::isChipPowered)
.def("powerChip", &DetectorPythonInterface::powerChip)
.def("readRegister", &Detector::readRegister)
.def("writeRegister", &Detector::writeRegister)
.def("writeAdcRegister", &Detector::writeAdcRegister)
.def("setBitInRegister", &Detector::setBitInRegister)
.def("clearBitInRegister", &Detector::clearBitInRegister)
.def("readRegister", &DetectorPythonInterface::readRegister)
.def("writeRegister", &DetectorPythonInterface::writeRegister)
.def("writeAdcRegister", &DetectorPythonInterface::writeAdcRegister)
.def("setBitInRegister", &DetectorPythonInterface::setBitInRegister)
.def("clearBitInRegister", &DetectorPythonInterface::clearBitInRegister)
.def("setDynamicRange", &Detector::setDynamicRange)
.def("getDynamicRange", &Detector::getDynamicRange)
.def("getFirmwareVersion", &Detector::getFirmwareVersion)
.def("getServerVersion", &Detector::getServerVersion)
.def("getClientVersion", &Detector::getClientVersion)
.def("getReceiverVersion", &Detector::getReceiverVersion)
.def("getDetectorNumber", &Detector::getDetectorNumber)
.def("getRateCorrection", &Detector::getRateCorrection)
.def("setRateCorrection", &Detector::setRateCorrection)
.def("setDynamicRange", &DetectorPythonInterface::setDynamicRange)
.def("getDynamicRange", &DetectorPythonInterface::getDynamicRange)
.def("getFirmwareVersion", &DetectorPythonInterface::getFirmwareVersion)
.def("getServerVersion", &DetectorPythonInterface::getServerVersion)
.def("getClientVersion", &DetectorPythonInterface::getClientVersion)
.def("getReceiverVersion", &DetectorPythonInterface::getReceiverVersion)
.def("getDetectorNumber", &DetectorPythonInterface::getDetectorNumber)
.def("getRateCorrection", &DetectorPythonInterface::getRateCorrection)
.def("setRateCorrection", &DetectorPythonInterface::setRateCorrection)
.def("startAcquisition", &Detector::startAcquisition)
.def("stopAcquisition", &Detector::stopAcquisition)
.def("startReceiver", &Detector::startReceiver)
.def("stopReceiver", &Detector::stopReceiver)
.def("startAcquisition", &DetectorPythonInterface::startAcquisition)
.def("stopAcquisition", &DetectorPythonInterface::stopAcquisition)
.def("startReceiver", &DetectorPythonInterface::startReceiver)
.def("stopReceiver", &DetectorPythonInterface::stopReceiver)
.def("getFilePath",
(std::string(Detector::*)()) & Detector::getFilePath,
(std::string(DetectorPythonInterface::*)()) &
DetectorPythonInterface::getFilePath,
"Using multiSlsDetector")
.def("getFilePath",
(std::string(Detector::*)(int)) & Detector::getFilePath,
(std::string(DetectorPythonInterface::*)(int)) &
DetectorPythonInterface::getFilePath,
"File path for individual detector")
.def("setFilePath",
(void (Detector::*)(std::string)) & Detector::setFilePath)
.def("setFilePath",
(void (Detector::*)(std::string, int)) & Detector::setFilePath)
.def("setFilePath", (void (DetectorPythonInterface::*)(std::string)) &
DetectorPythonInterface::setFilePath)
.def("setFileName", &Detector::setFileName)
.def("getFileName", &Detector::getFileName)
.def("setFileIndex", &Detector::setFileIndex)
.def("getFileIndex", &Detector::getFileIndex)
.def("setFileName", &DetectorPythonInterface::setFileName)
.def("getFileName", &DetectorPythonInterface::getFileName)
.def("setFileIndex", &DetectorPythonInterface::setFileIndex)
.def("getFileIndex", &DetectorPythonInterface::getFileIndex)
.def("setExposureTime", &Detector::setExposureTime)
.def("getExposureTime", &Detector::getExposureTime)
.def("setSubExposureTime", &Detector::setSubExposureTime)
.def("getSubExposureTime", &Detector::getSubExposureTime)
.def("setPeriod", &Detector::setPeriod)
.def("getPeriod", &Detector::getPeriod)
.def("setSubExposureDeadTime", &Detector::setSubExposureDeadTime)
.def("getSubExposureDeadTime", &Detector::getSubExposureDeadTime)
.def("setExposureTime", &DetectorPythonInterface::setExposureTime)
.def("getExposureTime", &DetectorPythonInterface::getExposureTime)
.def("setSubExposureTime", &DetectorPythonInterface::setSubExposureTime)
.def("getSubExposureTime", &DetectorPythonInterface::getSubExposureTime)
.def("setPeriod", &DetectorPythonInterface::setPeriod)
.def("getPeriod", &DetectorPythonInterface::getPeriod)
.def("setSubExposureDeadTime", &DetectorPythonInterface::setSubExposureDeadTime)
.def("getSubExposureDeadTime", &DetectorPythonInterface::getSubExposureDeadTime)
.def("getCycles", &Detector::getCycles)
.def("setCycles", &Detector::setCycles)
.def("getNumberOfGates", &Detector::getNumberOfGates)
.def("setNumberOfGates", &Detector::setNumberOfGates)
.def("getDelay", &Detector::getDelay)
.def("setDelay", &Detector::setDelay)
.def("getCycles", &DetectorPythonInterface::getCycles)
.def("setCycles", &DetectorPythonInterface::setCycles)
.def("getNumberOfGates", &DetectorPythonInterface::getNumberOfGates)
.def("setNumberOfGates", &DetectorPythonInterface::setNumberOfGates)
.def("getDelay", &DetectorPythonInterface::getDelay)
.def("setDelay", &DetectorPythonInterface::setDelay)
.def("setStoragecellStart", &Detector::setStoragecellStart)
.def("getStoragecellStart", &Detector::getStoragecellStart)
.def("setNumberOfStorageCells", &Detector::setNumberOfStorageCells)
.def("getNumberOfStorageCells", &Detector::getNumberOfStorageCells)
.def("setStoragecellStart", &DetectorPythonInterface::setStoragecellStart)
.def("getStoragecellStart", &DetectorPythonInterface::getStoragecellStart)
.def("setNumberOfStorageCells", &DetectorPythonInterface::setNumberOfStorageCells)
.def("getNumberOfStorageCells", &DetectorPythonInterface::getNumberOfStorageCells)
.def("getTimingMode", &Detector::getTimingMode)
.def("setTimingMode", &Detector::setTimingMode)
.def("getTimingMode", &DetectorPythonInterface::getTimingMode)
.def("setTimingMode", &DetectorPythonInterface::setTimingMode)
.def("getDetectorType", &Detector::getDetectorType)
.def("getDetectorType", &DetectorPythonInterface::getDetectorType)
.def("setThresholdTemperature", &Detector::setThresholdTemperature)
.def("getThresholdTemperature", &Detector::getThresholdTemperature)
.def("setTemperatureControl", &Detector::setTemperatureControl)
.def("getTemperatureControl", &Detector::getTemperatureControl)
.def("getTemperatureEvent", &Detector::getTemperatureEvent)
.def("resetTemperatureEvent", &Detector::resetTemperatureEvent)
.def("setThresholdTemperature", &DetectorPythonInterface::setThresholdTemperature)
.def("getThresholdTemperature", &DetectorPythonInterface::getThresholdTemperature)
.def("setTemperatureControl", &DetectorPythonInterface::setTemperatureControl)
.def("getTemperatureControl", &DetectorPythonInterface::getTemperatureControl)
.def("getTemperatureEvent", &DetectorPythonInterface::getTemperatureEvent)
.def("resetTemperatureEvent", &DetectorPythonInterface::resetTemperatureEvent)
.def("getRxDataStreamStatus", &Detector::getRxDataStreamStatus)
.def("setRxDataStreamStatus", &Detector::setRxDataStreamStatus)
.def("getRxDataStreamStatus", &DetectorPythonInterface::getRxDataStreamStatus)
.def("setRxDataStreamStatus", &DetectorPythonInterface::setRxDataStreamStatus)
// Network stuff
.def("getReceiverHostname", &Detector::getReceiverHostname,
.def("getReceiverHostname",
&DetectorPythonInterface::getReceiverHostname,
py::arg("det_id") = -1)
.def("setReceiverHostname", &Detector::setReceiverHostname,
py::arg("hostname"), py::arg("det_id") = -1)
.def("getReceiverStreamingPort", &Detector::getReceiverStreamingPort)
.def("setReceiverStreamingPort", &Detector::setReceiverStreamingPort)
.def("getReceiverUDPPort", &Detector::getReceiverUDPPort)
.def("getReceiverUDPPort2", &Detector::getReceiverUDPPort2)
.def("setReceiverUDPPort", &Detector::setReceiverUDPPort)
.def("setReceiverUDPPort2", &Detector::setReceiverUDPPort2)
.def("setReceiverUDPIP", &Detector::setReceiverUDPIP)
.def("getReceiverUDPIP", &Detector::getReceiverUDPIP)
.def("getReceiverUDPMAC", &Detector::getReceiverUDPMAC)
.def("setReceiverUDPMAC", &Detector::setReceiverUDPMAC)
.def("setReceiverHostname",
&DetectorPythonInterface::setReceiverHostname, py::arg("hostname"),
py::arg("det_id") = -1)
.def("getReceiverStreamingPort",
&DetectorPythonInterface::getReceiverStreamingPort)
.def("setReceiverStreamingPort",
&DetectorPythonInterface::setReceiverStreamingPort)
.def("getReceiverUDPPort", &DetectorPythonInterface::getReceiverUDPPort)
.def("getReceiverUDPPort2",
&DetectorPythonInterface::getReceiverUDPPort2)
.def("setReceiverUDPPort", &DetectorPythonInterface::setReceiverUDPPort)
.def("setReceiverUDPPort2",
&DetectorPythonInterface::setReceiverUDPPort2)
.def("setReceiverUDPIP", &DetectorPythonInterface::setReceiverUDPIP)
.def("getReceiverUDPIP", &DetectorPythonInterface::getReceiverUDPIP)
.def("getReceiverUDPMAC", &DetectorPythonInterface::getReceiverUDPMAC)
.def("setReceiverUDPMAC", &DetectorPythonInterface::setReceiverUDPMAC)
.def("getReceiverPort", &Detector::getReceiverPort)
.def("setReceiverPort", &Detector::setReceiverPort)
.def("getReceiverPort", &DetectorPythonInterface::getReceiverPort)
.def("setReceiverPort", &DetectorPythonInterface::setReceiverPort)
.def("configureNetworkParameters",
&Detector::configureNetworkParameters)
.def("getDelayFrame", &Detector::getDelayFrame)
.def("setDelayFrame", &Detector::setDelayFrame)
.def("getDelayLeft", &Detector::getDelayLeft)
.def("setDelayLeft", &Detector::setDelayLeft)
.def("getDelayRight", &Detector::getDelayRight)
.def("setDelayRight", &Detector::setDelayRight)
.def("getLastClientIP", &Detector::getLastClientIP)
.def("getReceiverLastClientIP", &Detector::getReceiverLastClientIP)
&DetectorPythonInterface::configureNetworkParameters)
.def("getDelayFrame", &DetectorPythonInterface::getDelayFrame)
.def("setDelayFrame", &DetectorPythonInterface::setDelayFrame)
.def("getDelayLeft", &DetectorPythonInterface::getDelayLeft)
.def("setDelayLeft", &DetectorPythonInterface::setDelayLeft)
.def("getDelayRight", &DetectorPythonInterface::getDelayRight)
.def("setDelayRight", &DetectorPythonInterface::setDelayRight)
.def("getLastClientIP", &DetectorPythonInterface::getLastClientIP)
.def("getReceiverLastClientIP",
&DetectorPythonInterface::getReceiverLastClientIP)
.def("setFramesPerFile", &Detector::setFramesPerFile)
.def("getFramesPerFile", &Detector::getFramesPerFile)
.def("setReceiverFifoDepth", &Detector::setReceiverFifoDepth)
.def("getReceiverFifoDepth", &Detector::getReceiverFifoDepth)
.def("setFramesPerFile", &DetectorPythonInterface::setFramesPerFile)
.def("getFramesPerFile", &DetectorPythonInterface::getFramesPerFile)
.def("setReceiverFifoDepth",
&DetectorPythonInterface::setReceiverFifoDepth)
.def("getReceiverFifoDepth",
&DetectorPythonInterface::getReceiverFifoDepth)
.def("getReceiverFrameDiscardPolicy",
&Detector::getReceiverFrameDiscardPolicy)
&DetectorPythonInterface::getReceiverFrameDiscardPolicy)
.def("setReceiverFramesDiscardPolicy",
&Detector::setReceiverFramesDiscardPolicy)
.def("setPartialFramesPadding", &Detector::setPartialFramesPadding)
.def("getPartialFramesPadding", &Detector::getPartialFramesPadding)
&DetectorPythonInterface::setReceiverFramesDiscardPolicy)
.def("setPartialFramesPadding",
&DetectorPythonInterface::setPartialFramesPadding)
.def("getPartialFramesPadding",
&DetectorPythonInterface::getPartialFramesPadding)
.def("getUserDetails", &Detector::getUserDetails)
.def("getUserDetails", &DetectorPythonInterface::getUserDetails)
.def("checkDetectorVersionCompatibility",
&Detector::checkDetectorVersionCompatibility)
&DetectorPythonInterface::checkDetectorVersionCompatibility)
.def("checkReceiverVersionCompatibility",
&Detector::checkReceiverVersionCompatibility)
.def("getMeasuredPeriod", &Detector::getMeasuredPeriod)
.def("getMeasuredSubPeriod", &Detector::getMeasuredSubPeriod)
&DetectorPythonInterface::checkReceiverVersionCompatibility)
.def("getMeasuredPeriod", &DetectorPythonInterface::getMeasuredPeriod)
.def("getMeasuredSubPeriod",
&DetectorPythonInterface::getMeasuredSubPeriod)
.def("setFileWrite", &Detector::setFileWrite)
.def("getFileWrite", &Detector::getFileWrite)
.def("setFileOverWrite", &Detector::setFileOverWrite)
.def("getFileOverWrite", &Detector::getFileOverWrite)
.def("getDacVthreshold", &Detector::getDacVthreshold)
.def("setDacVthreshold", &Detector::setDacVthreshold)
.def("setNumberOfFrames", &Detector::setNumberOfFrames)
.def("getNumberOfFrames", &Detector::getNumberOfFrames)
.def("setFileWrite", &DetectorPythonInterface::setFileWrite)
.def("getFileWrite", &DetectorPythonInterface::getFileWrite)
.def("setFileOverWrite", &DetectorPythonInterface::setFileOverWrite)
.def("getFileOverWrite", &DetectorPythonInterface::getFileOverWrite)
.def("getDacVthreshold", &DetectorPythonInterface::getDacVthreshold)
.def("setDacVthreshold", &DetectorPythonInterface::setDacVthreshold)
.def("setNumberOfFrames", &DetectorPythonInterface::setNumberOfFrames)
.def("getNumberOfFrames", &DetectorPythonInterface::getNumberOfFrames)
// Overloaded calls
.def("getFramesCaughtByReceiver",
(int (Detector::*)()) & Detector::getFramesCaughtByReceiver)
(int (DetectorPythonInterface::*)()) &
DetectorPythonInterface::getFramesCaughtByReceiver)
.def("getFramesCaughtByReceiver",
(int (Detector::*)(int)) & Detector::getFramesCaughtByReceiver)
(int (DetectorPythonInterface::*)(int)) &
DetectorPythonInterface::getFramesCaughtByReceiver)
.def("resetFramesCaught", &Detector::resetFramesCaught)
.def("resetFramesCaught", &DetectorPythonInterface::resetFramesCaught)
.def("getReceiverCurrentFrameIndex",
&Detector::getReceiverCurrentFrameIndex)
.def("getGapPixels", &Detector::getGapPixels)
.def("setGapPixels", &Detector::setGapPixels)
.def("getFlippedDataX", &Detector::getFlippedDataX)
.def("getFlippedDataY", &Detector::getFlippedDataY)
.def("setFlippedDataX", &Detector::setFlippedDataX)
.def("setFlippedDataY", &Detector::setFlippedDataY)
&DetectorPythonInterface::getReceiverCurrentFrameIndex)
.def("getGapPixels", &DetectorPythonInterface::getGapPixels)
.def("setGapPixels", &DetectorPythonInterface::setGapPixels)
.def("getFlippedDataX", &DetectorPythonInterface::getFlippedDataX)
.def("getFlippedDataY", &DetectorPythonInterface::getFlippedDataY)
.def("setFlippedDataX", &DetectorPythonInterface::setFlippedDataX)
.def("setFlippedDataY", &DetectorPythonInterface::setFlippedDataY)
.def("getServerLock", &Detector::getServerLock)
.def("setServerLock", &Detector::setServerLock)
.def("getReceiverLock", &Detector::getReceiverLock)
.def("setReceiverLock", &Detector::setReceiverLock)
.def("getServerLock", &DetectorPythonInterface::getServerLock)
.def("setServerLock", &DetectorPythonInterface::setServerLock)
.def("getReceiverLock", &DetectorPythonInterface::getReceiverLock)
.def("setReceiverLock", &DetectorPythonInterface::setReceiverLock)
.def("getReadoutFlags", &Detector::getReadoutFlags)
.def("setReadoutFlag", &Detector::setReadoutFlag)
.def("getReadoutFlags", &DetectorPythonInterface::getReadoutFlags)
.def("setReadoutFlag", &DetectorPythonInterface::setReadoutFlag)
.def("setFileFormat", &Detector::setFileFormat)
.def("getFileFormat", &Detector::getFileFormat)
.def("setFileFormat", &DetectorPythonInterface::setFileFormat)
.def("getFileFormat", &DetectorPythonInterface::getFileFormat)
.def("getActive", &Detector::getActive)
.def("setActive", &Detector::setActive)
.def("getActive", &DetectorPythonInterface::getActive)
.def("setActive", &DetectorPythonInterface::setActive)
.def("getTenGigabitEthernet", &Detector::getTenGigabitEthernet)
.def("setTenGigabitEthernet", &Detector::setTenGigabitEthernet)
.def("getTenGigabitEthernet",
&DetectorPythonInterface::getTenGigabitEthernet)
.def("setTenGigabitEthernet",
&DetectorPythonInterface::setTenGigabitEthernet)
.def("getPatternLoops", &Detector::getPatternLoops, py::arg("level"),
.def("getPatternLoops", &DetectorPythonInterface::getPatternLoops,
py::arg("level"), py::arg("det_id") = -1)
.def("setPatternLoops", &DetectorPythonInterface::setPatternLoops,
py::arg("level"), py::arg("start"), py::arg("stop"), py::arg("n"),
py::arg("det_id") = -1)
.def("setPatternLoops", &Detector::setPatternLoops, py::arg("level"),
py::arg("start"), py::arg("stop"), py::arg("n"),
.def("setPatternWord", &DetectorPythonInterface::setPatternWord,
py::arg("addr"), py::arg("word"), py::arg("det_id") = -1)
.def("getPatternWord", &DetectorPythonInterface::getPatternWord,
py::arg("addr"), py::arg("det_id") = -1)
.def("setPatternIOControl",
&DetectorPythonInterface::setPatternIOControl, py::arg("word"),
py::arg("det_id") = -1)
.def("setPatternWord", &Detector::setPatternWord, py::arg("addr"),
py::arg("word"), py::arg("det_id") = -1)
.def("getPatternWord", &Detector::getPatternWord, py::arg("addr"),
.def("setPatternClockControl",
&DetectorPythonInterface::setPatternClockControl, py::arg("word"),
py::arg("det_id") = -1)
.def("setPatternIOControl", &Detector::setPatternIOControl,
py::arg("word"), py::arg("det_id") = -1)
.def("setPatternClockControl", &Detector::setPatternClockControl,
py::arg("word"), py::arg("det_id") = -1)
.def("setPatternWaitAddr", &Detector::setPatternWaitAddr,
.def("setPatternWaitAddr", &DetectorPythonInterface::setPatternWaitAddr,
py::arg("level"), py::arg("addr"), py::arg("det_id") = -1)
.def("getPatternWaitAddr", &Detector::getPatternWaitAddr,
.def("getPatternWaitAddr", &DetectorPythonInterface::getPatternWaitAddr,
py::arg("level"), py::arg("det_id") = -1)
.def("setPatternWaitTime", &Detector::setPatternWaitTime,
.def("setPatternWaitTime", &DetectorPythonInterface::setPatternWaitTime,
py::arg("level"), py::arg("duration"), py::arg("det_id") = -1)
.def("getPatternWaitTime", &Detector::getPatternWaitTime,
.def("getPatternWaitTime", &DetectorPythonInterface::getPatternWaitTime,
py::arg("level"), py::arg("det_id") = -1)
.def("getImageSize", &Detector::getImageSize)
.def("setImageSize", &Detector::setImageSize)
.def("getNumberOfDetectors", &Detector::getNumberOfDetectors)
.def("getDetectorGeometry", &Detector::getDetectorGeometry);
.def("getImageSize", &DetectorPythonInterface::getImageSize)
.def("setImageSize", &DetectorPythonInterface::setImageSize)
.def("getNumberOfDetectors",
&DetectorPythonInterface::getNumberOfDetectors)
.def("getDetectorGeometry",
&DetectorPythonInterface::getDetectorGeometry);
// Experimental API to use the multi directly and inherit from to reduce
// code duplication need to investigate how to handle documentation
py::class_<multiSlsDetector> multiDetectorApi(m, "multiDetectorApi");
multiDetectorApi.def(py::init<int>())
.def("acquire", &multiSlsDetector::acquire)
.def_property("exptime",
py::cpp_function(&multiSlsDetector::setExposureTime,
py::arg(), py::arg() = -1, py::arg() = 0,
py::arg("det_id") = -1),
py::cpp_function(&multiSlsDetector::setExposureTime,
py::arg(), py::arg() = -1, py::arg() = 0,
py::arg("det_id") = -1))
.def("getExposureTime", &multiSlsDetector::setExposureTime, py::arg()=-1,
py::arg() = 0, py::arg("det_id") = -1)
.def_property_readonly(
"hostname", py::cpp_function(&multiSlsDetector::getHostname,
py::arg(), py::arg("det_id") = -1))
.def_property("busy",
py::cpp_function(&multiSlsDetector::getAcquiringFlag),
py::cpp_function(&multiSlsDetector::setAcquiringFlag))
.def_property_readonly(
"rx_tcpport", py::cpp_function(&multiSlsDetector::getReceiverPort))
.def_property_readonly(
"detectornumber",
py::cpp_function(&multiSlsDetector::getDetectorNumber))
.def_property("rx_udpip",
py::cpp_function(&multiSlsDetector::getReceiverUDPIP,
py::arg(), py::arg("det_id") = -1),
py::cpp_function(&multiSlsDetector::setReceiverUDPIP,
py::arg(), py::arg("ip"),
py::arg("det_id") = -1))
.def("_getReceiverUDPIP", &multiSlsDetector::getReceiverUDPIP)
.def("_setReceiverUDPIP", &multiSlsDetector::setReceiverUDPIP)
.def("getPatternLoops", &multiSlsDetector::getPatternLoops,
py::arg("level"), py::arg("det_id") = -1)
.def("setPatternLoops", &multiSlsDetector::setPatternLoops)
.def("setPatternWord", &multiSlsDetector::setPatternWord,
py::arg("addr"), py::arg("word"), py::arg("det_id") = -1);
py::module io = m.def_submodule("io", "Submodule for io");
io.def("read_my302_file", &read_my302_file, "some");

11
python/src/typecaster.h Normal file
View File

@ -0,0 +1,11 @@
#pragma once
#include <pybind11/pybind11.h>
#include "Result.h"
// Add type_typecaster to pybind for our wrapper type
namespace pybind11 {
namespace detail {
template <typename Type, typename Alloc>
struct type_caster<sls::Result<Type, Alloc>>
: list_caster<sls::Result<Type, Alloc>, Type> {};
} // namespace detail
} // namespace pybind11