Setting pattern from memory (#218)

* ToString accepts c-style arrays

* added patternParameters to python

* fixed patwait time bug in validation

* moved load from file function to patterParameters

* server using patternparamters structure to get pattern

Co-authored-by: Erik Frojdh <erik.frojdh@gmail.com>
This commit is contained in:
Dhanya Thattil 2020-11-24 20:32:07 +01:00 committed by GitHub
parent 9e8c8f4bbc
commit e63fa1d7c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 350 additions and 194 deletions

View File

@ -28,6 +28,7 @@ set( PYTHON_FILES
enums.py enums.py
errors.py errors.py
gotthard.py gotthard.py
pattern.py
gotthard2.py gotthard2.py
moench.py moench.py
proxy.py proxy.py

View File

@ -0,0 +1,14 @@
from slsdet import Detector, patternParameters
d = Detector()
pat = patternParameters()
#Access to memers 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 d.fformat = fileFormat.BINARY
# Altough not recommended for convenience all enums # 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 * from slsdet import *
d.speed = speedLevel.FULL_SPEED d.speed = speedLevel.FULL_SPEED
@ -15,6 +15,6 @@ d.speed = speedLevel.FULL_SPEED
import slsdet.enums import slsdet.enums
for enum in dir(slsdet.enums): for enum in dir(slsdet.enums):
# filter out special memebers # filter out special members
if not enum.startswith('_'): if not enum.startswith('_'):
print(enum) print(enum)

View File

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

View File

@ -55,7 +55,7 @@ def generate_enum_string(enums):
data.append('.export_values();\n\n') data.append('.export_values();\n\n')
return ''.join(data) 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 = f.read()
data = remove_comments(data) data = remove_comments(data)

View File

@ -8,6 +8,7 @@ from .mythen3 import Mythen3
from .gotthard2 import Gotthard2 from .gotthard2 import Gotthard2
from .gotthard import Gotthard from .gotthard import Gotthard
from .moench import Moench from .moench import Moench
from .pattern import patternParameters
import _slsdet import _slsdet
xy = _slsdet.xy xy = _slsdet.xy

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

@ -0,0 +1,25 @@
import _slsdet
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

View File

@ -1271,6 +1271,11 @@ void init_det(py::module &m) {
(void (Detector::*)(const std::string &, sls::Positions)) & (void (Detector::*)(const std::string &, sls::Positions)) &
Detector::setPattern, Detector::setPattern,
py::arg(), py::arg() = Positions{}) py::arg(), py::arg() = Positions{})
.def("setPattern",
(void (Detector::*)(const defs::patternParameters *,
sls::Positions)) &
Detector::setPattern,
py::arg(), py::arg() = Positions{})
.def("savePattern", .def("savePattern",
(void (Detector::*)(const std::string &)) & Detector::savePattern, (void (Detector::*)(const std::string &)) & Detector::savePattern,
py::arg()) py::arg())

View File

@ -2,6 +2,7 @@
* warning */ * warning */
#include <pybind11/chrono.h> #include <pybind11/chrono.h>
#include <pybind11/numpy.h>
#include <pybind11/operators.h> #include <pybind11/operators.h>
#include <pybind11/pybind11.h> #include <pybind11/pybind11.h>
#include <pybind11/stl.h> #include <pybind11/stl.h>
@ -16,6 +17,20 @@ void init_enums(py::module &m) {
xy.def_readwrite("x", &slsDetectorDefs::xy::x); xy.def_readwrite("x", &slsDetectorDefs::xy::x);
xy.def_readwrite("y", &slsDetectorDefs::xy::y); xy.def_readwrite("y", &slsDetectorDefs::xy::y);
py::class_<slsDetectorDefs::patternParameters> patternParameters(
m, "patternParameters");
using pat = slsDetectorDefs::patternParameters;
PYBIND11_NUMPY_DTYPE(pat, word, patioctrl, patlimits, patloop, patnloop,
patwait, patwaittime);
patternParameters.def(py::init());
patternParameters.def("numpy_view", [](py::object &obj) {
pat &o = obj.cast<pat &>();
return py::array_t<pat>(1, &o, obj);
});
patternParameters.def("load", &pat::load);
py::enum_<slsDetectorDefs::detectorType>(Defs, "detectorType") py::enum_<slsDetectorDefs::detectorType>(Defs, "detectorType")
.value("GENERIC", slsDetectorDefs::detectorType::GENERIC) .value("GENERIC", slsDetectorDefs::detectorType::GENERIC)
.value("EIGER", slsDetectorDefs::detectorType::EIGER) .value("EIGER", slsDetectorDefs::detectorType::EIGER)

View File

@ -1,4 +1,5 @@
#include <pybind11/chrono.h> #include <pybind11/chrono.h>
#include <pybind11/numpy.h>
#include <pybind11/operators.h> #include <pybind11/operators.h>
#include <pybind11/pybind11.h> #include <pybind11/pybind11.h>
#include <pybind11/stl.h> #include <pybind11/stl.h>
@ -9,10 +10,22 @@ 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"); py::class_<slsDetectorDefs::xy> xy(m, "xy");
xy.def(py::init()); 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("x", &slsDetectorDefs::xy::x);
xy.def_readwrite("y", &slsDetectorDefs::xy::y); xy.def_readwrite("y", &slsDetectorDefs::xy::y);
[[ENUMS]] py::class_<slsDetectorDefs::patternParameters> patternParameters(
m, "patternParameters");
using pat = slsDetectorDefs::patternParameters;
PYBIND11_NUMPY_DTYPE(pat, word, patioctrl, patlimits, patloop, patnloop,
patwait, patwaittime);
patternParameters.def(py::init());
patternParameters.def("numpy_view", [](py::object &obj) {
pat& o = obj.cast<pat&>();
return py::array_t<pat>(1, &o, obj); });
patternParameters.def("load", &pat::load);
[[ENUMS]]
} }

