Introduced pattern class

This commit is contained in:
Erik Frojdh 2020-11-27 10:03:15 +01:00
parent 8ca1d9c50c
commit d9b2a90651
22 changed files with 384 additions and 118 deletions

View File

@ -4,6 +4,7 @@ pybind11_add_module(_slsdet
src/enums.cpp src/enums.cpp
src/detector.cpp src/detector.cpp
src/network.cpp src/network.cpp
src/pattern.cpp
) )
target_link_libraries(_slsdet PUBLIC target_link_libraries(_slsdet PUBLIC

View File

@ -8,7 +8,8 @@ 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 from .pattern import Pattern, patternParameters
import _slsdet import _slsdet
xy = _slsdet.xy xy = _slsdet.xy

View File

@ -1,5 +1,7 @@
import _slsdet import _slsdet
from _slsdet import Pattern
class patternParameters(_slsdet.patternParameters): class patternParameters(_slsdet.patternParameters):
def __init__(self): def __init__(self):
super().__init__() super().__init__()

View File

@ -1272,8 +1272,7 @@ void init_det(py::module &m) {
Detector::setPattern, Detector::setPattern,
py::arg(), py::arg() = Positions{}) py::arg(), py::arg() = Positions{})
.def("setPattern", .def("setPattern",
(void (Detector::*)(const defs::patternParameters *, (void (Detector::*)(const sls::Pattern &, sls::Positions)) &
sls::Positions)) &
Detector::setPattern, Detector::setPattern,
py::arg(), py::arg() = Positions{}) py::arg(), py::arg() = Positions{})
.def("savePattern", .def("savePattern",

View File

@ -7,6 +7,7 @@
#include <pybind11/pybind11.h> #include <pybind11/pybind11.h>
#include <pybind11/stl.h> #include <pybind11/stl.h>
#include "sls/Pattern.h"
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
namespace py = pybind11; namespace py = pybind11;
void init_enums(py::module &m) { void init_enums(py::module &m) {
@ -17,20 +18,6 @@ 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, 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);
});
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

@ -5,6 +5,7 @@
#include <pybind11/stl.h> #include <pybind11/stl.h>
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#include "sls/Pattern.h"
namespace py = pybind11; namespace py = pybind11;
void init_enums(py::module &m) { void init_enums(py::module &m) {
py::class_<slsDetectorDefs> Defs(m, "slsDetectorDefs"); py::class_<slsDetectorDefs> Defs(m, "slsDetectorDefs");
@ -14,18 +15,5 @@ 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, 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); });
patternParameters.def("load", &pat::load);
[[ENUMS]] [[ENUMS]]
} }

View File

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

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

@ -0,0 +1,42 @@
#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);
});
// m.def("get_memoryview1d", []() {
// return py::memoryview::from_memory(
// buffer, // buffer pointer
// sizeof(uint8_t) * 8 // buffer size
// );
// })
// patternParameters.def("load", &pat::load);
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);
// m.def("get_memoryview1d", []() {
// return py::memoryview::from_memory(data(), // buffer pointer
// sizeof(pat) // buffer size
// );
// });
}

View File

