Merge pull request #223 from slsdetectorgroup/savepatternbackup

Savepatternbackup
This commit is contained in:
Dhanya Thattil 2020-11-30 14:00:31 +01:00 committed by GitHub
commit 9048e7f6c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
61 changed files with 650 additions and 373 deletions

View File

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

View File

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

View File

@ -1,5 +1,8 @@
import _slsdet
from _slsdet import Pattern
class patternParameters(_slsdet.patternParameters):
def __init__(self):
super().__init__()
@ -13,13 +16,38 @@ class patternParameters(_slsdet.patternParameters):
raise KeyError(f"Key: {name} not found")
def __setattr__(self, name, value):
if name in ['view', 'names']:
if name in ["view", "names"]:
self.__dict__[name] = value
elif name in self.names:
self.view[name] = value
else:
else:
raise KeyError(f"Key: {name} not found")
#Provide custom dir for tab completion
# 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

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

View File

@ -7,6 +7,7 @@
#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) {
@ -17,20 +18,6 @@ void init_enums(py::module &m) {
xy.def_readwrite("x", &slsDetectorDefs::xy::x);
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")
.value("GENERIC", slsDetectorDefs::detectorType::GENERIC)
.value("EIGER", slsDetectorDefs::detectorType::EIGER)

View File

@ -5,6 +5,7 @@
#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");
@ -14,18 +15,5 @@ void init_enums(py::module &m) {
xy.def_readwrite("x", &slsDetectorDefs::xy::x);
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);
[[ENUMS]]
}

View File

@ -19,6 +19,7 @@ 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 &);
PYBIND11_MODULE(_slsdet, m) {
m.doc() = R"pbdoc(
C/C++ API
@ -33,6 +34,7 @@ PYBIND11_MODULE(_slsdet, m) {
init_enums(m);
init_det(m);
init_network(m);
init_pattern(m);
// init_experimental(m);

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

@ -0,0 +1,47 @@
#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);
});
//.def_readwrite("name", &Pet::name)
// patternParameters.def_property(
// "some",
// [](py::object &obj) {
// pat &o = obj.cast<pat &>();
// return py::array_t<pat>(1, &o, obj);
// },
// [](py::object &obj) {
// pat &o = obj.cast<pat &>();
// return py::array_t<pat>(1, &o, obj);
// });
// patternParameters.def_property_readonly(
// "loop",
// [](py::object &obj) {
// pat &o = obj.cast<pat &>();
// return py::array_t<uint32_t>(6, &o.loop[0], 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);
}

View File

@ -0,0 +1 @@
../slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer

View File

@ -1 +0,0 @@
../slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServerv5.0.0

View File

@ -0,0 +1 @@
../slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer

View File

@ -1 +0,0 @@
../slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServerv5.0.0

View File

@ -0,0 +1 @@
../slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer

View File

@ -1 +0,0 @@
../slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServerv5.0.0

View File

@ -0,0 +1 @@
../slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer

View File

@ -1 +0,0 @@
../slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServerv5.0.0

View File

@ -0,0 +1 @@
../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer

View File

@ -1 +0,0 @@
../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv5.0.0

View File

@ -0,0 +1 @@
../slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer

View File

@ -1 +0,0 @@
../slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServerv5.0.0

View File

@ -0,0 +1 @@
../slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer

View File

@ -1 +0,0 @@
../slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServerv5.0.0

View File