View File

@ -7530,28 +7530,11 @@ int set_veto(int file_des) {
int set_pattern(int file_des) { int set_pattern(int file_des) {
ret = OK; ret = OK;
memset(mess, 0, sizeof(mess)); memset(mess, 0, sizeof(mess));
uint64_t *patwords = malloc(sizeof(uint64_t) * MAX_PATTERN_LENGTH);
memset(patwords, 0, sizeof(uint64_t) * MAX_PATTERN_LENGTH); patternParameters *pat = malloc(sizeof(patternParameters));
uint64_t patioctrl = 0; memset(pat, 0, sizeof(patternParameters));
int patlimits[2] = {0, 0};
int patloop[6] = {0, 0, 0, 0, 0, 0}; if (receiveDataOnly(file_des, pat, sizeof(patternParameters)) < 0)
int patnloop[3] = {0, 0, 0};
int patwait[3] = {0, 0, 0};
uint64_t patwaittime[3] = {0, 0, 0};
if (receiveData(file_des, patwords, sizeof(uint64_t) * MAX_PATTERN_LENGTH,
INT64) < 0)
return printSocketReadError();
if (receiveData(file_des, &patioctrl, sizeof(patioctrl), INT64) < 0)
return printSocketReadError();
if (receiveData(file_des, patlimits, sizeof(patlimits), INT32) < 0)
return printSocketReadError();
if (receiveData(file_des, patloop, sizeof(patloop), INT32) < 0)
return printSocketReadError();
if (receiveData(file_des, patnloop, sizeof(patnloop), INT32) < 0)
return printSocketReadError();
if (receiveData(file_des, patwait, sizeof(patwait), INT32) < 0)
return printSocketReadError();
if (receiveData(file_des, patwaittime, sizeof(patwaittime), INT64) < 0)
return printSocketReadError(); return printSocketReadError();
#if !defined(CHIPTESTBOARDD) && !defined(MOENCHD) && !defined(MYTHEN3D) #if !defined(CHIPTESTBOARDD) && !defined(MOENCHD) && !defined(MYTHEN3D)
@ -7562,95 +7545,95 @@ int set_pattern(int file_des) {
LOG(logINFO, LOG(logINFO,
("Setting Pattern Word (printing every 10 words that are not 0\n")); ("Setting Pattern Word (printing every 10 words that are not 0\n"));
for (int i = 0; i < MAX_PATTERN_LENGTH; ++i) { for (int i = 0; i < MAX_PATTERN_LENGTH; ++i) {
if ((i % 10 == 0) && patwords[i] != 0) { if ((i % 10 == 0) && pat->word[i] != 0) {
LOG(logINFO, ("Setting Pattern Word (addr:0x%x, word:0x%llx)\n", LOG(logINFO, ("Setting Pattern Word (addr:0x%x, word:0x%llx)\n",
i, (long long int)patwords[i])); i, (long long int)pat->word[i]));
} }
writePatternWord(i, patwords[i]); writePatternWord(i, pat->word[i]);
} }
int numLoops = -1, retval0 = -1, retval1 = -1; int numLoops = -1, retval0 = -1, retval1 = -1;
uint64_t retval64 = -1; uint64_t retval64 = -1;
#ifndef MYTHEN3D #ifndef MYTHEN3D
if (ret == OK) { if (ret == OK) {
retval64 = writePatternIOControl(patioctrl); retval64 = writePatternIOControl(pat->patioctrl);
validate64(patioctrl, retval64, "set pattern IO Control", HEX); validate64(pat->patioctrl, retval64, "set pattern IO Control", HEX);
} }
#endif #endif
if (ret == OK) { if (ret == OK) {
numLoops = -1; numLoops = -1;
retval0 = patlimits[0]; retval0 = pat->patlimits[0];
retval1 = patlimits[1]; retval1 = pat->patlimits[1];
setPatternLoop(-1, &retval0, &retval1, &numLoops); setPatternLoop(-1, &retval0, &retval1, &numLoops);
validate(patlimits[0], retval0, "set pattern Limits start address", validate(pat->patlimits[0], retval0,
HEX); "set pattern Limits start address", HEX);
validate(patlimits[1], retval1, "set pattern Limits start address", validate(pat->patlimits[1], retval1,
"set pattern Limits start address", HEX);
}
if (ret == OK) {
retval0 = pat->patloop[0];
retval1 = pat->patloop[1];
numLoops = pat->patnloop[0];
setPatternLoop(0, &retval0, &retval1, &numLoops);
validate(pat->patloop[0], retval0,
"set pattern Loop 0 start address", HEX);
validate(pat->patloop[1], retval1,
"set pattern Loop 0 stop address", HEX);
validate(pat->patnloop[0], numLoops, "set pattern Loop 0 num loops",
HEX); HEX);
} }
if (ret == OK) { if (ret == OK) {
retval0 = patloop[0]; retval0 = pat->patloop[2];
retval1 = patloop[1]; retval1 = pat->patloop[3];
numLoops = patnloop[0]; numLoops = pat->patnloop[1];
setPatternLoop(0, &patloop[0], &patloop[1], &numLoops); setPatternLoop(1, &retval0, &retval1, &numLoops);
validate(patloop[0], retval0, "set pattern Loop 0 start address", validate(pat->patloop[2], retval0,
HEX); "set pattern Loop 1 start address", HEX);
validate(patloop[1], retval1, "set pattern Loop 0 stop address", validate(pat->patloop[3], retval1,
HEX); "set pattern Loop 1 stop address", HEX);
validate(patnloop[0], numLoops, "set pattern Loop 0 num loops", validate(pat->patnloop[1], numLoops, "set pattern Loop 1 num loops",
HEX); HEX);
} }
if (ret == OK) { if (ret == OK) {
retval0 = patloop[2]; retval0 = pat->patloop[4];
retval1 = patloop[3]; retval1 = pat->patloop[5];
numLoops = patnloop[1]; numLoops = pat->patnloop[2];
setPatternLoop(1, &patloop[2], &patloop[3], &numLoops); setPatternLoop(2, &retval0, &retval1, &numLoops);
validate(patloop[2], retval0, "set pattern Loop 1 start address", validate(pat->patloop[4], retval0,
HEX); "set pattern Loop 2 start address", HEX);
validate(patloop[3], retval1, "set pattern Loop 1 stop address", validate(pat->patloop[5], retval1,
HEX); "set pattern Loop 2 stop address", HEX);
validate(patnloop[1], numLoops, "set pattern Loop 1 num loops", validate(pat->patnloop[2], numLoops, "set pattern Loop 2 num loops",
HEX); HEX);
} }
if (ret == OK) { if (ret == OK) {
retval0 = patloop[4]; retval0 = setPatternWaitAddress(0, pat->patwait[0]);
retval1 = patloop[5]; validate(pat->patwait[0], retval0,
numLoops = patnloop[2]; "set pattern Loop 0 wait address", HEX);
setPatternLoop(2, &patloop[4], &patloop[5], &numLoops);
validate(patloop[4], retval0, "set pattern Loop 2 start address",
HEX);
validate(patloop[5], retval1, "set pattern Loop 2 stop address",
HEX);
validate(patnloop[2], numLoops, "set pattern Loop 2 num loops",
HEX);
} }
if (ret == OK) { if (ret == OK) {
retval0 = setPatternWaitAddress(0, patwait[0]); retval0 = setPatternWaitAddress(1, pat->patwait[1]);
validate(patwait[0], retval0, "set pattern Loop 0 wait address", validate(pat->patwait[1], retval0,
HEX); "set pattern Loop 1 wait address", HEX);
} }
if (ret == OK) { if (ret == OK) {
retval0 = setPatternWaitAddress(1, patwait[1]); retval0 = setPatternWaitAddress(2, pat->patwait[2]);
validate(patwait[1], retval0, "set pattern Loop 1 wait address", validate(pat->patwait[2], retval0,
HEX); "set pattern Loop 2 wait address", HEX);
} }
if (ret == OK) { if (ret == OK) {
retval0 = setPatternWaitAddress(2, patwait[2]); uint64_t retval64 = setPatternWaitTime(0, pat->patwaittime[0]);
validate(patwait[2], retval0, "set pattern Loop 2 wait address", validate64(pat->patwaittime[0], retval64,
HEX); "set pattern Loop 0 wait time", HEX);
} }
if (ret == OK) { if (ret == OK) {
uint64_t retval64 = setPatternWaitTime(0, patwaittime[0]); retval64 = setPatternWaitTime(1, pat->patwaittime[1]);
validate64(patwaittime[0], retval64, "set pattern Loop 0 wait time", validate64(pat->patwaittime[1], retval64,
HEX); "set pattern Loop 1 wait time", HEX);
} }
if (ret == OK) { if (ret == OK) {
retval64 = setPatternWaitTime(1, patwaittime[1]); retval64 = setPatternWaitTime(2, pat->patwaittime[2]);
validate64(patwaittime[1], retval64, "set pattern Loop 1 wait time", validate64(pat->patwaittime[2], retval64,
HEX); "set pattern Loop 2 wait time", HEX);
}
if (ret == OK) {
retval64 = setPatternWaitTime(2, patwaittime[2]);
validate64(patwaittime[1], retval64, "set pattern Loop 2 wait time",
HEX);
} }
} }
#endif #endif

View File

@ -1457,6 +1457,10 @@ class Detector {
* (instead of executing line by line)*/ * (instead of executing line by line)*/
void setPattern(const std::string &fname, Positions pos = {}); void setPattern(const std::string &fname, Positions pos = {});
/** [CTB][Moench][Mythen3] Loads pattern parameters structure directly to
* server */
void setPattern(const defs::patternParameters *pat, Positions pos = {});
/** [CTB][Moench][Mythen3] [Ctb][Moench][Mythen3] Saves pattern to file /** [CTB][Moench][Mythen3] [Ctb][Moench][Mythen3] Saves pattern to file
* (ascii). \n [Ctb][Moench] Also executes pattern.*/ * (ascii). \n [Ctb][Moench] Also executes pattern.*/
void savePattern(const std::string &fname); void savePattern(const std::string &fname);

View File

@ -1790,6 +1790,10 @@ void Detector::setPattern(const std::string &fname, Positions pos) {
pimpl->Parallel(&Module::setPattern, pos, fname); pimpl->Parallel(&Module::setPattern, pos, fname);
} }
void Detector::setPattern(const defs::patternParameters *pat, Positions pos) {
pimpl->Parallel(&Module::setPatternStructure, pos, pat);
}
Result<uint64_t> Detector::getPatternIOControl(Positions pos) const { Result<uint64_t> Detector::getPatternIOControl(Positions pos) const {
return pimpl->Parallel(&Module::getPatternIOControl, pos); return pimpl->Parallel(&Module::getPatternIOControl, pos);
} }

View File

@ -1915,104 +1915,35 @@ void Module::setLEDEnable(bool enable) {
void Module::setPattern(const std::string &fname) { void Module::setPattern(const std::string &fname) {
auto pat = sls::make_unique<patternParameters>(); auto pat = sls::make_unique<patternParameters>();
std::ifstream input_file(fname); pat->load(fname);
if (!input_file) { setPatternStructure(pat.get());
throw RuntimeError("Could not open pattern file " + fname + }
" for reading");
void Module::setPatternStructure(const defs::patternParameters *pat) {
// verifications
if (pat->patlimits[0] >= MAX_PATTERN_LENGTH ||
pat->patlimits[1] >= MAX_PATTERN_LENGTH) {
throw RuntimeError("Invalid Pattern limits address [" +
ToString(pat->patlimits[0]) + std::string(", ") +
ToString(pat->patlimits[1]) + std::string("]"));
} }
for (std::string line; std::getline(input_file, line);) { for (int i = 0; i != 3; ++i) {
if (line.find('#') != std::string::npos) { if (pat->patloop[i * 2 + 0] >= MAX_PATTERN_LENGTH ||
line.erase(line.find('#')); pat->patloop[i * 2 + 1] >= MAX_PATTERN_LENGTH) {
throw RuntimeError(
"Invalid Pattern loop address for level " + ToString(i) +
std::string(" [") + ToString(pat->patloop[i * 2 + 0]) +
std::string(", ") + ToString(pat->patloop[i * 2 + 1]) +
std::string("]"));
} }
LOG(logDEBUG1) << "line after removing comments:\n\t" << line; if (pat->patwait[i] >= MAX_PATTERN_LENGTH) {
if (line.length() > 1) { throw RuntimeError("Invalid Pattern wait address for level " +
ToString(i) + std::string(" ") +
// convert command and string to a vector ToString(pat->patwait[i]));
std::istringstream iss(line);
auto it = std::istream_iterator<std::string>(iss);
std::vector<std::string> args = std::vector<std::string>(
it, std::istream_iterator<std::string>());
std::string cmd = args[0];
int nargs = args.size() - 1;
if (cmd == "patword") {
if (nargs != 2) {
throw RuntimeError("Invalid arguments for " +
ToString(args));
}
uint32_t addr = StringTo<uint32_t>(args[1]);
if (addr >= MAX_PATTERN_LENGTH) {
throw RuntimeError("Invalid address for " + ToString(args));
}
pat->word[addr] = StringTo<uint64_t>(args[2]);
} else if (cmd == "patioctrl") {
if (nargs != 1) {
throw RuntimeError("Invalid arguments for " +
ToString(args));
}
pat->patioctrl = StringTo<uint64_t>(args[1]);
} else if (cmd == "patlimits") {
if (nargs != 2) {
throw RuntimeError("Invalid arguments for " +
ToString(args));
}
pat->patlimits[0] = StringTo<uint32_t>(args[1]);
pat->patlimits[1] = StringTo<uint32_t>(args[2]);
if (pat->patlimits[0] >= MAX_PATTERN_LENGTH ||
pat->patlimits[1] >= MAX_PATTERN_LENGTH) {
throw RuntimeError("Invalid address for " + ToString(args));
}
} else if (cmd == "patloop0" || cmd == "patloop1" ||
cmd == "patloop2") {
if (nargs != 2) {
throw RuntimeError("Invalid arguments for " +
ToString(args));
}
int level = cmd[cmd.find_first_of("012")] - '0';
int patloop1 = StringTo<uint32_t>(args[1]);
int patloop2 = StringTo<uint32_t>(args[2]);
pat->patloop[level * 2 + 0] = patloop1;
pat->patloop[level * 2 + 1] = patloop2;
if (patloop1 >= MAX_PATTERN_LENGTH ||
patloop2 >= MAX_PATTERN_LENGTH) {
throw RuntimeError("Invalid address for " + ToString(args));
}
} else if (cmd == "patnloop0" || cmd == "patnloop1" ||
cmd == "patnloop2") {
if (nargs != 1) {
throw RuntimeError("Invalid arguments for " +
ToString(args));
}
int level = cmd[cmd.find_first_of("012")] - '0';
pat->patnloop[level] = StringTo<uint32_t>(args[1]);
} else if (cmd == "patwait0" || cmd == "patwait1" ||
cmd == "patwait2") {
if (nargs != 1) {
throw RuntimeError("Invalid arguments for " +
ToString(args));
}
int level = cmd[cmd.find_first_of("012")] - '0';
pat->patwait[level] = StringTo<uint32_t>(args[1]);
if (pat->patwait[level] >= MAX_PATTERN_LENGTH) {
throw RuntimeError("Invalid address for " + ToString(args));
}
} else if (cmd == "patwaittime0" || cmd == "patwaittime1" ||
cmd == "patwaittime2") {
if (nargs != 1) {
throw RuntimeError("Invalid arguments for " +
ToString(args));
}
int level = cmd[cmd.find_first_of("012")] - '0';
pat->patwaittime[level] = StringTo<uint64_t>(args[1]);
} else {
throw RuntimeError("Unknown command in pattern file " + cmd);
}
} }
} }
LOG(logDEBUG1) << "Sending pattern from file to detector:" << *pat; LOG(logDEBUG1) << "Sending pattern from file to detector:" << *pat;
sendToDetector(F_SET_PATTERN, pat.get(), sizeof(patternParameters), nullptr, sendToDetector(F_SET_PATTERN, pat, sizeof(patternParameters), nullptr, 0);
0);
} }
uint64_t Module::getPatternIOControl() const { uint64_t Module::getPatternIOControl() const {

View File

@ -463,6 +463,7 @@ class Module : public virtual slsDetectorDefs {
* * * *
* ************************************************/ * ************************************************/
void setPattern(const std::string &fname); void setPattern(const std::string &fname);
void setPatternStructure(const defs::patternParameters *pat);
uint64_t getPatternIOControl() const; uint64_t getPatternIOControl() const;
void setPatternIOControl(uint64_t word); void setPatternIOControl(uint64_t word);
uint64_t getPatternWord(int addr) const; uint64_t getPatternWord(int addr) const;

View File

@ -10,6 +10,7 @@ set(SOURCES
src/ZmqSocket.cpp src/ZmqSocket.cpp
src/UdpRxSocket.cpp src/UdpRxSocket.cpp
src/sls_detector_exceptions.cpp src/sls_detector_exceptions.cpp
src/sls_detector_defs.cpp
) )
# Header files to install as a part of the library # Header files to install as a part of the library

View File

@ -181,6 +181,23 @@ std::string ToString(const std::map<KeyType, ValueType> &m) {
return os.str(); return os.str();
} }
/**
* Print a c style array
*/
template<typename T, size_t size>
std::string ToString(const T(&arr)[size]){
std::ostringstream os;
os << '[';
if (size){
size_t i = 0;
os << ToString(arr[i++]);
for (; i<size; ++i)
os << ", " << ToString(arr[i]);
}
os << ']';
return os.str();
}
/** /**
* For a container loop over all elements and call ToString on the element * For a container loop over all elements and call ToString on the element
* Container<std::string> is excluded * Container<std::string> is excluded

View File

@ -21,6 +21,7 @@
#include <bitset> #include <bitset>
#include <chrono> #include <chrono>
#include <cstdint> #include <cstdint>
#include <cstring>
#include <string> #include <string>
#else #else
// C includes // C includes
@ -472,19 +473,36 @@ typedef struct {
int gates{0}; int gates{0};
scanParameters scanParams{}; scanParameters scanParams{};
} __attribute__((packed)); } __attribute__((packed));
#endif
/** pattern structure */ /** pattern structure */
#ifdef __cplusplus
struct patternParameters { struct patternParameters {
uint64_t word[MAX_PATTERN_LENGTH]{}; #else
uint64_t patioctrl{0}; typedef struct __attribute__((packed)){
uint32_t patlimits[2]{};
uint32_t patloop[6]{};
uint32_t patnloop[3]{};
uint32_t patwait[3]{};
uint64_t patwaittime[3]{};
} __attribute__((packed));
#endif #endif
uint64_t word[MAX_PATTERN_LENGTH];
uint64_t patioctrl;
uint32_t patlimits[2];
uint32_t patloop[6];
uint32_t patnloop[3];
uint32_t patwait[3];
uint64_t patwaittime[3];
#ifdef __cplusplus
public:
patternParameters(){
// Since the def has to be c compatible we can't use {} for the members
memset(this, 0, sizeof(patternParameters));
}
void load(const std::string& fname);
} __attribute__((packed));
#else
} patternParameters;
#endif
#ifdef __cplusplus #ifdef __cplusplus
protected: protected:

View File

@ -3,10 +3,10 @@
#define APILIB 0x201119 #define APILIB 0x201119
#define APIRECEIVER 0x201119 #define APIRECEIVER 0x201119
#define APIGUI 0x201119 #define APIGUI 0x201119
#define APICTB 0x201119 #define APICTB 0x201124
#define APIGOTTHARD 0x201119 #define APIGOTTHARD 0x201124
#define APIGOTTHARD2 0x201119 #define APIGOTTHARD2 0x201124
#define APIJUNGFRAU 0x201119 #define APIJUNGFRAU 0x201124
#define APIMYTHEN3 0x201119 #define APIMYTHEN3 0x201124
#define APIMOENCH 0x201119 #define APIMOENCH 0x201124
#define APIEIGER 0x201119 #define APIEIGER 0x201124

View File

@ -0,0 +1,97 @@
#include "sls/sls_detector_defs.h"
#include "sls/logger.h"
#include "sls/ToString.h"
#include <fstream>
#include <sstream>
#include <iterator>
using sls::RuntimeError;
using sls::StringTo;
using sls::ToString;
void slsDetectorDefs::patternParameters::load(const std::string& fname){
std::ifstream input_file(fname);
if (!input_file) {
throw RuntimeError("Could not open pattern file " + fname +
" for reading");
}
for (std::string line; std::getline(input_file, line);) {
if (line.find('#') != std::string::npos) {
line.erase(line.find('#'));
}
LOG(logDEBUG1) << "line after removing comments:\n\t" << line;
if (line.length() > 1) {
// convert command and string to a vector
std::istringstream iss(line);
auto it = std::istream_iterator<std::string>(iss);
std::vector<std::string> args = std::vector<std::string>(
it, std::istream_iterator<std::string>());
std::string cmd = args[0];
int nargs = args.size() - 1;
if (cmd == "patword") {
if (nargs != 2) {
throw RuntimeError("Invalid arguments for " +
ToString(args));
}
uint32_t addr = StringTo<uint32_t>(args[1]);
if (addr >= MAX_PATTERN_LENGTH) {
throw RuntimeError("Invalid address for " + ToString(args));
}
word[addr] = StringTo<uint64_t>(args[2]);
} else if (cmd == "patioctrl") {
if (nargs != 1) {
throw RuntimeError("Invalid arguments for " +
ToString(args));
}
patioctrl = StringTo<uint64_t>(args[1]);
} else if (cmd == "patlimits") {
if (nargs != 2) {
throw RuntimeError("Invalid arguments for " +
ToString(args));
}
patlimits[0] = StringTo<uint32_t>(args[1]);
patlimits[1] = StringTo<uint32_t>(args[2]);
} else if (cmd == "patloop0" || cmd == "patloop1" ||
cmd == "patloop2") {
if (nargs != 2) {
throw RuntimeError("Invalid arguments for " +
ToString(args));
}
int level = cmd[cmd.find_first_of("012")] - '0';
int patloop1 = StringTo<uint32_t>(args[1]);
int patloop2 = StringTo<uint32_t>(args[2]);
patloop[level * 2 + 0] = patloop1;
patloop[level * 2 + 1] = patloop2;
} else if (cmd == "patnloop0" || cmd == "patnloop1" ||
cmd == "patnloop2") {
if (nargs != 1) {
throw RuntimeError("Invalid arguments for " +
ToString(args));
}
int level = cmd[cmd.find_first_of("012")] - '0';
patnloop[level] = StringTo<uint32_t>(args[1]);
} else if (cmd == "patwait0" || cmd == "patwait1" ||
cmd == "patwait2") {
if (nargs != 1) {
throw RuntimeError("Invalid arguments for " +
ToString(args));
}
int level = cmd[cmd.find_first_of("012")] - '0';
patwait[level] = StringTo<uint32_t>(args[1]);
} else if (cmd == "patwaittime0" || cmd == "patwaittime1" ||
cmd == "patwaittime2") {
if (nargs != 1) {
throw RuntimeError("Invalid arguments for " +
ToString(args));
}
int level = cmd[cmd.find_first_of("012")] - '0';
patwaittime[level] = StringTo<uint64_t>(args[1]);
} else {
throw RuntimeError("Unknown command in pattern file " + cmd);
}
}
}
}

View File

@ -3,6 +3,7 @@
#include "sls/ToString.h" #include "sls/ToString.h"
#include "sls/network_utils.h" #include "sls/network_utils.h"
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#include "sls/container_utils.h"
#include <array> #include <array>
#include <map> #include <map>
#include <sstream> #include <sstream>
@ -299,3 +300,26 @@ TEST_CASE("Streaming of slsDetectorDefs::scanParameters") {
"500\nsettleTime 0.5s\n]"); "500\nsettleTime 0.5s\n]");
} }
} }
TEST_CASE("Printing c style arrays of int"){
int arr[]{3, 5};
REQUIRE(ToString(arr) == "[3, 5]");
}
TEST_CASE("Printing c style arrays of uint8"){
uint8_t arr[]{1,2,3,4,5};
REQUIRE(ToString(arr) == "[1, 2, 3, 4, 5]");
}
TEST_CASE("Printing c style arrays of double"){
double arr[]{3.4, 5.3, 6.2};
REQUIRE(ToString(arr) == "[3.4, 5.3, 6.2]");
}
TEST_CASE("Print a member of patternParameters"){
auto pat = sls::make_unique<slsDetectorDefs::patternParameters>();
pat->patlimits[0] = 4;
pat->patlimits[1] = 100;
REQUIRE(ToString(pat->patlimits) == "[4, 100]");
}