@ -4,6 +4,7 @@ set(SOURCES
src/Detector.cpp src/Detector.cpp
src/CmdProxy.cpp src/CmdProxy.cpp
src/CmdParser.cpp src/CmdParser.cpp
src/Pattern.cpp
) )
add_library(slsDetectorObject OBJECT add_library(slsDetectorObject OBJECT

View File

@ -2,6 +2,7 @@
#include "sls/Result.h" #include "sls/Result.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/Pattern.h"
#include <chrono> #include <chrono>
#include <map> #include <map>
#include <memory> #include <memory>
@ -15,6 +16,7 @@ class DetectorImpl;
class MacAddr; class MacAddr;
class IpAddr; class IpAddr;
// Free function to avoid dependence on class // Free function to avoid dependence on class
// and avoid the option to free another objects // and avoid the option to free another objects
// shm by mistake // shm by mistake
@ -1459,7 +1461,7 @@ class Detector {
/** [CTB][Moench][Mythen3] Loads pattern parameters structure directly to /** [CTB][Moench][Mythen3] Loads pattern parameters structure directly to
* server */ * server */
void setPattern(const defs::patternParameters *pat, Positions pos = {}); void setPattern(const Pattern& 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.*/

View File

@ -0,0 +1,42 @@
#pragma once
#include "sls/sls_detector_defs.h"
#ifdef __cplusplus
#include <memory>
namespace sls {
#endif
// Common C/C++ structure to handle pattern data
typedef struct __attribute__((packed)) {
uint64_t word[MAX_PATTERN_LENGTH];
uint64_t ioctrl;
uint32_t limits[2];
// loop0 start, loop0 stop .. loop2 start, loop2 stop
uint32_t loop[6];
uint32_t nloop[3];
uint32_t wait[3];
uint64_t waittime[3];
} patternParameters;
#ifdef __cplusplus
class Pattern{
patternParameters* pat = new patternParameters{};
public:
Pattern();
~Pattern();
Pattern(const Pattern& other);
bool operator==(const Pattern& other) const;
bool operator!=(const Pattern& other) const;
patternParameters* data();
patternParameters* data() const;
constexpr size_t size() const noexcept{ return sizeof(patternParameters);}
void validate() const;
void load(const std::string &fname);
std::string str() const { return {}; }
};
} //namespace sls
#endif

View File

@ -9,6 +9,7 @@
#include "sls/logger.h" #include "sls/logger.h"
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#include "sls/versionAPI.h" #include "sls/versionAPI.h"
#include "sls/Pattern.h"
#include <chrono> #include <chrono>
#include <fstream> #include <fstream>
@ -1754,19 +1755,19 @@ void Detector::setLEDEnable(bool enable, Positions pos) {
// Pattern // Pattern
void Detector::savePattern(const std::string &fname) { void Detector::savePattern(const std::string &fname) {
auto t = pimpl->Parallel(&Module::getPattern, {}); // auto t = pimpl->Parallel(&Module::getPattern, {});
// auto pat = t.tsquash("Inconsistent pattern parameters between modules"); // auto pat = t.tsquash("Inconsistent pattern parameters between modules");
auto pat = std::move(t[0]);
// pat->save(fname); // pat->save(fname);
} // namespace sls } // namespace sls
void Detector::setPattern(const std::string &fname, Positions pos) { void Detector::setPattern(const std::string &fname, Positions pos) {
auto pat = sls::make_unique<defs::patternParameters>(); // Pattern pat;
pat->load(fname); // pat.load(fname);
pimpl->Parallel(&Module::setPattern, pos, pat.get()); // setPattern(pat, pos);
} }
void Detector::setPattern(const defs::patternParameters *pat, Positions pos) { void Detector::setPattern(const Pattern& pat, Positions pos) {
pat.validate();
pimpl->Parallel(&Module::setPattern, pos, pat); pimpl->Parallel(&Module::setPattern, pos, pat);
} }

View File

@ -1913,15 +1913,13 @@ void Module::setLEDEnable(bool enable) {
// Pattern // Pattern
void Module::setPattern(const defs::patternParameters *pat) { void Module::setPattern(const Pattern& pat) {
pat->validate(); sendToDetector(F_SET_PATTERN, pat.data(), pat.size(), nullptr, 0);
sendToDetector(F_SET_PATTERN, pat, sizeof(patternParameters), nullptr, 0);
} }
std::unique_ptr<defs::patternParameters> Module::getPattern() { Pattern Module::getPattern() {
auto pat = sls::make_unique<defs::patternParameters>(); Pattern pat;
*pat = sendToDetector<defs::patternParameters>(F_GET_PATTERN); sendToDetector(F_GET_PATTERN, nullptr, 0, pat.data(), pat.size());
pat->validate();
return pat; return pat;
} }

View File

@ -5,6 +5,7 @@
#include "sls/logger.h" #include "sls/logger.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/Pattern.h"
#include <array> #include <array>
#include <cmath> #include <cmath>
@ -462,8 +463,8 @@ class Module : public virtual slsDetectorDefs {
* Pattern * * Pattern *
* * * *
* ************************************************/ * ************************************************/
void setPattern(const defs::patternParameters *pat); void setPattern(const Pattern& pat);
std::unique_ptr<defs::patternParameters> getPattern(); Pattern getPattern();
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

@ -0,0 +1,166 @@
#include "sls/Pattern.h"
#include "sls/ToString.h"
#include "sls/logger.h"
#include <fstream>
#include <iterator>
#include <sstream>
namespace sls {
Pattern::Pattern() = default;
Pattern::~Pattern() { delete pat; }
Pattern::Pattern(const Pattern &other) {
memcpy(pat, other.pat, sizeof(patternParameters));
}
bool Pattern::operator==(const Pattern &other) const {
for (size_t i = 0; i<(sizeof(pat->word)/sizeof(pat->word[0])); ++i){
if (pat->word[i] != other.pat->word[i])
return false;
}
if (pat->ioctrl != other.pat->ioctrl)
return false;
for (size_t i = 0; i<(sizeof(pat->limits)/sizeof(pat->limits[0])); ++i){
if (pat->limits[i] != other.pat->limits[i])
return false;
}
for (size_t i = 0; i<(sizeof(pat->loop)/sizeof(pat->loop[0])); ++i){
if (pat->loop[i] != other.pat->loop[i])
return false;
}
for (size_t i = 0; i<(sizeof(pat->nloop)/sizeof(pat->nloop[0])); ++i){
if (pat->nloop[i] != other.pat->nloop[i])
return false;
}
for (size_t i = 0; i<(sizeof(pat->wait)/sizeof(pat->wait[0])); ++i){
if (pat->wait[i] != other.pat->wait[i])
return false;
}
for (size_t i = 0; i<(sizeof(pat->waittime)/sizeof(pat->waittime[0])); ++i){
if (pat->waittime[i] != other.pat->waittime[i])
return false;
}
return true;
}
bool Pattern::operator!=(const Pattern& other) const{
return !(*this==other);
}
patternParameters *Pattern::data() { return pat; }
patternParameters *Pattern::data() const { return pat; }
void Pattern::validate() const {
if (pat->limits[0] >= MAX_PATTERN_LENGTH ||
pat->limits[1] >= MAX_PATTERN_LENGTH) {
throw RuntimeError("Invalid Pattern limits address [" +
ToString(pat->limits[0]) + std::string(", ") +
ToString(pat->limits[1]) + std::string("]"));
}
for (int i = 0; i != 3; ++i) {
if (pat->loop[i * 2 + 0] >= MAX_PATTERN_LENGTH ||
pat->loop[i * 2 + 1] >= MAX_PATTERN_LENGTH) {
throw RuntimeError(
"Invalid Pattern loop address for level " + ToString(i) +
std::string(" [") + ToString(pat->loop[i * 2 + 0]) +
std::string(", ") + ToString(pat->loop[i * 2 + 1]) +
std::string("]"));
}
if (pat->wait[i] >= MAX_PATTERN_LENGTH) {
throw RuntimeError("Invalid Pattern wait address for level " +
ToString(i) + std::string(" ") +
ToString(pat->wait[i]));
}
}
}
void Pattern::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));
}
pat->word[addr] = StringTo<uint64_t>(args[2]);
} else if (cmd == "patioctrl") {
if (nargs != 1) {
throw RuntimeError("Invalid arguments for " +
ToString(args));
}
pat->ioctrl = StringTo<uint64_t>(args[1]);
} else if (cmd == "patlimits") {
if (nargs != 2) {
throw RuntimeError("Invalid arguments for " +
ToString(args));
}
pat->limits[0] = StringTo<uint32_t>(args[1]);
pat->limits[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 loop1 = StringTo<uint32_t>(args[1]);
int loop2 = StringTo<uint32_t>(args[2]);
pat->loop[level * 2 + 0] = loop1;
pat->loop[level * 2 + 1] = loop2;
} 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->nloop[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->wait[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';
pat->waittime[level] = StringTo<uint64_t>(args[1]);
} else {
throw RuntimeError("Unknown command in pattern file " + cmd);
}
}
}
}
} // namespace sls

View File

@ -15,6 +15,7 @@ target_sources(tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/test-Result.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-Result.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-CmdParser.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-CmdParser.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-Module.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-Module.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-Pattern.cpp
) )
target_include_directories(tests PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../src>") target_include_directories(tests PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../src>")

View File

@ -0,0 +1,31 @@
#include "catch.hpp"
#include "sls/Pattern.h"
using sls::Pattern;
TEST_CASE("Pattern is default constructable and has zeroed fields"){
Pattern p;
for (int i = 0; i!=MAX_PATTERN_LENGTH; ++i)
REQUIRE(p.data()->word[i] == 0);
REQUIRE(p.data()->ioctrl == 0);
}
TEST_CASE("Copy construct pattern"){
Pattern p;
p.data()->loop[0] = 7;
Pattern p1(p);
REQUIRE(p1.data()->loop[0] == 7);
}
TEST_CASE("Compare patterns"){
Pattern p;
Pattern p1;
REQUIRE(p == p1);
p1.data()->word[500] = 1;
REQUIRE_FALSE(p == p1);
}

View File

@ -10,7 +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 # 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

@ -44,9 +44,9 @@ std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::ROI &roi);
std::string ToString(const slsDetectorDefs::rxParameters &r); std::string ToString(const slsDetectorDefs::rxParameters &r);
std::ostream &operator<<(std::ostream &os, std::ostream &operator<<(std::ostream &os,
const slsDetectorDefs::rxParameters &r); const slsDetectorDefs::rxParameters &r);
std::string ToString(const slsDetectorDefs::patternParameters &r); // std::string ToString(const slsDetectorDefs::patternParameters &r);
std::ostream &operator<<(std::ostream &os, // std::ostream &operator<<(std::ostream &os,
const slsDetectorDefs::patternParameters &r); // const slsDetectorDefs::patternParameters &r);
std::string ToString(const slsDetectorDefs::scanParameters &r); std::string ToString(const slsDetectorDefs::scanParameters &r);
std::ostream &operator<<(std::ostream &os, std::ostream &operator<<(std::ostream &os,
const slsDetectorDefs::scanParameters &r); const slsDetectorDefs::scanParameters &r);

View File

@ -475,34 +475,34 @@ typedef struct {
} __attribute__((packed)); } __attribute__((packed));
#endif #endif
/** pattern structure */ // /** pattern structure */
#ifdef __cplusplus // #ifdef __cplusplus
struct patternParameters { // struct patternParameters {
#else // #else
typedef struct __attribute__((packed)) { // typedef struct __attribute__((packed)) {
#endif // #endif
uint64_t word[MAX_PATTERN_LENGTH]; // uint64_t word[MAX_PATTERN_LENGTH];
uint64_t ioctrl; // uint64_t ioctrl;
uint32_t limits[2]; // uint32_t limits[2];
// loop0 start, loop0 stop .. loop2 start, loop2 stop // // loop0 start, loop0 stop .. loop2 start, loop2 stop
uint32_t loop[6]; // uint32_t loop[6];
uint32_t nloop[3]; // uint32_t nloop[3];
uint32_t wait[3]; // uint32_t wait[3];
uint64_t waittime[3]; // uint64_t waittime[3];
#ifdef __cplusplus // #ifdef __cplusplus
public: // public:
patternParameters() { // patternParameters() {
// Since the def has to be c compatible we can't use {} for the // // Since the def has to be c compatible we can't use {} for the
// members // // members
memset(this, 0, sizeof(patternParameters)); // memset(this, 0, sizeof(patternParameters));
} // }
void load(const std::string &fname); // void load(const std::string &fname);
void save(const std::string &fname); // void save(const std::string &fname);
void validate() const; // void validate() const;
} __attribute__((packed)); // } __attribute__((packed));
#else // #else
} patternParameters; // } patternParameters;
#endif // #endif
#ifdef __cplusplus #ifdef __cplusplus
protected: protected:

