diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 7120d0ca3..c6dc763c2 100755 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -28,6 +28,7 @@ set( PYTHON_FILES enums.py errors.py gotthard.py + pattern.py gotthard2.py moench.py proxy.py diff --git a/python/examples/manipulate_pattern.py b/python/examples/manipulate_pattern.py new file mode 100644 index 000000000..83c0314f8 --- /dev/null +++ b/python/examples/manipulate_pattern.py @@ -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") diff --git a/python/examples/use_enum.py b/python/examples/use_enum.py index 67c55394d..8e8eaf210 100644 --- a/python/examples/use_enum.py +++ b/python/examples/use_enum.py @@ -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) diff --git a/python/scripts/basic.py b/python/scripts/basic.py index 4e11b33ee..2135b4a58 100755 --- a/python/scripts/basic.py +++ b/python/scripts/basic.py @@ -10,6 +10,8 @@ from slsdet.lookup import view, find import slsdet + + d = Detector() e = Eiger() c = Ctb() diff --git a/python/scripts/generate_enums.py b/python/scripts/generate_enums.py index 29c73f628..e43f45adf 100644 --- a/python/scripts/generate_enums.py +++ b/python/scripts/generate_enums.py @@ -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) diff --git a/python/slsdet/__init__.py b/python/slsdet/__init__.py index f6df36332..9f5cbc40d 100755 --- a/python/slsdet/__init__.py +++ b/python/slsdet/__init__.py @@ -8,6 +8,7 @@ from .mythen3 import Mythen3 from .gotthard2 import Gotthard2 from .gotthard import Gotthard from .moench import Moench +from .pattern import patternParameters import _slsdet xy = _slsdet.xy diff --git a/python/slsdet/pattern.py b/python/slsdet/pattern.py new file mode 100644 index 000000000..2cf2c3bcf --- /dev/null +++ b/python/slsdet/pattern.py @@ -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 \ No newline at end of file diff --git a/python/src/detector.cpp b/python/src/detector.cpp index 0a86001f9..99125b2a4 100644 --- a/python/src/detector.cpp +++ b/python/src/detector.cpp @@ -1271,6 +1271,11 @@ 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 defs::patternParameters *, + sls::Positions)) & + Detector::setPattern, + py::arg(), py::arg() = Positions{}) .def("savePattern", (void (Detector::*)(const std::string &)) & Detector::savePattern, py::arg()) diff --git a/python/src/enums.cpp b/python/src/enums.cpp index e42c63339..e01750b6c 100644 --- a/python/src/enums.cpp +++ b/python/src/enums.cpp @@ -2,6 +2,7 @@ * warning */ #include +#include #include #include #include @@ -16,6 +17,20 @@ void init_enums(py::module &m) { xy.def_readwrite("x", &slsDetectorDefs::xy::x); xy.def_readwrite("y", &slsDetectorDefs::xy::y); + py::class_ 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(); + return py::array_t(1, &o, obj); + }); + patternParameters.def("load", &pat::load); + py::enum_(Defs, "detectorType") .value("GENERIC", slsDetectorDefs::detectorType::GENERIC) .value("EIGER", slsDetectorDefs::detectorType::EIGER) diff --git a/python/src/enums_in.cpp b/python/src/enums_in.cpp index 2e21b2d58..6a63f6a00 100644 --- a/python/src/enums_in.cpp +++ b/python/src/enums_in.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -9,10 +10,22 @@ void init_enums(py::module &m) { py::class_ Defs(m, "slsDetectorDefs"); py::class_ xy(m, "xy"); xy.def(py::init()); - xy.def(py::init()); + xy.def(py::init()); xy.def_readwrite("x", &slsDetectorDefs::xy::x); xy.def_readwrite("y", &slsDetectorDefs::xy::y); -[[ENUMS]] + py::class_ 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(); + return py::array_t(1, &o, obj); }); + patternParameters.def("load", &pat::load); + + [[ENUMS]] } diff --git a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer index aa9c05bf3..ab74dd65a 100755 Binary files a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer and b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer differ diff --git a/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer b/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer index 0af3accf3..5393a8bf4 100755 Binary files a/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer and b/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer differ diff --git a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer index c0979f026..9aa3598e8 100755 Binary files a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer and b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer differ diff --git a/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer b/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer index afdf76f34..b42eb2b91 100755 Binary files a/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer and b/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer differ diff --git a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer index 5c7146e34..354f5d3bb 100755 Binary files a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer and b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer differ diff --git a/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer b/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer index 66d391ea0..a6be46884 100755 Binary files a/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer and b/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer differ diff --git a/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer b/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer index dfbdf7bb3..886f9b85d 100755 Binary files a/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer and b/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer differ diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 2df69676c..831a29414 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -7530,28 +7530,11 @@ int set_veto(int file_des) { int set_pattern(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); - uint64_t *patwords = malloc(sizeof(uint64_t) * MAX_PATTERN_LENGTH); - memset(patwords, 0, sizeof(uint64_t) * MAX_PATTERN_LENGTH); - uint64_t patioctrl = 0; - int patlimits[2] = {0, 0}; - int patloop[6] = {0, 0, 0, 0, 0, 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) + + 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) @@ -7562,95 +7545,95 @@ int set_pattern(int file_des) { LOG(logINFO, ("Setting Pattern Word (printing every 10 words that are not 0\n")); 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", - 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; uint64_t retval64 = -1; #ifndef MYTHEN3D if (ret == OK) { - retval64 = writePatternIOControl(patioctrl); - validate64(patioctrl, retval64, "set pattern IO Control", HEX); + retval64 = writePatternIOControl(pat->patioctrl); + validate64(pat->patioctrl, retval64, "set pattern IO Control", HEX); } #endif if (ret == OK) { numLoops = -1; - retval0 = patlimits[0]; - retval1 = patlimits[1]; + retval0 = pat->patlimits[0]; + retval1 = pat->patlimits[1]; setPatternLoop(-1, &retval0, &retval1, &numLoops); - validate(patlimits[0], retval0, "set pattern Limits start address", - HEX); - validate(patlimits[1], retval1, "set pattern Limits start address", + validate(pat->patlimits[0], retval0, + "set pattern Limits start address", HEX); + 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); } if (ret == OK) { - retval0 = patloop[0]; - retval1 = patloop[1]; - numLoops = patnloop[0]; - setPatternLoop(0, &patloop[0], &patloop[1], &numLoops); - validate(patloop[0], retval0, "set pattern Loop 0 start address", - HEX); - validate(patloop[1], retval1, "set pattern Loop 0 stop address", - HEX); - validate(patnloop[0], numLoops, "set pattern Loop 0 num loops", + 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 = patloop[2]; - retval1 = patloop[3]; - numLoops = patnloop[1]; - setPatternLoop(1, &patloop[2], &patloop[3], &numLoops); - validate(patloop[2], retval0, "set pattern Loop 1 start address", - HEX); - validate(patloop[3], retval1, "set pattern Loop 1 stop address", - HEX); - validate(patnloop[1], numLoops, "set pattern Loop 1 num loops", + 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 = patloop[4]; - retval1 = patloop[5]; - numLoops = patnloop[2]; - 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); + retval0 = setPatternWaitAddress(0, pat->patwait[0]); + validate(pat->patwait[0], retval0, + "set pattern Loop 0 wait address", HEX); } if (ret == OK) { - retval0 = setPatternWaitAddress(0, patwait[0]); - validate(patwait[0], retval0, "set pattern Loop 0 wait address", - HEX); + retval0 = setPatternWaitAddress(1, pat->patwait[1]); + validate(pat->patwait[1], retval0, + "set pattern Loop 1 wait address", HEX); } if (ret == OK) { - retval0 = setPatternWaitAddress(1, patwait[1]); - validate(patwait[1], retval0, "set pattern Loop 1 wait address", - HEX); + retval0 = setPatternWaitAddress(2, pat->patwait[2]); + validate(pat->patwait[2], retval0, + "set pattern Loop 2 wait address", HEX); } if (ret == OK) { - retval0 = setPatternWaitAddress(2, patwait[2]); - validate(patwait[2], retval0, "set pattern Loop 2 wait address", - HEX); + uint64_t retval64 = setPatternWaitTime(0, pat->patwaittime[0]); + validate64(pat->patwaittime[0], retval64, + "set pattern Loop 0 wait time", HEX); } if (ret == OK) { - uint64_t retval64 = setPatternWaitTime(0, patwaittime[0]); - validate64(patwaittime[0], retval64, "set pattern Loop 0 wait time", - HEX); + retval64 = setPatternWaitTime(1, pat->patwaittime[1]); + validate64(pat->patwaittime[1], retval64, + "set pattern Loop 1 wait time", HEX); } if (ret == OK) { - retval64 = setPatternWaitTime(1, patwaittime[1]); - validate64(patwaittime[1], retval64, "set pattern Loop 1 wait time", - HEX); - } - if (ret == OK) { - retval64 = setPatternWaitTime(2, patwaittime[2]); - validate64(patwaittime[1], retval64, "set pattern Loop 2 wait time", - HEX); + retval64 = setPatternWaitTime(2, pat->patwaittime[2]); + validate64(pat->patwaittime[2], retval64, + "set pattern Loop 2 wait time", HEX); } } #endif diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index 6b219de2f..26e6f0afd 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -1457,6 +1457,10 @@ class Detector { * (instead of executing line by line)*/ 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 * (ascii). \n [Ctb][Moench] Also executes pattern.*/ void savePattern(const std::string &fname); diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 50f3da660..b5012beba 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -1790,6 +1790,10 @@ void Detector::setPattern(const std::string &fname, Positions pos) { pimpl->Parallel(&Module::setPattern, pos, fname); } +void Detector::setPattern(const defs::patternParameters *pat, Positions pos) { + pimpl->Parallel(&Module::setPatternStructure, pos, pat); +} + Result Detector::getPatternIOControl(Positions pos) const { return pimpl->Parallel(&Module::getPatternIOControl, pos); } diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index c8fca9c78..6fb9c04fc 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -1915,104 +1915,35 @@ void Module::setLEDEnable(bool enable) { void Module::setPattern(const std::string &fname) { auto pat = sls::make_unique(); - std::ifstream input_file(fname); - if (!input_file) { - throw RuntimeError("Could not open pattern file " + fname + - " for reading"); + pat->load(fname); + setPatternStructure(pat.get()); +} + +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);) { - if (line.find('#') != std::string::npos) { - line.erase(line.find('#')); + 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("]")); } - 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(iss); - std::vector args = std::vector( - it, std::istream_iterator()); - - 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(args[1]); - if (addr >= MAX_PATTERN_LENGTH) { - throw RuntimeError("Invalid address for " + ToString(args)); - } - pat->word[addr] = StringTo(args[2]); - } else if (cmd == "patioctrl") { - if (nargs != 1) { - throw RuntimeError("Invalid arguments for " + - ToString(args)); - } - pat->patioctrl = StringTo(args[1]); - } else if (cmd == "patlimits") { - if (nargs != 2) { - throw RuntimeError("Invalid arguments for " + - ToString(args)); - } - pat->patlimits[0] = StringTo(args[1]); - pat->patlimits[1] = StringTo(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(args[1]); - int patloop2 = StringTo(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(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(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(args[1]); - } else { - throw RuntimeError("Unknown command in pattern file " + cmd); - } + 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.get(), sizeof(patternParameters), nullptr, - 0); + sendToDetector(F_SET_PATTERN, pat, sizeof(patternParameters), nullptr, 0); } uint64_t Module::getPatternIOControl() const { diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 7e9abeb53..451c544e4 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -463,6 +463,7 @@ class Module : public virtual slsDetectorDefs { * * * ************************************************/ void setPattern(const std::string &fname); + void setPatternStructure(const defs::patternParameters *pat); uint64_t getPatternIOControl() const; void setPatternIOControl(uint64_t word); uint64_t getPatternWord(int addr) const; diff --git a/slsSupportLib/CMakeLists.txt b/slsSupportLib/CMakeLists.txt index 4ea86add5..086765df9 100755 --- a/slsSupportLib/CMakeLists.txt +++ b/slsSupportLib/CMakeLists.txt @@ -10,6 +10,7 @@ set(SOURCES src/ZmqSocket.cpp src/UdpRxSocket.cpp src/sls_detector_exceptions.cpp + src/sls_detector_defs.cpp ) # Header files to install as a part of the library diff --git a/slsSupportLib/include/sls/ToString.h b/slsSupportLib/include/sls/ToString.h index bccf85e2e..79515df01 100644 --- a/slsSupportLib/include/sls/ToString.h +++ b/slsSupportLib/include/sls/ToString.h @@ -181,6 +181,23 @@ std::string ToString(const std::map &m) { return os.str(); } +/** + * Print a c style array + */ +template +std::string ToString(const T(&arr)[size]){ + std::ostringstream os; + os << '['; + if (size){ + size_t i = 0; + os << ToString(arr[i++]); + for (; i is excluded diff --git a/slsSupportLib/include/sls/sls_detector_defs.h b/slsSupportLib/include/sls/sls_detector_defs.h index 897f18a9b..1681bdbf0 100644 --- a/slsSupportLib/include/sls/sls_detector_defs.h +++ b/slsSupportLib/include/sls/sls_detector_defs.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #else // C includes @@ -472,19 +473,36 @@ typedef struct { int gates{0}; scanParameters scanParams{}; } __attribute__((packed)); +#endif + /** pattern structure */ +#ifdef __cplusplus struct patternParameters { - uint64_t word[MAX_PATTERN_LENGTH]{}; - uint64_t patioctrl{0}; - uint32_t patlimits[2]{}; - uint32_t patloop[6]{}; - uint32_t patnloop[3]{}; - uint32_t patwait[3]{}; - uint64_t patwaittime[3]{}; - } __attribute__((packed)); - +#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: diff --git a/slsSupportLib/include/sls/versionAPI.h b/slsSupportLib/include/sls/versionAPI.h index fb7b821a4..284092aa4 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -3,10 +3,10 @@ #define APILIB 0x201119 #define APIRECEIVER 0x201119 #define APIGUI 0x201119 -#define APICTB 0x201119 -#define APIGOTTHARD 0x201119 -#define APIGOTTHARD2 0x201119 -#define APIJUNGFRAU 0x201119 -#define APIMYTHEN3 0x201119 -#define APIMOENCH 0x201119 -#define APIEIGER 0x201119 +#define APICTB 0x201124 +#define APIGOTTHARD 0x201124 +#define APIGOTTHARD2 0x201124 +#define APIJUNGFRAU 0x201124 +#define APIMYTHEN3 0x201124 +#define APIMOENCH 0x201124 +#define APIEIGER 0x201124 diff --git a/slsSupportLib/src/sls_detector_defs.cpp b/slsSupportLib/src/sls_detector_defs.cpp new file mode 100644 index 000000000..fc00ecaab --- /dev/null +++ b/slsSupportLib/src/sls_detector_defs.cpp @@ -0,0 +1,97 @@ +#include "sls/sls_detector_defs.h" +#include "sls/logger.h" +#include "sls/ToString.h" +#include +#include +#include + +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(iss); + std::vector args = std::vector( + it, std::istream_iterator()); + + 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(args[1]); + if (addr >= MAX_PATTERN_LENGTH) { + throw RuntimeError("Invalid address for " + ToString(args)); + } + word[addr] = StringTo(args[2]); + } else if (cmd == "patioctrl") { + if (nargs != 1) { + throw RuntimeError("Invalid arguments for " + + ToString(args)); + } + patioctrl = StringTo(args[1]); + } else if (cmd == "patlimits") { + if (nargs != 2) { + throw RuntimeError("Invalid arguments for " + + ToString(args)); + } + patlimits[0] = StringTo(args[1]); + patlimits[1] = StringTo(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(args[1]); + int patloop2 = StringTo(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(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(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(args[1]); + } else { + throw RuntimeError("Unknown command in pattern file " + cmd); + } + } + } +} \ No newline at end of file diff --git a/slsSupportLib/tests/test-ToString.cpp b/slsSupportLib/tests/test-ToString.cpp index adeb53c50..1e7e16508 100644 --- a/slsSupportLib/tests/test-ToString.cpp +++ b/slsSupportLib/tests/test-ToString.cpp @@ -3,6 +3,7 @@ #include "sls/ToString.h" #include "sls/network_utils.h" #include "sls/sls_detector_defs.h" +#include "sls/container_utils.h" #include #include #include @@ -298,4 +299,27 @@ TEST_CASE("Streaming of slsDetectorDefs::scanParameters") { REQUIRE(oss.str() == "[enabled\ndac vth2\nstart 500\nstop 1500\nstep " "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(); + pat->patlimits[0] = 4; + pat->patlimits[1] = 100; + REQUIRE(ToString(pat->patlimits) == "[4, 100]"); + } \ No newline at end of file