@ -22,6 +22,7 @@ add_executable(ctbDetectorServer_virtual
include_directories(
../slsDetectorServer/include
../../slsSupportLib/include
../../slsDetectorSoftware/include/sls/
)
target_include_directories(ctbDetectorServer_virtual

View File

@ -2,10 +2,11 @@ current_dir = $(shell pwd)
main_inc = ../slsDetectorServer/include/
main_src = ../slsDetectorServer/src/
support_lib = ../../slsSupportLib/include/
det_lib = ../../slsDetectorSoftware/include/sls/
CROSS = bfin-uclinux-
CC = $(CROSS)gcc
CFLAGS += -Wall -std=gnu99 -DCHIPTESTBOARDD -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(current_dir) #-DDEBUG1 #-DVERBOSEI #-DVERBOSE
CFLAGS += -Wall -std=gnu99 -DCHIPTESTBOARDD -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(det_lib) -I$(current_dir) #-DDEBUG1 #-DVERBOSEI #-DVERBOSE
LDLIBS += -lm -lrt -pthread
PROGS = ctbDetectorServer
DESTDIR ?= bin

View File

@ -20,6 +20,7 @@ add_executable(moenchDetectorServer_virtual
include_directories(
../slsDetectorServer/include
../../slsSupportLib/include
../../slsDetectorSoftware/include/sls/
)
target_include_directories(moenchDetectorServer_virtual

View File

@ -2,10 +2,11 @@ current_dir = $(shell pwd)
main_inc = ../slsDetectorServer/include/
main_src = ../slsDetectorServer/src/
support_lib = ../../slsSupportLib/include/
det_lib = ../../slsDetectorSoftware/include/sls/
CROSS = bfin-uclinux-
CC = $(CROSS)gcc
CFLAGS += -Wall -std=gnu99 -DMOENCHD -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(current_dir)#-DVERBOSEI #-DVERBOSE
CFLAGS += -Wall -std=gnu99 -DMOENCHD -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(det_lib) -I$(current_dir)#-DVERBOSEI #-DVERBOSE
LDLIBS += -lm -lrt -pthread
PROGS = moenchDetectorServer
DESTDIR ?= bin

View File

@ -17,6 +17,7 @@ add_executable(mythen3DetectorServer_virtual
include_directories(
../slsDetectorServer/include
../../slsSupportLib/include
../../slsDetectorSoftware/include/sls/
)
target_include_directories(mythen3DetectorServer_virtual

View File

@ -2,10 +2,11 @@ current_dir = $(shell pwd)
main_inc = ../slsDetectorServer/include/
main_src = ../slsDetectorServer/src/
support_lib = ../../slsSupportLib/include/
det_lib = ../../slsDetectorSoftware/include/sls/
CROSS = nios2-buildroot-linux-gnu-
CC = $(CROSS)gcc
CFLAGS += -Wall -std=gnu99 -DMYTHEN3D -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(current_dir) #-DDEBUG1 #-DVERBOSEI #-DVERBOSE
CFLAGS += -Wall -std=gnu99 -DMYTHEN3D -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(det_lib) -I$(current_dir) #-DDEBUG1 #-DVERBOSEI #-DVERBOSE
LDLIBS += -lm -lrt -pthread
PROGS = mythen3DetectorServer
DESTDIR ?= bin

View File

@ -242,4 +242,5 @@ int validate_udp_configuration(int);
int get_bursts_left(int);
int start_readout(int);
int set_default_dacs(int);
int is_virtual(int);
int is_virtual(int);
int get_pattern(int);

View File

@ -5,6 +5,10 @@
#include "sls/sls_detector_funcs.h"
#include "slsDetectorFunctionList.h"
#if defined(CHIPTESTBOARDD) || defined(MOENCHD) || defined(MYTHEN3D)
#include "Pattern.h"
#endif
#include <arpa/inet.h>
#include <pthread.h>
#include <string.h>
@ -361,6 +365,7 @@ void function_table() {
flist[F_START_READOUT] = &start_readout;
flist[F_SET_DEFAULT_DACS] = &set_default_dacs;
flist[F_IS_VIRTUAL] = &is_virtual;
flist[F_GET_PATTERN] = &get_pattern;
// check
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
@ -7531,17 +7536,22 @@ int set_pattern(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
patternParameters *pat = malloc(sizeof(patternParameters));
memset(pat, 0, sizeof(patternParameters));
if (receiveDataOnly(file_des, pat, sizeof(patternParameters)) < 0)
return printSocketReadError();
#if !defined(CHIPTESTBOARDD) && !defined(MOENCHD) && !defined(MYTHEN3D)
functionNotImplemented();
#else
patternParameters *pat = malloc(sizeof(patternParameters));
memset(pat, 0, sizeof(patternParameters));
// ignoring endianness for eiger
if (receiveData(file_des, pat, sizeof(patternParameters), INT32) < 0) {
if (pat != NULL)
free(pat);
return printSocketReadError();
}
if (Server_VerifyLock() == OK) {
LOG(logINFO, ("Setting Pattern from file\n"));
LOG(logINFO, ("Setting Pattern from structure\n"));
LOG(logINFO,
("Setting Pattern Word (printing every 10 words that are not 0\n"));
for (int i = 0; i < MAX_PATTERN_LENGTH; ++i) {
@ -7551,95 +7561,194 @@ int set_pattern(int file_des) {
}
writePatternWord(i, pat->word[i]);
}
int numLoops = -1, retval0 = -1, retval1 = -1;
uint64_t retval64 = -1;
#ifndef MYTHEN3D
if (ret == OK) {
retval64 = writePatternIOControl(pat->patioctrl);
validate64(pat->patioctrl, retval64, "set pattern IO Control", HEX);
uint64_t retval64 = writePatternIOControl(pat->ioctrl);
validate64(pat->ioctrl, retval64, "set pattern IO Control", HEX);
}
#endif
if (ret == OK) {
numLoops = -1;
retval0 = pat->patlimits[0];
retval1 = pat->patlimits[1];
int numLoops = -1;
int retval0 = pat->limits[0];
int retval1 = pat->limits[1];
setPatternLoop(-1, &retval0, &retval1, &numLoops);
validate(pat->patlimits[0], retval0,
validate(pat->limits[0], retval0,
"set pattern Limits start address", HEX);
validate(pat->patlimits[1], retval1,
validate(pat->limits[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);
}
if (ret == OK) {
retval0 = pat->patloop[2];
retval1 = pat->patloop[3];
numLoops = pat->patnloop[1];
setPatternLoop(1, &retval0, &retval1, &numLoops);
validate(pat->patloop[2], retval0,
"set pattern Loop 1 start address", HEX);
validate(pat->patloop[3], retval1,
"set pattern Loop 1 stop address", HEX);
validate(pat->patnloop[1], numLoops, "set pattern Loop 1 num loops",
HEX);
}
if (ret == OK) {
retval0 = pat->patloop[4];
retval1 = pat->patloop[5];
numLoops = pat->patnloop[2];
setPatternLoop(2, &retval0, &retval1, &numLoops);
validate(pat->patloop[4], retval0,
"set pattern Loop 2 start address", HEX);
validate(pat->patloop[5], retval1,
"set pattern Loop 2 stop address", HEX);
validate(pat->patnloop[2], numLoops, "set pattern Loop 2 num loops",
HEX);
}
if (ret == OK) {
retval0 = setPatternWaitAddress(0, pat->patwait[0]);
validate(pat->patwait[0], retval0,
"set pattern Loop 0 wait address", HEX);
}
if (ret == OK) {
retval0 = setPatternWaitAddress(1, pat->patwait[1]);
validate(pat->patwait[1], retval0,
"set pattern Loop 1 wait address", HEX);
}
if (ret == OK) {
retval0 = setPatternWaitAddress(2, pat->patwait[2]);
validate(pat->patwait[2], retval0,
"set pattern Loop 2 wait address", HEX);
}
if (ret == OK) {
uint64_t retval64 = setPatternWaitTime(0, pat->patwaittime[0]);
validate64(pat->patwaittime[0], retval64,
"set pattern Loop 0 wait time", HEX);
}
if (ret == OK) {
retval64 = setPatternWaitTime(1, pat->patwaittime[1]);
validate64(pat->patwaittime[1], retval64,
"set pattern Loop 1 wait time", HEX);
}
if (ret == OK) {
retval64 = setPatternWaitTime(2, pat->patwaittime[2]);
validate64(pat->patwaittime[2], retval64,
"set pattern Loop 2 wait time", HEX);
for (int i = 0; i <= 2; ++i) {
char msg[128];
int retval0 = -1, retval1 = -1, numLoops = -1;
uint64_t retval64 = -1;
// patloop
retval0 = pat->loop[i * 2 + 0];
retval1 = pat->loop[i * 2 + 1];
numLoops = pat->nloop[i];
setPatternLoop(i, &retval0, &retval1, &numLoops);
memset(msg, 0, sizeof(msg));
sprintf(msg, "set pattern Loop %d start address", i);
validate(pat->loop[i * 2 + 0], retval0, msg, HEX);
if (ret == FAIL) {
break;
}
memset(msg, 0, sizeof(msg));
sprintf(msg, "set pattern Loop %d stop address", i);
validate(pat->loop[i * 2 + 1], retval1, msg, HEX);
if (ret == FAIL) {
break;
}
memset(msg, 0, sizeof(msg));
sprintf(msg, "set pattern Loop %d num loops", i);
validate(pat->nloop[i], numLoops, msg, HEX);
if (ret == FAIL) {
break;
}
// patwait
memset(msg, 0, sizeof(msg));
sprintf(msg, "set pattern Loop %d wait address", i);
retval0 = setPatternWaitAddress(i, pat->wait[i]);
validate(pat->wait[i], retval0, msg, HEX);
if (ret == FAIL) {
break;
}
// patwaittime
memset(msg, 0, sizeof(msg));
sprintf(msg, "set pattern Loop %d wait time", i);
retval64 = setPatternWaitTime(i, pat->waittime[i]);
validate64(pat->waittime[i], retval64, msg, HEX);
if (ret == FAIL) {
break;
}
}
}
}
if (pat != NULL)
free(pat);
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
}
int get_pattern(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
#if !defined(CHIPTESTBOARDD) && !defined(MOENCHD) && !defined(MYTHEN3D)
functionNotImplemented();
return Server_SendResult(file_des, INT32, NULL, 0);
#else
patternParameters *pat = malloc(sizeof(patternParameters));
memset(pat, 0, sizeof(patternParameters));
if (Server_VerifyLock() == OK) {
LOG(logINFO, ("Getting Pattern from structure\n"));
// patword
LOG(logDEBUG,
("retval pattern word (printing every 10 words that are not 0\n"));
for (int i = 0; i < MAX_PATTERN_LENGTH; ++i) {
pat->word[i] = readPatternWord(i);
if ((int64_t)pat->word[i] == -1) {
ret = FAIL;
sprintf(mess, "could not read pattern word for address 0x%x\n",
i);
LOG(logERROR, (mess));
break;
}
// debug print
if ((i % 10 == 0) && pat->word[i] != 0) {
LOG(logDEBUG,
("retval Patpattern word (addr:0x%x, word:0x%llx)\n", i,
(long long int)pat->word[i]));
}
}
// patioctrl
#ifndef MYTHEN3D
if (ret == OK) {
pat->ioctrl = writePatternIOControl(-1);
LOG(logDEBUG, ("retval pattern io control:0x%llx\n",
(long long int)pat->ioctrl));
}
#endif
if (ret == OK) {
// patlimits
int numLoops = -1;
int retval0 = -1;
int retval1 = -1;
setPatternLoop(-1, &retval0, &retval1, &numLoops);
pat->limits[0] = retval0;
pat->limits[1] = retval1;
LOG(logDEBUG, ("retval pattern limits start:0x%x stop:0x%x\n",
pat->limits[0], pat->limits[1]));
for (int i = 0; i <= 2; ++i) {
// patloop
{
int numLoops = -1;
int retval0 = -1;
int retval1 = -1;
setPatternLoop(i, &retval0, &retval1, &numLoops);
pat->nloop[i] = numLoops;
pat->loop[i * 2 + 0] = retval0;
pat->loop[i * 2 + 1] = retval1;
LOG(logDEBUG, ("retval pattern loop level %d start:0x%x "
"stop:0x%x numLoops:%d\n",
i, pat->loop[i * 2 + 0],
pat->loop[i * 2 + 0], pat->nloop[i]));
}
// patwait
{
pat->wait[i] = setPatternWaitAddress(i, -1);
if ((int)pat->wait[i] == -1) {
ret = FAIL;
sprintf(mess,
"could not read pattern wait address for level "
"%d\n",
i);
LOG(logERROR, (mess));
break;
}
LOG(logDEBUG,
("retval pattern wait address for level %d: 0x%x\n", i,
pat->wait[i]));
}
// patwaittime
{
pat->waittime[i] = setPatternWaitTime(i, -1);
if ((int64_t)pat->waittime[i] == -1) {
ret = FAIL;
sprintf(
mess,
"could not read pattern wait time for level %d\n",
i);
LOG(logERROR, (mess));
break;
}
LOG(logDEBUG,
("retval pattern wait time for level %d: %lld\n", i,
(long long int)pat->waittime[i]));
}
}
}
}
// ignoring endianness for eiger
int ret =
Server_SendResult(file_des, INT32, pat, sizeof(patternParameters));
if (pat != NULL)
free(pat);
return ret;
#endif
}
int get_scan(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));

View File

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

View File

@ -2,6 +2,7 @@
#include "sls/Result.h"
#include "sls/network_utils.h"
#include "sls/sls_detector_defs.h"
#include "sls/Pattern.h"
#include <chrono>
#include <map>
#include <memory>
@ -15,6 +16,7 @@ class DetectorImpl;
class MacAddr;
class IpAddr;
// Free function to avoid dependence on class
// and avoid the option to free another objects
// shm by mistake
@ -1459,7 +1461,7 @@ class Detector {
/** [CTB][Moench][Mythen3] Loads pattern parameters structure directly to
* 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
* (ascii). \n [Ctb][Moench] Also executes pattern.*/

View File

@ -0,0 +1,41 @@
#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;
size_t size() const noexcept { return sizeof(patternParameters); }
void validate() const;
void load(const std::string &fname);
void save(const std::string &fname);
std::string str() const;
};
} // namespace sls
#endif

View File

@ -5,6 +5,7 @@
#include "CmdProxy.h"
#include "DetectorImpl.h"
#include "Module.h"
#include "sls/Pattern.h"
#include "sls/container_utils.h"
#include "sls/logger.h"
#include "sls/sls_detector_defs.h"
@ -1754,44 +1755,22 @@ void Detector::setLEDEnable(bool enable, Positions pos) {
// Pattern
void Detector::savePattern(const std::string &fname) {
std::ofstream outfile;
outfile.open(fname.c_str(), std::ios_base::out);
if (!outfile.is_open()) {
throw RuntimeError("Could not create file to save pattern");
}
// get pattern limits
auto r = pimpl->Parallel(&Module::getPatternLoopAddresses, {}, -1)
.tsquash("Inconsistent pattern limits");
CmdProxy proxy(this);
// pattern words
for (int i = r[0]; i <= r[1]; ++i) {
std::ostringstream os;
os << "0x" << std::hex << i;
auto addr = os.str();
proxy.Call("patword", {addr}, -1, defs::GET_ACTION, outfile);
}
// rest of pattern file
std::vector<std::string> commands{
"patioctrl", "patlimits", "patloop0", "patnloop0",
"patloop1", "patnloop1", "patloop2", "patnloop2",
"patwait0", "patwaittime0", "patwait1", "patwaittime1",
"patwait2", "patwaittime2", "patmask", "patsetbit",
};
auto det_type = getDetectorType().squash();
if (det_type == defs::MYTHEN3) {
commands.erase(commands.begin(), commands.begin() + 2);
}
for (const auto &cmd : commands)
proxy.Call(cmd, {}, -1, defs::GET_ACTION, outfile);
auto t = pimpl->Parallel(&Module::getPattern, {});
auto pat = t.tsquash("Inconsistent pattern parameters between modules");
pat.validate();
pat.save(fname);
}
void Detector::setPattern(const std::string &fname, Positions pos) {
pimpl->Parallel(&Module::setPattern, pos, fname);
Pattern pat;
pat.load(fname);
pat.validate();
setPattern(pat, pos);
}
void Detector::setPattern(const defs::patternParameters *pat, Positions pos) {
pimpl->Parallel(&Module::setPatternStructure, pos, pat);
void Detector::setPattern(const Pattern &pat, Positions pos) {
pat.validate();
pimpl->Parallel(&Module::setPattern, pos, pat);
}
Result<uint64_t> Detector::getPatternIOControl(Positions pos) const {

View File

@ -1913,37 +1913,14 @@ void Module::setLEDEnable(bool enable) {
// Pattern
void Module::setPattern(const std::string &fname) {
auto pat = sls::make_unique<patternParameters>();
pat->load(fname);
setPatternStructure(pat.get());
void Module::setPattern(const Pattern &pat) {
sendToDetector(F_SET_PATTERN, pat.data(), pat.size(), nullptr, 0);
}
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 (int i = 0; i != 3; ++i) {
if (pat->patloop[i * 2 + 0] >= MAX_PATTERN_LENGTH ||
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("]"));
}
if (pat->patwait[i] >= MAX_PATTERN_LENGTH) {
throw RuntimeError("Invalid Pattern wait address for level " +
ToString(i) + std::string(" ") +
ToString(pat->patwait[i]));
}
}
LOG(logDEBUG1) << "Sending pattern from file to detector:" << *pat;
sendToDetector(F_SET_PATTERN, pat, sizeof(patternParameters), nullptr, 0);
Pattern Module::getPattern() {
Pattern pat;
sendToDetector(F_GET_PATTERN, nullptr, 0, pat.data(), pat.size());
return pat;
}
uint64_t Module::getPatternIOControl() const {

View File

@ -5,6 +5,7 @@
#include "sls/logger.h"
#include "sls/network_utils.h"
#include "sls/sls_detector_defs.h"
#include "sls/Pattern.h"
#include <array>
#include <cmath>
@ -462,8 +463,8 @@ class Module : public virtual slsDetectorDefs {
* Pattern *
* *
* ************************************************/
void setPattern(const std::string &fname);
void setPatternStructure(const defs::patternParameters *pat);
void setPattern(const Pattern& pat);
Pattern getPattern();
uint64_t getPatternIOControl() const;
void setPatternIOControl(uint64_t word);
uint64_t getPatternWord(int addr) const;

View File

@ -0,0 +1,240 @@
#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);
}
}
}
}
void Pattern::save(const std::string &fname) {
std::ofstream output_file(fname);
if (!output_file) {
throw RuntimeError("Could not open pattern file " + fname +
" for writing");
}
std::ostringstream os;
// pattern word
for (uint32_t i = pat->limits[0]; i <= pat->limits[1]; ++i) {
output_file << "patword " << ToStringHex(i, 4) << " "
<< ToStringHex(pat->word[i], 16) << std::endl;
}
// patioctrl
output_file << "patioctrl " << ToStringHex(pat->ioctrl, 16) << std::endl;
// patlimits
output_file << "patlimits " << ToStringHex(pat->limits[0], 4) << " "
<< ToStringHex(pat->limits[1], 4) << std::endl;
for (size_t i = 0; i < 3; ++i) {
// patloop
output_file << "patloop" << i << " "
<< ToStringHex(pat->loop[i * 2 + 0], 4) << " "
<< ToStringHex(pat->loop[i * 2 + 1], 4) << std::endl;
// patnloop
output_file << "patnloop" << i << " " << pat->nloop[i] << std::endl;
}
for (size_t i = 0; i < 3; ++i) {
// patwait
output_file << "patwait" << i << " " << ToStringHex(pat->wait[i], 4)
<< std::endl;
// patwaittime
output_file << "patwaittime" << i << " " << pat->waittime[i]
<< std::endl;
}
}
std::string Pattern::str() const {
std::ostringstream oss;
oss << '[' << std::setfill('0') << std::endl;
int addr_width = 4;
int word_width = 16;
for (int i = 0; i < MAX_PATTERN_LENGTH; ++i) {
if (pat->word[i] != 0) {
oss << "patword " << ToStringHex(i, addr_width) << " "
<< ToStringHex(pat->word[i], word_width) << std::endl;
}
}
oss << "patioctrl " << ToStringHex(pat->ioctrl, word_width) << std::endl
<< "patlimits " << ToStringHex(pat->limits[0], addr_width) << " "
<< ToStringHex(pat->limits[1], addr_width) << std::endl
<< "patloop0 " << ToStringHex(pat->loop[0], addr_width) << " "
<< ToStringHex(pat->loop[1], addr_width) << std::endl
<< "patnloop0 " << pat->nloop[0] << std::endl
<< "patloop1 " << ToStringHex(pat->loop[2], addr_width) << " "
<< ToStringHex(pat->loop[3], addr_width) << std::endl
<< "patnloop1 " << pat->nloop[1] << std::endl
<< "patloop2 " << ToStringHex(pat->loop[4], addr_width) << " "
<< ToStringHex(pat->loop[5], addr_width) << std::endl
<< "patnloop2 " << pat->nloop[2] << std::endl
<< "patwait0 " << ToStringHex(pat->wait[0], addr_width) << std::endl
<< "patwaittime0 " << pat->waittime[0] << std::endl
<< "patwait1 " << ToStringHex(pat->wait[1], addr_width) << std::endl
<< "patwaittime1 " << pat->waittime[1] << std::endl
<< "patwait2 " << ToStringHex(pat->wait[2], addr_width) << std::endl
<< "patwaittime2 " << pat->waittime[2] << std::endl
<< ']';
return oss.str();
}
} // namespace sls

View File

@ -15,6 +15,7 @@ target_sources(tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/test-Result.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-CmdParser.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>")

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/UdpRxSocket.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

View File

@ -44,9 +44,6 @@ std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::ROI &roi);
std::string ToString(const slsDetectorDefs::rxParameters &r);
std::ostream &operator<<(std::ostream &os,
const slsDetectorDefs::rxParameters &r);
std::string ToString(const slsDetectorDefs::patternParameters &r);
std::ostream &operator<<(std::ostream &os,
const slsDetectorDefs::patternParameters &r);
std::string ToString(const slsDetectorDefs::scanParameters &r);
std::ostream &operator<<(std::ostream &os,
const slsDetectorDefs::scanParameters &r);
@ -182,16 +179,15 @@ std::string ToString(const std::map<KeyType, ValueType> &m) {
}
/**
* Print a c style array
* Print a c style array
*/
template<typename T, size_t size>
std::string ToString(const T(&arr)[size]){
template <typename T, size_t size> std::string ToString(const T (&arr)[size]) {
std::ostringstream os;
os << '[';
if (size){
if (size) {
size_t i = 0;
os << ToString(arr[i++]);
for (; i<size; ++i)
for (; i < size; ++i)
os << ", " << ToString(arr[i]);
}
os << ']';

View File

@ -475,35 +475,6 @@ typedef struct {
} __attribute__((packed));
#endif
/** pattern structure */
#ifdef __cplusplus
struct patternParameters {
#else
typedef struct __attribute__((packed)){
#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
protected:
#endif

View File

@ -217,6 +217,7 @@ enum detFuncs {
F_START_READOUT,
F_SET_DEFAULT_DACS,
F_IS_VIRTUAL,
F_GET_PATTERN,
NUM_DET_FUNCTIONS,
RECEIVER_ENUM_START = 256, /**< detector function should not exceed this
@ -539,6 +540,7 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_START_READOUT: return "F_START_READOUT";
case F_SET_DEFAULT_DACS: return "F_SET_DEFAULT_DACS";
case F_IS_VIRTUAL: return "F_IS_VIRTUAL";
case F_GET_PATTERN: return "F_GET_PATTERN";
case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS";
case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";

View File

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

View File

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

View File

@ -1,97 +0,0 @@
#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

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