View File

@ -88,43 +88,43 @@ std::ostream &operator<<(std::ostream &os,
return os << ToString(r); return os << ToString(r);
} }
std::string ToString(const slsDetectorDefs::patternParameters &r) { // std::string ToString(const slsDetectorDefs::patternParameters &r) {
std::ostringstream oss; // std::ostringstream oss;
oss << '[' << std::setfill('0') << std::endl; // oss << '[' << std::setfill('0') << std::endl;
int addr_width = 4; // int addr_width = 4;
int word_width = 16; // int word_width = 16;
for (int i = 0; i < MAX_PATTERN_LENGTH; ++i) { // for (int i = 0; i < MAX_PATTERN_LENGTH; ++i) {
if (r.word[i] != 0) { // if (r.word[i] != 0) {
oss << "patword " << ToStringHex(i, addr_width) << " " // oss << "patword " << ToStringHex(i, addr_width) << " "
<< ToStringHex(r.word[i], word_width) << std::endl; // << ToStringHex(r.word[i], word_width) << std::endl;
} // }
} // }
oss << "patioctrl " << ToStringHex(r.ioctrl, word_width) << std::endl // oss << "patioctrl " << ToStringHex(r.ioctrl, word_width) << std::endl
<< "patlimits " << ToStringHex(r.limits[0], addr_width) << " " // << "patlimits " << ToStringHex(r.limits[0], addr_width) << " "
<< ToStringHex(r.limits[1], addr_width) << std::endl // << ToStringHex(r.limits[1], addr_width) << std::endl
<< "patloop0 " << ToStringHex(r.loop[0], addr_width) << " " // << "patloop0 " << ToStringHex(r.loop[0], addr_width) << " "
<< ToStringHex(r.loop[1], addr_width) << std::endl // << ToStringHex(r.loop[1], addr_width) << std::endl
<< "patnloop0 " << r.nloop[0] << std::endl // << "patnloop0 " << r.nloop[0] << std::endl
<< "patloop1 " << ToStringHex(r.loop[2], addr_width) << " " // << "patloop1 " << ToStringHex(r.loop[2], addr_width) << " "
<< ToStringHex(r.loop[3], addr_width) << std::endl // << ToStringHex(r.loop[3], addr_width) << std::endl
<< "patnloop1 " << r.nloop[1] << std::endl // << "patnloop1 " << r.nloop[1] << std::endl
<< "patloop2 " << ToStringHex(r.loop[4], addr_width) << " " // << "patloop2 " << ToStringHex(r.loop[4], addr_width) << " "
<< ToStringHex(r.loop[5], addr_width) << std::endl // << ToStringHex(r.loop[5], addr_width) << std::endl
<< "patnloop2 " << r.nloop[2] << std::endl // << "patnloop2 " << r.nloop[2] << std::endl
<< "patwait0 " << ToStringHex(r.wait[0], addr_width) << std::endl // << "patwait0 " << ToStringHex(r.wait[0], addr_width) << std::endl
<< "patwaittime0 " << r.waittime[0] << std::endl // << "patwaittime0 " << r.waittime[0] << std::endl
<< "patwait1 " << ToStringHex(r.wait[1], addr_width) << std::endl // << "patwait1 " << ToStringHex(r.wait[1], addr_width) << std::endl
<< "patwaittime1 " << r.waittime[1] << std::endl // << "patwaittime1 " << r.waittime[1] << std::endl
<< "patwait2 " << ToStringHex(r.wait[2], addr_width) << std::endl // << "patwait2 " << ToStringHex(r.wait[2], addr_width) << std::endl
<< "patwaittime2 " << r.waittime[2] << std::endl // << "patwaittime2 " << r.waittime[2] << std::endl
<< ']'; // << ']';
return oss.str(); // return oss.str();
} // }
std::ostream &operator<<(std::ostream &os, // std::ostream &operator<<(std::ostream &os,
const slsDetectorDefs::patternParameters &r) { // const slsDetectorDefs::patternParameters &r) {
return os << ToString(r); // return os << ToString(r);
} // }
std::string ToString(const slsDetectorDefs::scanParameters &r) { std::string ToString(const slsDetectorDefs::scanParameters &r) {
std::ostringstream oss; std::ostringstream oss;

View File

@ -2,6 +2,7 @@
#include "sls/TimeHelper.h" #include "sls/TimeHelper.h"
#include "sls/ToString.h" #include "sls/ToString.h"
#include "sls/network_utils.h" #include "sls/network_utils.h"
#include "sls/Pattern.h"
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#include "sls/container_utils.h" #include "sls/container_utils.h"
#include <array> #include <array>
@ -317,9 +318,9 @@ TEST_CASE("Printing c style arrays of double"){
} }
TEST_CASE("Print a member of patternParameters"){ TEST_CASE("Print a member of patternParameters"){
auto pat = sls::make_unique<slsDetectorDefs::patternParameters>(); auto pat = sls::make_unique<sls::patternParameters>();
pat->patlimits[0] = 4; pat->limits[0] = 4;
pat->patlimits[1] = 100; pat->limits[1] = 100;
REQUIRE(ToString(pat->patlimits) == "[4, 100]"); REQUIRE(ToString(pat->limits) == "[4, 100]");
} }