Release of 5.1.0 (#237)

* Setting pattern from memory (#218)

* ToString accepts c-style arrays

* fixed patwait time bug in validation

* Introduced pattern class

* compile for servers too

* Python binding for Pattern

* added scanParameters in Python

* slsReceiver: avoid potential memory leak around Implementation::generalData

* additional constructors for scanPrameters in python

* bugfix: avoid potentital memory leak in receiver if called outside constructor context

* added scanParameters in Python

* additional constructors for scanPrameters in python

* M3defaultpattern (#227)

* default pattern for m3 and moench including Python bindings

* M3settings (#228)

* some changes to compile on RH7 and in the server to load the default chip status register at startup

* Updated mythen3DeectorServer_developer executable with correct initialization at startup

Co-authored-by: Erik Frojdh <erik.frojdh@gmail.com>
Co-authored-by: Anna Bergamaschi <anna.bergamaschi@psi.ch>

* Pattern.h as a public header files (#229)

* fixed buffer overflow but caused by using global instead of local enum

* replacing out of range trimbits with edge values

* replacing dac values that are out of range after interpolation

* updated pybind11 to 2.6.2

* Mythen3 improved synchronization (#231)

Disabling scans for multi module Mythen3, since there is no feedback of the detectors being ready
startDetector first starts the slaves then the master
acquire firs calls startDetector for the slaves then acquire on the master
getMaster to read back from hardware which one is master

* New server for JF to go with the new FW (#232)

* Modified Jungfrau speed settings for HW1.0 - FW fix version 1.1.1, compilation date 210218

* Corrected bug. DBIT clk phase is implemented in both HW version 1.0 and 2.0. Previous version did not update the DBIT phase shift on the configuration of a speed.

* fix for m3 scan with single module

* m3 fw version

* m3 server

* bugfix for bottom when setting quad

* new strategy for finding zmq based on cppzmq



Co-authored-by: Dhanya Thattil <dhanya.thattil@psi.ch>
Co-authored-by: Dhanya Thattil <33750417+thattil@users.noreply.github.com>
Co-authored-by: Alejandro Homs Puron <ahoms@esrf.fr>
Co-authored-by: Anna Bergamaschi <anna.bergamaschi@psi.ch>
Co-authored-by: Xiaoqiang Wang <xiaoqiangwang@gmail.com>
Co-authored-by: lopez_c <carlos.lopez-cuenca@psi.ch>
This commit is contained in:
Erik Fröjdh
2021-03-22 14:43:11 +01:00
committed by GitHub
parent 64de9f3ad0
commit 2f2fe4dd47
168 changed files with 3614 additions and 9057 deletions

View File

@@ -4,6 +4,8 @@ pybind11_add_module(_slsdet
src/enums.cpp
src/detector.cpp
src/network.cpp
src/pattern.cpp
src/scan.cpp
)
target_link_libraries(_slsdet PUBLIC
@@ -28,6 +30,7 @@ set( PYTHON_FILES
enums.py
errors.py
gotthard.py
pattern.py
gotthard2.py
moench.py
proxy.py

View File

@@ -0,0 +1,14 @@
from slsdet import Detector, patternParameters
d = Detector()
pat = patternParameters()
#Access to members of the structure using numpy arrays
pat.patlimits = 0x0, 0xa
d.setPattern(pat)
#Load pattern from file
pat.load("/some/dir/some.pat")

View File

@@ -6,7 +6,7 @@ d = Detector()
d.fformat = fileFormat.BINARY
# Altough not recommended for convenience all enums
# and some other things can be impored using *
# and some other things can be imported using *
from slsdet import *
d.speed = speedLevel.FULL_SPEED
@@ -15,6 +15,6 @@ d.speed = speedLevel.FULL_SPEED
import slsdet.enums
for enum in dir(slsdet.enums):
# filter out special memebers
# filter out special members
if not enum.startswith('_'):
print(enum)

View File

@@ -0,0 +1,19 @@
from slsdet import Mythen3, scanParameters, dacIndex
#Configure scan
sp = scanParameters()
sp.enable = 1
sp.dacInd = dacIndex.VTH1
sp.startOffset = 0
sp.stopOffset = 1000
sp.stepSize = 100
sp.dacSettleTime_ns = int(1e9)
# Send scan to detector
d = Mythen3()
d.setScan(sp)

View File

@@ -10,6 +10,8 @@ from slsdet.lookup import view, find
import slsdet
d = Detector()
e = Eiger()
c = Ctb()

View File

@@ -0,0 +1,80 @@
import subprocess
import os
import sys
from pathlib import Path
import shutil as sh
from argparse import ArgumentParser
class color:
HEADER = "\033[95m"
BLUE = "\033[94m"
CYAN = "\033[96m"
GREEN = "\033[92m"
YELLOW = "\033[93m"
RED = "\033[91m"
ENDC = "\033[0m"
BOLD = "\033[1m"
UNDERLINE = "\033[4m"
MAGENTA = "\033[35m"
@staticmethod
def red(s):
return f"{color.RED}{s}{color.ENDC}"
@staticmethod
def green(s):
return f"{color.GREEN}{s}{color.ENDC}"
def add_to_path():
paths = [
"/opt/uClinux/bfin-uclinux/bin",
"/opt/nios2-gcc/bin",
"/opt/eldk-5.1/powerpc-4xx-softfloat/sysroots/i686-eldk-linux/usr/bin/ppc405-linux",
]
os.environ["PATH"] += os.pathsep + os.pathsep.join(paths)
def rc_to_string(rc):
if rc == 0:
return color.green("OK")
else:
return color.red("FAIL")
parser = ArgumentParser()
parser.add_argument('-t', '--tag', help = 'Tag added to server file name', default='developer')
parser.add_argument('-g', '--git', help='Add new servers to the git repo', action="store_true")
args = parser.parse_args()
servers = [
"eigerDetectorServer",
"jungfrauDetectorServer",
"mythen3DetectorServer",
"gotthard2DetectorServer",
"gotthardDetectorServer",
"ctbDetectorServer",
"moenchDetectorServer",
]
server_root = Path("../../slsDetectorServers/").resolve()
add_to_path()
for server in servers:
bin_name = f"{server}_{args.tag}"
path = server_root / server
print(f"{bin_name} - ", end="")
os.chdir(path)
try:
sh.rmtree(path/'bin')
except FileNotFoundError:
pass
p = subprocess.run(["make"], stdout=subprocess.DEVNULL)
print(rc_to_string(p.returncode))
if p.returncode == 0:
sh.move(f"bin/{server}", f"bin/{bin_name}")
if args.git:
print("Adding to git")
subprocess.run(['git', 'add', 'bin', '-f'])

View File

@@ -55,7 +55,7 @@ def generate_enum_string(enums):
data.append('.export_values();\n\n')
return ''.join(data)
with open('../../slsSupportLib/include/sls_detector_defs.h') as f:
with open('../../slsSupportLib/include/sls/sls_detector_defs.h') as f:
data = f.read()
data = remove_comments(data)

View File

@@ -2,11 +2,12 @@
Setup file for slsdet
Build upon the pybind11 example found here: https://github.com/pybind/python_example
"""
from setuptools import setup, Extension, find_packages
from setuptools.command.build_ext import build_ext
import sys
import setuptools
import os
import sys
sys.path.append('../libs/pybind11')
from setuptools import setup, find_packages
from pybind11.setup_helpers import Pybind11Extension, build_ext
__version__ = os.environ.get('GIT_DESCRIBE_TAG', 'developer')
@@ -19,109 +20,29 @@ def get_conda_path():
return os.environ['CONDA_PREFIX']
# class get_pybind_include(object):
# """Helper class to determine the pybind11 include path
# The purpose of this class is to postpone importing pybind11
# until it is actually installed, so that the ``get_include()``
# method can be invoked. """
# def __init__(self, user=False):
# self.user = user
# def __str__(self):
# import pybind11
# return pybind11.get_include(self.user)
#TODO migrate to CMake build?
ext_modules = [
Extension(
Pybind11Extension(
'_slsdet',
['src/main.cpp',
'src/enums.cpp',
'src/detector.cpp',
'src/network.cpp'],
'src/network.cpp',
'src/pattern.cpp',
'src/scan.cpp',],
include_dirs=[
# Path to pybind11 headers
# get_pybind_include(),
# get_pybind_include(user=True),
os.path.join('../libs/pybind11/include'),
os.path.join(get_conda_path(), 'include'),
],
libraries=['SlsDetector', 'SlsReceiver', 'zmq'],
libraries=['SlsDetector', 'SlsSupport', 'SlsReceiver', 'zmq'],
library_dirs=[
os.path.join(get_conda_path(), 'lib'),
os.path.join(get_conda_path(), 'bin'),
],
language='c++'
),
]
# As of Python 3.6, CCompiler has a `has_flag` method.
# cf http://bugs.python.org/issue26689
def has_flag(compiler, flagname):
"""Return a boolean indicating whether a flag name is supported on
the specified compiler.
"""
import tempfile
with tempfile.NamedTemporaryFile('w', suffix='.cpp') as f:
f.write('int main (int argc, char **argv) { return 0; }')
try:
compiler.compile([f.name], extra_postargs=[flagname])
except setuptools.distutils.errors.CompileError:
return False
return True
def cpp_flag(compiler):
"""Return the -std=c++[11/14] compiler flag.
The c++14 is prefered over c++11 (when it is available).
"""
if has_flag(compiler, '-std=c++14'):
return '-std=c++14'
elif has_flag(compiler, '-std=c++11'):
return '-std=c++11'
else:
raise RuntimeError('Unsupported compiler -- at least C++11 support '
'is needed!')
class BuildExt(build_ext):
"""A custom build extension for adding compiler-specific options."""
c_opts = {
'msvc': ['/EHsc'],
'unix': [],
}
if sys.platform == 'darwin':
c_opts['unix'] += ['-stdlib=libc++', '-mmacosx-version-min=10.7']
def build_extensions(self):
ct = self.compiler.compiler_type
opts = self.c_opts.get(ct, [])
if ct == 'unix':
opts.append('-DVERSION_INFO="%s"' % self.distribution.get_version())
opts.append(cpp_flag(self.compiler))
if has_flag(self.compiler, '-fvisibility=hidden'):
opts.append('-fvisibility=hidden')
elif ct == 'msvc':
opts.append('/DVERSION_INFO=\\"%s\\"' % self.distribution.get_version())
for ext in self.extensions:
ext.extra_compile_args = opts
print('**************************************************')
print(ct)
print(opts)
print('**************************************************')
build_ext.build_extensions(self)
def get_shared_lib():
return [f for f in os.listdir('.') if '_slsdet' in f]
setup(
name='slsdet',
version=__version__,
@@ -132,6 +53,6 @@ setup(
long_description='',
packages=find_packages(exclude=['contrib', 'docs', 'tests']),
ext_modules=ext_modules,
cmdclass={'build_ext': BuildExt},
cmdclass={"build_ext": build_ext},
zip_safe=False,
)

View File

@@ -8,6 +8,8 @@ from .mythen3 import Mythen3
from .gotthard2 import Gotthard2
from .gotthard import Gotthard
from .moench import Moench
from .pattern import Pattern, patternParameters
import _slsdet
xy = _slsdet.xy
@@ -18,3 +20,4 @@ from .enums import *
IpAddr = _slsdet.IpAddr
MacAddr = _slsdet.MacAddr
scanParameters = _slsdet.scanParameters

View File

@@ -1696,6 +1696,8 @@ class Detector(CppDetectorApi):
To change settings as well or set threshold without trimbits, use setThresholdEnergy.
:setter: It loads trim files from settingspath.
"""
if self.type == detectorType.MYTHEN3:
return self.getAllThresholdEnergy()
return self.getThresholdEnergy()
@threshold.setter

53
python/slsdet/pattern.py Normal file
View File

@@ -0,0 +1,53 @@
import _slsdet
from _slsdet import Pattern
class patternParameters(_slsdet.patternParameters):
def __init__(self):
super().__init__()
self.view = self.numpy_view()
self.names = self.view.dtype.names
def __getattr__(self, name):
if name in self.names:
return self.view[name][0]
else:
raise KeyError(f"Key: {name} not found")
def __setattr__(self, name, value):
if name in ["view", "names"]:
self.__dict__[name] = value
elif name in self.names:
self.view[name] = value
else:
raise KeyError(f"Key: {name} not found")
# Provide custom dir for tab completion
def __dir__(self):
return self.names
class Pattern(_slsdet.Pattern):
def __init__(self):
super().__init__()
self.view = self.data().numpy_view()
self.names = self.view.dtype.names
def __getattr__(self, name):
if name in self.names:
return self.view[name][0]
else:
raise KeyError(f"Key: {name} not found")
def __setattr__(self, name, value):
if name in ["view", "names"]:
self.__dict__[name] = value
elif name in self.names:
self.view[name] = value
else:
raise KeyError(f"Key: {name} not found")
# Provide custom dir for tab completion
def __dir__(self):
return self.names

View File

@@ -102,6 +102,34 @@ void init_det(py::module &m) {
(void (Detector::*)(defs::detectorSettings, sls::Positions)) &
Detector::setSettings,
py::arg(), py::arg() = Positions{})
.def("getThresholdEnergy",
(Result<int>(Detector::*)(sls::Positions) const) &
Detector::getThresholdEnergy,
py::arg() = Positions{})
.def("getAllThresholdEnergy",
(Result<std::array<int, 3>>(Detector::*)(sls::Positions) const) &
Detector::getAllThresholdEnergy,
py::arg() = Positions{})
.def("setThresholdEnergy",
(void (Detector::*)(int, defs::detectorSettings, bool,
sls::Positions)) &
Detector::setThresholdEnergy,
py::arg(), py::arg() = defs::STANDARD, py::arg() = true,
py::arg() = Positions{})
.def("setThresholdEnergy",
(void (Detector::*)(std::array<int, 3>, defs::detectorSettings,
bool, sls::Positions)) &
Detector::setThresholdEnergy,
py::arg(), py::arg() = defs::STANDARD, py::arg() = true,
py::arg() = Positions{})
.def("getSettingsPath",
(Result<std::string>(Detector::*)(sls::Positions) const) &
Detector::getSettingsPath,
py::arg() = Positions{})
.def("setSettingsPath",
(void (Detector::*)(const std::string &, sls::Positions)) &
Detector::setSettingsPath,
py::arg(), py::arg() = Positions{})
.def("loadTrimbits",
(void (Detector::*)(const std::string &, sls::Positions)) &
Detector::loadTrimbits,
@@ -114,6 +142,14 @@ void init_det(py::module &m) {
(void (Detector::*)(int, sls::Positions)) &
Detector::setAllTrimbits,
py::arg(), py::arg() = Positions{})
.def("getTrimEnergies",
(Result<std::vector<int>>(Detector::*)(sls::Positions) const) &
Detector::getTrimEnergies,
py::arg() = Positions{})
.def("setTrimEnergies",
(void (Detector::*)(std::vector<int>, sls::Positions)) &
Detector::setTrimEnergies,
py::arg(), py::arg() = Positions{})
.def("getGapPixelsinCallback",
(bool (Detector::*)() const) & Detector::getGapPixelsinCallback)
.def("setGapPixelsinCallback",
@@ -783,24 +819,6 @@ void init_det(py::module &m) {
(void (Detector::*)(sls::ns, sls::Positions)) &
Detector::setSubDeadTime,
py::arg(), py::arg() = Positions{})
.def("getThresholdEnergy",
(Result<int>(Detector::*)(sls::Positions) const) &
Detector::getThresholdEnergy,
py::arg() = Positions{})
.def("setThresholdEnergy",
(void (Detector::*)(int, defs::detectorSettings, bool,
sls::Positions)) &
Detector::setThresholdEnergy,
py::arg(), py::arg() = defs::STANDARD, py::arg() = true,
py::arg() = Positions{})
.def("getSettingsPath",
(Result<std::string>(Detector::*)(sls::Positions) const) &
Detector::getSettingsPath,
py::arg() = Positions{})
.def("setSettingsPath",
(void (Detector::*)(const std::string &, sls::Positions)) &
Detector::setSettingsPath,
py::arg(), py::arg() = Positions{})
.def("getOverFlowMode",
(Result<bool>(Detector::*)(sls::Positions) const) &
Detector::getOverFlowMode,
@@ -816,14 +834,6 @@ void init_det(py::module &m) {
.def("setBottom",
(void (Detector::*)(bool, sls::Positions)) & Detector::setBottom,
py::arg(), py::arg() = Positions{})
.def("getTrimEnergies",
(Result<std::vector<int>>(Detector::*)(sls::Positions) const) &
Detector::getTrimEnergies,
py::arg() = Positions{})
.def("setTrimEnergies",
(void (Detector::*)(std::vector<int>, sls::Positions)) &
Detector::setTrimEnergies,
py::arg(), py::arg() = Positions{})
.def("getRateCorrection",
(Result<sls::ns>(Detector::*)(sls::Positions) const) &
Detector::getRateCorrection,
@@ -1122,6 +1132,10 @@ void init_det(py::module &m) {
(Result<std::array<ns, 3>>(Detector::*)(sls::Positions) const) &
Detector::getGateDelayForAllGates,
py::arg() = Positions{})
.def("getMaster",
(Result<bool>(Detector::*)(sls::Positions) const) &
Detector::getMaster,
py::arg() = Positions{})
.def("getNumberOfAnalogSamples",
(Result<int>(Detector::*)(sls::Positions) const) &
Detector::getNumberOfAnalogSamples,
@@ -1271,9 +1285,17 @@ void init_det(py::module &m) {
(void (Detector::*)(const std::string &, sls::Positions)) &
Detector::setPattern,
py::arg(), py::arg() = Positions{})
.def("setPattern",
(void (Detector::*)(const sls::Pattern &, sls::Positions)) &
Detector::setPattern,
py::arg(), py::arg() = Positions{})
.def("savePattern",
(void (Detector::*)(const std::string &)) & Detector::savePattern,
py::arg())
.def("loadDefaultPattern",
(void (Detector::*)(sls::Positions)) &
Detector::loadDefaultPattern,
py::arg() = Positions{})
.def("getPatternIOControl",
(Result<uint64_t>(Detector::*)(sls::Positions) const) &
Detector::getPatternIOControl,

View File

@@ -2,10 +2,12 @@
* warning */
#include <pybind11/chrono.h>
#include <pybind11/numpy.h>
#include <pybind11/operators.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "sls/Pattern.h"
#include "sls/sls_detector_defs.h"
namespace py = pybind11;
void init_enums(py::module &m) {

View File

@@ -1,18 +1,19 @@
#include <pybind11/chrono.h>
#include <pybind11/numpy.h>
#include <pybind11/operators.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "sls/sls_detector_defs.h"
#include "sls/Pattern.h"
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(py::init<int,int>());
xy.def(py::init<int, int>());
xy.def_readwrite("x", &slsDetectorDefs::xy::x);
xy.def_readwrite("y", &slsDetectorDefs::xy::y);
[[ENUMS]]
[[ENUMS]]
}

View File

@@ -19,6 +19,8 @@ void init_enums(py::module &);
void init_experimental(py::module &);
void init_det(py::module &);
void init_network(py::module &);
void init_pattern(py::module &);
void init_scan(py::module &);
PYBIND11_MODULE(_slsdet, m) {
m.doc() = R"pbdoc(
C/C++ API
@@ -33,6 +35,8 @@ PYBIND11_MODULE(_slsdet, m) {
init_enums(m);
init_det(m);
init_network(m);
init_pattern(m);
init_scan(m);
// init_experimental(m);

29
python/src/pattern.cpp Normal file
View File

@@ -0,0 +1,29 @@
#include <pybind11/chrono.h>
#include <pybind11/numpy.h>
#include <pybind11/operators.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "sls/Pattern.h"
#include "sls/sls_detector_defs.h"
namespace py = pybind11;
void init_pattern(py::module &m) {
using pat = sls::patternParameters;
py::class_<pat> patternParameters(m, "patternParameters");
PYBIND11_NUMPY_DTYPE(pat, word, ioctrl, limits, loop, nloop, wait,
waittime);
patternParameters.def(py::init());
patternParameters.def("numpy_view", [](py::object &obj) {
pat &o = obj.cast<pat &>();
return py::array_t<pat>(1, &o, obj);
});
py::class_<sls::Pattern> Pattern(m, "Pattern");
Pattern.def(py::init());
Pattern.def("load", &sls::Pattern::load);
Pattern.def("data", (pat * (sls::Pattern::*)()) & sls::Pattern::data,
py::return_value_policy::reference);
}

39
python/src/scan.cpp Normal file
View File

@@ -0,0 +1,39 @@
#include <pybind11/chrono.h>
#include <pybind11/numpy.h>
#include <pybind11/operators.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <sstream>
#include "sls/sls_detector_defs.h"
namespace py = pybind11;
void init_scan(py::module &m) {
using sp = slsDetectorDefs::scanParameters;
py::class_<sp> scanParameters(m, "scanParameters");
scanParameters.def(py::init());
scanParameters.def(py::init<slsDetectorDefs::dacIndex, int, int, int>());
scanParameters.def(py::init<slsDetectorDefs::dacIndex, int, int, int, std::chrono::nanoseconds>());
scanParameters.def_readwrite("enable", &sp::enable);
scanParameters.def_readwrite("dacInd", &sp::dacInd);
scanParameters.def_readwrite("startOffset", &sp::startOffset);
scanParameters.def_readwrite("stopOffset", &sp::stopOffset);
scanParameters.def_readwrite("stepSize", &sp::stepSize);
scanParameters.def_readwrite("dacSettleTime_ns", &sp::dacSettleTime_ns);
scanParameters.def("__repr__", [](const sp &a){
std::ostringstream oss;
auto indent = " ";
oss << "<scanParameters>\n";
oss << indent << "enable: " << a.enable << '\n';
oss << indent << "dacInd: " << a.dacInd << '\n';
oss << indent << "startOffset: " << a.startOffset << '\n';
oss << indent << "stopOffset: " << a.stopOffset << '\n';
oss << indent << "stepSize: " << a.stepSize << '\n';
oss << indent << "dacSettleTime_ns: " << a.dacSettleTime_ns;
return oss.str();
});
}